Problema removiendo clave de registro

Iniciado por Kaxperday, 15 Abril 2016, 15:53 PM

0 Miembros y 1 Visitante están viendo este tema.

Kaxperday

Código (cpp) [Seleccionar]

bool RemoveFromRegistry(bool privileges, LPCWSTR keyName)
{
HKEY hKeyOutput;
HKEY hKeyInput;
DWORD options;
BOOL ret = FALSE;

hKeyInput = (privileges) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
options = (arquitecturax64()) ? KEY_ALL_ACCESS | KEY_WOW64_64KEY : KEY_ALL_ACCESS | KEY_WOW64_32KEY;

if (RegOpenKeyEx(hKeyInput, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, options, &hKeyOutput) == NO_ERROR)
{
//options = (arquitecturax64()) ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
if (RegDeleteKeyEx(hKeyOutput, keyName, options, NULL) == NO_ERROR)
{
ret = TRUE;
}
RegCloseKey(hKeyInput);
RegCloseKey(hKeyOutput);
}
return ret;
}


La clave esta creada y el nombre es el mismo que cuando la creé "pepito", el caso que cuando la voy a eliminar falla el RegDeleteKeyEx y no se porqué, ¿qué puedo estar haciendo mal?.

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

¿Qué parte falla?
-¿Entra al if del open?
-¿Comprobaste que la clave abierta es la correcta?
-¿Entra al if del delete?

-En caso de que haya algún error, ¿qué error da GetLastError?

HardForo

Estoy de acuerdo con que descartes cosas sino dificil
HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *

Kaxperday

#3
Cita de: ivancea96 en 15 Abril 2016, 16:54 PM
¿Qué parte falla?
-¿Entra al if del open?
-¿Comprobaste que la clave abierta es la correcta?
-¿Entra al if del delete?

-En caso de que haya algún error, ¿qué error da GetLastError?

Lo probé todo lo que dijistes pero no lo puse en el código.

Entra en el if de RegOpenKeyEx pero no en el de RegDeleteKeyEx ya que da error.

También probé a llamar a GetLastError() pero returnaba 0, lo puse justo detrás del if del delete.

Y poco más, la dirección de la clave abierta debe de ser la misma ya que para crearla uso el mismo código para abrirla (el mismo open). No entiendo que puede fallar :/

Con permisos ocurre lo mismo.

Iré mirando, gracias por las respuestas, y a ver si lo encuentro solución.

Saludos.

Edito: Mejor os paso el código con el "debugger" XD:

Código (cpp) [Seleccionar]

bool RemoveFromRegistry(bool privileges, LPCWSTR keyName)
{
HKEY hKeyOutput;
HKEY hKeyInput;
DWORD options;
BOOL ret = FALSE;
//poner HKEY_USERS
hKeyInput = (privileges) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
options = (arquitecturax64()) ? KEY_ALL_ACCESS | KEY_WOW64_64KEY : KEY_ALL_ACCESS | KEY_WOW64_32KEY;

if (RegOpenKeyEx(hKeyInput, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, options, &hKeyOutput) == NO_ERROR)
{
cout << "hola1";
options = (arquitecturax64()) ? KEY_WOW64_64KEY : KEY_WOW64_32KEY;
if (RegDeleteKeyEx(hKeyOutput, keyName, options, NULL) == NO_ERROR)
{
cout << "hola2";

ret = TRUE;
}
RegCloseKey(hKeyInput);
RegCloseKey(hKeyOutput);
cout << GetLastError();
}
cout << "hola3";
return ret;
}


Salida:

Citar
hola10hola3
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Prueba a poner GetLastError después del RegDeleteKeyEx. Antes de los RegClsoeKey.
Si sale un error diferente de 0, mira su significado con FormatMessage.

Si sigues sin obtener error, asegúrate que la primera clave es la correcta: antes del Delete, enumera las sub-claves para asegurarte de que existe. Si no quieres enumerar, al menos trata de abrirla.

Abre como administrador, no vaya a ser un error trivial.

Kaxperday

#5
Cita de: ivancea96 en 15 Abril 2016, 21:31 PM
Prueba a poner GetLastError después del RegDeleteKeyEx. Antes de los RegClsoeKey.
Si sale un error diferente de 0, mira su significado con FormatMessage.

Si sigues sin obtener error, asegúrate que la primera clave es la correcta: antes del Delete, enumera las sub-claves para asegurarte de que existe. Si no quieres enumerar, al menos trata de abrirla.

Abre como administrador, no vaya a ser un error trivial.

Hola ivancea, gracias por la respuesta.

Se me olvidó mencionar anteriormente que no tiene privilegios la aplicación, pero es que no los debería de necesitar, para crear la clave y leerla en HKEY_CURRENT_USER no necesita privilegios, y para borrarla pues debería de ser igual (ya que también he probado a hacerlo intentandola borrar con privilegios y falla también, luego los privilegios no son el problema).

He probado como dijistes a listar el directorio (hacer un enum RegEnumKeyEx), en este caso para "HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run" y ha mostrado las claves con éxito incluida la que quiero borrar "pepito" :)

Luego puedo escribir en HKEY_CURRENT_USER con RegSetValueEx y leer sus variables para comprobar si existen con RegGetValue, pero el RegDeleteEx... ni con privilegios ni sin ellos es capaz de borrar en HKEY_CURRENT_USER ni en HKEY_LOCAL_MACHINE.

He probado a llamarla de 3 maneras:

Citar
RegDeleteKeyEx(hKeyOutput, keyName, options, RRF_RT_REG_SZ)
RegDeleteKeyEx(hKeyOutput, keyName, options, REG_SZ)
RegDeleteKeyEx(hKeyOutput, keyName, options, NULL)

Todas sin éxito, la clave creada es de tipo REG_SZ.

Y es que no sé, mirad esta es la funcion que ancla al registro y crea la clave que luego procedemos a borrar, funciona perfectamente:

Código (cpp) [Seleccionar]

bool AttachToRegistry(bool privileges, LPCWSTR keyName)
{
WCHAR processPath[MAX_PATH];
HKEY hKeyOutput;
HKEY hKeyInput;
DWORD options;
BOOL ret = FALSE;

hKeyInput = (privileges) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
options = (arquitecturax64()) ? KEY_ALL_ACCESS | KEY_WOW64_64KEY : KEY_ALL_ACCESS | KEY_WOW64_32KEY;

if (GetModuleFileName(NULL, processPath, MAX_PATH))
{
std::wstring p = L"\"" + std::wstring(processPath) + L"\"";

if (RegOpenKeyEx(hKeyInput, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, options, &hKeyOutput) == NO_ERROR)
{
if (RegSetValueEx(hKeyOutput, keyName, NULL, REG_SZ, (LPBYTE)p.c_str(), p.length()*2) == NO_ERROR)
{
ret = TRUE;
}
RegCloseKey(hKeyInput);
RegCloseKey(hKeyOutput);
}
}

return ret;
}


Como la de borrar es una copia de la misma, ha diferencia de que en vez de llamar a RegSetValueEx llama a RegDeleteKeyEx, probaré con RegDeleteKey y os cuento.

Saludos.

Edito: Acabo de probar con RegDeleteKey el resultado es el mismo, no funciona ni con ni sin permisos, no hay manera de borrarla, ¿algún hook?.

En el main mismo:

Código (cpp) [Seleccionar]

if (RegDeleteKey(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\pepito") == ERROR_SUCCESS)
{
cout << "Borrado";
}
cout << GetLastError();


Muestra 0, es decir no borra ni entra en el if y no detecta error.

Probaré con un tercer método que si espero que funcione, con "system", ahora os digo.

Con batch da error:, con y sin permisos:

Código:
Código (cpp) [Seleccionar]
system("REG DELETE HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\pepito");

"¿Desea eliminar permanentemente la clave del Registro HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\pepito (Sí/No)? si
ERROR: El sistema no ha podido encontrar la clave o el valor del Registro
especificados."

Me dice que no la encuentra, pero bien que aparece en regedit y al hacer el enum. :"DDD
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Utiliza FormatMessage para ver el error que lanza. Guarda el retorno en una variable en vez de ponerlo directamente en wl if.

Y recuerda que el último parámetro de RegDeleteKeyEx es reservado y debe ser NULL.

Kaxperday

#7
Cita de: ivancea96 en 16 Abril 2016, 11:51 AM
Utiliza FormatMessage para ver el error que lanza. Guarda el retorno en una variable en vez de ponerlo directamente en wl if.

Y recuerda que el último parámetro de RegDeleteKeyEx es reservado y debe ser NULL.

Wow sorprendente resultado, desconocía la función FormatMessage.

Código (cpp) [Seleccionar]

LSTATUS l = RegDeleteKeyW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\pepito");
LPTSTR errorText = NULL;

FormatMessageW(
// use system message tables to retrieve error text
FORMAT_MESSAGE_FROM_SYSTEM
// allocate buffer on local heap for error text
| FORMAT_MESSAGE_ALLOCATE_BUFFER
// Important! will fail otherwise, since we're not
// (and CANNOT) pass insertion parameters
| FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,    // unused with FORMAT_MESSAGE_FROM_SYSTEM
l,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&errorText,  // output
0, // minimum size for output buffer
NULL);   // arguments - see note

if (NULL != errorText)
{
// ... do something with the string `errorText` - log it, display it to the user, etc.
wcout << errorText;
// release memory allocated by FormatMessage()
LocalFree(errorText);
errorText = NULL;
}


Salida: "El sistema no puede encontrar el archivo especificado." Con y sin permisos no lo encuentra. Y yo me pregunto, ¿como no lo encuentra si esta todo bien? ¿quizás porque use unicode?, he probado también a eliminar otra clave del mismo directorio "Spotify", y el resultado ha sido el mismo, que no lo encuentra. :"D
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Si tal, prueba a borrar con RegDeleteTree.

Kaxperday

Cita de: ivancea96 en 16 Abril 2016, 12:19 PM
Si tal, prueba a borrar con RegDeleteTree.

Mismo resultado:

Código (cpp) [Seleccionar]

if (RegDeleteTree(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\pepito") == NO_ERROR){
cout << "conseguido";
return true;
}


Caso perdido, que se quede con el registro, se le regalo :"D
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.