elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Ingresar Registrarse
18 Noviembre 2008, 11:11  



+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++
| | |-+  WIN32 API: el registro
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Imprimir
Autor Tema: WIN32 API: el registro  (Leído 282 veces)
EL PRINTERO

Desconectado Desconectado

Mensajes: 72



Ver Perfil
WIN32 API: el registro
« en: 02 Mayo 2008, 18:57 »

Win32: API: El registro

Windows ideó una novedosa forma para organizar información sobre su propio sistema y programas, y posteriormente la hizo accesible para las aplicaciones. Hablamos del registro de Windows, o simplemente "registry". Esto ha hecho muy útil para las aplicaciones el poder manipular su información indistintamente del directorio donde son instaladas, además de poder proteger (o al menos "esconder") su información.

En fin, vamos al grano pués. Pensaba dar más información al respecto, pero creo que todos conocemos al registry, ¿no? Entonces no se diga más.

Bueno, solo una cosa. El registry está organizado de forma jerárquica. La máxima jerarquía se define por un conjunto de "llaves", las cuáles varían de acuerdo al sistema operativo, pero actualmente (y en Windows XP) podemos hablar de cinco.

HKEY_CLASSES_ROOT. Aquí se guarda información relacionada con los componentes COM y derivados, así como información sobre los tipos de archivos. Usualmente nunca nos meteremos a esa carpeta.

HKEY_CURRENT_USER. En esta carpeta se guarda información del usuario que actualmente se ha loggeado al sistema. Muy útil cuando queremos guardar "perfiles" dependiendo del usuario.

HKEY_LOCAL_MACHINE. En este nodo se guarda información relacionada con la máquina, es decir, toda la información de los programas que no dependan de un usuario en particular debe ir aquí.

HKEY_USERS. Aquí se guarda información sobre los diferentes usuarios del sistema. Lo usa Windows de forma interna y no deberíamos de meterle mano.

HKEY_CURRENT_CONFIG. Tiene la información sobre la actual configuración de Windows (fuentes, colores, vistas, etc). Nuestras narices deberían de mantenerse alejadas de aquí, en la medida de lo posible.

Así pués, el registro es una estructura de árbol. Debajo de los cinco nodos anteriormente mencionados se guardan "llaves", que pueden tener un valor asociado o bien más llaves hijas. Entonces lo que tenemos que hacer para manipular datos del registro, es abrir la llave, leer o escribir, y cerrar la llave. Obvio Windows nos provée funciones para ello. Antes de mencionarlas, empero, quiero recordarles que el acceso a estas llaves está regido por los permisos que un usuario tenga. Es decir, si el usuario bajo el cuál se ejecuta la aplicación intenta escribir una llave en el registry y que no tenga permisos, la llamada a la función mandará un error.

Ahora sí veamos cómo funciona el asunto. Vamos a poner un ejemplo. Supongamos que tenemos una clase de configuración, del sistema Super Sales, y queremos que al mandarse llamar el método Load se carguen los diferentes valores. No se rían que el ejemplo es real y lo saqué de un código que ando escribiendo en estas fechas. Mi método Load tiene la siguiente forma:


Código:
void Configuration::Load()
{
    try
    {
        _path = GetValue(_T("path"));
        _dsn = GetValue(_T("dsn"));
        _dbuser = GetValue(_T("dbuser"));
        _dbpassword = GetValue(_T("dbpassword"));
        _language = GetValue(_T("language"));
    }
    catch (const Exception& ex)
    {
        _corrupted = true;
        throw ex;
    }
}


Obvio lo que nos interesa está en GetValue, la cuál se va a conectar al registroy bajar el valor que tenga la llave correspondiente, que se pasa como parámetro. Dado que estos datos se guardan siempre en HKEY_LOCAL_MACHINE bajo Software/Dark Software/Super Sales, solo necesito como parámetro el nombre de la llave misma. La función GetValue luce así:

Código:
CString Configuration::GetValue(const CString& name)
{
    TCHAR buffer[MAX_PATH];
    DWORD size;
    HRESULT ret;
    HKEY key;

    ret = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Dark Software\\Super Sales\\"), NULL, KEY_READ, &key);
    if (ret != ERROR_SUCCESS)
        throw Exception(IDS_ERR_SYS_CONFIGFILE, __FILE__, __LINE__);

    size = sizeof(TCHAR) * MAX_PATH;
    ret = ::RegQueryValueEx(key, name, NULL, NULL, (LPBYTE)buffer, &size);
    if (ret != ERROR_SUCCESS)
        throw Exception(IDS_ERR_SYS_CONFIGFILE, __FILE__, __LINE__);

    ::RegCloseKey(key);

    return buffer;
}


Más claro ni el agua, ¿verdad? OK. De todas formas lo explico. La función RegOpenKeyEx se encarga --sorpresa sorpresa-- de abrir una llave del registro. El primer parámetro es una macro que identifica el nodo del registry sobre el cuál tendremos que buscar. En mi caso, empleo HKEY_LOCAL_MACHINE porque son valores que deben estar disponibles para la aplicación en cualquier caso. Si solo fuera información de un usuario (como preferencias) hubiera elegido HKEY_CURRENT_USER. El segundo parámetro es el path que me llevará hasta la llave que contiene los valores que ando buscando. Como les dije, éste es Software\Dark Software\Super Sales. El tercer parámetro siempre tiene que ser nulo. Quizás lo ocupen en algún futuro, pero por ahorita siempre deberá ser NULL. Con el cuarto parámetro especifico la operación que voy a realizar así como los parámetros de seguridad. En este caso vamos a leer, así que le pasamos KEY_READ, mientras que KEY_WRITE se usa para escribir. Hay otros parámetros, pero solo estos dos son los más importantes. Los otros o son solo de sistema o forman parte de alguno de los dos mencionados (KEY_WRITE se define como STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY). Por supuesto, podemos emplear KEY_ALL_ACCESS si queremos especificar todas las opciones (lectura y escritura). La función regresa ERROR_SUCCESS si todo salió bien, o un código de error si salió mal. Las causas por las que puede fallar son esencialmente dos: o no se tienen permisos suficientes, o las llaves proporcionadas no existen. ¡Ah! Se me olvidaba que hay un quinto parámetro. Este es un handle a la llave que vamos a abrir y obvio es de lo más importante. Habrán vissto que el tipo de dato es HKEY. Tenlo en cuenta para un momentín.

Luego tenemos que obtener el valor. Es decir, ya tenemos una llave abierta, ahora debemos buscar las sub-llaves y sacar el valor. Obvio, emplearemos
RegQueryValueEx. El primer parámetro es la llave que abrimos con RegOpenKeyEx, que les dije que tuvieran en cuenta. El segundo parámetro es el nombre de la sub-llave que queremos obtener (y que en este ejemplo, se pasa como parámetro). El tercer parámetro es reservado y siempre deberá ser nulo. El cuarto parámetro es un puntero a un DWORD y nos va a indicar el tipo de dato (REG_SZ si es una cadena de texto, REG_BINARY si es un conjunto binario, REG_DWORD si es un número, etc).Finalmente, el quinto parámetro es un puntero a el búfer en el que vamos a obtener nuestro valor (el tipo de dato variará de acuerdo al tipo de la sub-llave; en nuestro caso es un puntero a caracter dado que se trata de un REG_SZ), y el sexto parámetro es de entrada y de salida, y especifica el tamaño del búfer, y de salida especifica el tamaño que se escribió. La función nos regresa ERROR_SUCCESS si todo salió chido, ERROR_FILE_NOT_FOUND si no se encontró la sub-llave, o ERROR_MORE_DATA si el tamaño del búfer no fue lo suficientemente grande.

Por último, empleamos RegCloseKey para cerrar la llave. Y listo. Voilà. Sehr gut. Facilito, ¿no?

El siguiente pedazo de código es la función Save que se encarga de guardar los cambios en el registro. Es muy similar a su contraparte:


Código:
void Configuration::Save()
{
    try
    {
        SetValue(_T("path"), _path);
        SetValue(_T("dsn"), _dsn);
        SetValue(_T("dbuser"), _dbuser);
        SetValue(_T("dbpassword"), _dbpassword);
        SetValue(_T("language"), _language);
    }
    catch (const Exception& ex)
    {
        _corrupted = true;
        throw ex;
    }
}


Al igual que Load, la llamada al registro queda en manos de una función auxiliar, cuyo código es el siguiente:

Código:
void Configuration::SetValue(const CString& name, const CString& value)
{
    TCHAR buffer[MAX_PATH];
    DWORD size;
    HRESULT ret;
    CString str;

    HKEY key;

    ret = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Dark Software\\Super Sales\\"), NULL, KEY_SET_VALUE, &key);
    if (ret != ERROR_SUCCESS)
        throw Exception(IDS_ERR_SYS_CONFIGFILE, __FILE__, __LINE__);

    _tcscpy(buffer, name);

    size = sizeof(TCHAR) * MAX_PATH;
    str.Format(_T("Software\\Dark Software\\Super Sales\\%s"), name);
    ret = ::RegSetValueEx(HKEY_LOCAL_MACHINE, str, NULL, REG_SZ, (BYTE*)buffer, size);
    if (ret != ERROR_SUCCESS)
        throw Exception(IDS_ERR_SYS_CONFIGFILE, __FILE__, __LINE__);

    ::RegCloseKey(key);
}


La primera llamada ya la conocen. Abrimos la llave con RegOpenKeyEx. La única diferencia, de hecho, es que ahora llamamos a RegQueryValue. A diferencia de cuando buscábamos leer el valor, aquí no es necesario abrir llave alguna. De hecho, la llamada se hace directamente desde RegSetValueEx. Pero empleamos RegOpenKeyEx y RegCloseKey para cerciorarnos de que la llave existe. El primer parámetro es el nodo (HKEY_LOCAL_MACHINE en este caso). La segunda es el llamado a la dirección completa (llave + sub-llave) donde queremos guardar el valor. El tercer parámetro será siempre nulo, el cuarto indica el tipo de dato a guardar, el quinto el valor que queremos guardar y, finalmente, el sexto indica el tamaño de nuestro búfer. Regresa ERROR_SUCCESS si todo salió bien.

Bueno, como has visto, es una forma fácil de guardar datos y sin tener tanto embrollo de guardarlos en un archivo de configuración. Pero ¿qué pasa si queremos crear llaves y sub-llaves? ¿O modificarlas? Bueno, eso lo discutiremos en la siguiente entrega de este blog.

Publicado por: Fernando Arturo Gómez Flores
ORIGEN: http://kithkanan-programacionencpp.blogspot.com/

« Última modificación: 02 Mayo 2008, 18:59 por EL PRINTERO » En línea

TIGRE CAPO
CHACA GATO
Chino Moreno

Desconectado Desconectado

Mensajes: 93


White Pony [ ! ]


Ver Perfil
Re: WIN32 API: el registro
« Respuesta #1 en: 02 Mayo 2008, 18:59 »

Es un buen tutorial, aunque estaria mejor si estuviese desarrollado plenamente con las APIs de Windows, sin utilizar C++ como medio.
En línea



¿Necesitas información sobre una función que comenté? Lo mas seguro es que la encuentres en MSDN
Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.388


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: WIN32 API: el registro
« Respuesta #2 en: 02 Mayo 2008, 19:18 »

En línea

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este"
Juan Domingo Peron
Chino Moreno

Desconectado Desconectado

Mensajes: 93


White Pony [ ! ]


Ver Perfil
Re: WIN32 API: el registro
« Respuesta #3 en: 02 Mayo 2008, 20:05 »

Se supone que estos tutoriales son para quienes se inician con las APIs de Windows, por lo que les van a resultar mas sencillos que mirar la informacion directamente en MSDN.
En línea



¿Necesitas información sobre una función que comenté? Lo mas seguro es que la encuentres en MSDN
Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.388


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: WIN32 API: el registro
« Respuesta #4 en: 02 Mayo 2008, 20:24 »

Se supone que estos tutoriales son para quienes se inician con las APIs de Windows, por lo que les van a resultar mas sencillos que mirar la informacion directamente en MSDN.

¿Cuales tutoriales? En fin, doy por hecho que no entraste al enlace, no solo hay una referencia sino que ademas hay una exlicacion (About) y ejemplos (About y Using). Igual agradezco tu opinion y dedicacion al foro.
En línea

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este"
Juan Domingo Peron
Chino Moreno

Desconectado Desconectado

Mensajes: 93


White Pony [ ! ]


Ver Perfil
Re: WIN32 API: el registro
« Respuesta #5 en: 02 Mayo 2008, 20:28 »

Cuando digo "estos tutoriales" me refiero porsupuesto al unico tutorial que podria referirme en este contexto, es decir el que puedes leer en esta misma pagina.

A partir de esta pequeña explicacion puedes reescribir todo tu post.
En línea



¿Necesitas información sobre una función que comenté? Lo mas seguro es que la encuentres en MSDN
Eternal Idol N&P

Desconectado Desconectado

Mensajes: 1.388


Assembly (x86/x64), C/C++, Kernel Mode (WDM/WDF)


Ver Perfil WWW
Re: WIN32 API: el registro
« Respuesta #6 en: 02 Mayo 2008, 20:31 »

Cuando digo "estos tutoriales" me refiero porsupuesto al unico tutorial que podria referirme en este contexto, es decir el que puedes leer en esta misma pagina.

A partir de esta pequeña explicacion puedes reescribir todo tu post.

Por supuesto (la necesitaba verdaderamente) y ahora vos podes aprovechar para responderme y publicar una mensaje mas de gran utilidad.
En línea

http://www.nacionalypopular.com/
http://www.lucheyvuelve.com.ar/

"La economia nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de este"
Juan Domingo Peron
Chino Moreno

Desconectado Desconectado

Mensajes: 93


White Pony [ ! ]


Ver Perfil
Re: WIN32 API: el registro
« Respuesta #7 en: 02 Mayo 2008, 20:58 »

La verdad no entiendo muy bien que quieres decir con tu ultimo post. Es sarcasmo lo que denota tu tono o tal vez intentas decirme otra cosa?
En línea



¿Necesitas información sobre una función que comenté? Lo mas seguro es que la encuentres en MSDN
Páginas: [1] Ir Arriba Imprimir 
Ir a:  







Consolas     La Web de Goku     MilW0rm     MundoDivx

Hispabyte     Truzone     TodoReviews     ZonaPhotoshop

Foros de ayuda    Yashira.org    Videojuegos    indetectables.net   

Noticias Informatica    Seguridad Informática    ADSL    eNYe Sec

Todas las webs afiliadas están libres de publicidad engañosa.

Powered by SMF 1.1.7 | SMF © 2006-2008, Simple Machines LLC