[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:
Alex Ionescu 2006-06-22 23:06:14 +00:00
parent b1d543c345
commit 3b350f6972
3 changed files with 577 additions and 555 deletions

View file

@ -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; /* Do the read */
Status = NtReadVirtualMemory(hProcess,
(PVOID)lpBaseAddress,
lpBuffer,
nSize,
lpNumberOfBytesRead);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus (Status);
return FALSE;
}
Status = NtReadVirtualMemory( hProcess, (PVOID)lpBaseAddress,lpBuffer, nSize, /* Return success */
(PULONG)lpNumberOfBytesRead return TRUE;
);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus (Status);
return FALSE;
}
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;
BOOLEAN UnProtect; PVOID Base;
BOOLEAN UnProtect;
if (lpNumberOfBytesWritten) /* Set parameters for protect call */
RegionSize = nSize;
Base = lpBaseAddress;
/* Check the current status */
Status = NtProtectVirtualMemory(hProcess,
&Base,
&RegionSize,
PAGE_EXECUTE_READWRITE,
&OldValue);
if (NT_SUCCESS(Status))
{
/* Check if we are unprotecting */
UnProtect = OldValue & (PAGE_READWRITE |
PAGE_WRITECOPY |
PAGE_EXECUTE_READWRITE |
PAGE_EXECUTE_WRITECOPY) ? FALSE : TRUE;
if (UnProtect)
{ {
*lpNumberOfBytesWritten = 0; /* Set the new protection */
} Status = NtProtectVirtualMemory(hProcess,
&Base,
while (nSize) &RegionSize,
{ OldValue,
Status = NtQueryVirtualMemory(hProcess, &OldValue);
lpBaseAddress,
MemoryBasicInformation,
&MemInfo,
sizeof(MEMORY_BASIC_INFORMATION),
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)
{
MemInfo.BaseAddress = lpBaseAddress;
MemInfo.RegionSize = Length;
if (MemInfo.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ))
{
MemInfo.Protect &= ~(PAGE_EXECUTE|PAGE_EXECUTE_READ);
MemInfo.Protect |= PAGE_EXECUTE_READWRITE;
}
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))
{
SetLastErrorByStatus (Status);
return FALSE;
}
if (UnProtect && !NT_SUCCESS(ProtectStatus))
{ {
SetLastErrorByStatus (ProtectStatus); /* We failed */
SetLastErrorByStatus(Status);
return FALSE; return FALSE;
} }
lpBaseAddress = (LPVOID)((ULONG_PTR)lpBaseAddress + Length);
lpBuffer = (LPCVOID)((ULONG_PTR)lpBuffer + Length); /* Flush the ITLB */
nSize -= Length; NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
if (lpNumberOfBytesWritten) return TRUE;
{
*lpNumberOfBytesWritten += Length;
}
} }
return TRUE; else
{
/* 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;
}
/* Otherwise, do the write */
Status = NtWriteVirtualMemory(hProcess,
lpBaseAddress,
(LPVOID)lpBuffer,
nSize,
lpNumberOfBytesWritten);
/* And restore the protection */
NtProtectVirtualMemory(hProcess,
&Base,
&RegionSize,
OldValue,
&OldValue);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(STATUS_ACCESS_VIOLATION);
return FALSE;
}
/* Flush the ITLB */
NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
return TRUE;
}
}
else
{
/* We failed */
SetLastErrorByStatus(Status);
return FALSE;
}
} }
/* EOF */ /* EOF */

View file

@ -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,371 +11,367 @@
#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; ANSI_STRING AnsiName;
LARGE_INTEGER MaximumSize; PUNICODE_STRING UnicodeCache;
PLARGE_INTEGER MaximumSizePointer; LPCWSTR UnicodeName = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
ANSI_STRING AnsiName;
UNICODE_STRING UnicodeName;
PSECURITY_DESCRIPTOR SecurityDescriptor;
if ((flProtect & (MASK_PAGE_FLAGS | MASK_SEC_FLAGS)) != flProtect) /* Check for a name */
{ if (lpName)
DPRINT1("Invalid flProtect 0x%08x\n", flProtect); {
SetLastError(ERROR_INVALID_PARAMETER); /* Use TEB Cache */
return NULL; UnicodeCache = &NtCurrentTeb()->StaticUnicodeString;
}
if (lpFileMappingAttributes)
{
SecurityDescriptor = lpFileMappingAttributes->lpSecurityDescriptor;
}
else
{
SecurityDescriptor = NULL;
}
if (dwMaximumSizeLow == 0 && dwMaximumSizeHigh == 0) /* Convert to unicode */
{ RtlInitAnsiString(&AnsiName, lpName);
MaximumSizePointer = NULL; Status = RtlAnsiStringToUnicodeString(UnicodeCache, &AnsiName, FALSE);
} if (!NT_SUCCESS(Status))
else {
{ /* Conversion failed */
MaximumSize.u.LowPart = dwMaximumSizeLow; SetLastErrorByStatus(Status);
MaximumSize.u.HighPart = dwMaximumSizeHigh; return NULL;
MaximumSizePointer = &MaximumSize; }
}
if (lpName != NULL) /* Otherwise, save the buffer */
{ UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
RtlInitAnsiString(&AnsiName, }
(LPSTR)lpName);
RtlAnsiStringToUnicodeString(&UnicodeName,
&AnsiName,
TRUE);
}
InitializeObjectAttributes(&ObjectAttributes, /* Call the Unicode version */
(lpName ? &UnicodeName : NULL), return CreateFileMappingW(hFile,
0, lpFileMappingAttributes,
(lpName ? hBaseDir : NULL), flProtect,
SecurityDescriptor); dwMaximumSizeHigh,
dwMaximumSizeLow,
Status = NtCreateSection(&SectionHandle, UnicodeName);
SECTION_ALL_ACCESS,
&ObjectAttributes,
MaximumSizePointer,
flProtect & MASK_PAGE_FLAGS,
flProtect & MASK_SEC_FLAGS,
((hFile != INVALID_HANDLE_VALUE) ? hFile : NULL));
if (lpName != NULL)
{
RtlFreeUnicodeString(&UnicodeName);
}
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return NULL;
}
return SectionHandle;
} }
/* /*
* @implemented * @implemented
*/ */
HANDLE STDCALL HANDLE
NTAPI
CreateFileMappingW(HANDLE hFile, CreateFileMappingW(HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes, LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect, DWORD flProtect,
DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow, DWORD dwMaximumSizeLow,
LPCWSTR lpName) LPCWSTR lpName)
{ {
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;
DPRINT1("Invalid flProtect 0x%08x\n", flProtect);
SetLastError(ERROR_INVALID_PARAMETER); /* 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)
{
/* 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);
return NULL;
}
}
/* Now create the actual section */
Status = NtCreateSection(&SectionHandle,
DesiredAccess,
ObjectAttributes,
SectionSize,
flProtect,
Attributes,
hFile);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return NULL; return NULL;
} }
if (lpFileMappingAttributes)
{
SecurityDescriptor = lpFileMappingAttributes->lpSecurityDescriptor;
}
else
{
SecurityDescriptor = NULL;
}
if (dwMaximumSizeLow == 0 && dwMaximumSizeHigh == 0) /* Return the section */
{ return SectionHandle;
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,
SECTION_ALL_ACCESS,
&ObjectAttributes,
MaximumSizePointer,
flProtect & MASK_PAGE_FLAGS,
flProtect & MASK_SEC_FLAGS,
((hFile != INVALID_HANDLE_VALUE) ? hFile : NULL));
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return NULL;
}
return SectionHandle;
} }
/* /*
* @implemented * @implemented
*/ */
LPVOID STDCALL LPVOID
NTAPI
MapViewOfFileEx(HANDLE hFileMappingObject, MapViewOfFileEx(HANDLE hFileMappingObject,
DWORD dwDesiredAccess, DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh, DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow, DWORD dwFileOffsetLow,
DWORD dwNumberOfBytesToMap, DWORD dwNumberOfBytesToMap,
LPVOID lpBaseAddress) LPVOID lpBaseAddress)
{ {
NTSTATUS Status; NTSTATUS Status;
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 */
Protect = PAGE_READWRITE; ViewBase = lpBaseAddress;
else if ((dwDesiredAccess & FILE_MAP_READ) == FILE_MAP_READ) ViewSize = dwNumberOfBytesToMap;
Protect = PAGE_READONLY;
else if ((dwDesiredAccess & FILE_MAP_ALL_ACCESS) == FILE_MAP_ALL_ACCESS)
Protect = PAGE_READWRITE;
else if ((dwDesiredAccess & FILE_MAP_COPY) == FILE_MAP_COPY)
Protect = PAGE_WRITECOPY;
else
Protect = PAGE_READWRITE;
if (lpBaseAddress == NULL) /* Convert flags to NT Protection Attributes */
{ if (dwDesiredAccess & FILE_MAP_WRITE)
BaseAddress = NULL; {
} Protect = PAGE_READWRITE;
else }
{ else if (dwDesiredAccess & FILE_MAP_READ)
BaseAddress = lpBaseAddress; {
} Protect = PAGE_READONLY;
}
else if (dwDesiredAccess & FILE_MAP_COPY)
{
Protect = PAGE_WRITECOPY;
}
else
{
Protect = PAGE_NOACCESS;
}
ViewSize = (ULONG) dwNumberOfBytesToMap; /* Map the section */
Status = ZwMapViewOfSection(hFileMappingObject,
NtCurrentProcess(),
&ViewBase,
0,
0,
&SectionOffset,
&ViewSize,
ViewShare,
0,
Protect);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return NULL;
}
Status = ZwMapViewOfSection(hFileMappingObject, /* Return the base */
NtCurrentProcess(), return ViewBase;
&BaseAddress,
0,
dwNumberOfBytesToMap,
&SectionOffset,
&ViewSize,
ViewShare,
0,
Protect);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return NULL;
}
return BaseAddress;
} }
/* /*
* @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)
{ {
return MapViewOfFileEx(hFileMappingObject, /* Call the extended API */
dwDesiredAccess, return MapViewOfFileEx(hFileMappingObject,
dwFileOffsetHigh, dwDesiredAccess,
dwFileOffsetLow, dwFileOffsetHigh,
dwNumberOfBytesToMap, dwFileOffsetLow,
NULL); dwNumberOfBytesToMap,
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))
{ {
SetLastErrorByStatus(Status); /* We failed */
return FALSE; SetLastErrorByStatus(Status);
} return FALSE;
return TRUE; }
/* Otherwise, return sucess */
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; ANSI_STRING AnsiName;
OBJECT_ATTRIBUTES ObjectAttributes; PUNICODE_STRING UnicodeCache;
ANSI_STRING AnsiName;
UNICODE_STRING UnicodeName;
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)
{ {
NTSTATUS Status; NTSTATUS Status;
HANDLE SectionHandle; HANDLE SectionHandle;
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);
Status = ZwOpenSection(&SectionHandle,
SECTION_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
return NULL;
}
return SectionHandle; /* Convert COPY to READ */
if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ;
/* Open the section */
Status = ZwOpenSection(&SectionHandle,
dwDesiredAccess,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return NULL;
}
/* Otherwise, return the handle */
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;
Status = NtFlushVirtualMemory(NtCurrentProcess(), /* Flush the view */
(LPVOID)lpBaseAddress, Status = NtFlushVirtualMemory(NtCurrentProcess(),
dwNumberOfBytesToFlush, (LPVOID)lpBaseAddress,
&NumberOfBytesFlushed); dwNumberOfBytesToFlush,
if (!NT_SUCCESS(Status)) &NumberOfBytesFlushed);
{ if (!NT_SUCCESS(Status))
SetLastErrorByStatus(Status); {
return FALSE; /* We failed */
} SetLastErrorByStatus(Status);
return TRUE; return FALSE;
}
/* Return success */
return TRUE;
} }
/* EOF */ /* EOF */

View file

@ -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,221 +11,250 @@
#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;
Status = NtAllocateVirtualMemory(hProcess, /* Allocate the memory */
(PVOID *)&lpAddress, Status = NtAllocateVirtualMemory(hProcess,
0, (PVOID *)&lpAddress,
&dwSize, 0,
flAllocationType, &dwSize,
flProtect); flAllocationType,
if (!NT_SUCCESS(Status)) flProtect);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return(NULL); SetLastErrorByStatus(Status);
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 */
lpAddress, return VirtualAllocEx(GetCurrentProcess(),
dwSize, lpAddress,
flAllocationType, dwSize,
flProtect)); flAllocationType,
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;
Status = NtFreeVirtualMemory(hProcess, /* Free the memory */
(PVOID *)&lpAddress, Status = NtFreeVirtualMemory(hProcess,
(PULONG)&dwSize, (PVOID *)&lpAddress,
dwFreeType); (PULONG)&dwSize,
if (!NT_SUCCESS(Status)) dwFreeType);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return(FALSE); SetLastErrorByStatus(Status);
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 */
lpAddress, return VirtualFreeEx(GetCurrentProcess(),
dwSize, lpAddress,
dwFreeType)); dwSize,
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 */
lpAddress, return VirtualProtectEx(GetCurrentProcess(),
dwSize, lpAddress,
flNewProtect, dwSize,
lpflOldProtect)); flNewProtect,
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;
Status = NtProtectVirtualMemory(hProcess, /* Change the protection */
&lpAddress, Status = NtProtectVirtualMemory(hProcess,
&dwSize, &lpAddress,
flNewProtect, &dwSize,
(PULONG)lpflOldProtect); flNewProtect,
if (!NT_SUCCESS(Status)) (PULONG)lpflOldProtect);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return(FALSE); SetLastErrorByStatus(Status);
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;
Status = NtLockVirtualMemory(NtCurrentProcess(), /* Lock the memory */
lpAddress, Status = NtLockVirtualMemory(NtCurrentProcess(),
dwSize, lpAddress,
&BytesLocked); dwSize,
if (!NT_SUCCESS(Status)) &BytesLocked);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return(FALSE); SetLastErrorByStatus(Status);
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 */
lpAddress, return VirtualQueryEx(NtCurrentProcess(),
lpBuffer, lpAddress,
dwLength)); lpBuffer,
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;
Status = NtQueryVirtualMemory(hProcess, /* Query basic information */
(LPVOID)lpAddress, Status = NtQueryVirtualMemory(hProcess,
MemoryBasicInformation, (LPVOID)lpAddress,
lpBuffer, MemoryBasicInformation,
sizeof(MEMORY_BASIC_INFORMATION), lpBuffer,
&ResultLength ); sizeof(MEMORY_BASIC_INFORMATION),
if (!NT_SUCCESS(Status)) &ResultLength);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return 0; SetLastErrorByStatus(Status);
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;
Status = NtUnlockVirtualMemory(NtCurrentProcess(), /* Unlock the memory */
lpAddress, Status = NtUnlockVirtualMemory(NtCurrentProcess(),
dwSize, lpAddress,
&BytesLocked); dwSize,
if (!NT_SUCCESS(Status)) &BytesLocked);
if (!NT_SUCCESS(Status))
{ {
SetLastErrorByStatus(Status); /* We failed */
return(FALSE); SetLastErrorByStatus(Status);
return FALSE;
} }
return(TRUE);
/* Return success */
return TRUE;
} }
/* EOF */ /* EOF */