2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for RtlDosApplyFileIsolationRedirection_Ustr
5 * PROGRAMMER: Giannis Adamopoulos
10 #define ok_eq_hex(value, expected) ok((value) == (expected), #value " = 0x%lx, expected 0x%lx\n", value, expected)
11 #define ok_eq_pointer(value, expected) ok((value) == (expected), #value " = %p, expected %p\n", value, expected)
13 #define EXPECT_IN_SAME_DIR (WCHAR*)0xdead
15 UNICODE_STRING DotDll
= RTL_CONSTANT_STRING(L
".DLL");
20 NTSTATUS ExpectedStatus
;
22 WCHAR
* ExpectedSubString
;
25 struct test_data Tests
[] =
27 /* Not redirected file */
28 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"somefilesomefile", NULL
},
29 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"ntdll.dll", NULL
},
30 /* Files redirected with sxs */
31 {__LINE__
, STATUS_SUCCESS
, L
"GDIPLUS", L
"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."},
32 {__LINE__
, STATUS_SUCCESS
, L
"GDIPLUS.DLL", L
"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."},
33 {__LINE__
, STATUS_SUCCESS
, L
"COMCTL32.DLL", L
"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
34 {__LINE__
, STATUS_SUCCESS
, L
"comctl32.DLL", L
"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
35 {__LINE__
, STATUS_SUCCESS
, L
"c:\\windows\\system32\\comctl32.DLL", L
"\\winsxs\\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82"},
36 /* Files not redirected with sxs */
37 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"MSVCR90.DLL", NULL
},
38 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"c:\\windows\\system32\\MSVCR90.DLL", NULL
},
39 /* Files defined in the manifest, one exists, one doesn't */
40 {__LINE__
, STATUS_SUCCESS
, L
"deptest.dll", EXPECT_IN_SAME_DIR
},
41 {__LINE__
, STATUS_SUCCESS
, L
"adllfile.dll", EXPECT_IN_SAME_DIR
},
42 /* A file that exists in the same dir but isn't mentioned in the manifest */
43 {__LINE__
, STATUS_SUCCESS
, L
"fil1.txt", EXPECT_IN_SAME_DIR
},
44 /* This is a weird case; the source doesn't exist but does get redirected */
45 {__LINE__
, STATUS_SUCCESS
, L
"c:\\windows\\system32\\gdiplus.DLL", L
"\\winsxs\\x86_microsoft.windows.gdiplus_6595b64144ccf1df_1."},
46 /* But redirecting gdiplus from a different directory doesn't work */
47 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"c:\\GDIPLUS.DLL", NULL
},
48 {__LINE__
, STATUS_SXS_KEY_NOT_FOUND
, L
"c:\\comctl32.DLL", NULL
},
49 /* Redirection based on .local */
50 {__LINE__
, STATUS_SUCCESS
, L
"test", EXPECT_IN_SAME_DIR
},
51 {__LINE__
, STATUS_SUCCESS
, L
"test.dll", EXPECT_IN_SAME_DIR
},
52 {__LINE__
, STATUS_SUCCESS
, L
"c:\\test.dll", EXPECT_IN_SAME_DIR
},
53 /* known dlls are also covered */
54 {__LINE__
, STATUS_SUCCESS
, L
"shell32", EXPECT_IN_SAME_DIR
},
55 {__LINE__
, STATUS_SUCCESS
, L
"shell32.dll", EXPECT_IN_SAME_DIR
},
56 {__LINE__
, STATUS_SUCCESS
, L
"c:\\shell32.dll", EXPECT_IN_SAME_DIR
}
59 HANDLE
_CreateActCtxFromFile(LPCWSTR FileName
, int line
)
61 ACTCTXW ActCtx
= {sizeof(ACTCTX
)};
63 WCHAR buffer
[MAX_PATH
] , *separator
;
65 ok (GetModuleFileNameW(NULL
, buffer
, MAX_PATH
), "GetModuleFileName failed\n");
66 separator
= wcsrchr(buffer
, L
'\\');
68 wcscpy(separator
+ 1, FileName
);
70 ActCtx
.lpSource
= buffer
;
72 SetLastError(0xdeaddead);
73 h
= CreateActCtxW(&ActCtx
);
74 ok_(__FILE__
, line
)(h
!= INVALID_HANDLE_VALUE
, "CreateActCtx failed for %S\n", FileName
);
75 // In win10 last error is unchanged and in win2k3 it is ERROR_BAD_EXE_FORMAT
76 ok_(__FILE__
, line
)(GetLastError() == ERROR_BAD_EXE_FORMAT
|| GetLastError() == 0xdeaddead, "Wrong last error %lu\n", GetLastError());
81 void TestRedirection(void)
83 WCHAR SystemDir
[MAX_PATH
];
84 WCHAR TestPath
[MAX_PATH
];
85 WCHAR ParameterBuffer
[MAX_PATH
];
90 GetSystemDirectoryW(SystemDir
, MAX_PATH
);
91 GetModuleFileNameW(NULL
, TestPath
, MAX_PATH
);
92 separator
= wcsrchr(TestPath
, L
'\\');
96 for (i
= 0; i
< _countof(Tests
); i
++)
98 UNICODE_STRING OriginalName
, DynamicString
;
99 PUNICODE_STRING StringUsed
= NULL
;
101 if (memcmp(Tests
[i
].Param
, L
"c:\\windows\\system32", 38) == 0)
103 wcscpy(ParameterBuffer
, SystemDir
);
104 wcscat(ParameterBuffer
, &Tests
[i
].Param
[19]);
108 wcscpy(ParameterBuffer
, Tests
[i
].Param
);
111 RtlInitUnicodeString(&OriginalName
, ParameterBuffer
);
112 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
114 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
123 ok(Status
== Tests
[i
].ExpectedStatus
, "%d: Status 0x%lx, expected 0x%lx\n", Tests
[i
].testline
, Status
, Tests
[i
].ExpectedStatus
);
125 if(Tests
[i
].ExpectedSubString
&& DynamicString
.Buffer
== NULL
)
127 ok(0, "%d: Expected a returned string\n", Tests
[i
].testline
);
130 if (Tests
[i
].ExpectedSubString
&& DynamicString
.Buffer
!= NULL
)
132 if (Tests
[i
].ExpectedSubString
== EXPECT_IN_SAME_DIR
)
134 ok(wcsstr(DynamicString
.Buffer
, TestPath
) != 0, "%d: Expected string %S in %S\n", Tests
[i
].testline
, TestPath
, DynamicString
.Buffer
);
138 RtlDowncaseUnicodeString(&DynamicString
, &DynamicString
, FALSE
);
139 ok(wcsstr(DynamicString
.Buffer
, Tests
[i
].ExpectedSubString
) != 0, "%d: Expected string %S in %S\n", Tests
[i
].testline
, Tests
[i
].ExpectedSubString
, DynamicString
.Buffer
);
147 UNICODE_STRING Param
, DynamicString
, StaticString
;
148 PUNICODE_STRING StringUsed
= NULL
;
150 WCHAR buffer
[MAX_PATH
];
152 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
153 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
162 ok(Status
==STATUS_INVALID_PARAMETER
, "0x%lx\n", Status
);
164 RtlInitEmptyUnicodeString(&Param
, NULL
, 0);
165 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
166 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
175 ok(Status
==STATUS_SXS_KEY_NOT_FOUND
, "0x%lx\n", Status
);
177 /* Tests for NULL termination of OriginalName */
178 Param
.MaximumLength
= Param
.Length
= 12 * sizeof(WCHAR
);
179 Param
.Buffer
= L
"comctl32.dllcrapcrap";
180 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
181 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
190 ok(Status
==STATUS_SUCCESS
, "\n");
192 /* Tests for the Extension parameter */
193 RtlInitUnicodeString(&Param
, L
"comctl32.dll");
194 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
195 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
204 ok(Status
==STATUS_SUCCESS
, "\n");
206 RtlInitUnicodeString(&Param
, L
"comctl32");
207 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
208 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
217 ok(Status
==STATUS_SXS_KEY_NOT_FOUND
, "0x%lx\n", Status
);
219 RtlInitUnicodeString(&Param
, L
"comctl32");
220 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
221 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
230 ok(Status
==STATUS_SUCCESS
, "\n");
232 /* Tests for the DynamicString parameter */
233 RtlInitUnicodeString(&Param
, L
"comctl32.dll");
234 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
235 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
244 ok(Status
==STATUS_SUCCESS
, "\n");
245 ok(DynamicString
.Length
>0 , "\n");
246 ok(DynamicString
.MaximumLength
== DynamicString
.Length
+ sizeof(WCHAR
) , "\n");
247 if (DynamicString
.Buffer
&& DynamicString
.Length
)
248 ok(wcslen(DynamicString
.Buffer
) * sizeof(WCHAR
) == DynamicString
.Length
, "got %d and %d\n", wcslen(DynamicString
.Buffer
) * sizeof(WCHAR
) , DynamicString
.Length
);
250 ok(DynamicString
.Buffer
!= NULL
, "Expected non NULL buffer\n");
251 ok(StringUsed
== &DynamicString
, "\n");
253 /* Tests for the StaticString parameter */
254 wcscpy(buffer
, L
"comctl32.dll");
255 StaticString
.Buffer
= buffer
;
256 StaticString
.Length
= sizeof(L
"comctl32.dll");
257 StaticString
.MaximumLength
= sizeof(buffer
);
258 Param
= StaticString
;
259 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
268 ok(Status
==STATUS_SXS_KEY_NOT_FOUND
, "0x%lx\n", Status
);
270 wcscpy(buffer
, L
"comctl32.dll");
271 StaticString
.Buffer
= buffer
;
272 StaticString
.Length
= sizeof(L
"comctl32.dll");
273 StaticString
.MaximumLength
= sizeof(buffer
);
274 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
283 ok(Status
==STATUS_SXS_KEY_NOT_FOUND
, "0x%lx\n", Status
);
285 RtlInitUnicodeString(&Param
, L
"comctl32.dll");
286 RtlInitEmptyUnicodeString(&StaticString
, buffer
, sizeof(buffer
));
287 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
296 ok(Status
==STATUS_SUCCESS
, "\n");
297 ok(StaticString
.Length
>0 , "\n");
298 ok(StaticString
.MaximumLength
== sizeof(buffer
) , "\n");
299 if (StaticString
.Buffer
&& StaticString
.Length
)
300 ok(wcslen(StaticString
.Buffer
) * sizeof(WCHAR
) == StaticString
.Length
, "got %d and %d\n", wcslen(StaticString
.Buffer
) * sizeof(WCHAR
) , StaticString
.Length
);
302 ok(StaticString
.Length
!= 0, "Expected non 0 lenght\n");
303 ok(StringUsed
== &StaticString
, "\n");
305 RtlInitEmptyUnicodeString(&StaticString
, buffer
, 5 * sizeof(WCHAR
));
306 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
315 ok(Status
== STATUS_BUFFER_TOO_SMALL
, "0x%lx\n", Status
);
317 RtlInitUnicodeString(&Param
, L
"comctl32.dll");
318 RtlInitEmptyUnicodeString(&StaticString
, buffer
, sizeof(buffer
));
319 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
320 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
329 ok(Status
==STATUS_SUCCESS
, "\n");
330 ok(StaticString
.Length
>0 , "\n");
331 ok(StaticString
.MaximumLength
== sizeof(buffer
) , "\n");
332 if (StaticString
.Buffer
&& StaticString
.Length
)
333 ok(wcslen(StaticString
.Buffer
) * sizeof(WCHAR
) == StaticString
.Length
, "got %d and %d\n", wcslen(StaticString
.Buffer
) * sizeof(WCHAR
) , StaticString
.Length
);
335 ok(StaticString
.Length
!= 0, "Expected non 0 lenght\n");
336 ok(DynamicString
.Buffer
== NULL
, "\n");
337 ok(DynamicString
.Length
== 0, "\n");
338 ok(DynamicString
.MaximumLength
== 0, "\n");
339 ok(StringUsed
== &StaticString
, "\n");
341 /* Test a small buffer and a dynamic buffer */
342 RtlInitUnicodeString(&Param
, L
"comctl32.dll");
343 RtlInitEmptyUnicodeString(&StaticString
, buffer
, 5 * sizeof(WCHAR
));
344 RtlInitEmptyUnicodeString(&DynamicString
, NULL
, 0);
345 StaticString
.Buffer
[0] = 1;
346 Status
= RtlDosApplyFileIsolationRedirection_Ustr(TRUE
,
355 ok(Status
==STATUS_SUCCESS
, "\n");
356 ok(StaticString
.Buffer
== buffer
, "\n");
357 ok(StaticString
.Length
== 0 , "%d\n", StaticString
.Length
);
358 ok(StaticString
.Buffer
[0] == 0, "\n");
359 ok(StaticString
.MaximumLength
== 5 * sizeof(WCHAR
) , "%d\n", StaticString
.MaximumLength
);
360 ok(DynamicString
.Length
>0 , "\n");
361 ok(DynamicString
.MaximumLength
== DynamicString
.Length
+ sizeof(WCHAR
) , "\n");
362 if (DynamicString
.Buffer
&& DynamicString
.Length
)
363 ok(wcslen(DynamicString
.Buffer
) * sizeof(WCHAR
) == DynamicString
.Length
, "got %d and %d\n", wcslen(DynamicString
.Buffer
) * sizeof(WCHAR
) , DynamicString
.Length
);
365 ok(DynamicString
.Length
!= 0, "Expected non 0 lenght\n");
367 ok(StringUsed
== &DynamicString
, "\n");
370 START_TEST(RtlDosApplyFileIsolationRedirection_Ustr
)
374 argc
= winetest_get_mainargs( &test_argv
);
377 HANDLE h
= _CreateActCtxFromFile(L
"ntdlltest.manifest", __LINE__
);
378 BOOL bactivated
= FALSE
;
381 if (h
!= INVALID_HANDLE_VALUE
)
382 bactivated
= ActivateActCtx(h
, &cookie
);
388 DeactivateActCtx(0, cookie
);
392 WCHAR TestPath
[MAX_PATH
];
394 STARTUPINFOW si
= { sizeof(si
) };
395 PROCESS_INFORMATION pi
;
398 GetModuleFileNameW(NULL
, TestPath
, MAX_PATH
);
399 separator
= wcsrchr(TestPath
, L
'\\');
401 wcscpy(separator
, L
"testdata\\ntdll_apitest.exe RtlDosApplyFileIsolationRedirection_Ustr DoTest");
403 created
= CreateProcessW(NULL
, TestPath
, NULL
, NULL
, FALSE
, 0, NULL
, NULL
, &si
, &pi
);
404 ok(created
, "Expected CreateProcess to succeed\n");
407 winetest_wait_child_process(pi
.hProcess
);
408 CloseHandle(pi
.hThread
);
409 CloseHandle(pi
.hProcess
);