From: Vibhav Pant vibhavp@gmail.com
The test will only run if the platform has a non-zero minimum large page size, and will check whether the correct privilege checks are enforced if large page backed mappings are requested, and whether only mapping sizes that are multiples of the minimum large page size are accepted. --- dlls/kernel32/tests/process.c | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c index 8e168622c17..c0916bc60f0 100644 --- a/dlls/kernel32/tests/process.c +++ b/dlls/kernel32/tests/process.c @@ -82,6 +82,7 @@ static BOOL (WINAPI *pGetNumaProcessorNode)(UCHAR, PUCHAR); static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI *pNtQueryInformationThread)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); static NTSTATUS (WINAPI *pNtQuerySystemInformationEx)(SYSTEM_INFORMATION_CLASS, void*, ULONG, void*, ULONG, ULONG*); +static NTSTATUS (WINAPI *pRtlAdjustPrivilege)(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); static DWORD (WINAPI *pWTSGetActiveConsoleSessionId)(void); static HANDLE (WINAPI *pCreateToolhelp32Snapshot)(DWORD, DWORD); static BOOL (WINAPI *pProcess32First)(HANDLE, PROCESSENTRY32*); @@ -252,6 +253,7 @@ static BOOL init(void) pNtQueryInformationProcess = (void *)GetProcAddress(hntdll, "NtQueryInformationProcess"); pNtQueryInformationThread = (void *)GetProcAddress(hntdll, "NtQueryInformationThread"); pNtQuerySystemInformationEx = (void *)GetProcAddress(hntdll, "NtQuerySystemInformationEx"); + pRtlAdjustPrivilege = (void *)GetProcAddress(hntdll, "RtlAdjustPrivilege");
pGetNativeSystemInfo = (void *) GetProcAddress(hkernel32, "GetNativeSystemInfo"); pGetSystemRegistryQuota = (void *) GetProcAddress(hkernel32, "GetSystemRegistryQuota"); @@ -4347,6 +4349,67 @@ static void test_largepages(void) ok((size == 0) || (size == 2*1024*1024) || (size == 4*1024*1024), "GetLargePageMinimum reports %Id size\n", size); }
+static void test_large_page_file_mapping( void ) +{ + SIZE_T size; + BOOLEAN enabled; + NTSTATUS status; + DWORD err; + HANDLE file; + HANDLE token; + HANDLE process_token; + + if (!pGetLargePageMinimum) + { + win_skip( "No GetLargePageMinimum support.\n" ); + return; + } + if (!pRtlAdjustPrivilege) + { + win_skip( "No RtlAdjustPrivilege support.\n" ); + return; + } + + size = pGetLargePageMinimum(); + if (size == 0) + { + trace( "No large pages support, skipping test.\n" ); + return; + } + ok( OpenProcessToken( GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token ), + "OpenProcessToken failed (%ld)\n", GetLastError() ); + ok( DuplicateToken( process_token, SecurityImpersonation, &token ), + "DuplicateToken failed (%ld)\n", GetLastError() ); + ok( ImpersonateLoggedOnUser( token ), "ImpersonateLoggedOnUser failed (%ld)\n", + GetLastError() ); + status = pRtlAdjustPrivilege( SE_LOCK_MEMORY_PRIVILEGE, TRUE, TRUE, &enabled ); + if (status != STATUS_SUCCESS) + { + trace( "Couldn't get SE_LOCK_MEMORY_PRIVILEGE (%ld), skipping large page file " + "mapping test.\n", + status ); + } + else + { + file = + CreateFileMappingW( INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE | SEC_LARGE_PAGES | SEC_COMMIT, 0, size - 1, NULL ); + err = GetLastError(); + ok( file == NULL && err == ERROR_INVALID_PARAMETER, + "CreateFileMappingW should fail with ERROR_INVALID_PARAMETER (got %ld instead)\n", + err ); + if (file != NULL) CloseHandle( file ); + + file = + CreateFileMappingW( INVALID_HANDLE_VALUE, NULL, + PAGE_READWRITE | SEC_LARGE_PAGES | SEC_COMMIT, 0, size * 2, NULL ); + ok( file != NULL, "CreateFileMappingW failed (%ld)\n", GetLastError() ); + if ( file != NULL ) CloseHandle( file ); + } + + ok( RevertToSelf(), "RevertToSelf failed (%ld)\n", GetLastError() ); +} + struct proc_thread_attr { DWORD_PTR attr; @@ -5668,6 +5731,7 @@ START_TEST(process) test_GetLogicalProcessorInformationEx(); test_GetSystemCpuSetInformation(); test_largepages(); + test_large_page_file_mapping(); test_ProcThreadAttributeList(); test_SuspendProcessState(); test_SuspendProcessNewThread();