Функция MoveVolatileMemory

Копирует содержимое блока исходной памяти в блок памяти назначения и поддерживает перекрывающиеся блоки исходной и целевой памяти.

Важно!

Некоторые сведения относятся к предварительному продукту, который может быть существенно изменен до его коммерческого выпуска. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Параметры

Назначение Param [out]

Указатель на начальный адрес места назначения скопированного блока.

Источник Param [in]

Указатель на начальный адрес блока памяти для копирования.

Длина param [in]

Размер блока памяти для копирования в байтах.

Синтаксис

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

Замечания

Этот API существует для обеспечения поведения MoveMemory (т. е. копирования памяти из одного расположения в другое) в ситуациях, когда разработчик должен убедиться, что операция копирования возникает (т. е. не подлежит оптимизации компилятора). В отличие от CopyVolatileMemory, этот API обрабатывает случаи, когда буфер источника и назначения перекрывается.

API имеет следующие свойства:

  • API не распознается как встроенный компилятор, поэтому компилятор никогда не оптимизирует вызов (полностью или замените вызов эквивалентной последовательностью инструкций). Это отличается от MoveMemory, которое зависит от различных оптимизаций компилятора.
  • Когда вызов возвращается, данные копируются из источника в назначение. Эти функции, доступ к памяти к источнику и назначению , будут выполняться только в функции (т. е. компилятор не может перемещать доступ к памяти из этой функции).
  • API может выполнять неподготовленный доступ к памяти, если платформа позволяет ей.
  • API может получить доступ к расположениям памяти более одного раза в рамках операции копирования.
  • Аналогично MoveMemory в том, что он поддерживает операции копирования, когда источник и назначение перекрываются друг с другом.

Примечание.

Эта функция работает во всех версиях Windows, а не только на последних версиях. Чтобы получить объявление функции из заголовка winbase.h , необходимо использовать последний пакет SDK. Вам также нужна библиотека (volatileaccessu.lib) из последнего пакета SDK. Однако результирующий двоичный файл будет работать в более ранних версиях Windows.

Пример

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

Requirements

Минимальный поддерживаемый клиент: сборка предварительной версии Windows 11 Insider Preview ТБ D

Заголовок: winbase.h (включая Winbase.h)

Библиотека режима ядра: volatileaccessk.lib

Библиотека пользовательского режима: volatileaccessu.lib

См. также