[KERNEL32]: Fix various bugs in the file mapping APIs, mainly related to lack of EXECUTE mappings and incorrect error codes.

svn path=/trunk/; revision=54336
This commit is contained in:
Alex Ionescu 2011-11-07 15:43:37 +00:00
parent bef20836c3
commit 6d37c787cd

View file

@ -6,14 +6,14 @@
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/ */
/* INCLUDES ******************************************************************/ /* INCLUDES *******************************************************************/
#include <k32.h> #include <k32.h>
#define NDEBUG #define NDEBUG
#include <debug.h> #include <debug.h>
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS ******************************************************************/
/* /*
* @implemented * @implemented
@ -73,7 +73,23 @@ CreateFileMappingW(HANDLE hFile,
if (flProtect == PAGE_READWRITE) if (flProtect == PAGE_READWRITE)
{ {
/* Give it */ /* Give it */
DesiredAccess |= (SECTION_MAP_WRITE | SECTION_MAP_READ); DesiredAccess |= SECTION_MAP_WRITE;
}
else if (flProtect == PAGE_EXECUTE_READWRITE)
{
/* Give it */
DesiredAccess |= (SECTION_MAP_WRITE | SECTION_MAP_EXECUTE);
}
else if (flProtect == PAGE_EXECUTE_READ)
{
/* Give it */
DesiredAccess |= SECTION_MAP_EXECUTE;
}
if ((flProtect != PAGE_READONLY) && (flProtect != PAGE_WRITECOPY))
{
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
} }
/* Now check if we got a name */ /* Now check if we got a name */
@ -114,21 +130,21 @@ CreateFileMappingW(HANDLE hFile,
flProtect, flProtect,
Attributes, Attributes,
hFile); hFile);
if (Status == STATUS_OBJECT_NAME_EXISTS)
{
SetLastError(ERROR_ALREADY_EXISTS);
return SectionHandle;
}
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* We failed */ /* We failed */
BaseSetLastNTError(Status); BaseSetLastNTError(Status);
return NULL; return NULL;
} }
else if (Status == STATUS_OBJECT_NAME_EXISTS)
{
SetLastError(ERROR_ALREADY_EXISTS);
}
else
{
SetLastError(ERROR_SUCCESS);
}
SetLastError(ERROR_SUCCESS);
/* Return the section */ /* Return the section */
return SectionHandle; return SectionHandle;
} }
@ -160,17 +176,19 @@ MapViewOfFileEx(HANDLE hFileMappingObject,
ViewSize = dwNumberOfBytesToMap; ViewSize = dwNumberOfBytesToMap;
/* Convert flags to NT Protection Attributes */ /* Convert flags to NT Protection Attributes */
if (dwDesiredAccess & FILE_MAP_WRITE) if (dwDesiredAccess == FILE_MAP_COPY)
{ {
Protect = PAGE_READWRITE; Protect = PAGE_WRITECOPY;
}
else if (dwDesiredAccess & FILE_MAP_WRITE)
{
Protect = (dwDesiredAccess & FILE_MAP_EXECUTE) ?
PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
} }
else if (dwDesiredAccess & FILE_MAP_READ) else if (dwDesiredAccess & FILE_MAP_READ)
{ {
Protect = PAGE_READONLY; Protect = (dwDesiredAccess & FILE_MAP_EXECUTE) ?
} PAGE_EXECUTE_READ : PAGE_READONLY;
else if (dwDesiredAccess & FILE_MAP_COPY)
{
Protect = PAGE_WRITECOPY;
} }
else else
{ {
@ -232,6 +250,18 @@ UnmapViewOfFile(LPCVOID lpBaseAddress)
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress); Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* Check if the pages were protected */
if (Status == STATUS_INVALID_PAGE_PROTECTION)
{
/* Flush the region if it was a "secure memory cache" */
if (RtlFlushSecureMemoryCache((PVOID)lpBaseAddress, 0))
{
/* Now try to unmap again */
Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress);
if (NT_SUCCESS(Status)) return TRUE;
}
}
/* We failed */ /* We failed */
BaseSetLastNTError(Status); BaseSetLastNTError(Status);
return FALSE; return FALSE;
@ -244,44 +274,13 @@ UnmapViewOfFile(LPCVOID lpBaseAddress)
/* /*
* @implemented * @implemented
*/ */
/* FIXME: Convert to the new macros */
HANDLE HANDLE
NTAPI NTAPI
OpenFileMappingA(DWORD dwDesiredAccess, OpenFileMappingA(IN DWORD dwDesiredAccess,
BOOL bInheritHandle, IN BOOL bInheritHandle,
LPCSTR lpName) IN LPCSTR lpName)
{ {
NTSTATUS Status; ConvertOpenWin32AnsiObjectApiToUnicodeApi(FileMapping, dwDesiredAccess, bInheritHandle, lpName);
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 */
BaseSetLastNTError(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);
} }
/* /*
@ -290,9 +289,9 @@ OpenFileMappingA(DWORD dwDesiredAccess,
/* FIXME: Convert to the new macros */ /* FIXME: Convert to the new macros */
HANDLE HANDLE
NTAPI NTAPI
OpenFileMappingW(DWORD dwDesiredAccess, OpenFileMappingW(IN DWORD dwDesiredAccess,
BOOL bInheritHandle, IN BOOL bInheritHandle,
LPCWSTR lpName) IN LPCWSTR lpName)
{ {
NTSTATUS Status; NTSTATUS Status;
HANDLE SectionHandle; HANDLE SectionHandle;
@ -316,12 +315,16 @@ OpenFileMappingW(DWORD dwDesiredAccess,
NULL); NULL);
/* Convert COPY to READ */ /* Convert COPY to READ */
if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ; if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = SECTION_MAP_READ;
/* Fixup execute */
if (dwDesiredAccess == FILE_MAP_EXECUTE)
{
dwDesiredAccess = (dwDesiredAccess & ~FILE_MAP_EXECUTE) | SECTION_MAP_EXECUTE;
}
/* Open the section */ /* Open the section */
Status = ZwOpenSection(&SectionHandle, Status = ZwOpenSection(&SectionHandle, dwDesiredAccess, &ObjectAttributes);
dwDesiredAccess,
&ObjectAttributes);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* We failed */ /* We failed */
@ -329,7 +332,6 @@ OpenFileMappingW(DWORD dwDesiredAccess,
return NULL; return NULL;
} }
SetLastError(ERROR_SUCCESS);
/* Otherwise, return the handle */ /* Otherwise, return the handle */
return SectionHandle; return SectionHandle;
} }
@ -339,8 +341,8 @@ OpenFileMappingW(DWORD dwDesiredAccess,
*/ */
BOOL BOOL
NTAPI NTAPI
FlushViewOfFile(LPCVOID lpBaseAddress, FlushViewOfFile(IN LPCVOID lpBaseAddress,
SIZE_T dwNumberOfBytesToFlush) IN SIZE_T dwNumberOfBytesToFlush)
{ {
SIZE_T NumberOfBytesToFlush; SIZE_T NumberOfBytesToFlush;
NTSTATUS Status; NTSTATUS Status;
@ -354,7 +356,7 @@ FlushViewOfFile(LPCVOID lpBaseAddress,
(LPVOID)lpBaseAddress, (LPVOID)lpBaseAddress,
&NumberOfBytesToFlush, &NumberOfBytesToFlush,
&IoStatusBlock); &IoStatusBlock);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status) && (Status != STATUS_NOT_MAPPED_DATA))
{ {
/* We failed */ /* We failed */
BaseSetLastNTError(Status); BaseSetLastNTError(Status);