Partager via


Fonction MoveVolatileMemory

Copie le contenu d’un bloc de mémoire source dans un bloc de mémoire de destination, et prend en charge les blocs de mémoire source et de destination qui se chevauchent.

Important

Certaines informations portent sur la préversion du produit qui est susceptible d’être en grande partie modifié avant sa commercialisation. Microsoft n’offre aucune garantie, expresse ou implicite, concernant les informations fournies ici.

Paramètres

Paramètre Destination [out]

Un pointeur vers l’adresse de début de la destination du bloc copié.

Paramètre Source [in]

Un pointeur vers l’adresse de début du bloc de mémoire à copier.

Paramètre Length [in]

La taille du bloc de mémoire à copier, exprimée en octets.

Syntaxe

volatile void* __cdecl
  MoveVolatileMemory (
    _Out_writes_bytes_all_(Length) volatile void* Destination,
    _In_reads_bytes_(Length) volatile const void* Source,
    SIZE_T Length
  );

Notes

Cette API est destinée à fournir le comportement deMoveMemory (c’est-à-dire copier le contenu d’un emplacement vers un autre) dans les situations où le développeur doit être sûr que l’opération de copie se produit (autrement dit, qu’elle n’est pas soumise à des optimisations du compilateur). Contrairement à CopyVolatileMemory, cette API gère les cas où la mémoire tamponSource et de Destination se chevauchent.

L’API a les propriétés suivantes :

  • L’API n’est pas reconnue comme étant intrinsèque au compilateur : le compilateur n’optimise donc jamais l’appel (entièrement ou en remplaçant l’appel par une séquence « équivalente » d’instructions). Ceci diffère de MoveMemory, qui est soumise à différentes optimisations du compilateur.
  • Quand l’appel retourne, les données ont été copiées de la Source vers la Destination. Ces accès mémoire des fonctions à la Source et à la Destination seront effectués seulement au sein de la fonction (autrement dit, le compilateur ne peut pas déplacer les accès mémoire en dehors de cette fonction).
  • L’API peut effectuer des accès mémoire non alignés si la plateforme l’autorise.
  • L’API peut accéder plusieurs fois à des emplacements mémoire dans le cadre de son opération de copie.
  • Elle est similaire à MoveMemory en cela qu’elle prend en charge les opérations de copie quand la Source et la Destination se chevauchent.

Remarque

Cette fonction fonctionne sur toutes les versions de Windows, pas seulement sur la dernière. Vous devez utiliser le SDK le plus récent pour obtenir la déclaration de fonction de l’en-tête winbase.h. Vous avez également besoin de la bibliothèque (volatileaccessu.lib) du SDK le plus récent. Cependant, le fichier binaire résultant s’exécutera correctement sur les versions antérieures de Windows.

Exemple

HEADER MyHeader;
UCHAR RawBuffer[100];

// Ensure that the shared memory (which could be constantly changing)
// is copied in to the local MyHeader variable.
// Note that the compiler is allowed to optimize away calls to
// MoveMemory/RtlMoveMemory so those functions are not guaranteed to actually
// make a local copy of data.
//
// MoveVolatileMemory does handle
// buffers that overlap with each other (MoveMemory semantics).
// Assume SharedMemory points to virtual memory that is also mapped in an untrusted process.
// Assume that untrusted process is changing the memory contents while you are accessing it.
PVOID SharedMemory;

MoveVolatileMemory(&MyHeader, SharedMemory, sizeof(MyHeader));

if (MyHeader.Size < 100) {
  // Because MyHeader is local and we are guaranteed we actually made
  // a local copy, we can be sure that the "Size" value will not change
  // between the previous bounds check and the below call to RtlFillMemory.
  // If RtlMoveMemory/RtlMoveMemory had been used to copy the data, it is possible
  // that a compiler may optimize away the call to MoveMemory and instead fetch
  // the “size” field of MyHeader directly from untrusted memory two times.
  // The first time it would be fetched for the bounds check, and the second
  // time it is fetched is for the call to FillMemory. It is possible the memory
  // could have changed between the two accesses resulting in the size check
  // being ineffective.

  FillMemory (RawBuffer, MyHeader.Size, 0);
}

Spécifications

Client minimal pris en charge : Windows 11 Insider Preview Build TBD

En-tête : winbase.h (include Winbase.h)

Bibliothèque en mode noyau : volatileaccessk.lib

Bibliothèque en mode utilisateur : volatileaccessu.lib

Voir aussi