1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Test for RtlComputePrivatizedDllName_U 5 * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 11 static WCHAR ProcessDir[MAX_PATH]; 12 static WCHAR LocalDir[MAX_PATH + 10]; 13 14 static BOOL InitTestData() 15 { 16 static const UNICODE_STRING PathDividerFind = RTL_CONSTANT_STRING(L"\\/"); 17 UNICODE_STRING StrU; 18 USHORT PathDivider; 19 20 GetModuleFileNameW(NULL, ProcessDir, RTL_NUMBER_OF(ProcessDir)); 21 GetModuleFileNameW(NULL, LocalDir, RTL_NUMBER_OF(LocalDir)); 22 23 RtlInitUnicodeString(&StrU, ProcessDir); 24 25 if (!NT_SUCCESS(RtlFindCharInUnicodeString(RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END, 26 &StrU, &PathDividerFind, &PathDivider))) 27 { 28 skip("Failed to find path divider\n"); 29 return FALSE; 30 } 31 ProcessDir[PathDivider / sizeof(WCHAR) + 1] = UNICODE_NULL; 32 33 RtlInitUnicodeString(&StrU, LocalDir); 34 StrU.MaximumLength = sizeof(LocalDir); 35 36 if (!NT_SUCCESS(RtlAppendUnicodeToString(&StrU, L".Local\\"))) 37 { 38 skip("Failed to append .Local\\\n"); 39 return FALSE; 40 } 41 return TRUE; 42 } 43 44 static void ok_strings_(PCUNICODE_STRING RealName, PCUNICODE_STRING LocalName, LPCWSTR DllName, int line) 45 { 46 WCHAR ExpectReal[MAX_PATH*2]; 47 WCHAR ExpectLocal[MAX_PATH*2]; 48 int RealLen; 49 int ExpectLen; 50 51 RealLen = swprintf(ExpectReal, L"%s%s", ProcessDir, DllName) * sizeof(WCHAR); 52 ExpectLen = swprintf(ExpectLocal, L"%s%s", LocalDir, DllName) * sizeof(WCHAR); 53 54 ok_(__FILE__, line)(RealLen == RealName->Length, "Expected Real %u, got %u\n", 55 (UINT)RealLen, (UINT)RealName->Length); 56 ok_(__FILE__, line)(ExpectLen == LocalName->Length, "Expected Local %u, got %u\n", 57 (UINT)ExpectLen, (UINT)LocalName->Length); 58 59 ok_(__FILE__, line)(!wcscmp(RealName->Buffer, ExpectReal), "Expected Real %s, got %s\n", 60 wine_dbgstr_w(ExpectReal), wine_dbgstr_w(RealName->Buffer)); 61 ok_(__FILE__, line)(!wcscmp(LocalName->Buffer, ExpectLocal), "Expected Local %s, got %s\n", 62 wine_dbgstr_w(ExpectLocal), wine_dbgstr_w(LocalName->Buffer)); 63 } 64 #define ok_strings(Real, Local, Dll) ok_strings_(Real, Local, Dll, __LINE__) 65 66 67 static void cleanup(PUNICODE_STRING String, WCHAR* Buffer, USHORT BufferSize) 68 { 69 if (String->Buffer != Buffer) 70 { 71 RtlFreeUnicodeString(String); 72 RtlInitEmptyUnicodeString(String, Buffer, BufferSize); 73 } 74 } 75 76 77 static void test_dllnames(void) 78 { 79 WCHAR Buf1[MAX_PATH]; 80 WCHAR Buf2[MAX_PATH]; 81 82 UNICODE_STRING Str1, Str2; 83 UNICODE_STRING DllName; 84 NTSTATUS Status; 85 86 RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1)); 87 RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2)); 88 89 RtlInitUnicodeString(&DllName, L"kernel32.dll"); 90 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 91 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 92 ok_strings(&Str1, &Str2, L"kernel32.dll"); 93 cleanup(&Str1, Buf1, sizeof(Buf1)); 94 cleanup(&Str2, Buf2, sizeof(Buf2)); 95 96 97 RtlInitUnicodeString(&DllName, L"kernel32"); 98 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 99 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 100 ok_strings(&Str1, &Str2, L"kernel32.DLL"); 101 cleanup(&Str1, Buf1, sizeof(Buf1)); 102 cleanup(&Str2, Buf2, sizeof(Buf2)); 103 104 RtlInitUnicodeString(&DllName, L"kernel32.dll.dll"); 105 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 106 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 107 ok_strings(&Str1, &Str2, L"kernel32.dll.dll"); 108 cleanup(&Str1, Buf1, sizeof(Buf1)); 109 cleanup(&Str2, Buf2, sizeof(Buf2)); 110 111 RtlInitUnicodeString(&DllName, L"kernel32.dll.exe"); 112 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 113 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 114 ok_strings(&Str1, &Str2, L"kernel32.dll.exe"); 115 cleanup(&Str1, Buf1, sizeof(Buf1)); 116 cleanup(&Str2, Buf2, sizeof(Buf2)); 117 118 RtlInitUnicodeString(&DllName, L"kernel32."); 119 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 120 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 121 ok_strings(&Str1, &Str2, L"kernel32."); 122 cleanup(&Str1, Buf1, sizeof(Buf1)); 123 cleanup(&Str2, Buf2, sizeof(Buf2)); 124 125 RtlInitUnicodeString(&DllName, L".kernel32"); 126 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 127 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 128 ok_strings(&Str1, &Str2, L".kernel32.DLL"); 129 cleanup(&Str1, Buf1, sizeof(Buf1)); 130 cleanup(&Str2, Buf2, sizeof(Buf2)); 131 132 RtlInitUnicodeString(&DllName, L"..kernel32"); 133 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 134 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 135 ok_strings(&Str1, &Str2, L"..kernel32"); 136 cleanup(&Str1, Buf1, sizeof(Buf1)); 137 cleanup(&Str2, Buf2, sizeof(Buf2)); 138 139 RtlInitUnicodeString(&DllName, L".kernel32."); 140 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 141 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 142 ok_strings(&Str1, &Str2, L".kernel32."); 143 cleanup(&Str1, Buf1, sizeof(Buf1)); 144 cleanup(&Str2, Buf2, sizeof(Buf2)); 145 146 147 RtlInitUnicodeString(&DllName, L"test\\kernel32.dll"); 148 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 149 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 150 ok_strings(&Str1, &Str2, L"kernel32.dll"); 151 cleanup(&Str1, Buf1, sizeof(Buf1)); 152 cleanup(&Str2, Buf2, sizeof(Buf2)); 153 154 RtlInitUnicodeString(&DllName, L"test/kernel32.dll"); 155 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 156 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 157 ok_strings(&Str1, &Str2, L"kernel32.dll"); 158 cleanup(&Str1, Buf1, sizeof(Buf1)); 159 cleanup(&Str2, Buf2, sizeof(Buf2)); 160 161 RtlInitUnicodeString(&DllName, L"test.dll/kernel32"); 162 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 163 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 164 ok_strings(&Str1, &Str2, L"kernel32.DLL"); 165 cleanup(&Str1, Buf1, sizeof(Buf1)); 166 cleanup(&Str2, Buf2, sizeof(Buf2)); 167 168 RtlInitUnicodeString(&DllName, L"test.dll\\kernel32"); 169 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 170 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 171 ok_strings(&Str1, &Str2, L"kernel32.DLL"); 172 cleanup(&Str1, Buf1, sizeof(Buf1)); 173 cleanup(&Str2, Buf2, sizeof(Buf2)); 174 175 RtlInitUnicodeString(&DllName, L"//"); 176 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 177 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 178 ok_strings(&Str1, &Str2, L".DLL"); 179 cleanup(&Str1, Buf1, sizeof(Buf1)); 180 cleanup(&Str2, Buf2, sizeof(Buf2)); 181 182 // Bug :) 183 RtlInitUnicodeString(&DllName, L"\\"); 184 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 185 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 186 if (wcsstr(Str1.Buffer, L"\\\\")) 187 { 188 trace("Allowing bug found in windows' implementation\n"); 189 ok_strings(&Str1, &Str2, L"\\.DLL"); 190 } 191 else 192 { 193 ok_strings(&Str1, &Str2, L".DLL"); 194 } 195 cleanup(&Str1, Buf1, sizeof(Buf1)); 196 cleanup(&Str2, Buf2, sizeof(Buf2)); 197 198 RtlInitUnicodeString(&DllName, L""); 199 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 200 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 201 ok_strings(&Str1, &Str2, L".DLL"); 202 cleanup(&Str1, Buf1, sizeof(Buf1)); 203 cleanup(&Str2, Buf2, sizeof(Buf2)); 204 } 205 206 static void test_allocations(void) 207 { 208 WCHAR Buf1[10]; 209 WCHAR Buf2[10]; 210 211 UNICODE_STRING Str1, Str2; 212 UNICODE_STRING DllName; 213 NTSTATUS Status; 214 215 RtlInitEmptyUnicodeString(&Str1, Buf1, sizeof(Buf1)); 216 RtlInitEmptyUnicodeString(&Str2, Buf2, sizeof(Buf2)); 217 218 RtlInitUnicodeString(&DllName, L"kernel32.dll"); 219 Status = RtlComputePrivatizedDllName_U(&DllName, &Str1, &Str2); 220 ok(Status == STATUS_SUCCESS, "0x%lx\n", Status); 221 ok_strings(&Str1, &Str2, L"kernel32.dll"); 222 ok(Str1.Buffer != Buf1, "Expected a changed buffer\n"); 223 ok(Str2.Buffer != Buf2, "Expected a changed buffer\n"); 224 cleanup(&Str1, Buf1, sizeof(Buf1)); 225 cleanup(&Str2, Buf2, sizeof(Buf2)); 226 } 227 228 229 START_TEST(RtlComputePrivatizedDllName_U) 230 { 231 if (!InitTestData()) 232 return; 233 234 test_dllnames(); 235 test_allocations(); 236 } 237