Compartilhar via


Função MoveVolatileMemory

Copia o conteúdo de um bloco de memória de origem para um bloco de memória de destino e dá suporte a blocos de memória de origem e de destino sobrepostos.

Importante

Algumas informações referem-se a um produto de pré-lançamento que pode ser substancialmente modificado antes de ser lançado comercialmente. A Microsoft não oferece nenhuma garantia, explícita ou implícita, quanto às informações fornecidas aqui.

Parâmetros

Destino do param [saída]

Um ponteiro para o endereço inicial do destino do bloco copiado.

Origem do param [entrada]

Um ponteiro para o endereço inicial do bloco de memória a ser copiado.

Comprimento do param [entrada]

O tamanho do bloco de memória a ser copiado, em bytes.

Sintaxe

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

Comentários

Essa API existe para fornecer comportamento MoveMemory (ou seja, copiar memória de um local para outro) em situações em que o desenvolvedor precisa ter certeza de que a operação de cópia ocorre (ou seja, não está sujeita a otimizações do compilador). Ao contrário de CopyVolatileMemory, essa API lida com casos em que o buffer de Origem e de Destino se sobrepõem.

A API tem as seguintes propriedades:

  • A API não é reconhecida como um compilador intrínseco, portanto, o compilador nunca otimizará a chamada (seja totalmente ou substituindo a chamada por uma sequência "equivalente" de instruções). Isso difere de MoveMemory, que está sujeito a uma variedade de otimizações do compilador.
  • Quando a chamada retorna, os dados foram copiados da Origem para o Destino. Os acessos à Origem e ao Destino da memória dessa função só serão executados dentro da função (ou seja, o compilador não pode mover os acessos à memória para fora dessa função).
  • A API poderá executar acessos à memória não alinhados se a plataforma permitir.
  • A API pode acessar locais de memória mais de uma vez como parte da operação de cópia dela.
  • Semelhante ao MoveMemory, no sentido de que dá suporte a operações de cópia quando a Origem e o Destino se sobrepõem

Observação

Esta função funciona em todas as versões do Windows, não apenas na mais recente. Você precisa consumir o SDK mais recente para obter a declaração de função do cabeçalho winbase.h. Você também precisa da biblioteca (volatileaccessu.lib) do SDK mais recente. No entanto, o binário resultante será executado bem em versões mais antigas do Windows.

Exemplo

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);
}

Requisitos

Cliente mínimo suportado: Windows 11 Insider Preview Build TBD

Cabeçalho: winbase.h (incluir Winbase.h)

Biblioteca de modo kernel: volatileaccessk.lib

Biblioteca de modo de usuário: volatileaccessu.lib

Confira também