Partager via


CreateILockBytesOnHGlobal, fonction (coml2api.h)

La fonction CreateILockBytesOnHGlobal crée un objet de tableau d’octets qui utilise un handle de mémoire HGLOBAL pour stocker les octets destinés au stockage en mémoire d’un fichier composé. Cet objet est l’implémentation fournie par OLE de l’interface ILockBytes .

L’objet tableau d’octets retourné prend en charge la lecture et l’écriture, mais ne prend pas en charge le verrouillage de région. L’objet appelle la fonction GlobalReAlloc pour augmenter le bloc de mémoire en fonction des besoins.

Syntaxe

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

Paramètres

[in] hGlobal

Un handle de mémoire alloué par la fonction GlobalAlloc ou, si NULL , un nouveau handle doit être alloué à la place. Le handle doit être alloué comme pouvant être déplacé et nondiscardable.

[in] fDeleteOnRelease

Indicateur qui spécifie si le handle sous-jacent de cet objet de tableau d’octets doit être libéré automatiquement lorsque l’objet est libéré. Si la valeur est FALSE, l’appelant doit libérer le hGlobal après la version finale. Si la valeur est TRUE, la version finale libère automatiquement le paramètre hGlobal .

[out] pplkbyt

Adresse de la variable pointeur ILockBytes qui reçoit le pointeur d’interface vers le nouvel objet de tableau d’octets.

Valeur retournée

Cette fonction prend en charge les valeurs de retour standard E_INVALIDARG et E_OUTOFMEMORY, ainsi que les éléments suivants :

Remarques

Si hGlobal a la valeur NULL, createILockBytesOnHGlobal alloue un nouveau handle de mémoire et le tableau d’octets est vide initialement.

Si hGlobal n’a pas la valeur NULL, le contenu initial de l’objet tableau d’octets est le contenu actuel du bloc de mémoire. Ainsi, cette fonction peut être utilisée pour ouvrir un tableau d’octets existant en mémoire, par exemple pour recharger un objet de stockage créé précédemment par la fonction StgCreateDocfileOnILockBytes . Le handle de mémoire et son contenu ne sont pas perturbés par la création du nouvel objet de tableau d’octets.

La taille initiale du tableau d’octets est la taille de hGlobal retournée par la fonction GlobalSize . Il ne s’agit pas nécessairement de la même taille que celle qui a été initialement allouée pour le handle en raison de l’arrondi. Si la taille logique du tableau d’octets est importante, suivez l’appel à CreateILockBytesOnHGlobal avec un appel à ILockBytes ::SetSize.

Après avoir créé l’objet de tableau d’octets avec CreateStreamOnHGlobal, StgCreateDocfileOnILockBytes peut être utilisé pour créer un objet de stockage en mémoire, ou StgOpenStorageOnILockBytes peut être utilisé pour rouvrir un objet de stockage existant qui est déjà contenu dans le bloc de mémoire. GetHGlobalFromILockBytes peut être appelé pour récupérer le handle de mémoire associé à l’objet de tableau d’octets.

Si un handle de mémoire est passé à CreateILockBytesOnHGlobal ou si GetHGlobalFromILockBytes est appelé, le handle de mémoire de cette fonction est directement accessible par l’appelant pendant qu’il est toujours utilisé par l’objet tableau d’octets. Il convient de faire preuve de prudence dans l’utilisation de cette fonctionnalité et de ses implications :

  • Ne libérez pas le handle de mémoire hGlobal pendant la durée de vie de l’objet de tableau d’octets. ILockBytes ::Release doit être appelé avant que le handle de mémoire ne soit libéré.
  • N’appelez pas GlobalReAlloc pour modifier la taille du handle de mémoire pendant la durée de vie de l’objet de tableau d’octets. Cela peut entraîner des blocages d’application ou une altération de la mémoire. Évitez de créer plusieurs objets de tableau d’octets sur le même handle de mémoire, car les méthodes ILockBytes ::WriteAt et ILockBytes ::SetSize peuvent appeler GlobalReAlloc en interne.
  • Si possible, évitez d’accéder au bloc de mémoire pendant la durée de vie de l’objet de tableau d’octets, car l’objet peut appeler En interne GlobalReAlloc et ne pas faire d’hypothèses sur sa taille et son emplacement. Si le bloc de mémoire doit être accessible, les appels d’accès à la mémoire doivent être entourés d’appels à GlobalLock et GlobalUnLock.
  • Évitez d’appeler les méthodes de l’objet pendant que le handle de mémoire est verrouillé avec GlobalLock. Cela peut entraîner l’échec imprévisible des appels de méthode.
Si l’appelant définit le paramètre fDeleteOnRelease sur FALSE, l’appelant doit également libérer le hGlobal après la version finale. Si l’appelant définit le paramètre fDeleteOnRelease sur TRUE, la version finale libère automatiquement le hGlobal. Le handle de mémoire passé en tant que paramètre hGlobal doit être alloué comme mobile et nondiscardable, comme illustré dans l’exemple suivant :
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 accepte la mémoire allouée avec GMEM_FIXED, mais cette utilisation n’est pas recommandée. Les HGLOBALs alloués avec GMEM_FIXED ne sont pas vraiment des handles et leur valeur peut changer lorsqu’ils sont réalloués. Si le handle de mémoire a été alloué avec GMEM_FIXED et que fDeleteOnRelease a la valeur FALSE, l’appelant doit appeler GetHGlobalFromILockBytes pour obtenir la valeur HGLOBAL correcte afin de libérer le handle.

Cette implémentation d’ILockBytes ne prend pas en charge le verrouillage de région. Les applications qui utilisent cette implémentation avec les fonctions StgCreateDocfileOnILockBytes ou StgOpenStorageOnILockBytes doivent éviter d’ouvrir plusieurs instances simultanées sur le même objet ILockBytes .

Avant Windows 7 et Windows Server 2008 R2, cette implémentation n’avait pas zéro mémoire lors de l’appel de GlobalReAlloc pour augmenter le bloc de mémoire. L’augmentation de la taille du tableau d’octets avec ILockBytes ::SetSize ou en écrivant dans un emplacement au-delà de la fin actuelle du tableau d’octets laissera non initialisées toutes les parties non écrites de la mémoire nouvellement allouée. Les objets de stockage retournés par StgCreateDocfileOnILockBytes et StgOpenStorageOnILockBytes peuvent augmenter la taille du tableau d’octets sans initialiser tout l’espace nouvellement alloué.

Les fichiers composés en mémoire sont généralement utilisés comme espace de travail ou avec des API qui nécessitent un objet de stockage. Dans ce cas, la mémoire non initialisée n’est généralement pas un problème. Toutefois, si le contenu du bloc de mémoire est écrit dans un fichier, envisagez les alternatives suivantes pour éviter toute divulgation potentielle d’informations :

  • Copiez le contenu logique du fichier composé en mémoire dans le fichier de destination à l’aide de la méthode IStorage ::CopyTo plutôt que d’écrire directement le contenu du bloc de mémoire.
  • Au lieu d’un fichier composé en mémoire, créez un fichier temporaire en appelant StgCreateStorageEx avec une valeur NULL pour le paramètre pwcsName . Quand il est temps d’écrire dans le fichier de destination, utilisez la méthode IRootStorage ::SwitchToFile .
  • Implémentez l’interface ILockBytes de telle sorte que les réaffectations de mémoire soient mises à zéro (voir par exemple l’indicateur HEAP_ZERO_MEMORY dans HeapReAlloc). Le contenu de la mémoire de ce tableau d’octets peut ensuite être écrit dans un fichier.

Configuration requise

Condition requise Valeur
Client minimal pris en charge Windows 2000 Professionnel [applications de bureau | Applications UWP]
Serveur minimal pris en charge Windows 2000 Server [applications de bureau | Applications UWP]
Plateforme cible Windows
En-tête coml2api.h (inclure Ole2.h)
Bibliothèque Ole32.lib
DLL Ole32.dll

Voir aussi

GetHGlobalFromILockBytes

ILockBytes

StgOpenStorageOnILockBytes