mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:45:50 +00:00
[AUDIT] These files are clean and simple stubs around NT apis and/or WINE code.
- Reformat the files. - Fix A->W calling. - Simpliy WriteProcessMemory to use NtProtectVirtualMemory to query the current state. - Call some APIs with the right DesiredAccess instead of allways sending _ALL_ACCESS. (for example, only use SECTION_MAP_READ | QUERY unless the caller wants r/w. - Flush ITLB when writing to process memory. svn path=/trunk/; revision=22519
This commit is contained in:
parent
b1d543c345
commit
3b350f6972
3 changed files with 577 additions and 555 deletions
|
@ -1,10 +1,9 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Win32 Base API
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* FILE: dll/win32/kernel32/mem/procmem.c
|
||||||
* FILE: lib/kernel32/mem/procmem.c
|
* PURPOSE: Handles virtual memory APIs
|
||||||
* PURPOSE:
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* PROGRAMMER: Boudewijn Dekker
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -12,7 +11,7 @@
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "../include/debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -20,138 +19,138 @@
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
NTAPI
|
||||||
ReadProcessMemory (
|
ReadProcessMemory(IN HANDLE hProcess,
|
||||||
HANDLE hProcess,
|
IN LPCVOID lpBaseAddress,
|
||||||
LPCVOID lpBaseAddress,
|
IN LPVOID lpBuffer,
|
||||||
LPVOID lpBuffer,
|
IN DWORD nSize,
|
||||||
DWORD nSize,
|
OUT LPDWORD lpNumberOfBytesRead)
|
||||||
LPDWORD lpNumberOfBytesRead
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = NtReadVirtualMemory( hProcess, (PVOID)lpBaseAddress,lpBuffer, nSize,
|
/* Do the read */
|
||||||
(PULONG)lpNumberOfBytesRead
|
Status = NtReadVirtualMemory(hProcess,
|
||||||
);
|
(PVOID)lpBaseAddress,
|
||||||
|
lpBuffer,
|
||||||
|
nSize,
|
||||||
|
lpNumberOfBytesRead);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus (Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
NTAPI
|
||||||
WriteProcessMemory (
|
WriteProcessMemory(IN HANDLE hProcess,
|
||||||
HANDLE hProcess,
|
IN LPVOID lpBaseAddress,
|
||||||
LPVOID lpBaseAddress,
|
IN LPCVOID lpBuffer,
|
||||||
LPCVOID lpBuffer,
|
IN SIZE_T nSize,
|
||||||
SIZE_T nSize,
|
OUT SIZE_T *lpNumberOfBytesWritten)
|
||||||
SIZE_T *lpNumberOfBytesWritten
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS Status, ProtectStatus = STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
MEMORY_BASIC_INFORMATION MemInfo;
|
ULONG OldValue;
|
||||||
ULONG Length;
|
SIZE_T RegionSize;
|
||||||
|
PVOID Base;
|
||||||
BOOLEAN UnProtect;
|
BOOLEAN UnProtect;
|
||||||
|
|
||||||
if (lpNumberOfBytesWritten)
|
/* Set parameters for protect call */
|
||||||
{
|
RegionSize = nSize;
|
||||||
*lpNumberOfBytesWritten = 0;
|
Base = lpBaseAddress;
|
||||||
}
|
|
||||||
|
|
||||||
while (nSize)
|
/* Check the current status */
|
||||||
|
Status = NtProtectVirtualMemory(hProcess,
|
||||||
|
&Base,
|
||||||
|
&RegionSize,
|
||||||
|
PAGE_EXECUTE_READWRITE,
|
||||||
|
&OldValue);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = NtQueryVirtualMemory(hProcess,
|
/* Check if we are unprotecting */
|
||||||
lpBaseAddress,
|
UnProtect = OldValue & (PAGE_READWRITE |
|
||||||
MemoryBasicInformation,
|
PAGE_WRITECOPY |
|
||||||
&MemInfo,
|
PAGE_EXECUTE_READWRITE |
|
||||||
sizeof(MEMORY_BASIC_INFORMATION),
|
PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
|
|
||||||
if (Length > nSize)
|
|
||||||
{
|
|
||||||
Length = nSize;
|
|
||||||
}
|
|
||||||
UnProtect = MemInfo.Protect & (PAGE_READWRITE|PAGE_WRITECOPY|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
|
|
||||||
if (UnProtect)
|
if (UnProtect)
|
||||||
{
|
{
|
||||||
MemInfo.BaseAddress = lpBaseAddress;
|
/* Set the new protection */
|
||||||
MemInfo.RegionSize = Length;
|
Status = NtProtectVirtualMemory(hProcess,
|
||||||
if (MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ))
|
&Base,
|
||||||
{
|
&RegionSize,
|
||||||
MemInfo.Protect &= ~(PAGE_EXECUTE|PAGE_EXECUTE_READ);
|
OldValue,
|
||||||
MemInfo.Protect |= PAGE_EXECUTE_READWRITE;
|
&OldValue);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MemInfo.Protect &= ~(PAGE_READONLY|PAGE_NOACCESS);
|
|
||||||
MemInfo.Protect |= PAGE_READWRITE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ProtectStatus = NtProtectVirtualMemory(hProcess,
|
|
||||||
&MemInfo.BaseAddress,
|
|
||||||
&MemInfo.RegionSize,
|
|
||||||
MemInfo.Protect,
|
|
||||||
&MemInfo.Protect);
|
|
||||||
if (!NT_SUCCESS(ProtectStatus))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus(ProtectStatus);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
Length = MemInfo.RegionSize - ((ULONG_PTR)lpBaseAddress - (ULONG_PTR)MemInfo.BaseAddress);
|
|
||||||
if (Length > nSize)
|
|
||||||
{
|
|
||||||
Length = nSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Write the memory */
|
||||||
Status = NtWriteVirtualMemory(hProcess,
|
Status = NtWriteVirtualMemory(hProcess,
|
||||||
lpBaseAddress,
|
lpBaseAddress,
|
||||||
(LPVOID)lpBuffer,
|
(LPVOID)lpBuffer,
|
||||||
Length,
|
nSize,
|
||||||
&Length);
|
lpNumberOfBytesWritten);
|
||||||
if (UnProtect)
|
|
||||||
{
|
|
||||||
ProtectStatus = NtProtectVirtualMemory(hProcess,
|
|
||||||
&MemInfo.BaseAddress,
|
|
||||||
&MemInfo.RegionSize,
|
|
||||||
MemInfo.Protect,
|
|
||||||
&MemInfo.Protect);
|
|
||||||
}
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (UnProtect && !NT_SUCCESS(ProtectStatus))
|
|
||||||
|
/* Flush the ITLB */
|
||||||
|
NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus (ProtectStatus);
|
/* Check if we were read only */
|
||||||
|
if ((OldValue & PAGE_NOACCESS) || (OldValue & PAGE_READONLY))
|
||||||
|
{
|
||||||
|
/* Restore protection and fail */
|
||||||
|
NtProtectVirtualMemory(hProcess,
|
||||||
|
&Base,
|
||||||
|
&RegionSize,
|
||||||
|
OldValue,
|
||||||
|
&OldValue);
|
||||||
|
SetLastErrorByStatus(STATUS_ACCESS_VIOLATION);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
lpBaseAddress = (LPVOID)((ULONG_PTR)lpBaseAddress + Length);
|
|
||||||
lpBuffer = (LPCVOID)((ULONG_PTR)lpBuffer + Length);
|
/* Otherwise, do the write */
|
||||||
nSize -= Length;
|
Status = NtWriteVirtualMemory(hProcess,
|
||||||
if (lpNumberOfBytesWritten)
|
lpBaseAddress,
|
||||||
|
(LPVOID)lpBuffer,
|
||||||
|
nSize,
|
||||||
|
lpNumberOfBytesWritten);
|
||||||
|
|
||||||
|
/* And restore the protection */
|
||||||
|
NtProtectVirtualMemory(hProcess,
|
||||||
|
&Base,
|
||||||
|
&RegionSize,
|
||||||
|
OldValue,
|
||||||
|
&OldValue);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
*lpNumberOfBytesWritten += Length;
|
/* We failed */
|
||||||
}
|
SetLastErrorByStatus(STATUS_ACCESS_VIOLATION);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Flush the ITLB */
|
||||||
|
NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We failed */
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Win32 Base API
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* FILE: dll/win32/kernel32/mem/section.c
|
||||||
* FILE: lib/kernel32/mem/section.c
|
* PURPOSE: Handles virtual memory APIs
|
||||||
* PURPOSE: Implementing file mapping
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -12,99 +11,61 @@
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "../include/debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
#define MASK_PAGE_FLAGS (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY)
|
|
||||||
#define MASK_SEC_FLAGS (SEC_COMMIT | SEC_IMAGE | SEC_NOCACHE | SEC_RESERVE)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HANDLE STDCALL
|
HANDLE
|
||||||
CreateFileMappingA(HANDLE hFile,
|
NTAPI
|
||||||
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
CreateFileMappingA(IN HANDLE hFile,
|
||||||
DWORD flProtect,
|
IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
||||||
DWORD dwMaximumSizeHigh,
|
IN DWORD flProtect,
|
||||||
DWORD dwMaximumSizeLow,
|
IN DWORD dwMaximumSizeHigh,
|
||||||
LPCSTR lpName)
|
IN DWORD dwMaximumSizeLow,
|
||||||
|
IN LPCSTR lpName)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE SectionHandle;
|
|
||||||
LARGE_INTEGER MaximumSize;
|
|
||||||
PLARGE_INTEGER MaximumSizePointer;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
ANSI_STRING AnsiName;
|
ANSI_STRING AnsiName;
|
||||||
UNICODE_STRING UnicodeName;
|
PUNICODE_STRING UnicodeCache;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
LPCWSTR UnicodeName = NULL;
|
||||||
|
|
||||||
if ((flProtect & (MASK_PAGE_FLAGS | MASK_SEC_FLAGS)) != flProtect)
|
/* Check for a name */
|
||||||
|
if (lpName)
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid flProtect 0x%08x\n", flProtect);
|
/* Use TEB Cache */
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (lpFileMappingAttributes)
|
|
||||||
{
|
|
||||||
SecurityDescriptor = lpFileMappingAttributes->lpSecurityDescriptor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SecurityDescriptor = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwMaximumSizeLow == 0 && dwMaximumSizeHigh == 0)
|
|
||||||
{
|
|
||||||
MaximumSizePointer = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaximumSize.u.LowPart = dwMaximumSizeLow;
|
|
||||||
MaximumSize.u.HighPart = dwMaximumSizeHigh;
|
|
||||||
MaximumSizePointer = &MaximumSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpName != NULL)
|
|
||||||
{
|
|
||||||
RtlInitAnsiString(&AnsiName,
|
|
||||||
(LPSTR)lpName);
|
|
||||||
RtlAnsiStringToUnicodeString(&UnicodeName,
|
|
||||||
&AnsiName,
|
|
||||||
TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
(lpName ? &UnicodeName : NULL),
|
|
||||||
0,
|
|
||||||
(lpName ? hBaseDir : NULL),
|
|
||||||
SecurityDescriptor);
|
|
||||||
|
|
||||||
Status = NtCreateSection(&SectionHandle,
|
|
||||||
SECTION_ALL_ACCESS,
|
|
||||||
&ObjectAttributes,
|
|
||||||
MaximumSizePointer,
|
|
||||||
flProtect & MASK_PAGE_FLAGS,
|
|
||||||
flProtect & MASK_SEC_FLAGS,
|
|
||||||
((hFile != INVALID_HANDLE_VALUE) ? hFile : NULL));
|
|
||||||
if (lpName != NULL)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString(&UnicodeName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Convert to unicode */
|
||||||
|
RtlInitAnsiString(&AnsiName, lpName);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* Conversion failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return SectionHandle;
|
|
||||||
|
/* Otherwise, save the buffer */
|
||||||
|
UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Call the Unicode version */
|
||||||
|
return CreateFileMappingW(hFile,
|
||||||
|
lpFileMappingAttributes,
|
||||||
|
flProtect,
|
||||||
|
dwMaximumSizeHigh,
|
||||||
|
dwMaximumSizeLow,
|
||||||
|
UnicodeName);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HANDLE STDCALL
|
HANDLE
|
||||||
|
NTAPI
|
||||||
CreateFileMappingW(HANDLE hFile,
|
CreateFileMappingW(HANDLE hFile,
|
||||||
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
||||||
DWORD flProtect,
|
DWORD flProtect,
|
||||||
|
@ -114,70 +75,85 @@ CreateFileMappingW(HANDLE hFile,
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE SectionHandle;
|
HANDLE SectionHandle;
|
||||||
LARGE_INTEGER MaximumSize;
|
OBJECT_ATTRIBUTES LocalAttributes;
|
||||||
PLARGE_INTEGER MaximumSizePointer;
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
UNICODE_STRING SectionName;
|
||||||
UNICODE_STRING UnicodeName;
|
ACCESS_MASK DesiredAccess;
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor;
|
LARGE_INTEGER LocalSize;
|
||||||
|
PLARGE_INTEGER SectionSize = NULL;
|
||||||
|
ULONG Attributes;
|
||||||
|
|
||||||
if ((flProtect & (MASK_PAGE_FLAGS | MASK_SEC_FLAGS)) != flProtect)
|
/* Set default access */
|
||||||
|
DesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ;
|
||||||
|
|
||||||
|
/* Get the attributes for the actual allocation and cleanup flProtect */
|
||||||
|
Attributes = flProtect & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT);
|
||||||
|
flProtect ^= Attributes;
|
||||||
|
|
||||||
|
/* If the caller didn't say anything, assume SEC_COMMIT */
|
||||||
|
if (!Attributes) Attributes = SEC_COMMIT;
|
||||||
|
|
||||||
|
/* Now check if the caller wanted write access */
|
||||||
|
if (flProtect == PAGE_READWRITE)
|
||||||
{
|
{
|
||||||
DPRINT1("Invalid flProtect 0x%08x\n", flProtect);
|
/* Give it */
|
||||||
|
DesiredAccess |= (SECTION_MAP_WRITE | SECTION_MAP_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now check if we got a name */
|
||||||
|
if (lpName) RtlInitUnicodeString(&SectionName, lpName);
|
||||||
|
|
||||||
|
/* Now convert the object attributes */
|
||||||
|
ObjectAttributes = BasepConvertObjectAttributes(&LocalAttributes,
|
||||||
|
lpFileMappingAttributes,
|
||||||
|
lpName ? &SectionName : NULL);
|
||||||
|
|
||||||
|
/* Check if we got a size */
|
||||||
|
if (dwMaximumSizeLow || dwMaximumSizeHigh)
|
||||||
|
{
|
||||||
|
/* Use a LARGE_INTEGER and convert */
|
||||||
|
SectionSize = &LocalSize;
|
||||||
|
SectionSize->LowPart = dwMaximumSizeLow;
|
||||||
|
SectionSize->HighPart = dwMaximumSizeHigh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure the handle is valid */
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
/* It's not, we'll only go on if we have a size */
|
||||||
|
hFile = NULL;
|
||||||
|
if (!SectionSize)
|
||||||
|
{
|
||||||
|
/* No size, so this isn't a valid non-mapped section */
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (lpFileMappingAttributes)
|
|
||||||
{
|
|
||||||
SecurityDescriptor = lpFileMappingAttributes->lpSecurityDescriptor;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SecurityDescriptor = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dwMaximumSizeLow == 0 && dwMaximumSizeHigh == 0)
|
/* Now create the actual section */
|
||||||
{
|
|
||||||
MaximumSizePointer = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MaximumSize.u.LowPart = dwMaximumSizeLow;
|
|
||||||
MaximumSize.u.HighPart = dwMaximumSizeHigh;
|
|
||||||
MaximumSizePointer = &MaximumSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpName != NULL)
|
|
||||||
{
|
|
||||||
RtlInitUnicodeString(&UnicodeName,
|
|
||||||
lpName);
|
|
||||||
}
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
(lpName ? &UnicodeName : NULL),
|
|
||||||
0,
|
|
||||||
(lpName ? hBaseDir : NULL),
|
|
||||||
SecurityDescriptor);
|
|
||||||
|
|
||||||
Status = NtCreateSection(&SectionHandle,
|
Status = NtCreateSection(&SectionHandle,
|
||||||
SECTION_ALL_ACCESS,
|
DesiredAccess,
|
||||||
&ObjectAttributes,
|
ObjectAttributes,
|
||||||
MaximumSizePointer,
|
SectionSize,
|
||||||
flProtect & MASK_PAGE_FLAGS,
|
flProtect,
|
||||||
flProtect & MASK_SEC_FLAGS,
|
Attributes,
|
||||||
((hFile != INVALID_HANDLE_VALUE) ? hFile : NULL));
|
hFile);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the section */
|
||||||
return SectionHandle;
|
return SectionHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LPVOID STDCALL
|
LPVOID
|
||||||
|
NTAPI
|
||||||
MapViewOfFileEx(HANDLE hFileMappingObject,
|
MapViewOfFileEx(HANDLE hFileMappingObject,
|
||||||
DWORD dwDesiredAccess,
|
DWORD dwDesiredAccess,
|
||||||
DWORD dwFileOffsetHigh,
|
DWORD dwFileOffsetHigh,
|
||||||
|
@ -189,38 +165,40 @@ MapViewOfFileEx(HANDLE hFileMappingObject,
|
||||||
LARGE_INTEGER SectionOffset;
|
LARGE_INTEGER SectionOffset;
|
||||||
ULONG ViewSize;
|
ULONG ViewSize;
|
||||||
ULONG Protect;
|
ULONG Protect;
|
||||||
LPVOID BaseAddress;
|
LPVOID ViewBase;
|
||||||
|
|
||||||
SectionOffset.u.LowPart = dwFileOffsetLow;
|
/* Convert the offset */
|
||||||
SectionOffset.u.HighPart = dwFileOffsetHigh;
|
SectionOffset.LowPart = dwFileOffsetLow;
|
||||||
|
SectionOffset.HighPart = dwFileOffsetHigh;
|
||||||
|
|
||||||
if ( ( dwDesiredAccess & FILE_MAP_WRITE) == FILE_MAP_WRITE)
|
/* Save the size and base */
|
||||||
|
ViewBase = lpBaseAddress;
|
||||||
|
ViewSize = dwNumberOfBytesToMap;
|
||||||
|
|
||||||
|
/* Convert flags to NT Protection Attributes */
|
||||||
|
if (dwDesiredAccess & FILE_MAP_WRITE)
|
||||||
|
{
|
||||||
Protect = PAGE_READWRITE;
|
Protect = PAGE_READWRITE;
|
||||||
else if ((dwDesiredAccess & FILE_MAP_READ) == FILE_MAP_READ)
|
}
|
||||||
|
else if (dwDesiredAccess & FILE_MAP_READ)
|
||||||
|
{
|
||||||
Protect = PAGE_READONLY;
|
Protect = PAGE_READONLY;
|
||||||
else if ((dwDesiredAccess & FILE_MAP_ALL_ACCESS) == FILE_MAP_ALL_ACCESS)
|
}
|
||||||
Protect = PAGE_READWRITE;
|
else if (dwDesiredAccess & FILE_MAP_COPY)
|
||||||
else if ((dwDesiredAccess & FILE_MAP_COPY) == FILE_MAP_COPY)
|
{
|
||||||
Protect = PAGE_WRITECOPY;
|
Protect = PAGE_WRITECOPY;
|
||||||
else
|
|
||||||
Protect = PAGE_READWRITE;
|
|
||||||
|
|
||||||
if (lpBaseAddress == NULL)
|
|
||||||
{
|
|
||||||
BaseAddress = NULL;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BaseAddress = lpBaseAddress;
|
Protect = PAGE_NOACCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewSize = (ULONG) dwNumberOfBytesToMap;
|
/* Map the section */
|
||||||
|
|
||||||
Status = ZwMapViewOfSection(hFileMappingObject,
|
Status = ZwMapViewOfSection(hFileMappingObject,
|
||||||
NtCurrentProcess(),
|
NtCurrentProcess(),
|
||||||
&BaseAddress,
|
&ViewBase,
|
||||||
|
0,
|
||||||
0,
|
0,
|
||||||
dwNumberOfBytesToMap,
|
|
||||||
&SectionOffset,
|
&SectionOffset,
|
||||||
&ViewSize,
|
&ViewSize,
|
||||||
ViewShare,
|
ViewShare,
|
||||||
|
@ -228,23 +206,27 @@ MapViewOfFileEx(HANDLE hFileMappingObject,
|
||||||
Protect);
|
Protect);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return BaseAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Return the base */
|
||||||
|
return ViewBase;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LPVOID STDCALL
|
LPVOID
|
||||||
|
NTAPI
|
||||||
MapViewOfFile(HANDLE hFileMappingObject,
|
MapViewOfFile(HANDLE hFileMappingObject,
|
||||||
DWORD dwDesiredAccess,
|
DWORD dwDesiredAccess,
|
||||||
DWORD dwFileOffsetHigh,
|
DWORD dwFileOffsetHigh,
|
||||||
DWORD dwFileOffsetLow,
|
DWORD dwFileOffsetLow,
|
||||||
DWORD dwNumberOfBytesToMap)
|
DWORD dwNumberOfBytesToMap)
|
||||||
{
|
{
|
||||||
|
/* Call the extended API */
|
||||||
return MapViewOfFileEx(hFileMappingObject,
|
return MapViewOfFileEx(hFileMappingObject,
|
||||||
dwDesiredAccess,
|
dwDesiredAccess,
|
||||||
dwFileOffsetHigh,
|
dwFileOffsetHigh,
|
||||||
|
@ -253,75 +235,75 @@ MapViewOfFile(HANDLE hFileMappingObject,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
|
NTAPI
|
||||||
UnmapViewOfFile(LPVOID lpBaseAddress)
|
UnmapViewOfFile(LPVOID lpBaseAddress)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
Status = NtUnmapViewOfSection(NtCurrentProcess(),
|
/* Unmap the section */
|
||||||
lpBaseAddress);
|
Status = NtUnmapViewOfSection(NtCurrentProcess(), lpBaseAddress);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Otherwise, return sucess */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HANDLE STDCALL
|
HANDLE
|
||||||
|
NTAPI
|
||||||
OpenFileMappingA(DWORD dwDesiredAccess,
|
OpenFileMappingA(DWORD dwDesiredAccess,
|
||||||
BOOL bInheritHandle,
|
BOOL bInheritHandle,
|
||||||
LPCSTR lpName)
|
LPCSTR lpName)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE SectionHandle;
|
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
||||||
ANSI_STRING AnsiName;
|
ANSI_STRING AnsiName;
|
||||||
UNICODE_STRING UnicodeName;
|
PUNICODE_STRING UnicodeCache;
|
||||||
|
|
||||||
if (lpName == NULL)
|
/* Check for a name */
|
||||||
|
if (lpName)
|
||||||
{
|
{
|
||||||
|
/* Use TEB Cache */
|
||||||
|
UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
|
||||||
|
|
||||||
|
/* Convert to unicode */
|
||||||
|
RtlInitAnsiString(&AnsiName, lpName);
|
||||||
|
Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Conversion failed */
|
||||||
|
SetLastErrorByStatus(Status);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We need a name */
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitAnsiString(&AnsiName,
|
/* Call the Unicode version */
|
||||||
(LPSTR)lpName);
|
return OpenFileMappingW(dwDesiredAccess,
|
||||||
RtlAnsiStringToUnicodeString(&UnicodeName,
|
bInheritHandle,
|
||||||
&AnsiName,
|
(LPCWSTR)UnicodeCache->Buffer);
|
||||||
TRUE);
|
|
||||||
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
|
||||||
&UnicodeName,
|
|
||||||
(bInheritHandle ? OBJ_INHERIT : 0),
|
|
||||||
hBaseDir,
|
|
||||||
NULL);
|
|
||||||
Status = NtOpenSection(&SectionHandle,
|
|
||||||
SECTION_ALL_ACCESS,
|
|
||||||
&ObjectAttributes);
|
|
||||||
RtlFreeUnicodeString (&UnicodeName);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastErrorByStatus (Status);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SectionHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
HANDLE STDCALL
|
HANDLE
|
||||||
|
NTAPI
|
||||||
OpenFileMappingW(DWORD dwDesiredAccess,
|
OpenFileMappingW(DWORD dwDesiredAccess,
|
||||||
BOOL bInheritHandle,
|
BOOL bInheritHandle,
|
||||||
LPCWSTR lpName)
|
LPCWSTR lpName)
|
||||||
|
@ -331,51 +313,64 @@ OpenFileMappingW(DWORD dwDesiredAccess,
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
UNICODE_STRING UnicodeName;
|
UNICODE_STRING UnicodeName;
|
||||||
|
|
||||||
if (lpName == NULL)
|
/* We need a name */
|
||||||
|
if (!lpName)
|
||||||
{
|
{
|
||||||
|
/* Otherwise, fail */
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitUnicodeString(&UnicodeName,
|
/* Convert attributes */
|
||||||
lpName);
|
RtlInitUnicodeString(&UnicodeName, lpName);
|
||||||
InitializeObjectAttributes(&ObjectAttributes,
|
InitializeObjectAttributes(&ObjectAttributes,
|
||||||
&UnicodeName,
|
&UnicodeName,
|
||||||
(bInheritHandle ? OBJ_INHERIT : 0),
|
(bInheritHandle ? OBJ_INHERIT : 0),
|
||||||
hBaseDir,
|
hBaseDir,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
|
/* Convert COPY to READ */
|
||||||
|
if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ;
|
||||||
|
|
||||||
|
/* Open the section */
|
||||||
Status = ZwOpenSection(&SectionHandle,
|
Status = ZwOpenSection(&SectionHandle,
|
||||||
SECTION_ALL_ACCESS,
|
dwDesiredAccess,
|
||||||
&ObjectAttributes);
|
&ObjectAttributes);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Otherwise, return the handle */
|
||||||
return SectionHandle;
|
return SectionHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
|
NTAPI
|
||||||
FlushViewOfFile(LPCVOID lpBaseAddress,
|
FlushViewOfFile(LPCVOID lpBaseAddress,
|
||||||
DWORD dwNumberOfBytesToFlush)
|
DWORD dwNumberOfBytesToFlush)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG NumberOfBytesFlushed;
|
ULONG NumberOfBytesFlushed;
|
||||||
|
|
||||||
|
/* Flush the view */
|
||||||
Status = NtFlushVirtualMemory(NtCurrentProcess(),
|
Status = NtFlushVirtualMemory(NtCurrentProcess(),
|
||||||
(LPVOID)lpBaseAddress,
|
(LPVOID)lpBaseAddress,
|
||||||
dwNumberOfBytesToFlush,
|
dwNumberOfBytesToFlush,
|
||||||
&NumberOfBytesFlushed);
|
&NumberOfBytesFlushed);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
/* $Id$
|
/*
|
||||||
*
|
* PROJECT: ReactOS Win32 Base API
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* FILE: dll/win32/kernel32/mem/virtual.c
|
||||||
* FILE: lib/kernel32/mem/virtual.c
|
* PURPOSE: Handles virtual memory APIs
|
||||||
* PURPOSE: Passing the Virtualxxx functions onto the kernel
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
@ -12,22 +11,24 @@
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "../include/debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LPVOID STDCALL
|
LPVOID
|
||||||
VirtualAllocEx(HANDLE hProcess,
|
NTAPI
|
||||||
LPVOID lpAddress,
|
VirtualAllocEx(IN HANDLE hProcess,
|
||||||
SIZE_T dwSize,
|
IN LPVOID lpAddress,
|
||||||
DWORD flAllocationType,
|
IN SIZE_T dwSize,
|
||||||
DWORD flProtect)
|
IN DWORD flAllocationType,
|
||||||
|
IN DWORD flProtect)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Allocate the memory */
|
||||||
Status = NtAllocateVirtualMemory(hProcess,
|
Status = NtAllocateVirtualMemory(hProcess,
|
||||||
(PVOID *)&lpAddress,
|
(PVOID *)&lpAddress,
|
||||||
0,
|
0,
|
||||||
|
@ -36,98 +37,109 @@ VirtualAllocEx(HANDLE hProcess,
|
||||||
flProtect);
|
flProtect);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return(NULL);
|
return NULL;
|
||||||
}
|
|
||||||
return(lpAddress);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the allocated address */
|
||||||
|
return lpAddress;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LPVOID STDCALL
|
LPVOID
|
||||||
VirtualAlloc(LPVOID lpAddress,
|
NTAPI
|
||||||
SIZE_T dwSize,
|
VirtualAlloc(IN LPVOID lpAddress,
|
||||||
DWORD flAllocationType,
|
IN SIZE_T dwSize,
|
||||||
DWORD flProtect)
|
IN DWORD flAllocationType,
|
||||||
|
IN DWORD flProtect)
|
||||||
{
|
{
|
||||||
return(VirtualAllocEx(GetCurrentProcess(),
|
/* Call the extended API */
|
||||||
|
return VirtualAllocEx(GetCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
dwSize,
|
dwSize,
|
||||||
flAllocationType,
|
flAllocationType,
|
||||||
flProtect));
|
flProtect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualFreeEx(HANDLE hProcess,
|
NTAPI
|
||||||
LPVOID lpAddress,
|
VirtualFreeEx(IN HANDLE hProcess,
|
||||||
SIZE_T dwSize,
|
IN LPVOID lpAddress,
|
||||||
DWORD dwFreeType)
|
IN SIZE_T dwSize,
|
||||||
|
IN DWORD dwFreeType)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Free the memory */
|
||||||
Status = NtFreeVirtualMemory(hProcess,
|
Status = NtFreeVirtualMemory(hProcess,
|
||||||
(PVOID *)&lpAddress,
|
(PVOID *)&lpAddress,
|
||||||
(PULONG)&dwSize,
|
(PULONG)&dwSize,
|
||||||
dwFreeType);
|
dwFreeType);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualFree(LPVOID lpAddress,
|
NTAPI
|
||||||
SIZE_T dwSize,
|
VirtualFree(IN LPVOID lpAddress,
|
||||||
DWORD dwFreeType)
|
IN SIZE_T dwSize,
|
||||||
|
IN DWORD dwFreeType)
|
||||||
{
|
{
|
||||||
return(VirtualFreeEx(GetCurrentProcess(),
|
/* Call the extended API */
|
||||||
|
return VirtualFreeEx(GetCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
dwSize,
|
dwSize,
|
||||||
dwFreeType));
|
dwFreeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualProtect(LPVOID lpAddress,
|
NTAPI
|
||||||
SIZE_T dwSize,
|
VirtualProtect(IN LPVOID lpAddress,
|
||||||
DWORD flNewProtect,
|
IN SIZE_T dwSize,
|
||||||
PDWORD lpflOldProtect)
|
IN DWORD flNewProtect,
|
||||||
|
OUT PDWORD lpflOldProtect)
|
||||||
{
|
{
|
||||||
return(VirtualProtectEx(GetCurrentProcess(),
|
/* Call the extended API */
|
||||||
|
return VirtualProtectEx(GetCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
dwSize,
|
dwSize,
|
||||||
flNewProtect,
|
flNewProtect,
|
||||||
lpflOldProtect));
|
lpflOldProtect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualProtectEx(HANDLE hProcess,
|
NTAPI
|
||||||
LPVOID lpAddress,
|
VirtualProtectEx(IN HANDLE hProcess,
|
||||||
SIZE_T dwSize,
|
IN LPVOID lpAddress,
|
||||||
DWORD flNewProtect,
|
IN SIZE_T dwSize,
|
||||||
PDWORD lpflOldProtect)
|
IN DWORD flNewProtect,
|
||||||
|
OUT PDWORD lpflOldProtect)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Change the protection */
|
||||||
Status = NtProtectVirtualMemory(hProcess,
|
Status = NtProtectVirtualMemory(hProcess,
|
||||||
&lpAddress,
|
&lpAddress,
|
||||||
&dwSize,
|
&dwSize,
|
||||||
|
@ -135,63 +147,72 @@ VirtualProtectEx(HANDLE hProcess,
|
||||||
(PULONG)lpflOldProtect);
|
(PULONG)lpflOldProtect);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualLock(LPVOID lpAddress,
|
NTAPI
|
||||||
SIZE_T dwSize)
|
VirtualLock(IN LPVOID lpAddress,
|
||||||
|
IN SIZE_T dwSize)
|
||||||
{
|
{
|
||||||
ULONG BytesLocked;
|
ULONG BytesLocked;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Lock the memory */
|
||||||
Status = NtLockVirtualMemory(NtCurrentProcess(),
|
Status = NtLockVirtualMemory(NtCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
dwSize,
|
dwSize,
|
||||||
&BytesLocked);
|
&BytesLocked);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
|
||||||
return(TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
DWORD STDCALL
|
DWORD
|
||||||
VirtualQuery(LPCVOID lpAddress,
|
NTAPI
|
||||||
PMEMORY_BASIC_INFORMATION lpBuffer,
|
VirtualQuery(IN LPCVOID lpAddress,
|
||||||
SIZE_T dwLength)
|
OUT PMEMORY_BASIC_INFORMATION lpBuffer,
|
||||||
|
IN SIZE_T dwLength)
|
||||||
{
|
{
|
||||||
return(VirtualQueryEx(NtCurrentProcess(),
|
/* Call the extended API */
|
||||||
|
return VirtualQueryEx(NtCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
lpBuffer,
|
lpBuffer,
|
||||||
dwLength));
|
dwLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
DWORD STDCALL
|
DWORD
|
||||||
VirtualQueryEx(HANDLE hProcess,
|
NTAPI
|
||||||
LPCVOID lpAddress,
|
VirtualQueryEx(IN HANDLE hProcess,
|
||||||
PMEMORY_BASIC_INFORMATION lpBuffer,
|
IN LPCVOID lpAddress,
|
||||||
SIZE_T dwLength)
|
OUT PMEMORY_BASIC_INFORMATION lpBuffer,
|
||||||
|
IN SIZE_T dwLength)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG ResultLength;
|
ULONG ResultLength;
|
||||||
|
|
||||||
|
/* Query basic information */
|
||||||
Status = NtQueryVirtualMemory(hProcess,
|
Status = NtQueryVirtualMemory(hProcess,
|
||||||
(LPVOID)lpAddress,
|
(LPVOID)lpAddress,
|
||||||
MemoryBasicInformation,
|
MemoryBasicInformation,
|
||||||
|
@ -200,33 +221,40 @@ VirtualQueryEx(HANDLE hProcess,
|
||||||
&ResultLength);
|
&ResultLength);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return(ResultLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Return the length returned */
|
||||||
|
return ResultLength;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL
|
||||||
VirtualUnlock(LPVOID lpAddress,
|
NTAPI
|
||||||
SIZE_T dwSize)
|
VirtualUnlock(IN LPVOID lpAddress,
|
||||||
|
IN SIZE_T dwSize)
|
||||||
{
|
{
|
||||||
ULONG BytesLocked;
|
ULONG BytesLocked;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Unlock the memory */
|
||||||
Status = NtUnlockVirtualMemory(NtCurrentProcess(),
|
Status = NtUnlockVirtualMemory(NtCurrentProcess(),
|
||||||
lpAddress,
|
lpAddress,
|
||||||
dwSize,
|
dwSize,
|
||||||
&BytesLocked);
|
&BytesLocked);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
/* We failed */
|
||||||
SetLastErrorByStatus(Status);
|
SetLastErrorByStatus(Status);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
return(TRUE);
|
|
||||||
|
/* Return success */
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue