Funzione CreateILockBytesOnHGlobal (coml2api.h)
La funzione CreateILockBytesOnHGlobal crea un oggetto array di byte che usa un handle di memoria HGLOBAL per archiviare i byte destinati all'archiviazione in memoria di un file composto. Questo oggetto è l'implementazione fornita da OLE dell'interfaccia ILockBytes .
L'oggetto matrice di byte restituito supporta sia la lettura che la scrittura, ma non supporta il blocco dell'area . L'oggetto chiama la funzione GlobalReAlloc per aumentare il blocco di memoria in base alle esigenze.
Sintassi
HRESULT CreateILockBytesOnHGlobal(
[in] HGLOBAL hGlobal,
[in] BOOL fDeleteOnRelease,
[out] LPLOCKBYTES *pplkbyt
);
Parametri
[in] hGlobal
Handle di memoria allocato dalla funzione GlobalAlloco se un nuovo handle deve essere allocato invece NULL. L'handle deve essere allocato come spostabile e nondiscardabile.
[in] fDeleteOnRelease
Flag che specifica se l'handle sottostante per questo oggetto matrice di byte deve essere liberato automaticamente quando l'oggetto viene rilasciato. Se impostato su FALSE, il chiamante deve liberare hGlobal dopo la versione finale. Se impostato su TRUE, la versione finale libera automaticamente il parametro hGlobal .
[out] pplkbyt
Indirizzo della variabile puntatore ILockBytes che riceve il puntatore dell'interfaccia al nuovo oggetto matrice di byte.
Valore restituito
Questa funzione supporta i valori restituiti standard E_INVALIDARG e E_OUTOFMEMORY, nonché quanto segue:
Commenti
Se hGlobal è NULL, CreateILockBytesOnHGlobal alloca un nuovo handle di memoria e la matrice di byte è vuota inizialmente.
Se hGlobal non è NULL, il contenuto iniziale dell'oggetto matrice di byte è il contenuto corrente del blocco di memoria. Questa funzione può quindi essere usata per aprire una matrice di byte esistente in memoria, ad esempio per ricaricare un oggetto di archiviazione creato in precedenza dalla funzione StgCreateDocfileOnILockBytes . L'handle di memoria e il relativo contenuto sono indisturbati dalla creazione del nuovo oggetto matrice di byte.
Le dimensioni iniziali della matrice di byte sono le dimensioni di hGlobal restituite dalla funzione GlobalSize . Questa non è necessariamente la stessa dimensione originariamente allocata per l'handle a causa dell'arrotondamento. Se la dimensione logica della matrice di byte è importante, seguire la chiamata a CreateILockBytesOnHGlobal con una chiamata a ILockBytes::SetSize.
Dopo aver creato l'oggetto matrice di byte con CreateStreamOnHGlobal, è possibile usare StgCreateDocfileOnILockBytes per creare un nuovo oggetto di archiviazione in memoria o StgOpenStorageOnILockBytes per riaprire un oggetto di archiviazione precedentemente esistente già contenuto nel blocco di memoria. GetHGlobalFromILockBytes può essere chiamato per recuperare l'handle di memoria associato all'oggetto matrice di byte.
Se un handle di memoria viene passato a CreateILockBytesOnHGlobal o se viene chiamato GetHGlobalFromILockBytes, l'handle di memoria di questa funzione può essere accessibile direttamente dal chiamante mentre è ancora in uso dall'oggetto matrice di byte. È consigliabile prestare attenzione all'uso di questa funzionalità e alle relative implicazioni:
- Non liberare l'handle di memoria hGlobal durante la durata dell'oggetto matrice di byte. ILockBytes::Release deve essere chiamato prima che l'handle di memoria venga liberato.
- Non chiamare GlobalReAlloc per modificare le dimensioni dell'handle di memoria durante la durata dell'oggetto matrice di byte. Questo può causare arresti anomali dell'applicazione o danneggiamento della memoria. Evitare di creare più oggetti matrice di byte nello stesso handle di memoria, perché i metodi ILockBytes::WriteAt e ILockBytes::SetSize possono chiamare internamente GlobalReAlloc.
- Se possibile, evitare di accedere al blocco di memoria durante la durata dell'oggetto matrice di byte, perché l'oggetto può chiamare internamente GlobalReAlloc e non effettuare ipotesi relative alle dimensioni e alla posizione. Se è necessario accedere al blocco di memoria, le chiamate di accesso alla memoria devono essere circondate da chiamate a GlobalLock e GlobalUnLock.
- Evitare di chiamare i metodi dell'oggetto mentre l'handle di memoria è bloccato con GlobalLock. Ciò può causare un errore imprevedibile delle chiamate al metodo.
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 accetta la memoria allocata con GMEM_FIXED, ma questo utilizzo non è consigliato. Gli HGLOBALs allocati con GMEM_FIXED non sono realmente handle e il loro valore può cambiare quando vengono riallocati. Se l'handle di memoria è stato allocato con GMEM_FIXED e fDeleteOnRelease è FALSE, il chiamante deve chiamare GetHGlobalFromILockBytes per ottenere il valore HGLOBAL corretto per liberare l'handle.
Questa implementazione di ILockBytes non supporta il blocco dell'area. Le applicazioni che usano questa implementazione con le funzioni StgCreateDocfileOnILockBytes o StgOpenStorageOnILockBytes devono evitare di aprire più istanze simultanee nello stesso oggetto ILockBytes .
Prima di Windows 7 e Windows Server 2008 R2, questa implementazione non ha avuto memoria zero quando si chiama GlobalReAlloc per aumentare il blocco di memoria. L'aumento delle dimensioni della matrice di byte con ILockBytes::SetSize o scrivendo in una posizione precedente alla fine corrente della matrice di byte lascerà eventuali parti non scritte della memoria appena allocata non inizializzata. Gli oggetti di archiviazione restituiti da StgCreateDocfileOnILockBytes e StgOpenStorageOnILockBytes possono aumentare le dimensioni della matrice di byte senza inizializzare tutti gli spazi appena allocati.
I file composti in memoria vengono in genere usati come spazio zero o con API che richiedono un oggetto di archiviazione e in questi casi la memoria non inizializzata in genere non è un problema. Tuttavia, se il contenuto del blocco di memoria verrà scritto in un file, prendere in considerazione le alternative seguenti per evitare potenziali divulgazione di informazioni:
- Copiare il contenuto logico del file composto in memoria nel file di destinazione usando il metodo IStorage::CopyTo anziché scrivere direttamente il contenuto del blocco di memoria.
- Anziché un file composto in memoria, creare un file temporaneo chiamando StgCreateStorageEx con un valore NULL per il parametro pwcsName . Quando è possibile scrivere nel file di destinazione, usare il metodo IRootStorage::SwitchToFile .
- Implementare l'interfaccia ILockBytes in modo che le reallocation della memoria siano zero (vedere ad esempio il flag HEAP_ZERO_MEMORY in HeapReAlloc). Il contenuto della memoria di questa matrice di byte può quindi essere scritto in un file.
Requisiti
Requisito | Valore |
---|---|
Client minimo supportato | Windows 2000 Professional [app desktop | App UWP] |
Server minimo supportato | Windows 2000 Server [app desktop | App UWP] |
Piattaforma di destinazione | Windows |
Intestazione | coml2api.h (include Ole2.h) |
Libreria | Ole32.lib |
DLL | Ole32.dll |