2 * Copyright 2015 Mark Jansen
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define WIN32_NO_STATUS
32 #include "wine/test.h"
36 #define GPLK_MACHINE 2
37 #define MAX_LAYER_LENGTH 256
38 #define LAYER_APPLY_TO_SYSTEM_EXES 1
42 static BOOL(WINAPI
*pAllowPermLayer
)(PCWSTR path
);
43 static BOOL(WINAPI
*pSdbSetPermLayerKeys
)(PCWSTR wszPath
, PCWSTR wszLayers
, BOOL bMachine
);
44 static BOOL(WINAPI
*pSdbGetPermLayerKeys
)(PCWSTR wszPath
, PWSTR pwszLayers
, PDWORD pdwBytes
, DWORD dwFlags
);
45 static BOOL(WINAPI
*pSetPermLayerState
)(PCWSTR wszPath
, PCWSTR wszLayer
, DWORD dwFlags
, BOOL bMachine
, BOOL bEnable
);
48 static DWORD g_Version
;
49 #define APPHELP_VISTA 0x0600
50 #define APPHELP_WIN8 0x0602
51 #define APPHELP_WIN10 0x1000
54 /* Helper function to disable Wow64 redirection on an os that reports it being enabled. */
55 static DWORD g_QueryFlag
= 0xffffffff;
56 static DWORD
QueryFlag(void)
58 if (g_QueryFlag
== 0xffffffff)
60 ULONG_PTR wow64_ptr
= 0;
61 NTSTATUS status
= NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information
, &wow64_ptr
, sizeof(wow64_ptr
), NULL
);
62 g_QueryFlag
= (NT_SUCCESS(status
) && wow64_ptr
!= 0) ? KEY_WOW64_64KEY
: 0;
67 /* Helper function to prepare the registry key with a value. */
68 static BOOL
setLayerValue(BOOL bMachine
, const char* valueName
, const char* value
)
71 LSTATUS lstatus
= RegCreateKeyExA(bMachine
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
72 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL
, 0, QueryFlag() | KEY_SET_VALUE
, NULL
, &key
, NULL
);
73 if (lstatus
== ERROR_SUCCESS
)
76 lstatus
= RegSetValueExA(key
, valueName
, 0, REG_SZ
, (const BYTE
*)value
, strlen(value
)+1);
79 lstatus
= RegDeleteValueA(key
, valueName
);
80 lstatus
= (lstatus
== ERROR_FILE_NOT_FOUND
? ERROR_SUCCESS
: lstatus
);
84 return lstatus
== ERROR_SUCCESS
;
88 static void expect_LayerValue_imp(BOOL bMachine
, const char* valueName
, const char* value
)
91 LSTATUS lstatus
= RegCreateKeyExA(bMachine
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
92 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL
, 0, QueryFlag() | KEY_QUERY_VALUE
, NULL
, &key
, NULL
);
93 winetest_ok(lstatus
== ERROR_SUCCESS
, "Expected to be able to open a registry key\n");
94 if (lstatus
== ERROR_SUCCESS
)
96 char data
[512] = { 0 };
98 DWORD dwDataLen
= sizeof(data
);
99 lstatus
= RegQueryValueExA(key
, valueName
, NULL
, &dwType
, (LPBYTE
)data
, &dwDataLen
);
102 winetest_ok(lstatus
== ERROR_SUCCESS
, "Expected to get a valid value, err: %u\n", lstatus
);
103 if (lstatus
== ERROR_SUCCESS
)
105 winetest_ok(dwType
== REG_SZ
, "Expected the type to be REG_SZ, was: %u\n", dwType
);
106 winetest_ok(!strcmp(data
, value
), "Expected the data to be: '%s', was: '%s'\n", value
, data
);
111 winetest_ok(lstatus
== ERROR_FILE_NOT_FOUND
, "Expected not to find the value %s\n", valueName
);
117 static void expect_LayerValue_imp2(BOOL bMachine
, const char* valueName
, const char* value
, int use_alt
, const char* alt_value
)
119 expect_LayerValue_imp(bMachine
, valueName
, use_alt
? alt_value
: value
);
123 void expect_Sdb_imp(PCSTR path
, DWORD type
, BOOL result
, DWORD lenResult
, PCSTR stringResult
)
125 WCHAR pathW
[MAX_PATH
], buffer
[MAX_LAYER_LENGTH
] = { 0 };
126 char resultBuffer
[MAX_LAYER_LENGTH
] = { 0 };
127 DWORD dwBufSize
= sizeof(buffer
);
129 /* In case of a failure, the buffer size is sometimes set to 0, and sometimes not touched,
130 depending on the version. Either case is fine, since the function returns FALSE anyway. */
132 MultiByteToWideChar(CP_ACP
, 0, path
, -1, pathW
, MAX_PATH
);
134 winetest_ok(pSdbGetPermLayerKeys(pathW
, buffer
, &dwBufSize
, type
) == result
, "Expected pSdbGetPermLayerKeys to %s\n", (result
? "succeed" : "fail"));
135 if (!result
&& lenResult
== 0xffffffff)
136 winetest_ok(dwBufSize
== 0 || dwBufSize
== sizeof(buffer
), "Expected dwBufSize to be 0 or %u, was %u\n", sizeof(buffer
), dwBufSize
);
138 winetest_ok(dwBufSize
== lenResult
||
139 /* W2k3 is off by 2 when concatenating user / machine */
140 broken(g_Version
< APPHELP_VISTA
&& type
== (GPLK_MACHINE
|GPLK_USER
) && (lenResult
+ 2) == dwBufSize
),
141 "Expected dwBufSize to be %u, was %u\n", lenResult
, dwBufSize
);
144 winetest_ok(lstrlenW(buffer
) * sizeof(WCHAR
) + sizeof(WCHAR
) == lenResult
, "Expected lstrlenW(buffer)*2+2 to be %u, was %u\n",
145 lenResult
, lstrlenW(buffer
) * sizeof(WCHAR
) + sizeof(WCHAR
));
147 WideCharToMultiByte(CP_ACP
, 0, buffer
, -1, resultBuffer
, sizeof(resultBuffer
), NULL
, NULL
);
148 winetest_ok(!strcmp(stringResult
, resultBuffer
), "Expected the result to be '%s', was '%s'\n", stringResult
, resultBuffer
);
152 /* In case of a failure, let the location be from where the function was invoked, not inside the function itself. */
153 #define expect_Sdb (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_Sdb_imp
154 #define expect_LayerValue (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_LayerValue_imp
155 #define expect_LayerValue2 (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_LayerValue_imp2
158 BOOL
wrapAllowPermLayer(const char* str
)
161 MultiByteToWideChar(CP_ACP
, 0, str
, -1, buf
, 100);
162 return pAllowPermLayer(buf
);
165 /* Brute forcing all ascii chars in the first 2 places seems to indicate that all it cares for is:
166 - Second char has to be a ':'
167 if it's not a ':', display a diagnostic message (and a different one for '\\').
168 - First char does not really matter, as long as it's not on a DRIVE_REMOTE (but, according to the logging this is meant to check for a CDROM drive...)
170 static void test_AllowPermLayer(void)
175 ok(pAllowPermLayer(NULL
) == FALSE
, "Expected AllowPermLayer to fail for NULL\n");
176 if (g_Version
< APPHELP_WIN8
)
178 ok(wrapAllowPermLayer("-:"), "Expected AllowPermLayer to succeed\n");
179 ok(wrapAllowPermLayer("@:"), "Expected AllowPermLayer to succeed\n");
180 ok(wrapAllowPermLayer("4:"), "Expected AllowPermLayer to succeed\n");
181 ok(wrapAllowPermLayer("*:"), "Expected AllowPermLayer to succeed\n");
183 ok(wrapAllowPermLayer("*a") == FALSE
, "Expected AllowPermLayer to fail\n");
184 ok(wrapAllowPermLayer("*\\") == FALSE
, "Expected AllowPermLayer to fail\n");
185 for (drive_letter
= 'a'; drive_letter
<= 'z'; ++drive_letter
)
187 sprintf(buf
, "%c:\\", drive_letter
);
188 drivetype
= GetDriveTypeA(buf
);
189 ok(wrapAllowPermLayer(buf
) == (drivetype
!= DRIVE_REMOTE
), "Expected AllowPermLayer to be %d for %c:\\\n", (drivetype
!= DRIVE_REMOTE
), drive_letter
);
193 static BOOL
wrapSdbSetPermLayerKeys(PCWSTR wszPath
, PCSTR szLayers
, BOOL bMachine
)
195 WCHAR wszLayers
[MAX_LAYER_LENGTH
];
196 MultiByteToWideChar(CP_ACP
, 0, szLayers
, -1, wszLayers
, MAX_LAYER_LENGTH
);
197 return pSdbSetPermLayerKeys(wszPath
, wszLayers
, bMachine
);
200 static void test_SdbSetPermLayerKeysLevel(BOOL bMachine
, const char* file
)
202 WCHAR fileW
[MAX_PATH
+20];
203 WCHAR emptyString
[1] = { 0 };
205 MultiByteToWideChar(CP_ACP
, 0, file
, -1, fileW
, MAX_PATH
+20);
207 /* Test some parameter validation. */
208 ok(pSdbSetPermLayerKeys(NULL
, NULL
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
209 ok(pSdbSetPermLayerKeys(NULL
, emptyString
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
210 ok(pSdbSetPermLayerKeys(emptyString
, emptyString
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
211 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to succeed\n");
212 ok(pSdbSetPermLayerKeys(fileW
, emptyString
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to fail\n");
215 ok(wrapSdbSetPermLayerKeys(fileW
, "TEST1", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
216 expect_LayerValue(bMachine
, file
, "TEST1");
218 ok(wrapSdbSetPermLayerKeys(fileW
, "TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
219 expect_LayerValue(bMachine
, file
, "TEST1 TEST2");
221 /* SdbSetPermLayerKeys does not do any validation of the value passed in. */
222 ok(wrapSdbSetPermLayerKeys(fileW
, "!#$% TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
223 expect_LayerValue(bMachine
, file
, "!#$% TEST1 TEST2");
225 ok(wrapSdbSetPermLayerKeys(fileW
, "!#$% TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
226 expect_LayerValue(bMachine
, file
, "!#$% TEST1 TEST2");
228 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to succeed\n");
229 expect_LayerValue(bMachine
, file
, NULL
);
231 ok(wrapSdbSetPermLayerKeys(fileW
, " ", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
232 expect_LayerValue(bMachine
, file
, " ");
234 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to fail\n");
235 expect_LayerValue(bMachine
, file
, NULL
);
238 static void test_SdbGetPermLayerKeys(void)
240 WCHAR pathW
[MAX_PATH
], buffer
[MAX_LAYER_LENGTH
] = { 0 };
241 char file
[MAX_PATH
+ 20], tmp
[MAX_PATH
+ 20];
242 BOOL bUser
, bMachine
;
244 DWORD dwBufSize
= sizeof(buffer
);
246 GetTempPathA(MAX_PATH
, tmp
);
247 GetLongPathNameA(tmp
, file
, sizeof(file
));
248 PathCombineA(tmp
, file
, "notexist.exe");
249 PathAppendA(file
, "test_file.exe");
251 /* Check that we can access the keys */
252 bUser
= setLayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
253 expect_LayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
254 ok(bUser
, "Expected to be able to set atleast the flags for the user\n");
257 skip("Cannot do any tests if I cannot set some values\n");
260 bMachine
= setLayerValue(TRUE
, file
, "WINXPSP3 WINXPSP2");
263 expect_LayerValue(TRUE
, file
, "WINXPSP3 WINXPSP2");
267 hfile
= CreateFileA(file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
268 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed on '%s'..\n", file
);
269 if (hfile
== INVALID_HANDLE_VALUE
)
271 skip("Running these tests is useless without a file present\n");
276 MultiByteToWideChar(CP_ACP
, 0, file
, -1, pathW
, MAX_PATH
);
278 /* Parameter validation */
279 ok(pSdbGetPermLayerKeys(NULL
, NULL
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
280 ok(pSdbGetPermLayerKeys(pathW
, NULL
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
281 ok(pSdbGetPermLayerKeys(pathW
, buffer
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
282 ok(pSdbGetPermLayerKeys(pathW
, buffer
, &dwBufSize
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
283 ok(dwBufSize
== 0, "Expected dwBufSize to be %u, was %u\n", 0, dwBufSize
);
285 /* It fails on a nonexisting file */
286 expect_Sdb(tmp
, GPLK_USER
| GPLK_MACHINE
, FALSE
, 0xffffffff, "");
287 expect_Sdb(file
, GPLK_USER
, TRUE
, 40, "RUNASADMIN WINXPSP3");
288 GetShortPathNameA(file
, tmp
, sizeof(tmp
));
289 expect_Sdb(tmp
, GPLK_USER
, TRUE
, 40, "RUNASADMIN WINXPSP3");
293 /* Query from HKLM */
294 expect_Sdb(file
, GPLK_MACHINE
, TRUE
, 36, "WINXPSP3 WINXPSP2");
295 /* Query from both, showing that duplicates are not removed */
296 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 76, "WINXPSP3 WINXPSP2 RUNASADMIN WINXPSP3");
298 /* Showing that no validation is done on the value read. */
299 ok(setLayerValue(TRUE
, file
, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 "), "Expected setLayerValue not to fail\n");
300 expect_Sdb(file
, GPLK_MACHINE
, TRUE
, 82, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 ");
301 /* Showing that a space is inserted, even if the last char was already a space. */
302 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 122, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 RUNASADMIN WINXPSP3");
303 /* Now clear the user key */
304 setLayerValue(FALSE
, file
, NULL
);
305 /* Request both, to show that the last space (from the key) is not cut off. */
306 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 82, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 ");
307 setLayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
311 skip("Skipping tests for HKLM, cannot alter the registry\n");
313 /* Fail from these paths */
314 sprintf(tmp
, "\\?\\%s", file
);
315 expect_Sdb(tmp
, GPLK_USER
, FALSE
, 0xffffffff, "");
316 sprintf(tmp
, "\\??\\%s", file
);
317 expect_Sdb(tmp
, GPLK_USER
, FALSE
, 0xffffffff, "");
319 ok(setLayerValue(FALSE
, file
, "!#!# RUNASADMIN RUNASADMIN !# WINXPSP3 "), "Expected setLayerValue not to fail\n");
320 /* There is no validation on information read back. */
321 expect_Sdb(file
, GPLK_USER
, TRUE
, 90, "!#!# RUNASADMIN RUNASADMIN !# WINXPSP3 ");
325 ok(DeleteFileA(file
), "DeleteFile failed....\n");
326 setLayerValue(FALSE
, file
, NULL
);
327 setLayerValue(TRUE
, file
, NULL
);
331 static BOOL
wrapSetPermLayerState(PCWSTR wszPath
, PCSTR szLayer
, DWORD dwFlags
, BOOL bMachine
, BOOL bEnable
)
333 WCHAR wszLayer
[MAX_LAYER_LENGTH
];
334 MultiByteToWideChar(CP_ACP
, 0, szLayer
, -1, wszLayer
, MAX_LAYER_LENGTH
);
335 return pSetPermLayerState(wszPath
, wszLayer
, dwFlags
, bMachine
, bEnable
);
338 static void test_SetPermLayerStateLevel(BOOL bMachine
, const char* file
)
340 WCHAR fileW
[MAX_PATH
+20];
341 WCHAR emptyString
[1] = { 0 };
344 MultiByteToWideChar(CP_ACP
, 0, file
, -1, fileW
, MAX_PATH
+20);
346 /* Test some parameter validation. */
347 ok(pSetPermLayerState(fileW
, NULL
, 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
348 expect_LayerValue(bMachine
, file
, NULL
);
350 ok(pSetPermLayerState(fileW
, NULL
, 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
351 expect_LayerValue(bMachine
, file
, NULL
);
353 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
354 expect_LayerValue(bMachine
, file
, NULL
);
356 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
357 expect_LayerValue(bMachine
, file
, NULL
);
359 ok(wrapSetPermLayerState(NULL
, NULL
, 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
360 expect_LayerValue(bMachine
, NULL
, NULL
);
362 ok(wrapSetPermLayerState(NULL
, NULL
, 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
363 expect_LayerValue(bMachine
, NULL
, NULL
);
365 ok(wrapSetPermLayerState(emptyString
, "", 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
366 expect_LayerValue(bMachine
, NULL
, NULL
);
368 ok(wrapSetPermLayerState(emptyString
, "", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
369 expect_LayerValue(bMachine
, NULL
, NULL
);
371 ok(wrapSetPermLayerState(emptyString
, "TEST", 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
372 expect_LayerValue(bMachine
, NULL
, NULL
);
374 if (g_Version
<= APPHELP_WIN8
)
376 ok(wrapSetPermLayerState(emptyString
, "TEST", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
377 expect_LayerValue(bMachine
, NULL
, NULL
);
381 /* Now, on to the actual tests. */
382 expect_LayerValue(bMachine
, file
, NULL
);
383 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
384 expect_LayerValue(bMachine
, file
, NULL
);
386 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
387 expect_LayerValue(bMachine
, file
, "TEST");
389 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
390 expect_LayerValue(bMachine
, file
, "TEST");
392 ok(wrapSetPermLayerState(fileW
, "test", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
393 expect_LayerValue(bMachine
, file
, "test");
395 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
396 expect_LayerValue(bMachine
, file
, NULL
);
398 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
399 expect_LayerValue(bMachine
, file
, "TEST");
401 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
402 expect_LayerValue2(bMachine
, file
, "TEST TEST1", g_Version
>= APPHELP_WIN8
, "TEST1 TEST");
404 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
405 expect_LayerValue2(bMachine
, file
, "TEST TEST1 TEST2", g_Version
>= APPHELP_WIN8
, "TEST2 TEST1 TEST");
407 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
408 expect_LayerValue2(bMachine
, file
, "TEST TEST2", g_Version
>= APPHELP_WIN8
, "TEST2 TEST");
410 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
411 expect_LayerValue(bMachine
, file
, "TEST2");
413 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
414 expect_LayerValue(bMachine
, file
, NULL
);
416 /* Valid flags until win8: !# */
417 /* Key is empty, now play around with the flags. */
418 for (dwFlag
= ((g_Version
>= APPHELP_WIN8
) ? 6 : 2); dwFlag
< 32; ++dwFlag
)
420 ok(wrapSetPermLayerState(fileW
, "TEST", (1<<dwFlag
), bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail on 0x%x\n", (1<<dwFlag
));
422 expect_LayerValue(bMachine
, file
, NULL
);
424 /* Add layer flags */
425 ok(wrapSetPermLayerState(fileW
, "TEST", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
426 expect_LayerValue(bMachine
, file
, "# TEST");
428 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
429 expect_LayerValue2(bMachine
, file
, "!# TEST TEST2", g_Version
>= APPHELP_WIN8
, "!# TEST2 TEST");
431 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
432 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST", g_Version
>= APPHELP_WIN8
, "!# TEST TEST2");
434 ok(wrapSetPermLayerState(fileW
, "TEST3", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
435 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST TEST3", g_Version
>= APPHELP_WIN8
, "!# TEST3 TEST TEST2");
437 /* Remove on a flag removes that flag from the start. */
438 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
439 expect_LayerValue2(bMachine
, file
, "# TEST TEST3", g_Version
>= APPHELP_WIN8
, "# TEST3 TEST");
441 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
442 expect_LayerValue2(bMachine
, file
, "TEST TEST3", g_Version
>= APPHELP_WIN8
, "TEST3 TEST");
444 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
| 2, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
445 expect_LayerValue2(bMachine
, file
, "!# TEST TEST3", g_Version
>= APPHELP_WIN8
, "!# TEST3 TEST");
447 ok(wrapSetPermLayerState(fileW
, "TEST3", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
448 expect_LayerValue(bMachine
, file
, "! TEST");
450 ok(wrapSetPermLayerState(fileW
, "TEST", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
451 expect_LayerValue(bMachine
, file
, NULL
);
453 /* Try adding multiple layers: */
454 ok(wrapSetPermLayerState(fileW
, "TEST TEST2", LAYER_APPLY_TO_SYSTEM_EXES
| 2, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
455 expect_LayerValue(bMachine
, file
, NULL
);
457 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
458 expect_LayerValue(bMachine
, file
, "TEST2");
460 /* Try adding flags in via layer string */
461 ok(wrapSetPermLayerState(fileW
, "#", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
462 expect_LayerValue(bMachine
, file
, "TEST2");
464 ok(wrapSetPermLayerState(fileW
, "!", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
465 expect_LayerValue(bMachine
, file
, "TEST2");
467 /* Now we prepare the registry with some crap to see how data is validated. */
468 setLayerValue(bMachine
, file
, "!#!# TEST2 TEST2 !# TEST ");
470 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
471 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST2 !# TEST TEST1", g_Version
>= APPHELP_WIN8
, "!# TEST1 TEST2 TEST2 !# TEST");
473 /* Removing a duplicate entry will remove all instances of it */
474 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
475 expect_LayerValue2(bMachine
, file
, "!# !# TEST TEST1", g_Version
>= APPHELP_WIN8
, "!# TEST1 !# TEST");
477 /* Adding a flag cleans other flags (from the start) */
478 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
479 expect_LayerValue2(bMachine
, file
, "!# TEST TEST1", g_Version
>= APPHELP_WIN8
, "!# TEST1 !# TEST");
481 if(g_Version
< APPHELP_WIN8
)
483 ok(wrapSetPermLayerState(fileW
, "$%$%^^", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
484 expect_LayerValue(bMachine
, file
, "!# TEST TEST1 $%$%^^");
487 setLayerValue(bMachine
, file
, "!#!# TEST2 !# TEST ");
488 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
489 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
491 /* Tabs are treated as spaces */
492 setLayerValue(bMachine
, file
, "!#!# TEST2 \t TEST2 !# \t TEST ");
493 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
494 expect_LayerValue2(bMachine
, file
, "!# !# TEST TEST2", g_Version
>= APPHELP_WIN8
, "!# TEST2 !# TEST");
496 /* Newlines are left as-is */
497 setLayerValue(bMachine
, file
, "!#!# TEST2 \n TEST2 !# \r\n TEST ");
498 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
499 expect_LayerValue2(bMachine
, file
, "!# \n !# \r\n TEST TEST2", g_Version
>= APPHELP_WIN8
, "!# TEST2 \n !# \r\n TEST");
501 /* Whitespace and duplicate flags are eaten from the start */
502 setLayerValue(bMachine
, file
, " !#!# TEST2 \t TEST2 !# \t TEST ");
503 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
504 expect_LayerValue(bMachine
, file
, "! TEST2 TEST2 !# TEST");
506 setLayerValue(bMachine
, file
, "!# !# TEST2 !# TEST ");
507 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
508 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
510 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
511 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
513 ok(wrapSetPermLayerState(fileW
, "", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
514 expect_LayerValue(bMachine
, file
, "TEST2 !# TEST");
516 /* First flags are cleaned, then a layer is removed. */
517 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
518 expect_LayerValue(bMachine
, file
, "!# TEST");
520 /* Nothing is changed, still it succeeds. */
521 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
522 expect_LayerValue(bMachine
, file
, "# TEST");
524 /* And remove the last bits. */
525 ok(wrapSetPermLayerState(fileW
, "TEST", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
526 expect_LayerValue(bMachine
, file
, NULL
);
529 static void test_SetPermLayer(void)
531 char file
[MAX_PATH
+ 20], tmp
[MAX_PATH
+ 20];
534 GetTempPathA(MAX_PATH
, tmp
);
535 GetLongPathNameA(tmp
, file
, sizeof(file
));
536 PathAppendA(file
, "test_file.exe");
538 hfile
= CreateFileA(file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
539 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed for '%s'\n", file
);
540 if (hfile
== INVALID_HANDLE_VALUE
)
542 skip("Running these tests is useless without a file present\n");
547 if (setLayerValue(FALSE
, file
, NULL
))
549 test_SdbSetPermLayerKeysLevel(FALSE
, file
);
550 test_SetPermLayerStateLevel(FALSE
, file
);
554 skip("Skipping SetPermLayerStateLevel tests for User, because I cannot prepare the environment\n");
556 if (setLayerValue(TRUE
, file
, NULL
))
558 test_SdbSetPermLayerKeysLevel(TRUE
, file
);
559 test_SetPermLayerStateLevel(TRUE
, file
);
563 skip("Skipping SetPermLayerStateLevel tests for Machine (HKLM), because I cannot prepare the environment\n");
565 ok(DeleteFileA(file
), "DeleteFile failed....\n");
568 static BOOL
create_file(LPCSTR dir
, LPCSTR name
, int filler
, size_t size
)
570 char target
[MAX_PATH
], *tmp
;
572 PathCombineA(target
, dir
, name
);
575 memset(tmp
, filler
, size
);
577 file
= CreateFileA(target
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
578 if(file
== INVALID_HANDLE_VALUE
)
581 WriteFile(file
, tmp
, size
, &size
, NULL
);
587 static BOOL
delete_file(LPCSTR dir
, LPCSTR name
)
589 char target
[MAX_PATH
];
590 PathCombineA(target
, dir
, name
);
591 return DeleteFileA(target
);
594 static char g_FakeDrive
= 0;
596 UINT (WINAPI
*pGetDriveTypeW
)(LPCWSTR target
) = NULL
;
597 UINT WINAPI
mGetDriveTypeW(LPCWSTR target
)
599 UINT uRet
= pGetDriveTypeW(target
);
600 if(g_FakeDrive
&& target
&& (char)*target
== g_FakeDrive
)
606 static PIMAGE_IMPORT_DESCRIPTOR
FindImportDescriptor(PBYTE DllBase
, PCSTR DllName
)
609 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor
= RtlImageDirectoryEntryToData((HMODULE
)DllBase
, TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &Size
);
610 while (ImportDescriptor
->Name
&& ImportDescriptor
->OriginalFirstThunk
)
612 PCHAR Name
= (PCHAR
)(DllBase
+ ImportDescriptor
->Name
);
613 if (!lstrcmpiA(Name
, DllName
))
615 return ImportDescriptor
;
622 static BOOL
RedirectIat(PCSTR TargetDllName
, PCSTR DllName
, PCSTR FunctionName
, ULONG_PTR NewFunction
, ULONG_PTR
* OriginalFunction
)
624 PBYTE DllBase
= (PBYTE
)GetModuleHandleA(TargetDllName
);
627 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor
= FindImportDescriptor(DllBase
, DllName
);
628 if (ImportDescriptor
)
630 // On loaded images, OriginalFirstThunk points to the name / ordinal of the function
631 PIMAGE_THUNK_DATA OriginalThunk
= (PIMAGE_THUNK_DATA
)(DllBase
+ ImportDescriptor
->OriginalFirstThunk
);
632 // FirstThunk points to the resolved address.
633 PIMAGE_THUNK_DATA FirstThunk
= (PIMAGE_THUNK_DATA
)(DllBase
+ ImportDescriptor
->FirstThunk
);
634 while (OriginalThunk
->u1
.AddressOfData
&& FirstThunk
->u1
.Function
)
636 if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk
->u1
.AddressOfData
))
638 PIMAGE_IMPORT_BY_NAME ImportName
= (PIMAGE_IMPORT_BY_NAME
)(DllBase
+ OriginalThunk
->u1
.AddressOfData
);
639 if (!lstrcmpiA((PCSTR
)ImportName
->Name
, FunctionName
))
642 VirtualProtect(&FirstThunk
->u1
.Function
, sizeof(ULONG_PTR
), PAGE_EXECUTE_READWRITE
, &dwOld
);
643 *OriginalFunction
= FirstThunk
->u1
.Function
;
644 FirstThunk
->u1
.Function
= NewFunction
;
645 VirtualProtect(&FirstThunk
->u1
.Function
, sizeof(ULONG_PTR
), dwOld
, &dwOld
);
652 skip("Unable to find the Import '%s' from '%s' in %s'\n", FunctionName
, DllName
, TargetDllName
);
656 skip("Unable to find the ImportDescriptor for '%s' in '%s'\n", DllName
, TargetDllName
);
661 skip("Unable to find the loaded module '%s'\n", TargetDllName
);
666 static BOOL
RestoreIat(PCSTR target
, PCSTR DllName
, PCSTR FunctionName
, ULONG_PTR OriginalFunction
)
669 return RedirectIat(target
, DllName
, FunctionName
, OriginalFunction
, &old
);
672 static BOOL
wrapSdbSetPermLayerKeys2(LPCSTR dir
, LPCSTR name
, PCSTR szLayers
, BOOL bMachine
)
674 char szPath
[MAX_PATH
];
675 WCHAR wszPath
[MAX_PATH
], wszLayers
[MAX_LAYER_LENGTH
];
676 PathCombineA(szPath
, dir
, name
);
677 MultiByteToWideChar(CP_ACP
, 0, szLayers
, -1, wszLayers
, MAX_LAYER_LENGTH
);
678 MultiByteToWideChar(CP_ACP
, 0, szPath
, -1, wszPath
, MAX_PATH
);
679 return pSdbSetPermLayerKeys(wszPath
, wszLayers
, bMachine
);
683 BOOL
expect_files(const char* dir
, int num
, ...)
685 char finddir
[MAX_PATH
+ 20];
687 WIN32_FIND_DATAA find
= { 0 };
693 PathCombineA(finddir
, dir
, "*");
694 hFind
= FindFirstFileA(finddir
, &find
);
695 if (hFind
!= INVALID_HANDLE_VALUE
)
700 if (!(find
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
704 file
= va_arg(args
, const char*);
705 cmp
= strcmp(file
, find
.cFileName
);
707 } while (cmp
== 0 && FindNextFileA(hFind
, &find
));
711 return cmp
== 0 && num
== 0;
715 static void test_Sign_Media(void)
717 char workdir
[MAX_PATH
], subdir
[MAX_PATH
], drive
[5] = "Z:";
720 DWORD logical_drives
= GetLogicalDrives();
722 for (drive
[0] = 'D'; drive
[0] <= 'Z'; drive
[0]++)
724 DWORD idx
= 1 << (drive
[0] - 'D' + 3);
725 if (!(logical_drives
& idx
))
727 g_FakeDrive
= drive
[0];
733 skip("Unable to find a free drive\n");
737 ret
= GetTempPathA(MAX_PATH
, workdir
);
738 ok(ret
, "GetTempPathA error: %d\n", GetLastError());
739 PathAppendA(workdir
, "apphelp_test");
741 ret
= CreateDirectoryA(workdir
, NULL
);
742 ok(ret
, "CreateDirectoryA error: %d\n", GetLastError());
744 PathCombineA(subdir
, workdir
, "sub");
745 ret
= CreateDirectoryA(subdir
, NULL
);
746 ok(ret
, "CreateDirectoryA error: %d\n", GetLastError());
748 ret
= DefineDosDeviceA(DDD_NO_BROADCAST_SYSTEM
, drive
, workdir
);
749 ok(ret
, "DefineDosDeviceA error: %d\n", GetLastError());
752 ret
= RedirectIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR
)mGetDriveTypeW
, (ULONG_PTR
*)&pGetDriveTypeW
);
753 if (g_Version
< APPHELP_WIN8
)
754 ok(ret
, "Expected redirect_iat to succeed\n");
757 ok(create_file(workdir
, "test.exe", 'a', 4), "create_file error: %d\n", GetLastError());
759 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
762 expect_LayerValue(0, "SIGN.MEDIA=4 test.exe", "TEST");
763 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
765 ok(create_file(workdir
, "test.txt", 'a', 1), "create_file error: %d\n", GetLastError());
767 if (!expect_files(workdir
, 2, "test.exe", "test.txt"))
769 skip("Skipping test, files are not returned in the expected order by the FS\n");
773 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
775 /* test.exe test.txt */
776 expect_LayerValue(0, "SIGN.MEDIA=9 test.exe", "TEST");
777 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
780 ok(create_file(workdir
, "test.zz", 'a', 0x1000), "create_file error: %d\n", GetLastError());
782 if (!expect_files(workdir
, 3, "test.exe", "test.txt", "test.zz"))
784 skip("Skipping test, files are not returned in the expected order by the FS\n");
788 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
789 /* (((4 << 1) ^ 1) << 1) ^ 0x1000 */
790 /* test.exe test.txt test.zz */
791 expect_LayerValue(0, "SIGN.MEDIA=1012 test.exe", "TEST");
792 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
795 ok(create_file(subdir
, "test.exe", 'a', 0x10203), "create_file error: %d\n", GetLastError());
797 if (!expect_files(subdir
, 1, "test.exe"))
799 skip("Skipping test, files are not returned in the expected order by the FS\n");
803 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
806 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST");
807 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
810 ok(create_file(subdir
, "test.bbb", 'a', 0), "create_file error: %d\n", GetLastError());
812 if (!expect_files(subdir
, 2, "test.bbb", "test.exe"))
814 skip("Skipping test, files are not returned in the expected order by the FS\n");
818 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
821 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST");
822 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
825 ok(create_file(subdir
, "TEST.txt", 'a', 0x30201), "create_file error: %d\n", GetLastError());
827 if (!expect_files(subdir
, 3, "test.bbb", "test.exe", "TEST.txt"))
829 skip("Skipping test, files are not returned in the expected order by the FS\n");
833 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
834 /* (0x10203 << 1) ^ 0x30201 */
835 /* test.exe TEST.txt */
836 expect_LayerValue(0, "SIGN.MEDIA=10607 sub\\test.exe", "TEST");
837 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
840 ok(create_file(subdir
, "TEST.aaa", 'a', 0x3a2a1), "create_file error: %d\n", GetLastError());
842 if (!expect_files(subdir
, 4, "TEST.aaa", "test.bbb", "test.exe", "TEST.txt"))
844 skip("Skipping test, files are not returned in the expected order by the FS\n");
848 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
849 /* (((0x3a2a1 << 1) ^ 0x10203) << 1) ^ 0x30201 */
850 /* TEST.aaa test.exe TEST.txt */
851 expect_LayerValue(0, "SIGN.MEDIA=F8C83 sub\\test.exe", "TEST");
852 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
855 ret
= RestoreIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR
)pGetDriveTypeW
);
856 ok(ret
, "Expected restore_iat to succeed\n");
858 ok(delete_file(subdir
, "test.bbb"), "delete_file error: %d\n", GetLastError());
859 ok(delete_file(subdir
, "TEST.aaa"), "delete_file error: %d\n", GetLastError());
860 ok(delete_file(subdir
, "TEST.txt"), "delete_file error: %d\n", GetLastError());
861 ok(delete_file(subdir
, "test.exe"), "delete_file error: %d\n", GetLastError());
862 ok(delete_file(workdir
, "test.zz"), "delete_file error: %d\n", GetLastError());
863 ok(delete_file(workdir
, "test.txt"), "delete_file error: %d\n", GetLastError());
864 ok(delete_file(workdir
, "test.exe"), "delete_file error: %d\n", GetLastError());
866 ret
= DefineDosDeviceA(DDD_REMOVE_DEFINITION
| DDD_NO_BROADCAST_SYSTEM
, drive
, NULL
);
867 ok(ret
, "DefineDosDeviceA error: %d\n", GetLastError());
869 ret
= RemoveDirectoryA(subdir
);
870 ok(ret
, "RemoveDirectoryA error: %d\n", GetLastError());
871 ret
= RemoveDirectoryA(workdir
);
872 ok(ret
, "RemoveDirectoryA error: %d\n", GetLastError());
878 RTL_OSVERSIONINFOEXW rtlinfo
;
879 /*SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");*/
880 hdll
= LoadLibraryA("apphelp.dll");
881 pAllowPermLayer
= (void *)GetProcAddress(hdll
, "AllowPermLayer");
882 pSdbSetPermLayerKeys
= (void *)GetProcAddress(hdll
, "SdbSetPermLayerKeys");
883 pSdbGetPermLayerKeys
= (void *)GetProcAddress(hdll
, "SdbGetPermLayerKeys");
884 pSetPermLayerState
= (void *)GetProcAddress(hdll
, "SetPermLayerState");
885 rtlinfo
.dwOSVersionInfoSize
= sizeof(rtlinfo
);
887 RtlGetVersion((PRTL_OSVERSIONINFOW
)&rtlinfo
);
889 RtlGetVersion(&rtlinfo
);
891 g_Version
= (rtlinfo
.dwMajorVersion
<< 8) | rtlinfo
.dwMinorVersion
;
893 if (!pAllowPermLayer
)
895 skip("Skipping tests with AllowPermLayer, function not found\n");
899 test_AllowPermLayer();
902 if (!pSdbSetPermLayerKeys
)
904 skip("Skipping tests with SdbSetPermLayerKeys, function not found\n");
908 if (!pSdbGetPermLayerKeys
)
910 skip("Skipping tests with SdbGetPermLayerKeys, function not found\n");
914 test_SdbGetPermLayerKeys();
917 if (!pSetPermLayerState
)
919 skip("Skipping tests with SetPermLayerState, function not found\n");