Author: ion Date: Mon Nov 7 15:43:37 2011 New Revision: 54336
URL: http://svn.reactos.org/svn/reactos?rev=54336&view=rev Log: [KERNEL32]: Fix various bugs in the file mapping APIs, mainly related to lack of EXECUTE mappings and incorrect error codes.
Modified: trunk/reactos/dll/win32/kernel32/client/file/filemap.c
Modified: trunk/reactos/dll/win32/kernel32/client/file/filemap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/f... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/file/filemap.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/file/filemap.c [iso-8859-1] Mon Nov 7 15:43:37 2011 @@ -6,14 +6,14 @@ * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) */
-/* INCLUDES ******************************************************************/ +/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG #include <debug.h>
-/* FUNCTIONS *****************************************************************/ +/* FUNCTIONS ******************************************************************/
/* * @implemented @@ -73,7 +73,23 @@ if (flProtect == PAGE_READWRITE) { /* 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 */ @@ -114,21 +130,21 @@ flProtect, Attributes, hFile); - - if (Status == STATUS_OBJECT_NAME_EXISTS) + if (!NT_SUCCESS(Status)) + { + /* We failed */ + BaseSetLastNTError(Status); + return NULL; + } + else if (Status == STATUS_OBJECT_NAME_EXISTS) { SetLastError(ERROR_ALREADY_EXISTS); - return SectionHandle; - } - - if (!NT_SUCCESS(Status)) - { - /* We failed */ - BaseSetLastNTError(Status); - return NULL; - } - - SetLastError(ERROR_SUCCESS); + } + else + { + SetLastError(ERROR_SUCCESS); + } + /* Return the section */ return SectionHandle; } @@ -160,17 +176,19 @@ ViewSize = dwNumberOfBytesToMap;
/* Convert flags to NT Protection Attributes */ - if (dwDesiredAccess & FILE_MAP_WRITE) - { - Protect = PAGE_READWRITE; + if (dwDesiredAccess == FILE_MAP_COPY) + { + 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) { - Protect = PAGE_READONLY; - } - else if (dwDesiredAccess & FILE_MAP_COPY) - { - Protect = PAGE_WRITECOPY; + Protect = (dwDesiredAccess & FILE_MAP_EXECUTE) ? + PAGE_EXECUTE_READ : PAGE_READONLY; } else { @@ -232,6 +250,18 @@ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)lpBaseAddress); 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 */ BaseSetLastNTError(Status); return FALSE; @@ -244,55 +274,24 @@ /* * @implemented */ +HANDLE +NTAPI +OpenFileMappingA(IN DWORD dwDesiredAccess, + IN BOOL bInheritHandle, + IN LPCSTR lpName) +{ + ConvertOpenWin32AnsiObjectApiToUnicodeApi(FileMapping, dwDesiredAccess, bInheritHandle, lpName); +} + +/* + * @implemented + */ /* FIXME: Convert to the new macros */ 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 */ - 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); -} - -/* - * @implemented - */ - /* FIXME: Convert to the new macros */ -HANDLE -NTAPI -OpenFileMappingW(DWORD dwDesiredAccess, - BOOL bInheritHandle, - LPCWSTR lpName) +OpenFileMappingW(IN DWORD dwDesiredAccess, + IN BOOL bInheritHandle, + IN LPCWSTR lpName) { NTSTATUS Status; HANDLE SectionHandle; @@ -316,12 +315,16 @@ NULL);
/* 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 */ - Status = ZwOpenSection(&SectionHandle, - dwDesiredAccess, - &ObjectAttributes); + Status = ZwOpenSection(&SectionHandle, dwDesiredAccess, &ObjectAttributes); if (!NT_SUCCESS(Status)) { /* We failed */ @@ -329,7 +332,6 @@ return NULL; }
- SetLastError(ERROR_SUCCESS); /* Otherwise, return the handle */ return SectionHandle; } @@ -339,8 +341,8 @@ */ BOOL NTAPI -FlushViewOfFile(LPCVOID lpBaseAddress, - SIZE_T dwNumberOfBytesToFlush) +FlushViewOfFile(IN LPCVOID lpBaseAddress, + IN SIZE_T dwNumberOfBytesToFlush) { SIZE_T NumberOfBytesToFlush; NTSTATUS Status; @@ -354,7 +356,7 @@ (LPVOID)lpBaseAddress, &NumberOfBytesToFlush, &IoStatusBlock); - if (!NT_SUCCESS(Status)) + if (!NT_SUCCESS(Status) && (Status != STATUS_NOT_MAPPED_DATA)) { /* We failed */ BaseSetLastNTError(Status);