Compartir a través de


Función CreateILockBytesOnHGlobal (coml2api.h)

La función CreateILockBytesOnHGlobal crea un objeto de matriz de bytes que usa un identificador de memoria HGLOBAL para almacenar los bytes destinados al almacenamiento en memoria de un archivo compuesto. Este objeto es la implementación proporcionada por OLE de la interfaz ILockBytes .

El objeto de matriz de bytes devuelto admite la lectura y escritura, pero no admite el bloqueo de regiones . El objeto llama a la función GlobalReAlloc para aumentar el bloque de memoria según sea necesario.

Sintaxis

HRESULT CreateILockBytesOnHGlobal(
  [in]  HGLOBAL     hGlobal,
  [in]  BOOL        fDeleteOnRelease,
  [out] LPLOCKBYTES *pplkbyt
);

Parámetros

[in] hGlobal

Identificador de memoria asignado por la función GlobalAlloco si se va a asignar null un nuevo identificador en su lugar. El identificador debe asignarse como desplazable y no discardable.

[in] fDeleteOnRelease

Marca que especifica si el identificador subyacente de este objeto de matriz de bytes se debe liberar automáticamente cuando se libera el objeto. Si se establece en FALSE, el autor de la llamada debe liberar hGlobal después de la versión final. Si se establece en TRUE, la versión final liberará automáticamente el parámetro hGlobal .

[out] pplkbyt

Dirección de la variable de puntero ILockBytes que recibe el puntero de interfaz al nuevo objeto de matriz de bytes.

Valor devuelto

Esta función admite los valores devueltos estándar E_INVALIDARG y E_OUTOFMEMORY, así como los siguientes:

Comentarios

Si hGlobal es NULL, CreateILockBytesOnHGlobal asigna un nuevo identificador de memoria y la matriz de bytes está vacía inicialmente.

Si hGlobal no es NULL, el contenido inicial del objeto de matriz de bytes es el contenido actual del bloque de memoria. Por lo tanto, esta función se puede usar para abrir una matriz de bytes existente en memoria, por ejemplo, para volver a cargar un objeto de almacenamiento creado anteriormente por la función StgCreateDocfileOnILockBytes . El identificador de memoria y su contenido no se alteran mediante la creación del nuevo objeto de matriz de bytes.

El tamaño inicial de la matriz de bytes es el tamaño de hGlobal tal y como devuelve la función GlobalSize . Este no es necesariamente el mismo tamaño que se asignó originalmente para el controlador debido al redondeo. Si el tamaño lógico de la matriz de bytes es importante, siga la llamada a CreateILockBytesOnHGlobal con una llamada a ILockBytes::SetSize.

Después de crear el objeto de matriz de bytes con CreateStreamOnHGlobal, StgCreateDocfileOnILockBytes se puede usar para crear un nuevo objeto de almacenamiento en memoria o StgOpenStorageOnILockBytes se puede usar para volver a abrir un objeto de almacenamiento existente que ya está incluido en el bloque de memoria. Se puede llamar a GetHGlobalFromILockBytes para recuperar el identificador de memoria asociado al objeto de matriz de bytes.

Si se pasa un identificador de memoria a CreateILockBytesOnHGlobal o si se llama a GetHGlobalFromILockBytes , el autor de la llamada puede acceder directamente al identificador de memoria de esta función mientras sigue siendo utilizado por el objeto de matriz de bytes. Se debe tener precaución adecuada en el uso de esta funcionalidad y sus implicaciones:

  • No libere el identificador de memoria hGlobal durante la duración del objeto de matriz de bytes. Se debe llamar a ILockBytes::Release antes de liberar el identificador de memoria.
  • No llame a GlobalReAlloc para cambiar el tamaño del identificador de memoria durante la duración del objeto de matriz de bytes. Esto puede provocar bloqueos de la aplicación o daños en la memoria. Evite crear varios objetos de matriz de bytes en el mismo identificador de memoria, ya que los métodos ILockBytes::WriteAt e ILockBytes::SetSize pueden llamar internamente a GlobalReAlloc.
  • Si es posible, evite acceder al bloque de memoria durante la vigencia del objeto de matriz de bytes, ya que el objeto puede llamar internamente a GlobalReAlloc y no realizar suposiciones sobre su tamaño y ubicación. Si se debe tener acceso al bloque de memoria, las llamadas de acceso a memoria deben estar rodeadas por llamadas a GlobalLock y GlobalUnLock.
  • Evite llamar a los métodos del objeto mientras el identificador de memoria está bloqueado con GlobalLock. Esto puede hacer que las llamadas al método produzcan un error de forma impredecible.
Si el autor de la llamada establece el parámetro fDeleteOnRelease en FALSE, el autor de la llamada también debe liberar hGlobal después de la versión final. Si el autor de la llamada establece el parámetro fDeleteOnRelease en TRUE, la versión final liberará automáticamente el hGlobal. El identificador de memoria pasado como parámetro hGlobal debe asignarse como extraíble y no discardable, como se muestra en el ejemplo siguiente:
HGLOBAL	hMem = ::GlobalAlloc(GMEM_MOVEABLE,iSize);
if (!hMem)
    AfxThrowMemoryException();

LPVOID pCompoundFile = ::GlobalLock(hMem);
... // Fill memory
::GlobalUnlock(hMem);

CComPtr<ILockBytes> spLockBytes;
HRESULT hr = ::CreateILockBytesOnHGlobal(hMem,FALSE,&spLockBytes);


CreateILockBytesOnHGlobal aceptará la memoria asignada con GMEM_FIXED, pero no se recomienda este uso. Los HGLOBALs asignados con GMEM_FIXED no son realmente identificadores y su valor puede cambiar cuando se reasignan. Si el identificador de memoria se asignó con GMEM_FIXED y fDeleteOnRelease es FALSE, el llamador debe llamar a GetHGlobalFromILockBytes para obtener el valor HGLOBAL correcto para liberar el identificador.

Esta implementación de ILockBytes no admite el bloqueo de regiones. Las aplicaciones que usan esta implementación con las funciones StgCreateDocfileOnILockBytes o StgOpenStorageOnILockBytes deben evitar abrir varias instancias simultáneas en el mismo objeto ILockBytes .

Antes de Windows 7 y Windows Server 2008 R2, esta implementación no tenía memoria cero al llamar a GlobalReAlloc para aumentar el bloque de memoria. Aumentar el tamaño de la matriz de bytes con ILockBytes::SetSize o escribiendo en una ubicación después del final actual de la matriz de bytes dejará cualquier parte no escrita de la memoria recién asignada sin inicializar. Los objetos de almacenamiento devueltos por StgCreateDocfileOnILockBytes y StgOpenStorageOnILockBytes pueden aumentar el tamaño de la matriz de bytes sin inicializar todo el espacio recién asignado.

Normalmente, los archivos compuestos en memoria se usan como espacio temporal o con API que requieren un objeto de almacenamiento y, en estos casos, la memoria no inicializada suele no ser un problema. Sin embargo, si el contenido del bloque de memoria se escribirá en un archivo, tenga en cuenta las siguientes alternativas para evitar la posible divulgación de información:

  • Copie el contenido lógico del archivo compuesto en memoria en el archivo de destino mediante el método IStorage::CopyTo en lugar de escribir directamente el contenido del bloque de memoria.
  • En lugar de un archivo compuesto en memoria, cree un archivo temporal llamando a StgCreateStorageEx con un valor NULL para el parámetro pwcsName . Cuando es el momento de escribir en el archivo de destino, use el método IRootStorage::SwitchToFile .
  • Implemente la interfaz ILockBytes de modo que las reasignaciones de memoria estén ceros (vea, por ejemplo, la marca de HEAP_ZERO_MEMORY en HeapReAlloc). El contenido de memoria de esta matriz de bytes se puede escribir en un archivo.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 2000 Professional [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows 2000 Server [aplicaciones de escritorio | Aplicaciones para UWP]
Plataforma de destino Windows
Encabezado coml2api.h (include Ole2.h)
Library Ole32.lib
Archivo DLL Ole32.dll

Consulte también

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes