[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;
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 */

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

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,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 */