2006-06-22 23:06:14 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Win32 Base API
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
|
|
* FILE: dll/win32/kernel32/mem/section.c
|
|
|
|
* PURPOSE: Handles virtual memory APIs
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
1999-04-18 08:56:23 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#include <k32.h>
|
1999-04-18 08:56:23 +00:00
|
|
|
|
2003-01-15 21:24:36 +00:00
|
|
|
#define NDEBUG
|
2007-09-02 19:42:22 +00:00
|
|
|
#include <debug.h>
|
2001-02-17 17:42:46 +00:00
|
|
|
|
1999-04-18 08:56:23 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
HANDLE
|
|
|
|
NTAPI
|
|
|
|
CreateFileMappingA(IN HANDLE hFile,
|
|
|
|
IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
|
|
|
IN DWORD flProtect,
|
|
|
|
IN DWORD dwMaximumSizeHigh,
|
|
|
|
IN DWORD dwMaximumSizeLow,
|
|
|
|
IN LPCSTR lpName)
|
1999-04-18 08:56:23 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ANSI_STRING AnsiName;
|
|
|
|
PUNICODE_STRING UnicodeCache;
|
|
|
|
LPCWSTR UnicodeName = 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, save the buffer */
|
|
|
|
UnicodeName = (LPCWSTR)UnicodeCache->Buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Call the Unicode version */
|
|
|
|
return CreateFileMappingW(hFile,
|
|
|
|
lpFileMappingAttributes,
|
|
|
|
flProtect,
|
|
|
|
dwMaximumSizeHigh,
|
|
|
|
dwMaximumSizeLow,
|
|
|
|
UnicodeName);
|
1999-04-18 08:56:23 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
HANDLE
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
CreateFileMappingW(HANDLE hFile,
|
2006-06-22 23:06:14 +00:00
|
|
|
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
|
|
|
|
DWORD flProtect,
|
|
|
|
DWORD dwMaximumSizeHigh,
|
|
|
|
DWORD dwMaximumSizeLow,
|
|
|
|
LPCWSTR lpName)
|
1999-04-18 08:56:23 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE SectionHandle;
|
|
|
|
OBJECT_ATTRIBUTES LocalAttributes;
|
|
|
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
UNICODE_STRING SectionName;
|
|
|
|
ACCESS_MASK DesiredAccess;
|
|
|
|
LARGE_INTEGER LocalSize;
|
|
|
|
PLARGE_INTEGER SectionSize = NULL;
|
|
|
|
ULONG Attributes;
|
|
|
|
|
|
|
|
/* Set default access */
|
|
|
|
DesiredAccess = STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ;
|
|
|
|
|
|
|
|
/* Get the attributes for the actual allocation and cleanup flProtect */
|
2010-10-02 01:12:53 +00:00
|
|
|
Attributes = flProtect & (SEC_FILE | SEC_IMAGE | SEC_RESERVE | SEC_NOCACHE | SEC_COMMIT | SEC_LARGE_PAGES);
|
2006-06-22 23:06:14 +00:00
|
|
|
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);
|
2009-05-12 08:58:38 +00:00
|
|
|
|
|
|
|
if (Status == STATUS_OBJECT_NAME_EXISTS)
|
|
|
|
{
|
|
|
|
SetLastError(ERROR_ALREADY_EXISTS);
|
|
|
|
return SectionHandle;
|
|
|
|
}
|
|
|
|
|
2006-06-22 23:06:14 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus(Status);
|
2003-12-16 21:32:18 +00:00
|
|
|
return NULL;
|
2006-06-22 23:06:14 +00:00
|
|
|
}
|
1999-04-18 08:56:23 +00:00
|
|
|
|
2009-05-12 08:58:38 +00:00
|
|
|
SetLastError(ERROR_SUCCESS);
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Return the section */
|
|
|
|
return SectionHandle;
|
|
|
|
}
|
1999-10-03 23:19:15 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
LPVOID
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
MapViewOfFileEx(HANDLE hFileMappingObject,
|
2006-06-22 23:06:14 +00:00
|
|
|
DWORD dwDesiredAccess,
|
|
|
|
DWORD dwFileOffsetHigh,
|
|
|
|
DWORD dwFileOffsetLow,
|
2008-10-23 18:19:20 +00:00
|
|
|
SIZE_T dwNumberOfBytesToMap,
|
2006-06-22 23:06:14 +00:00
|
|
|
LPVOID lpBaseAddress)
|
1999-04-18 08:56:23 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
LARGE_INTEGER SectionOffset;
|
2008-10-23 18:19:20 +00:00
|
|
|
SIZE_T ViewSize;
|
2006-06-22 23:06:14 +00:00
|
|
|
ULONG Protect;
|
|
|
|
LPVOID ViewBase;
|
|
|
|
|
|
|
|
/* Convert the offset */
|
|
|
|
SectionOffset.LowPart = dwFileOffsetLow;
|
|
|
|
SectionOffset.HighPart = dwFileOffsetHigh;
|
|
|
|
|
|
|
|
/* Save the size and base */
|
|
|
|
ViewBase = lpBaseAddress;
|
|
|
|
ViewSize = dwNumberOfBytesToMap;
|
|
|
|
|
|
|
|
/* Convert flags to NT Protection Attributes */
|
|
|
|
if (dwDesiredAccess & FILE_MAP_WRITE)
|
|
|
|
{
|
|
|
|
Protect = PAGE_READWRITE;
|
|
|
|
}
|
|
|
|
else if (dwDesiredAccess & FILE_MAP_READ)
|
|
|
|
{
|
|
|
|
Protect = PAGE_READONLY;
|
|
|
|
}
|
|
|
|
else if (dwDesiredAccess & FILE_MAP_COPY)
|
|
|
|
{
|
|
|
|
Protect = PAGE_WRITECOPY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Protect = PAGE_NOACCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
1999-09-27 20:58:46 +00:00
|
|
|
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Return the base */
|
|
|
|
return ViewBase;
|
|
|
|
}
|
2001-02-17 17:42:46 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
LPVOID
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
MapViewOfFile(HANDLE hFileMappingObject,
|
2006-06-22 23:06:14 +00:00
|
|
|
DWORD dwDesiredAccess,
|
|
|
|
DWORD dwFileOffsetHigh,
|
|
|
|
DWORD dwFileOffsetLow,
|
2008-10-23 18:19:20 +00:00
|
|
|
SIZE_T dwNumberOfBytesToMap)
|
1999-09-27 20:58:46 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Call the extended API */
|
|
|
|
return MapViewOfFileEx(hFileMappingObject,
|
|
|
|
dwDesiredAccess,
|
|
|
|
dwFileOffsetHigh,
|
|
|
|
dwFileOffsetLow,
|
|
|
|
dwNumberOfBytesToMap,
|
|
|
|
NULL);
|
1999-09-27 20:58:46 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
BOOL
|
|
|
|
NTAPI
|
2008-08-02 09:29:16 +00:00
|
|
|
UnmapViewOfFile(LPCVOID lpBaseAddress)
|
1999-09-27 20:58:46 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* Unmap the section */
|
2008-08-02 09:29:16 +00:00
|
|
|
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
|
2006-06-22 23:06:14 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, return sucess */
|
|
|
|
return TRUE;
|
1999-09-27 20:58:46 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
HANDLE
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
OpenFileMappingA(DWORD dwDesiredAccess,
|
2006-06-22 23:06:14 +00:00
|
|
|
BOOL bInheritHandle,
|
|
|
|
LPCSTR lpName)
|
1999-09-27 20:58:46 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
ANSI_STRING AnsiName;
|
|
|
|
PUNICODE_STRING UnicodeCache;
|
|
|
|
|
|
|
|
/* 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 */
|
2004-10-24 12:55:19 +00:00
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
2006-06-22 23:06:14 +00:00
|
|
|
}
|
1999-09-27 20:58:46 +00:00
|
|
|
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Call the Unicode version */
|
|
|
|
return OpenFileMappingW(dwDesiredAccess,
|
|
|
|
bInheritHandle,
|
|
|
|
(LPCWSTR)UnicodeCache->Buffer);
|
|
|
|
}
|
1999-10-03 23:19:15 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
HANDLE
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
OpenFileMappingW(DWORD dwDesiredAccess,
|
2006-06-22 23:06:14 +00:00
|
|
|
BOOL bInheritHandle,
|
|
|
|
LPCWSTR lpName)
|
1999-09-27 20:58:46 +00:00
|
|
|
{
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
HANDLE SectionHandle;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
UNICODE_STRING UnicodeName;
|
|
|
|
|
|
|
|
/* We need a name */
|
|
|
|
if (!lpName)
|
|
|
|
{
|
|
|
|
/* Otherwise, fail */
|
2004-10-24 12:55:19 +00:00
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
return NULL;
|
2006-06-22 23:06:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert attributes */
|
|
|
|
RtlInitUnicodeString(&UnicodeName, lpName);
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&UnicodeName,
|
|
|
|
(bInheritHandle ? OBJ_INHERIT : 0),
|
|
|
|
hBaseDir,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
}
|
1999-09-27 20:58:46 +00:00
|
|
|
|
2009-05-12 08:58:38 +00:00
|
|
|
SetLastError(ERROR_SUCCESS);
|
2006-06-22 23:06:14 +00:00
|
|
|
/* Otherwise, return the handle */
|
|
|
|
return SectionHandle;
|
|
|
|
}
|
2001-02-17 17:42:46 +00:00
|
|
|
|
2003-07-10 18:50:51 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-06-22 23:06:14 +00:00
|
|
|
BOOL
|
|
|
|
NTAPI
|
2001-02-17 17:42:46 +00:00
|
|
|
FlushViewOfFile(LPCVOID lpBaseAddress,
|
2008-05-21 16:10:00 +00:00
|
|
|
SIZE_T dwNumberOfBytesToFlush)
|
1999-11-17 21:20:15 +00:00
|
|
|
{
|
2008-05-21 16:10:00 +00:00
|
|
|
SIZE_T NumberOfBytesToFlush;
|
2006-06-22 23:06:14 +00:00
|
|
|
NTSTATUS Status;
|
2008-05-21 16:10:00 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
|
|
|
|
/* Save amount of bytes to flush to a local var */
|
|
|
|
NumberOfBytesToFlush = dwNumberOfBytesToFlush;
|
2006-06-22 23:06:14 +00:00
|
|
|
|
|
|
|
/* Flush the view */
|
|
|
|
Status = NtFlushVirtualMemory(NtCurrentProcess(),
|
|
|
|
(LPVOID)lpBaseAddress,
|
2008-05-21 16:10:00 +00:00
|
|
|
&NumberOfBytesToFlush,
|
|
|
|
&IoStatusBlock);
|
2006-06-22 23:06:14 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
/* We failed */
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Return success */
|
|
|
|
return TRUE;
|
1999-11-17 21:20:15 +00:00
|
|
|
}
|
|
|
|
|
1999-10-03 23:19:15 +00:00
|
|
|
/* EOF */
|