Debe introducir al menos 3 caracteres en el buscador.
Inicio / Wikis / Tutoriales / Los rincones del API Win32: Archivos proyectados en memoria - Herencia de descriptores

Los rincones del API Win32: Archivos proyectados en memoria - Herencia de descriptores

 ***-- (1 opiniones)
Creative Commons Tutorial de Juan Manuel - 27 de Agosto de 2005
Temas Relacionados: Programación estructurada
15. Herencia de descriptores
Este caso se basa en la característica que nos ofrece Windows de que un proceso pueda crear procesos hijos (o subprocesos). En la documentación de Win32 se define proceso-hijo como "un proceso que se crea por otro proceso, llamado proceso-padre". La definición no es muy buena (yo diría que es bastante mala), pero para ir tirando nos puede servir. Para aclarar, podemos decir que cada vez que desde nuestros programas llamamos la función CreateProcess, estamos creando un proceso-hijo.

Ya sabemos que al aplicar herencia de descriptores, en realidad lo que se hace es copiar la entrada correspondiente de la tabla de objetos del núcleo e incrementar en uno el contador de referencias. Lo único que debemos hacer, es informar al nuevo proceso del descriptor del objeto, para que pueda acceder a él.

El modo de comunicar estos procesos "cosanguíneos" es a través de los descriptores de objetos del núcleo.

El esquema es el siguiente:

  1. Crear una proyección de archivo (como ya sabemos hacer), indicando TRUE en el campo bHeredarDescriptor de la estructura SECURITY_ATTRIBUTES.
  2. Crear un proceso hijo llamando a CreateProcess desde el proceso padre.
  3. Notificar al proceso recién creado (el hijo). Para esto se puede utilizar cualquier sistema de notificación, como mensajes de ventana, variables de entorno, etc.
  4. Cuando hayamos terminado de utilizar el objeto, debemos llamar a CloseHandle, tanto en los procesos hijos como en el padre.



Duplicación de descriptores

¿Alguien pensaba que esto era todo? Pues no, en la plataforma Win32 siempre hay alguna sorpresa. El tercer y último método para compartir información se basa en la duplicación de descriptores.

Básicamente es lo mismo que la herencia de descriptores, pero la copia de descriptores se hace en el momento que queramos, y no durante la creación del proceso.

La duplicación se hace a través de la siguiente función:

BOOL DuplicateHandle( HANDLE hProcesoOrigen, HANDLE hDescriptorOrigen, HANDLE hProcesoDestino, LPHANDLE lpDescriptorDestino, DWORD dwAcceso, BOOL bHeredarDescriptor, DWORD dwOpciones );

Que nadie se asuste que la función es sencilla:

  • hProcesoOrigen: descriptor del proceso que contiene el descriptor del objeto. Este valor se puede obtener llamando a la función GetCurrentProcess (para obtener el descriptor del proceso llamante), o la función OpenProcess (para abrir cualquier otro proceso).
  • hDescriptorOrigen: el descriptor del objeto que queremos copiar.
  • hProcesoDestino: descriptor del proceso donde se copiará el objeto. Este puede ser el mismo o distinto valor que hProcesoOrigen.
  • lpDescriptorDestino: un puntero donde se almacenará el valor del nuevo descriptor. Si se pasa un NULL, el descriptor se duplicará, pero no se copiará su valor a este parámetro.
  • dwAcceso: indica el tipo de acceso que se permitirá al objeto recién copiado. Los valores permitidos dependen del tipo de objeto que estemos copiando, en nuestro caso, con los objetos proyección de archivo, se permiten los mismos valores que el parámetro dwTipoAcceso de la función OpenFileMapping.
  • bHeredarDescriptor: indica si el objeto recién copiado será heredable.
  • dwOpciones:indica opciones especiales, pudiendo utilizarse cualquier combinación de los siguientes valores:
    • DUPLICATE_CLOSE_SOURCE: Cierra el descriptor (con CloseHandle) del objeto origen.
    • DUPLICATE_SAME_ACCESS: Se ignora el parámetro dwAcceso y se utiliza el mismo valor que en el objeto origen.

La función retorna TRUE si todo ha ido bien, o FALSE en caso contrario.

Para compartir datos entre procesos utilizando esta técnica podemos optar por dos enfoques: duplicando el descriptor desde el proceso origen, o desde el proceso hijo.

En el primer caso, los pasos a seguir son los siguientes:

  1. Obtener el descriptor del proceso destino. Normalmente esto lo obtendremos a través de la función CreateProcess, a la hora de crear el proceso-hijo.
  2. Duplicar el descriptor de la proyección desde el proceso origen.
  3. Notificar al proceso destino de su nuevo descriptor.
  4. Ambos procesos (el origen y el destino), deben cerrar los objetos a través de la función CloseHandle.

En el segundo caso (duplicar desde el destino), los pasos a seguir son:

  1. Obtener el descriptor del proceso origen. Para ello necesitamos el identificador de proceso (Process ID) y obtener el descriptor a través de la función OpenProcess. Una llamada típica suele ser algo así como:
    hProcess = ::OpenProcess( PROCESS_DUP_HANDLE, FALSE, ProcessID );
  2. Duplicar el descriptor de la proyección desde el proceso destino.
  3. Ambos procesos deben cerrar los descriptores.

Este es el sistema seguido en el ejemplo de C++Builder.
Autor y licencia de 'Los rincones del API Win32: Archivos proyectados en memoria - Herencia de descriptores'
Juan Manuel Extraído de: http://www.lawebdejm.com

Creative Commons License
Esta obra está bajo una licencia de Creative Commons.
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.

Wikis relacionados con 'Los rincones del API Win32: Archivos proyectados en memoria - Herencia de descriptores'

Curso que profundiza en el gestor de montones (o montículos) dentro de Win32, así como... Más »
Aprenderás a utilizar uno de los mejores clientes P2P que actualmente existe (o sobrevive), a... Más »
Con este articulo serás capaz de instalar el eMule en tu ordenador y comenzar a... Más »
El Poeta posee la extraña capacidad para hablar sobre los orígenes. Digo "extraña" porque no... Más »
Si es correcta la sentencia con la cual Nietzsche afirma que “Todo lo que es... Más »
¿Estás seguro de que deseas eliminar este capítulo?