reactos/dll/win32/kernel32/mem/section.c
Timo Kreuzer 9ea495ba33 Create a branch for header work.
svn path=/branches/header-work/; revision=45691
2010-02-26 22:57:55 +00:00

391 lines
10 KiB
C

/*
* 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)
*/
/* INCLUDES ******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
HANDLE
NTAPI
CreateFileMappingA(IN HANDLE hFile,
IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
IN DWORD flProtect,
IN DWORD dwMaximumSizeHigh,
IN DWORD dwMaximumSizeLow,
IN LPCSTR lpName)
{
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);
}
/*
* @implemented
*/
HANDLE
NTAPI
CreateFileMappingW(HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName)
{
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 */
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 (Status == STATUS_OBJECT_NAME_EXISTS)
{
SetLastError(ERROR_ALREADY_EXISTS);
return SectionHandle;
}
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return NULL;
}
SetLastError(ERROR_SUCCESS);
/* Return the section */
return SectionHandle;
}
/*
* @implemented
*/
LPVOID
NTAPI
MapViewOfFileEx(HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
SIZE_T dwNumberOfBytesToMap,
LPVOID lpBaseAddress)
{
NTSTATUS Status;
LARGE_INTEGER SectionOffset;
SIZE_T ViewSize;
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;
}
/* Return the base */
return ViewBase;
}
/*
* @implemented
*/
LPVOID
NTAPI
MapViewOfFile(HANDLE hFileMappingObject,
DWORD dwDesiredAccess,
DWORD dwFileOffsetHigh,
DWORD dwFileOffsetLow,
SIZE_T dwNumberOfBytesToMap)
{
/* Call the extended API */
return MapViewOfFileEx(hFileMappingObject,
dwDesiredAccess,
dwFileOffsetHigh,
dwFileOffsetLow,
dwNumberOfBytesToMap,
NULL);
}
/*
* @implemented
*/
BOOL
NTAPI
UnmapViewOfFile(LPCVOID lpBaseAddress)
{
NTSTATUS Status;
/* Unmap the section */
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return FALSE;
}
/* Otherwise, return sucess */
return TRUE;
}
/*
* @implemented
*/
HANDLE
NTAPI
OpenFileMappingA(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCSTR lpName)
{
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 */
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/* Call the Unicode version */
return OpenFileMappingW(dwDesiredAccess,
bInheritHandle,
(LPCWSTR)UnicodeCache->Buffer);
}
/*
* @implemented
*/
HANDLE
NTAPI
OpenFileMappingW(DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName)
{
NTSTATUS Status;
HANDLE SectionHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING UnicodeName;
/* We need a name */
if (!lpName)
{
/* Otherwise, fail */
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/* 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;
}
SetLastError(ERROR_SUCCESS);
/* Otherwise, return the handle */
return SectionHandle;
}
/*
* @implemented
*/
BOOL
NTAPI
FlushViewOfFile(LPCVOID lpBaseAddress,
SIZE_T dwNumberOfBytesToFlush)
{
SIZE_T NumberOfBytesToFlush;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
/* Save amount of bytes to flush to a local var */
NumberOfBytesToFlush = dwNumberOfBytesToFlush;
/* Flush the view */
Status = NtFlushVirtualMemory(NtCurrentProcess(),
(LPVOID)lpBaseAddress,
&NumberOfBytesToFlush,
&IoStatusBlock);
if (!NT_SUCCESS(Status))
{
/* We failed */
SetLastErrorByStatus(Status);
return FALSE;
}
/* Return success */
return TRUE;
}
/* EOF */