From 1442edd29138c12c2c4ab62236ad6bc217f28458 Mon Sep 17 00:00:00 2001 From: Giannis Adamopoulos Date: Sun, 15 Jan 2017 00:42:10 +0000 Subject: [PATCH 1/1] [NTDLL_APITEST] - Add more tests for RtlDosApplyFileIsolationRedirection_Ustr. Unfortunately creating .local files and making it have instant effect seems to be impossible. So I added tests for .local than can be enabled to show that this is indeed the behaviour but I have disabled them to avoid random failed tests. svn path=/trunk/; revision=73551 --- ...RtlDosApplyFileIsolationRedirection_Ustr.c | 194 +++++++++++++----- 1 file changed, 137 insertions(+), 57 deletions(-) diff --git a/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c b/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c index c200f02a90c..54100a7ffff 100644 --- a/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c +++ b/rostests/apitests/ntdll/RtlDosApplyFileIsolationRedirection_Ustr.c @@ -13,72 +13,152 @@ #define ok_eq_hex(value, expected) ok((value) == (expected), #value " = 0x%lx, expected 0x%lx\n", value, expected) #define ok_eq_pointer(value, expected) ok((value) == (expected), #value " = %p, expected %p\n", value, expected) +#define EXPECT_IN_SAME_DIR (WCHAR*)0xdead + UNICODE_STRING DotDll = RTL_CONSTANT_STRING(L".DLL"); -void TestDefaultSxsRedirection(void) +struct test_data +{ + int testline; + NTSTATUS ExpectedStatus; + WCHAR* Param; + WCHAR* ExpectedSubString; +}; + +struct test_data Tests[] = { - UNICODE_STRING GdiPlusSXS = RTL_CONSTANT_STRING(L"\\WinSxS\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."); - UNICODE_STRING Comctl32SXS = RTL_CONSTANT_STRING(L"\\WinSxS\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"); - UNICODE_STRING Comctl32 = RTL_CONSTANT_STRING(L"COMCTL32.DLL"); - UNICODE_STRING GdiPlus = RTL_CONSTANT_STRING(L"GDIPLUS.DLL"); - UNICODE_STRING CallerBuffer; - UNICODE_STRING DynamicString; - PUNICODE_STRING FullNameOut; - USHORT Position; + /* Not redirected file */ + {__LINE__, STATUS_SXS_KEY_NOT_FOUND, L"somefilesomefile", NULL}, + {__LINE__, STATUS_SXS_KEY_NOT_FOUND, L"ntdll.dll", NULL}, + /* Files redirected with sxs */ + {__LINE__, STATUS_SUCCESS, L"GDIPLUS", L"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."}, + {__LINE__, STATUS_SUCCESS, L"GDIPLUS.DLL", L"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."}, + {__LINE__, STATUS_SUCCESS, L"COMCTL32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"}, + {__LINE__, STATUS_SUCCESS, L"comctl32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"}, + {__LINE__, STATUS_SUCCESS, L"c:\\windows\\system32\\comctl32.DLL", L"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"}, + /* This is a weird case; the source doesn't exist but does get redirected */ + {__LINE__, STATUS_SUCCESS, L"c:\\windows\\system32\\gdiplus.DLL", L"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."}, + /* But redirecting gdiplus from a different directory doesn't work */ + {__LINE__, STATUS_SXS_KEY_NOT_FOUND, L"c:\\GDIPLUS.DLL", NULL}, + {__LINE__, STATUS_SXS_KEY_NOT_FOUND, L"c:\\comctl32.DLL", NULL}, +#if 0 + /* Redirection based on .local */ + {__LINE__, STATUS_SUCCESS, L"test", EXPECT_IN_SAME_DIR}, + {__LINE__, STATUS_SUCCESS, L"test.dll", EXPECT_IN_SAME_DIR}, + {__LINE__, STATUS_SUCCESS, L"c:\\test.dll", EXPECT_IN_SAME_DIR}, + /* known dlls are also covered */ + {__LINE__, STATUS_SUCCESS, L"shell32", EXPECT_IN_SAME_DIR}, + {__LINE__, STATUS_SUCCESS, L"shell32.dll", EXPECT_IN_SAME_DIR}, + {__LINE__, STATUS_SUCCESS, L"c:\\shell32.dll", EXPECT_IN_SAME_DIR} +#endif +}; +void TestRedirection(void) +{ + WCHAR SystemDir[MAX_PATH]; + WCHAR TestPath[MAX_PATH]; + WCHAR ParameterBuffer[MAX_PATH]; + WCHAR* separator; NTSTATUS Status; + int i; - /* NOTE: in xp and 2k3 gdiplus does not exist in system32 */ - RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); - FullNameOut = NULL; - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - &GdiPlus, - &DotDll, - &CallerBuffer, - &DynamicString, - &FullNameOut, - NULL, - NULL, - NULL); - ok_eq_hex(Status, STATUS_SUCCESS); - ok_eq_pointer(CallerBuffer.Buffer, NULL); - ok_eq_pointer(FullNameOut, &DynamicString); - Status = RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE, - &GdiPlusSXS, - &DynamicString, - &Position); - ok_eq_hex(Status, STATUS_SUCCESS); - - - RtlInitUnicodeString(&CallerBuffer, NULL); - RtlInitUnicodeString(&DynamicString, NULL); - FullNameOut = NULL; - Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, - &Comctl32, - &DotDll, - &CallerBuffer, - &DynamicString, - &FullNameOut, - NULL, - NULL, - NULL); - ok_eq_hex(Status, STATUS_SUCCESS); - ok_eq_pointer(CallerBuffer.Buffer, NULL); - ok_eq_pointer(FullNameOut, &DynamicString); - Status = RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE, - &Comctl32SXS, - &DynamicString, - &Position); - ok_eq_hex(Status, STATUS_SUCCESS); -} + GetSystemDirectoryW(SystemDir, MAX_PATH); + GetModuleFileNameW(NULL, TestPath, MAX_PATH); + separator = wcsrchr(TestPath, L'\\'); + separator++; + *separator = 0; -void TestDotLocal(void) -{ + for (i = 0; i < _countof(Tests); i ++) + { + UNICODE_STRING OriginalName, DynamicString; + PUNICODE_STRING StringUsed = NULL; + + if (memcmp(Tests[i].Param, L"c:\\windows\\system32", 38) == 0) + { + wcscpy(ParameterBuffer, SystemDir); + wcscat(ParameterBuffer, &Tests[i].Param[19]); + } + else + { + wcscpy(ParameterBuffer, Tests[i].Param); + } + + RtlInitUnicodeString(&OriginalName, ParameterBuffer); + RtlInitEmptyUnicodeString(&DynamicString, NULL, 0); + + Status = RtlDosApplyFileIsolationRedirection_Ustr(TRUE, + &OriginalName, + &DotDll, + NULL, + &DynamicString, + &StringUsed, + NULL, + NULL, + NULL); + ok(Status == Tests[i].ExpectedStatus, "Status 0x%lx, expected 0x%lx\n", value, expected) + ok_eq_hex(Status, Tests[i].ExpectedStatus); + + if (DynamicString.Buffer) + { + BOOL exists = RtlDoesFileExists_U(DynamicString.Buffer); + ok(exists, "%d: Expected file %S to exist!\n", Tests[i].testline, DynamicString.Buffer); + } + + if(Tests[i].ExpectedSubString && DynamicString.Buffer == NULL) + { + ok(0, "%d: Expected a returned string\n", Tests[i].testline); + } + + if (Tests[i].ExpectedSubString && DynamicString.Buffer != NULL) + { + if (Tests[i].ExpectedSubString == EXPECT_IN_SAME_DIR) + { + ok(wcsstr(DynamicString.Buffer, TestPath) != 0, "%d: Expected string %S in %S\n", Tests[i].testline, TestPath, DynamicString.Buffer); + } + else + { + RtlDowncaseUnicodeString(&DynamicString, &DynamicString, FALSE); + ok(wcsstr(DynamicString.Buffer, Tests[i].ExpectedSubString) != 0, "%d: Expected string %S in %S\n", Tests[i].testline, Tests[i].ExpectedSubString, DynamicString.Buffer); + } + } + } } START_TEST(RtlDosApplyFileIsolationRedirection_Ustr) { - TestDotLocal(); - TestDefaultSxsRedirection(); +#if 0 + WCHAR TestPath[MAX_PATH]; + WCHAR* separator; + STARTUPINFOW si = { sizeof(si) }; + PROCESS_INFORMATION pi; + BOOL created; + HANDLE file; + + /* Create .local files */ + GetModuleFileNameW(NULL, TestPath, MAX_PATH); + + wcscat(TestPath, L".local"); + file = CreateFileW(TestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING , NULL); + CloseHandle(file); + separator = wcsrchr(TestPath, L'\\'); + separator++; + wcscpy(separator, L"test.dll"); + file = CreateFileW(TestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING , NULL); + CloseHandle(file); + wcscpy(separator, L"shell32.dll"); + file = CreateFileW(TestPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_NO_BUFFERING , NULL); + CloseHandle(file); + *separator = 0; +#endif + TestRedirection(); +#if 0 + /*Cleanup*/ + wcscpy(separator, L"test.dll"); + DeleteFileW(TestPath); + wcscpy(separator, L"shell32.dll"); + DeleteFileW(TestPath); + GetModuleFileNameW(NULL, TestPath, MAX_PATH); + wcscat(TestPath, L".local"); + DeleteFileW(TestPath); +#endif } \ No newline at end of file -- 2.17.1