VirtualCopy (Windows Embedded CE 6.0)
1/6/2010
This function dynamically maps a virtual address to a physical address by creating a new page-table entry. Terminate the mapping by calling VirtualFree.
Syntax
BOOL VirtualCopy(
LPVOID lpvDest,
LPVOID lpvSrc,
DWORD cbSize,
DWORD fdwProtect
);
Parameters
- lpvDest
[in] Pointer to the destination memory that must be reserved.
- lpvSrc
[in] Pointer to committed memory.
- cbSize
[in] Size, in bytes, of the region. The allocated pages include all pages containing 1 or more bytes in the range from lpAddress to lpAddress plus cbSize. This means that a 2-byte range straddling a page boundary causes both pages to be included in the allocated region.
fdwProtect
[in] Type of access protection. If the pages are being committed, any one of a number of flags can be specified, along with the PAGE_GUARD and PAGE_NOCACHE protection modifier flags. The following table shows possible values.Value Description PAGE_EXECUTE
Enables execute access to the committed region of pages. An attempt to read or write to the committed region causes an access violation.
PAGE_EXECUTE_READ
Enables execute and read access to the committed region of pages. An attempt to write to the committed region causes an access violation.
PAGE_EXECUTE_READWRITE
Enables execute, read, and write access to the committed region of pages.
PAGE_GUARD
Pages in the region become guard pages. Any attempt to read from or write to a guard page causes the OS to raise the STATUS_GUARD_PAGE exception and turn off the guard page status. Guard pages thus act as a one-time access alarm.
The PAGE_GUARD flag is a page protection modifier. An application uses it with one of the other page protection flags, with one exception: it cannot be used with PAGE_NOACCESS.
When an access attempt causes the OS to turn off guard page status, the underlying page protection takes over.
If a guard page exception occurs during a system service, the service typically returns a failure status indicator.
PAGE_NOACCESS
Disables all access to the committed region of pages. An attempt to read from, write to, or execute in the committed region causes an access violation exception called a general protection (GP) fault.
PAGE_NOCACHE
Allows no caching of the committed regions of pages. The hardware attributes for the physical memory should be specified as no cache. It is useful for device drivers; when, for example, mapping a video frame buffer with no caching. This flag is a page protection modifier and is valid only when used with one of the page protections other than PAGE_NOACCESS.
PAGE_READONLY
Enables read access to the committed region of pages. An attempt to write to the committed region causes an access violation. If the system differentiates between read-only access and execute access, an attempt to execute code in the committed region causes an access violation.
PAGE_READWRITE
Enables both read and write access to the committed region of pages.
PAGE_PHYSICAL
Used to map a physical memory region. When using this flag, divide the physical address, that is, lpvSrc, by 256. PAGE_PHYSICAL must only be used for memory not known to the kernel.
Return Value
TRUE indicates success FALSE indicates failure. To get extended error information, call GetLastError.
Remarks
For CE 6.0, a call to VirtualCopy fails if it crosses a 32-MB section boundary. For example, if you allocate 16 MB and it crosses a 32-MB boundary, you must make two VirtualCopy calls.
In Windows Embedded CE 6.0, Windows Embedded CE 6.0 R2, and Windows Embedded CE 6.0 R3, VirtualCopy is a kernel-mode-only function. For information about other kernel-mode only functions, see Kernel Mode APIs.
The one exception is that you can call VirtualCopy from user mode only from a user-mode driver, where its physical address range is specified in the registry. To port code that calls VirtualAlloc or VirtualCopy, consider doing one of the following, which are in order of preference in terms of security and robustness:
- Make the code that calls VirtualAlloc or VirtualCopy a driver.
- Make the code that calls VirtualAlloc or VirtualCopy into a DLL, and use LoadKernelLibrary to load it into kernel.
- Create a dummy kernel-mode driver that implements IOCTL_DO_VIRTUAL_COPY to call VirtualCopy.
If you want to call VirtualCopy to copy a physical or virtual buffer and that buffer is not page-aligned, the operation copies more data than you specified. If the start of the buffer is not page-aligned, the operation also copies data before the start of the specified buffer, starting from the beginning of the page. If the end of the buffer is not page-aligned, the operation copies data after the end of the specified buffer, ending at the following page boundary.
This is a security issue if the copied buffer is ever passed to user mode. The user-mode application can access the surrounding data that is not part of the specified buffer. To protect the surrounding data, use a buffer that is page-aligned and an even multiple of pages in size. If that is not possible, passing the data to user mode puts it at risk.
The virtual page offset and physical page offset must be the same because one virtual page can only be mapped to one physical page. For example, consider the following invalid call to VirtualCopy:
VirtualCopy (0x50000, 0xC00DA800, 0x1000, . . .);
The virtual to physical mapping requested are as follows:
(0x50000, 0x50800) to (0xC0DA800, 0xC0DB000)
(0x50800, 0x51000) to (0xC0DB000, 0xC0DB800)
In the above example, the virtual page (0x50000, 0x51000) must be mapped to two different physical pages, 0xC00DA000 and 0xC00DB000, but virtual memory cannot support this.
The following code example shows how VirtualCopy is called to map a 128-KB region at physical address 0x64000000.
VirtualCopy(pvDest, (void *) (0x64000000/256), 128*1024, PAGE_READWRITE | PAGE_PHYSICAL | PAGE_NOCACHE);
The PAGE_PHYSICAL value of fdwProtect must only be used for memory not known to the kernel. If you call VirtualCopy with PAGE_PHYSICAL to map kernel-managed RAM (for example, memory that has been allocated by AllocPhysMem or HalAllocateCommonBuffer), freeing the virtual memory can introduce an error in the reference count of the kernel.
Drivers or applications that run in user mode must use the User Mode Driver Framework to access physical memory.
This function ensures that the OS maps a mapped virtual address to the specific physical address of the registers or frame buffer that it needs to read or write. Before the thread calls VirtualCopy, it must first obtain a virtual address by calling VirtualAlloc. VirtualAlloc and VirtualCopy must be called at the beginning of every device driver thread or application that must access peripheral registers.
For code samples, see the sample device driver code provided with Platform Builder, located in the %_WINCEROOT%\Platform\%BSP%\Drivers and %_WINCEROOT%\Public\Common\OAK\Drivers directories.
The destination address defined by the lpvDest parameter must be an address range that has been reserved by a call to VirtualAlloc. VirtualAlloc, with the flags MEM_RESERVE and PAGE_NOACCESS set and a size greater than or equal to 2 MB, allocated outside the process virtual memory space. Otherwise, it is allocated inside the processes virtual memory space.
Requirements
Header | pkfuncs.h |
Library | coredll.lib |
Windows Embedded CE | Windows CE 2.10 and later |
See Also
Reference
Other Resources
CEL_VIRTUAL_COPY
CeLogData
HiveRAMRegion
MmMapIoSpace
NdisFlushBuffer
VirtualAlloc
VirtualFree