Los rincones del API Win32: Archivos proyectados en memoria - Objeto FileMapping (Proyección de archivo)
27 de Agosto de 2005
Programación estructurada
Una vez que tenemos el objeto archivo disponible, podemos crear la proyección, o bien abrir una proyeción ya creada.
Los objetos proyección son otro tipo de objetos del núcleo, que están disponibles para el proceso que los creó y los sus procesos-hijo (si son heredables). En cualquier momento podremos crear un nuevo objeto proyección (a través de CreateFileMapping), abrir una proyección existente (con OpenFileMapping) o bien duplicar el descriptor (con DuplicateHandle).
La creación de un nuevo objeto proyección de archivo se hace a través de la función del API Win32 CreateFileMapping:
HANDLE CreateFileMapping( HANDLE hArchivo, archivo abierto LPSECURITY_ATTRIBUTES lpSeguridad, estructura de seguridad DWORD flProtección, protección de la proyección DWORD dwTamañoMaxHigh, tamaño máximo (32 bits más altos) DWORD dwTamañoMaxLow, tamaño máximo (32 bits más bajos) LPCTSTR lpNombre nombre de la proyección );
Como vemos, esta función tampoco es sencilla, pero tranquilos, que allá vamos con la explicación:
La función nos retorna un descriptor de objeto proyección si todo va bien. Si el nombre indicado ya está siendo utilizado, se retornará ERROR_ALREADY_EXISTS, y nos retornará el descriptor del objeto con ese nombre (como si hubieramos utilizado OpenFileMapping).
Si la función falla, se retorna NULL.
Como cualquier otro objeto del núcleo, una vez terminenos de utilizarlo, debemos cerrarlo a través de la función CloseHandle.
Otra opción que se nos ofrece es acceder a un objeto proyección que haya sido previamente creado, ya sea en nuestro mismo proceso o en otros.
Esto se realiza a través de la función OpenFileMapping:
HANDLE OpenFileMapping( DWORD dwTipoAcceso, el tipo de acceso BOOL bHeredarDescriptor, si se hereda a subprocesos LPCTSTR lpNombre nombre de la proyección a abrir );
Ahora la cosa es algo más sencilla:
Retorna el descriptor del objeto proyección, o NULL si no encuentra ningún descriptor con ese nombre o si las banderas indicadas en dwTipoAcceso no son compatibles.
Al igual que con CreateFileMapping, debemos cerrar el descriptor del objeto del núcleo, ya que al abrir un objeto ya existente en el núcleo, se incrementa un contador de referencias interno. Cerrando el descriptor (con CloseHandle), decrementaremos el contador de referencias, o destruimos definitivamente el objeto (si el contador de referencias llega a cero).
Los objetos proyección son otro tipo de objetos del núcleo, que están disponibles para el proceso que los creó y los sus procesos-hijo (si son heredables). En cualquier momento podremos crear un nuevo objeto proyección (a través de CreateFileMapping), abrir una proyección existente (con OpenFileMapping) o bien duplicar el descriptor (con DuplicateHandle).
La creación de un nuevo objeto proyección de archivo se hace a través de la función del API Win32 CreateFileMapping:
HANDLE CreateFileMapping( HANDLE hArchivo, archivo abierto LPSECURITY_ATTRIBUTES lpSeguridad, estructura de seguridad DWORD flProtección, protección de la proyección DWORD dwTamañoMaxHigh, tamaño máximo (32 bits más altos) DWORD dwTamañoMaxLow, tamaño máximo (32 bits más bajos) LPCTSTR lpNombre nombre de la proyección );
Como vemos, esta función tampoco es sencilla, pero tranquilos, que allá vamos con la explicación:
- hArchivo: indica el descriptor del archivo que hemos abierto previamente. El modo de apertura de este archivo debe ser compatible con el parámetro "flProtección" indicado más abajo.
Si este parámetro es 0xFFFFFFFF, se creará la proyección sobre el propio archivo de paginación del sistema, en vez de utilizar un archivo dedicado. Windows recomienda utilizar el archivo de paginación cuando sea posible, ya que las operaciones se ejecutarán más rápido. Esto es debido a que cuando cerramos la proyección, Windows intentará grabar a disco todas las páginas modificadas (llamadas dirty-pages, es decir: páginas sucias), y esto es una operación lenta. El sistema se ahorra este proceso si utilizamos el archivo de proyección en vez de un archivo físico en disco. - lpSeguridad: un puntero a la estructura de seguridad, al igual que en la función CreateFile.
- flProtección: indica el modo de acceso que se permitirá a las distintas vistas de esta proyección. Los modos disponibles son:
- PAGE_READONLY: permite acceso de sólo lectura a los datos de la proyección. Cualquier intento de modificar una página proyectada, desembocará en una violación de acceso. Los archivos utilizados para este tipo deben abrirse al menos con la bandera GENERIC_READ.
- PAGE_READWRITE: permite acceso de lectura/escritura a los datos de la proyección. Los archivos proyectados con esta bandera deben abrirse con los modificadores GENERIC_READ y GENERIC_WRITE.
- PAGE_WRITECOPY: permite acceso de lectura/escritura a los datos de la proyección, pero utilizando el método "Copia con escritura". Los archivos proyectados con esta bandera deben abrirse con los modificadores GENERIC_READ y GENERIC_WRITE.
Además de las banderas de protección, se puede combinar cualquier número de las siguientes banderas:
- SEC_COMMIT: compromete espacio físico en memoria, o en el archivo de paginación, para todas las páginas de la proyección. Este es el valor por defecto.
- SEC_RESERVE: reserva memoria para todas las páginas de la proyección sin comprometer almacenamiento físico. Estas páginas puede comprometerse con alguna llamada posterior a VirtualAlloc. Esta bandera sólo es válida cuando se utiliza el descriptor de archivo 0xFFFFFFFF, es decir, el propio archivo de paginación del sistema.
- SEC_IMAGE: la proyección que se está realizando es la imagen de un archivo ejecutable o librería DLL. Esta bandera no puede aparecer combinada con ninguna otra.
- dwTamañoMaxHigh: contiene los 32 bits más altos del tamaño máximo permitido para la proyección. Si se indica un cero en este parámetro, se utilizará el valor pasado en dwTamañoMaxLow.
- dwTamañoMaxLow: contiene los 32 bits más bajos del tamaño máximo permitido para la protección. Si el valor de dwTamañoMaxHigh y dwTamañoMaxLow es cero, se utilizará el tamaño del archivo pasado en el primer parámetro, o lo que es lo mismo, el valor retornado por GetFileSize(hArchivo), aunque esto no es válido si estamos proyectando sobre el archivo de intercambio (hArchivo = 0xFFFFFFFF).
Si el tamaño total (el valor combinado de dwTamañoMaxHig y dwTamañoMaxLow) es mayor que el tamaño del archivo, el archivo en disco crecerá hasta el tamaño indicado.
Si el tamaño total es menor que el tamaño del archivo, sólo se tendrá acceso a los datos dentro del rango indicado por la combinación de dwTamañoMaxHigh y dwTamañoMaxLow.
Es importante calcular o estimar bien el tamaño que queremos darle al archivo, ya que una vez creada la proyección, no podremos modificar su tamaño. Un buen sistema para esto es crear la proyección de un tamaño lo suficientemente grande para que entren todos los datos provistos. Al finalizar el trabajo, cerrar la proyección, calcular el tamaño real que debería tener, y volver a crear otra proyección del tamaño justo, símplemente para ajustar el tamaño del fichero. - lpNombre: indica un puntero a la cadena que contiene el nombre asignado a la proyección. Este nombre se utilizará para que otros procesos puedan acceder al objeto. Se permite cualquier caracter expecto la barra invertida "\". Para crear un objeto de proyección sin nombre, se debe indicar NULL en este parámetro.
La función nos retorna un descriptor de objeto proyección si todo va bien. Si el nombre indicado ya está siendo utilizado, se retornará ERROR_ALREADY_EXISTS, y nos retornará el descriptor del objeto con ese nombre (como si hubieramos utilizado OpenFileMapping).
Si la función falla, se retorna NULL.
Como cualquier otro objeto del núcleo, una vez terminenos de utilizarlo, debemos cerrarlo a través de la función CloseHandle.
Otra opción que se nos ofrece es acceder a un objeto proyección que haya sido previamente creado, ya sea en nuestro mismo proceso o en otros.
Esto se realiza a través de la función OpenFileMapping:
HANDLE OpenFileMapping( DWORD dwTipoAcceso, el tipo de acceso BOOL bHeredarDescriptor, si se hereda a subprocesos LPCTSTR lpNombre nombre de la proyección a abrir );
Ahora la cosa es algo más sencilla:
- dwTipoAcceso: puede ser cualquier combinación de las siguientes banderas:
- FILE_MAP_WRITE: Se abre la proyección para lectura/escritura. La proyección original tuvo que ser creada con la bandera PAGE_READWRITE.
- FILE_MAP_READ: Se abre la proyección para sólo lectura.
- FILE_MAP_ALL_ACCESS: Lo mismo que FILE_MAP_WRITE.
- FILE_MAP_COPY: Se abre la proyección para lectura/escritura y "Copia con escritura". La primera vez que se modifican los datos de una página, se hace una copia de esta y se realizan las modificaciones sobre la copia. De este modo, el archivo original nunca será modificado. La proyección original ha tenido que ser creada con la bandera PAGE_WRITECOPY.
- bHeredarDescriptor: indica si el descriptor retornado se heredará a los subprocesos. Si un descriptor es heredable, cualquier proceso-hijo podrá tener acceso a él, permitiendo así otro sistema de comunicación entre procesos. De esto hablaremos más adelante, cuando tratemos el tema de comunicación entre procesos.
- lpNombre: un puntero a cadena con el nombre de la proyección que queremos abrir.
Retorna el descriptor del objeto proyección, o NULL si no encuentra ningún descriptor con ese nombre o si las banderas indicadas en dwTipoAcceso no son compatibles.
Al igual que con CreateFileMapping, debemos cerrar el descriptor del objeto del núcleo, ya que al abrir un objeto ya existente en el núcleo, se incrementa un contador de referencias interno. Cerrando el descriptor (con CloseHandle), decrementaremos el contador de referencias, o destruimos definitivamente el objeto (si el contador de referencias llega a cero).
Valora este capítulo:
Autor y licencia de 'Los rincones del API Win32: Archivos proyectados en memoria - Objeto FileMapping (Proyección de archivo)'
|
Opiniona sobre 'Los rincones del API Win32: Archivos proyectados en memoria - Objeto FileMapping (Proyección de archivo)' (1)
Tu nombre debe tener tres caracteres como mínimo.
Es necesario que te des de alta con una cuenta de correo válida.
Es necesario que te des de alta con una cuenta de correo válida.
El contenido del título de tu opinión debe tener tres caracteres como mínimo.
Es obligatorio que selecciones una valoración del recurso.
El contenido del comentario de tu opinión debe tener tres caracteres como mínimo.
Opina sobre este tutorial |
Wikis relacionados con 'Los rincones del API Win32: Archivos proyectados en memoria - Objeto FileMapping (Proyección de archivo)'
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 »
Aprenderás a acelerar el arranque de tu ordenador y a eliminar algunos virus que se...
Más »
¿Qué es una imagen ISO? Las imágenes ISO son archivos que siguen los estándares ISO-9660...
Más »

