2 * Copyright 2015,2016 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"
35 DWORD
get_host_winver();
38 #define GPLK_MACHINE 2
39 #define MAX_LAYER_LENGTH 256
40 #define LAYER_APPLY_TO_SYSTEM_EXES 1
44 static BOOL(WINAPI
*pAllowPermLayer
)(PCWSTR path
);
45 static BOOL(WINAPI
*pSdbSetPermLayerKeys
)(PCWSTR wszPath
, PCWSTR wszLayers
, BOOL bMachine
);
46 static BOOL(WINAPI
*pSdbGetPermLayerKeys
)(PCWSTR wszPath
, PWSTR pwszLayers
, PDWORD pdwBytes
, DWORD dwFlags
);
47 static BOOL(WINAPI
*pSetPermLayerState
)(PCWSTR wszPath
, PCWSTR wszLayer
, DWORD dwFlags
, BOOL bMachine
, BOOL bEnable
);
50 static DWORD g_WinVersion
;
51 #define WINVER_VISTA 0x0600
52 #define WINVER_WIN8 0x0602
53 #define WINVER_WIN10 0x1000
56 /* Helper function to disable Wow64 redirection on an os that reports it being enabled. */
57 static DWORD g_QueryFlag
= 0xffffffff;
58 static DWORD
QueryFlag(void)
60 if (g_QueryFlag
== 0xffffffff)
62 ULONG_PTR wow64_ptr
= 0;
63 NTSTATUS status
= NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information
, &wow64_ptr
, sizeof(wow64_ptr
), NULL
);
64 g_QueryFlag
= (NT_SUCCESS(status
) && wow64_ptr
!= 0) ? KEY_WOW64_64KEY
: 0;
69 /* Helper function to prepare the registry key with a value. */
70 static BOOL
setLayerValue(BOOL bMachine
, const char* valueName
, const char* value
)
73 LSTATUS lstatus
= RegCreateKeyExA(bMachine
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
74 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL
, 0, QueryFlag() | KEY_SET_VALUE
, NULL
, &key
, NULL
);
75 if (lstatus
== ERROR_SUCCESS
)
78 lstatus
= RegSetValueExA(key
, valueName
, 0, REG_SZ
, (const BYTE
*)value
, strlen(value
)+1);
81 lstatus
= RegDeleteValueA(key
, valueName
);
82 lstatus
= (lstatus
== ERROR_FILE_NOT_FOUND
? ERROR_SUCCESS
: lstatus
);
86 return lstatus
== ERROR_SUCCESS
;
90 static void expect_LayerValue_imp(BOOL bMachine
, const char* valueName
, const char* value
)
93 LSTATUS lstatus
= RegCreateKeyExA(bMachine
? HKEY_LOCAL_MACHINE
: HKEY_CURRENT_USER
,
94 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL
, 0, QueryFlag() | KEY_QUERY_VALUE
, NULL
, &key
, NULL
);
95 winetest_ok(lstatus
== ERROR_SUCCESS
, "Expected to be able to open a registry key\n");
96 if (lstatus
== ERROR_SUCCESS
)
98 char data
[512] = { 0 };
100 DWORD dwDataLen
= sizeof(data
);
101 lstatus
= RegQueryValueExA(key
, valueName
, NULL
, &dwType
, (LPBYTE
)data
, &dwDataLen
);
104 winetest_ok(lstatus
== ERROR_SUCCESS
, "Expected to get a valid value, err: %u\n", lstatus
);
105 if (lstatus
== ERROR_SUCCESS
)
107 winetest_ok(dwType
== REG_SZ
, "Expected the type to be REG_SZ, was: %u\n", dwType
);
108 winetest_ok(!strcmp(data
, value
), "Expected the data to be: '%s', was: '%s'\n", value
, data
);
113 winetest_ok(lstatus
== ERROR_FILE_NOT_FOUND
, "Expected not to find the value %s\n", valueName
);
119 static void expect_LayerValue_imp2(BOOL bMachine
, const char* valueName
, const char* value
, int use_alt
, const char* alt_value
)
121 expect_LayerValue_imp(bMachine
, valueName
, use_alt
? alt_value
: value
);
125 void expect_Sdb_imp(PCSTR path
, DWORD type
, BOOL result
, DWORD lenResult
, PCSTR stringResult
)
127 WCHAR pathW
[MAX_PATH
], buffer
[MAX_LAYER_LENGTH
] = { 0 };
128 char resultBuffer
[MAX_LAYER_LENGTH
] = { 0 };
129 DWORD dwBufSize
= sizeof(buffer
);
131 /* In case of a failure, the buffer size is sometimes set to 0, and sometimes not touched,
132 depending on the version. Either case is fine, since the function returns FALSE anyway. */
134 MultiByteToWideChar(CP_ACP
, 0, path
, -1, pathW
, MAX_PATH
);
136 winetest_ok(pSdbGetPermLayerKeys(pathW
, buffer
, &dwBufSize
, type
) == result
, "Expected pSdbGetPermLayerKeys to %s\n", (result
? "succeed" : "fail"));
137 if (!result
&& lenResult
== 0xffffffff)
138 winetest_ok(dwBufSize
== 0 || dwBufSize
== sizeof(buffer
), "Expected dwBufSize to be 0 or %u, was %u\n", sizeof(buffer
), dwBufSize
);
140 winetest_ok(dwBufSize
== lenResult
||
141 /* W2k3 is off by 2 when concatenating user / machine */
142 broken(g_WinVersion
< WINVER_VISTA
&& type
== (GPLK_MACHINE
|GPLK_USER
) && (lenResult
+ 2) == dwBufSize
),
143 "Expected dwBufSize to be %u, was %u\n", lenResult
, dwBufSize
);
146 winetest_ok(lstrlenW(buffer
) * sizeof(WCHAR
) + sizeof(WCHAR
) == lenResult
, "Expected lstrlenW(buffer)*2+2 to be %u, was %u\n",
147 lenResult
, lstrlenW(buffer
) * sizeof(WCHAR
) + sizeof(WCHAR
));
149 WideCharToMultiByte(CP_ACP
, 0, buffer
, -1, resultBuffer
, sizeof(resultBuffer
), NULL
, NULL
);
150 winetest_ok(!strcmp(stringResult
, resultBuffer
), "Expected the result to be '%s', was '%s'\n", stringResult
, resultBuffer
);
154 /* In case of a failure, let the location be from where the function was invoked, not inside the function itself. */
155 #define expect_Sdb (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_Sdb_imp
156 #define expect_LayerValue (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_LayerValue_imp
157 #define expect_LayerValue2 (winetest_set_location(__FILE__, __LINE__), 0) ? (void)0 : expect_LayerValue_imp2
160 BOOL
wrapAllowPermLayer(const char* str
)
163 MultiByteToWideChar(CP_ACP
, 0, str
, -1, buf
, 100);
164 return pAllowPermLayer(buf
);
167 /* Brute forcing all ascii chars in the first 2 places seems to indicate that all it cares for is:
168 - Second char has to be a ':'
169 if it's not a ':', display a diagnostic message (and a different one for '\\').
170 - 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...)
172 static void test_AllowPermLayer(void)
177 ok(pAllowPermLayer(NULL
) == FALSE
, "Expected AllowPermLayer to fail for NULL\n");
178 if (g_WinVersion
< WINVER_WIN8
)
180 ok(wrapAllowPermLayer("-:"), "Expected AllowPermLayer to succeed\n");
181 ok(wrapAllowPermLayer("@:"), "Expected AllowPermLayer to succeed\n");
182 ok(wrapAllowPermLayer("4:"), "Expected AllowPermLayer to succeed\n");
183 ok(wrapAllowPermLayer("*:"), "Expected AllowPermLayer to succeed\n");
185 ok(wrapAllowPermLayer("*a") == FALSE
, "Expected AllowPermLayer to fail\n");
186 ok(wrapAllowPermLayer("*\\") == FALSE
, "Expected AllowPermLayer to fail\n");
187 for (drive_letter
= 'a'; drive_letter
<= 'z'; ++drive_letter
)
189 sprintf(buf
, "%c:\\", drive_letter
);
190 drivetype
= GetDriveTypeA(buf
);
191 ok(wrapAllowPermLayer(buf
) == (drivetype
!= DRIVE_REMOTE
), "Expected AllowPermLayer to be %d for %c:\\\n", (drivetype
!= DRIVE_REMOTE
), drive_letter
);
195 static BOOL
wrapSdbSetPermLayerKeys(PCWSTR wszPath
, PCSTR szLayers
, BOOL bMachine
)
197 WCHAR wszLayers
[MAX_LAYER_LENGTH
];
198 MultiByteToWideChar(CP_ACP
, 0, szLayers
, -1, wszLayers
, MAX_LAYER_LENGTH
);
199 return pSdbSetPermLayerKeys(wszPath
, wszLayers
, bMachine
);
202 static void test_SdbSetPermLayerKeysLevel(BOOL bMachine
, const char* file
)
204 WCHAR fileW
[MAX_PATH
+20];
205 WCHAR emptyString
[1] = { 0 };
207 MultiByteToWideChar(CP_ACP
, 0, file
, -1, fileW
, MAX_PATH
+20);
209 /* Test some parameter validation. */
210 ok(pSdbSetPermLayerKeys(NULL
, NULL
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
211 ok(pSdbSetPermLayerKeys(NULL
, emptyString
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
212 ok(pSdbSetPermLayerKeys(emptyString
, emptyString
, bMachine
) == FALSE
, "Expected SdbSetPermLayerKeys to fail\n");
213 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to succeed\n");
214 ok(pSdbSetPermLayerKeys(fileW
, emptyString
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to fail\n");
217 ok(wrapSdbSetPermLayerKeys(fileW
, "TEST1", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
218 expect_LayerValue(bMachine
, file
, "TEST1");
220 ok(wrapSdbSetPermLayerKeys(fileW
, "TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
221 expect_LayerValue(bMachine
, file
, "TEST1 TEST2");
223 /* SdbSetPermLayerKeys does not do any validation of the value passed in. */
224 ok(wrapSdbSetPermLayerKeys(fileW
, "!#$% TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
225 expect_LayerValue(bMachine
, file
, "!#$% TEST1 TEST2");
227 ok(wrapSdbSetPermLayerKeys(fileW
, "!#$% TEST1 TEST2", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
228 expect_LayerValue(bMachine
, file
, "!#$% TEST1 TEST2");
230 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to succeed\n");
231 expect_LayerValue(bMachine
, file
, NULL
);
233 ok(wrapSdbSetPermLayerKeys(fileW
, " ", bMachine
), "Expected SdbSetPermLayerKeys to succeed\n");
234 expect_LayerValue(bMachine
, file
, " ");
236 ok(pSdbSetPermLayerKeys(fileW
, NULL
, bMachine
) == TRUE
, "Expected SdbSetPermLayerKeys to fail\n");
237 expect_LayerValue(bMachine
, file
, NULL
);
240 static void test_SdbGetPermLayerKeys(void)
242 WCHAR pathW
[MAX_PATH
], buffer
[MAX_LAYER_LENGTH
] = { 0 };
243 char file
[MAX_PATH
+ 20], tmp
[MAX_PATH
+ 20];
244 BOOL bUser
, bMachine
;
246 DWORD dwBufSize
= sizeof(buffer
);
248 GetTempPathA(MAX_PATH
, tmp
);
249 GetLongPathNameA(tmp
, file
, sizeof(file
));
250 PathCombineA(tmp
, file
, "notexist.exe");
251 PathAppendA(file
, "test_file.exe");
253 /* Check that we can access the keys */
254 bUser
= setLayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
255 expect_LayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
256 ok(bUser
, "Expected to be able to set atleast the flags for the user\n");
259 skip("Cannot do any tests if I cannot set some values\n");
262 bMachine
= setLayerValue(TRUE
, file
, "WINXPSP3 WINXPSP2");
265 expect_LayerValue(TRUE
, file
, "WINXPSP3 WINXPSP2");
269 hfile
= CreateFileA(file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
270 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed on '%s'..\n", file
);
271 if (hfile
== INVALID_HANDLE_VALUE
)
273 skip("Running these tests is useless without a file present\n");
278 MultiByteToWideChar(CP_ACP
, 0, file
, -1, pathW
, MAX_PATH
);
280 /* Parameter validation */
281 ok(pSdbGetPermLayerKeys(NULL
, NULL
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
282 ok(pSdbGetPermLayerKeys(pathW
, NULL
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
283 ok(pSdbGetPermLayerKeys(pathW
, buffer
, NULL
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
284 ok(pSdbGetPermLayerKeys(pathW
, buffer
, &dwBufSize
, 0) == FALSE
, "Expected pSdbGetPermLayerKeys to fail\n");
285 ok(dwBufSize
== 0, "Expected dwBufSize to be %u, was %u\n", 0, dwBufSize
);
287 /* It fails on a nonexisting file */
288 expect_Sdb(tmp
, GPLK_USER
| GPLK_MACHINE
, FALSE
, 0xffffffff, "");
289 expect_Sdb(file
, GPLK_USER
, TRUE
, 40, "RUNASADMIN WINXPSP3");
290 GetShortPathNameA(file
, tmp
, sizeof(tmp
));
291 expect_Sdb(tmp
, GPLK_USER
, TRUE
, 40, "RUNASADMIN WINXPSP3");
295 /* Query from HKLM */
296 expect_Sdb(file
, GPLK_MACHINE
, TRUE
, 36, "WINXPSP3 WINXPSP2");
297 /* Query from both, showing that duplicates are not removed */
298 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 76, "WINXPSP3 WINXPSP2 RUNASADMIN WINXPSP3");
300 /* Showing that no validation is done on the value read. */
301 ok(setLayerValue(TRUE
, file
, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 "), "Expected setLayerValue not to fail\n");
302 expect_Sdb(file
, GPLK_MACHINE
, TRUE
, 82, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 ");
303 /* Showing that a space is inserted, even if the last char was already a space. */
304 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 122, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 RUNASADMIN WINXPSP3");
305 /* Now clear the user key */
306 setLayerValue(FALSE
, file
, NULL
);
307 /* Request both, to show that the last space (from the key) is not cut off. */
308 expect_Sdb(file
, GPLK_USER
| GPLK_MACHINE
, TRUE
, 82, "!#!# WINXPSP3 WINXPSP3 !# WINXPSP2 ");
309 setLayerValue(FALSE
, file
, "RUNASADMIN WINXPSP3");
313 skip("Skipping tests for HKLM, cannot alter the registry\n");
315 /* Fail from these paths */
316 sprintf(tmp
, "\\?\\%s", file
);
317 expect_Sdb(tmp
, GPLK_USER
, FALSE
, 0xffffffff, "");
318 sprintf(tmp
, "\\??\\%s", file
);
319 expect_Sdb(tmp
, GPLK_USER
, FALSE
, 0xffffffff, "");
321 ok(setLayerValue(FALSE
, file
, "!#!# RUNASADMIN RUNASADMIN !# WINXPSP3 "), "Expected setLayerValue not to fail\n");
322 /* There is no validation on information read back. */
323 expect_Sdb(file
, GPLK_USER
, TRUE
, 90, "!#!# RUNASADMIN RUNASADMIN !# WINXPSP3 ");
327 ok(DeleteFileA(file
), "DeleteFile failed....\n");
328 setLayerValue(FALSE
, file
, NULL
);
329 setLayerValue(TRUE
, file
, NULL
);
333 static BOOL
wrapSetPermLayerState(PCWSTR wszPath
, PCSTR szLayer
, DWORD dwFlags
, BOOL bMachine
, BOOL bEnable
)
335 WCHAR wszLayer
[MAX_LAYER_LENGTH
];
336 MultiByteToWideChar(CP_ACP
, 0, szLayer
, -1, wszLayer
, MAX_LAYER_LENGTH
);
337 return pSetPermLayerState(wszPath
, wszLayer
, dwFlags
, bMachine
, bEnable
);
340 static void test_SetPermLayerStateLevel(BOOL bMachine
, const char* file
)
342 WCHAR fileW
[MAX_PATH
+20];
343 WCHAR emptyString
[1] = { 0 };
346 MultiByteToWideChar(CP_ACP
, 0, file
, -1, fileW
, MAX_PATH
+20);
348 /* Test some parameter validation. */
349 ok(pSetPermLayerState(fileW
, NULL
, 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
350 expect_LayerValue(bMachine
, file
, NULL
);
352 ok(pSetPermLayerState(fileW
, NULL
, 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
353 expect_LayerValue(bMachine
, file
, NULL
);
355 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
356 expect_LayerValue(bMachine
, file
, NULL
);
358 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
359 expect_LayerValue(bMachine
, file
, NULL
);
361 ok(wrapSetPermLayerState(NULL
, NULL
, 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
362 expect_LayerValue(bMachine
, NULL
, NULL
);
364 ok(wrapSetPermLayerState(NULL
, NULL
, 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
365 expect_LayerValue(bMachine
, NULL
, NULL
);
367 ok(wrapSetPermLayerState(emptyString
, "", 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
368 expect_LayerValue(bMachine
, NULL
, NULL
);
370 ok(wrapSetPermLayerState(emptyString
, "", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
371 expect_LayerValue(bMachine
, NULL
, NULL
);
373 ok(wrapSetPermLayerState(emptyString
, "TEST", 0, bMachine
, 0) == FALSE
, "Expected SetPermLayerState to fail\n");
374 expect_LayerValue(bMachine
, NULL
, NULL
);
376 if (g_WinVersion
<= WINVER_WIN8
)
378 ok(wrapSetPermLayerState(emptyString
, "TEST", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
379 expect_LayerValue(bMachine
, NULL
, NULL
);
383 /* Now, on to the actual tests. */
384 expect_LayerValue(bMachine
, file
, NULL
);
385 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
386 expect_LayerValue(bMachine
, file
, NULL
);
388 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
389 expect_LayerValue(bMachine
, file
, "TEST");
391 ok(wrapSetPermLayerState(fileW
, "", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
392 expect_LayerValue(bMachine
, file
, "TEST");
394 ok(wrapSetPermLayerState(fileW
, "test", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
395 expect_LayerValue(bMachine
, file
, "test");
397 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
398 expect_LayerValue(bMachine
, file
, NULL
);
400 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
401 expect_LayerValue(bMachine
, file
, "TEST");
403 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
404 expect_LayerValue2(bMachine
, file
, "TEST TEST1", g_WinVersion
>= WINVER_WIN8
, "TEST1 TEST");
406 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
407 expect_LayerValue2(bMachine
, file
, "TEST TEST1 TEST2", g_WinVersion
>= WINVER_WIN8
, "TEST2 TEST1 TEST");
409 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
410 expect_LayerValue2(bMachine
, file
, "TEST TEST2", g_WinVersion
>= WINVER_WIN8
, "TEST2 TEST");
412 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
413 expect_LayerValue(bMachine
, file
, "TEST2");
415 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
416 expect_LayerValue(bMachine
, file
, NULL
);
418 /* Valid flags until win8: !# */
419 /* Key is empty, now play around with the flags. */
420 for (dwFlag
= ((g_WinVersion
>= WINVER_WIN8
) ? 6 : 2); dwFlag
< 32; ++dwFlag
)
422 ok(wrapSetPermLayerState(fileW
, "TEST", (1<<dwFlag
), bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail on 0x%x\n", (1<<dwFlag
));
424 expect_LayerValue(bMachine
, file
, NULL
);
426 /* Add layer flags */
427 ok(wrapSetPermLayerState(fileW
, "TEST", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
428 expect_LayerValue(bMachine
, file
, "# TEST");
430 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
431 expect_LayerValue2(bMachine
, file
, "!# TEST TEST2", g_WinVersion
>= WINVER_WIN8
, "!# TEST2 TEST");
433 ok(wrapSetPermLayerState(fileW
, "TEST", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
434 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST", g_WinVersion
>= WINVER_WIN8
, "!# TEST TEST2");
436 ok(wrapSetPermLayerState(fileW
, "TEST3", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
437 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST TEST3", g_WinVersion
>= WINVER_WIN8
, "!# TEST3 TEST TEST2");
439 /* Remove on a flag removes that flag from the start. */
440 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
441 expect_LayerValue2(bMachine
, file
, "# TEST TEST3", g_WinVersion
>= WINVER_WIN8
, "# TEST3 TEST");
443 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
444 expect_LayerValue2(bMachine
, file
, "TEST TEST3", g_WinVersion
>= WINVER_WIN8
, "TEST3 TEST");
446 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
| 2, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
447 expect_LayerValue2(bMachine
, file
, "!# TEST TEST3", g_WinVersion
>= WINVER_WIN8
, "!# TEST3 TEST");
449 ok(wrapSetPermLayerState(fileW
, "TEST3", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
450 expect_LayerValue(bMachine
, file
, "! TEST");
452 ok(wrapSetPermLayerState(fileW
, "TEST", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
453 expect_LayerValue(bMachine
, file
, NULL
);
455 /* Try adding multiple layers: */
456 ok(wrapSetPermLayerState(fileW
, "TEST TEST2", LAYER_APPLY_TO_SYSTEM_EXES
| 2, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
457 expect_LayerValue(bMachine
, file
, NULL
);
459 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
460 expect_LayerValue(bMachine
, file
, "TEST2");
462 /* Try adding flags in via layer string */
463 ok(wrapSetPermLayerState(fileW
, "#", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
464 expect_LayerValue(bMachine
, file
, "TEST2");
466 ok(wrapSetPermLayerState(fileW
, "!", 0, bMachine
, 1) == FALSE
, "Expected SetPermLayerState to fail\n");
467 expect_LayerValue(bMachine
, file
, "TEST2");
469 /* Now we prepare the registry with some crap to see how data is validated. */
470 setLayerValue(bMachine
, file
, "!#!# TEST2 TEST2 !# TEST ");
472 ok(wrapSetPermLayerState(fileW
, "TEST1", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
473 expect_LayerValue2(bMachine
, file
, "!# TEST2 TEST2 !# TEST TEST1", g_WinVersion
>= WINVER_WIN8
, "!# TEST1 TEST2 TEST2 !# TEST");
475 /* Removing a duplicate entry will remove all instances of it */
476 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
477 expect_LayerValue2(bMachine
, file
, "!# !# TEST TEST1", g_WinVersion
>= WINVER_WIN8
, "!# TEST1 !# TEST");
479 /* Adding a flag cleans other flags (from the start) */
480 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
481 expect_LayerValue2(bMachine
, file
, "!# TEST TEST1", g_WinVersion
>= WINVER_WIN8
, "!# TEST1 !# TEST");
483 if(g_WinVersion
< WINVER_WIN8
)
485 ok(wrapSetPermLayerState(fileW
, "$%$%^^", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
486 expect_LayerValue(bMachine
, file
, "!# TEST TEST1 $%$%^^");
489 setLayerValue(bMachine
, file
, "!#!# TEST2 !# TEST ");
490 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
491 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
493 /* Tabs are treated as spaces */
494 setLayerValue(bMachine
, file
, "!#!# TEST2 \t TEST2 !# \t TEST ");
495 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
496 expect_LayerValue2(bMachine
, file
, "!# !# TEST TEST2", g_WinVersion
>= WINVER_WIN8
, "!# TEST2 !# TEST");
498 /* Newlines are left as-is */
499 setLayerValue(bMachine
, file
, "!#!# TEST2 \n TEST2 !# \r\n TEST ");
500 ok(wrapSetPermLayerState(fileW
, "TEST2", 0, bMachine
, 1) == TRUE
, "Expected SetPermLayerState to succeed\n");
501 expect_LayerValue2(bMachine
, file
, "!# \n !# \r\n TEST TEST2", g_WinVersion
>= WINVER_WIN8
, "!# TEST2 \n !# \r\n TEST");
503 /* Whitespace and duplicate flags are eaten from the start */
504 setLayerValue(bMachine
, file
, " !#!# TEST2 \t TEST2 !# \t TEST ");
505 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
506 expect_LayerValue(bMachine
, file
, "! TEST2 TEST2 !# TEST");
508 setLayerValue(bMachine
, file
, "!# !# TEST2 !# TEST ");
509 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
510 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
512 ok(wrapSetPermLayerState(fileW
, "", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
513 expect_LayerValue(bMachine
, file
, "! TEST2 !# TEST");
515 ok(wrapSetPermLayerState(fileW
, "", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
516 expect_LayerValue(bMachine
, file
, "TEST2 !# TEST");
518 /* First flags are cleaned, then a layer is removed. */
519 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
520 expect_LayerValue(bMachine
, file
, "!# TEST");
522 /* Nothing is changed, still it succeeds. */
523 ok(wrapSetPermLayerState(fileW
, "TEST2", 2, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
524 expect_LayerValue(bMachine
, file
, "# TEST");
526 /* And remove the last bits. */
527 ok(wrapSetPermLayerState(fileW
, "TEST", LAYER_APPLY_TO_SYSTEM_EXES
, bMachine
, 0) == TRUE
, "Expected SetPermLayerState to succeed\n");
528 expect_LayerValue(bMachine
, file
, NULL
);
531 static void test_SetPermLayer(void)
533 char file
[MAX_PATH
+ 20], tmp
[MAX_PATH
+ 20];
536 GetTempPathA(MAX_PATH
, tmp
);
537 GetLongPathNameA(tmp
, file
, sizeof(file
));
538 PathAppendA(file
, "test_file.exe");
540 hfile
= CreateFileA(file
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
541 ok(hfile
!= INVALID_HANDLE_VALUE
, "CreateFile failed for '%s'\n", file
);
542 if (hfile
== INVALID_HANDLE_VALUE
)
544 skip("Running these tests is useless without a file present\n");
549 if (setLayerValue(FALSE
, file
, NULL
))
551 test_SdbSetPermLayerKeysLevel(FALSE
, file
);
552 test_SetPermLayerStateLevel(FALSE
, file
);
556 skip("Skipping SetPermLayerStateLevel tests for User, because I cannot prepare the environment\n");
558 if (setLayerValue(TRUE
, file
, NULL
))
560 test_SdbSetPermLayerKeysLevel(TRUE
, file
);
561 test_SetPermLayerStateLevel(TRUE
, file
);
565 skip("Skipping SetPermLayerStateLevel tests for Machine (HKLM), because I cannot prepare the environment\n");
567 ok(DeleteFileA(file
), "DeleteFile failed....\n");
570 static BOOL
create_file(LPCSTR dir
, LPCSTR name
, int filler
, size_t size
)
572 char target
[MAX_PATH
], *tmp
;
574 PathCombineA(target
, dir
, name
);
577 memset(tmp
, filler
, size
);
579 file
= CreateFileA(target
, GENERIC_WRITE
, 0, NULL
, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL
, NULL
);
580 if(file
== INVALID_HANDLE_VALUE
)
583 WriteFile(file
, tmp
, size
, &size
, NULL
);
589 static BOOL
delete_file(LPCSTR dir
, LPCSTR name
)
591 char target
[MAX_PATH
];
592 PathCombineA(target
, dir
, name
);
593 return DeleteFileA(target
);
596 static char g_FakeDrive
= 0;
598 UINT (WINAPI
*pGetDriveTypeW
)(LPCWSTR target
) = NULL
;
599 UINT WINAPI
mGetDriveTypeW(LPCWSTR target
)
601 UINT uRet
= pGetDriveTypeW(target
);
602 if(g_FakeDrive
&& target
&& (char)*target
== g_FakeDrive
)
608 static PIMAGE_IMPORT_DESCRIPTOR
FindImportDescriptor(PBYTE DllBase
, PCSTR DllName
)
611 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor
= RtlImageDirectoryEntryToData((HMODULE
)DllBase
, TRUE
, IMAGE_DIRECTORY_ENTRY_IMPORT
, &Size
);
612 while (ImportDescriptor
->Name
&& ImportDescriptor
->OriginalFirstThunk
)
614 PCHAR Name
= (PCHAR
)(DllBase
+ ImportDescriptor
->Name
);
615 if (!lstrcmpiA(Name
, DllName
))
617 return ImportDescriptor
;
624 static BOOL
RedirectIat(PCSTR TargetDllName
, PCSTR DllName
, PCSTR FunctionName
, ULONG_PTR NewFunction
, ULONG_PTR
* OriginalFunction
)
626 PBYTE DllBase
= (PBYTE
)GetModuleHandleA(TargetDllName
);
629 PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor
= FindImportDescriptor(DllBase
, DllName
);
630 if (ImportDescriptor
)
632 // On loaded images, OriginalFirstThunk points to the name / ordinal of the function
633 PIMAGE_THUNK_DATA OriginalThunk
= (PIMAGE_THUNK_DATA
)(DllBase
+ ImportDescriptor
->OriginalFirstThunk
);
634 // FirstThunk points to the resolved address.
635 PIMAGE_THUNK_DATA FirstThunk
= (PIMAGE_THUNK_DATA
)(DllBase
+ ImportDescriptor
->FirstThunk
);
636 while (OriginalThunk
->u1
.AddressOfData
&& FirstThunk
->u1
.Function
)
638 if (!IMAGE_SNAP_BY_ORDINAL32(OriginalThunk
->u1
.AddressOfData
))
640 PIMAGE_IMPORT_BY_NAME ImportName
= (PIMAGE_IMPORT_BY_NAME
)(DllBase
+ OriginalThunk
->u1
.AddressOfData
);
641 if (!lstrcmpiA((PCSTR
)ImportName
->Name
, FunctionName
))
644 VirtualProtect(&FirstThunk
->u1
.Function
, sizeof(ULONG_PTR
), PAGE_EXECUTE_READWRITE
, &dwOld
);
645 *OriginalFunction
= FirstThunk
->u1
.Function
;
646 FirstThunk
->u1
.Function
= NewFunction
;
647 VirtualProtect(&FirstThunk
->u1
.Function
, sizeof(ULONG_PTR
), dwOld
, &dwOld
);
654 skip("Unable to find the Import '%s' from '%s' in %s'\n", FunctionName
, DllName
, TargetDllName
);
658 skip("Unable to find the ImportDescriptor for '%s' in '%s'\n", DllName
, TargetDllName
);
663 skip("Unable to find the loaded module '%s'\n", TargetDllName
);
668 static BOOL
RestoreIat(PCSTR target
, PCSTR DllName
, PCSTR FunctionName
, ULONG_PTR OriginalFunction
)
671 return RedirectIat(target
, DllName
, FunctionName
, OriginalFunction
, &old
);
674 static BOOL
wrapSdbSetPermLayerKeys2(LPCSTR dir
, LPCSTR name
, PCSTR szLayers
, BOOL bMachine
)
676 char szPath
[MAX_PATH
];
677 WCHAR wszPath
[MAX_PATH
], wszLayers
[MAX_LAYER_LENGTH
];
678 PathCombineA(szPath
, dir
, name
);
679 MultiByteToWideChar(CP_ACP
, 0, szLayers
, -1, wszLayers
, MAX_LAYER_LENGTH
);
680 MultiByteToWideChar(CP_ACP
, 0, szPath
, -1, wszPath
, MAX_PATH
);
681 return pSdbSetPermLayerKeys(wszPath
, wszLayers
, bMachine
);
685 BOOL
expect_files(const char* dir
, int num
, ...)
687 char finddir
[MAX_PATH
+ 20];
689 WIN32_FIND_DATAA find
= { 0 };
695 PathCombineA(finddir
, dir
, "*");
696 hFind
= FindFirstFileA(finddir
, &find
);
697 if (hFind
!= INVALID_HANDLE_VALUE
)
702 if (!(find
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
))
706 file
= va_arg(args
, const char*);
707 cmp
= strcmp(file
, find
.cFileName
);
709 } while (cmp
== 0 && FindNextFileA(hFind
, &find
));
713 return cmp
== 0 && num
== 0;
717 static void test_Sign_Media(void)
719 char workdir
[MAX_PATH
], subdir
[MAX_PATH
], drive
[5] = "Z:";
722 DWORD logical_drives
= GetLogicalDrives();
724 for (drive
[0] = 'D'; drive
[0] <= 'Z'; drive
[0]++)
726 DWORD idx
= 1 << (drive
[0] - 'D' + 3);
727 if (!(logical_drives
& idx
))
729 g_FakeDrive
= drive
[0];
735 skip("Unable to find a free drive\n");
739 ret
= GetTempPathA(MAX_PATH
, workdir
);
740 ok(ret
, "GetTempPathA error: %d\n", GetLastError());
741 PathAppendA(workdir
, "apphelp_test");
743 ret
= CreateDirectoryA(workdir
, NULL
);
744 ok(ret
, "CreateDirectoryA error: %d\n", GetLastError());
746 PathCombineA(subdir
, workdir
, "sub");
747 ret
= CreateDirectoryA(subdir
, NULL
);
748 ok(ret
, "CreateDirectoryA error: %d\n", GetLastError());
750 ret
= DefineDosDeviceA(DDD_NO_BROADCAST_SYSTEM
, drive
, workdir
);
751 ok(ret
, "DefineDosDeviceA error: %d\n", GetLastError());
754 ret
= RedirectIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR
)mGetDriveTypeW
, (ULONG_PTR
*)&pGetDriveTypeW
);
755 if (g_WinVersion
< WINVER_WIN8
)
756 ok(ret
, "Expected redirect_iat to succeed\n");
759 ok(create_file(workdir
, "test.exe", 'a', 4), "create_file error: %d\n", GetLastError());
761 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
764 expect_LayerValue(0, "SIGN.MEDIA=4 test.exe", "TEST");
765 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
767 ok(create_file(workdir
, "test.txt", 'a', 1), "create_file error: %d\n", GetLastError());
769 if (!expect_files(workdir
, 2, "test.exe", "test.txt"))
771 skip("Skipping test, files are not returned in the expected order by the FS\n");
775 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
777 /* test.exe test.txt */
778 expect_LayerValue(0, "SIGN.MEDIA=9 test.exe", "TEST");
779 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
782 ok(create_file(workdir
, "test.zz", 'a', 0x1000), "create_file error: %d\n", GetLastError());
784 if (!expect_files(workdir
, 3, "test.exe", "test.txt", "test.zz"))
786 skip("Skipping test, files are not returned in the expected order by the FS\n");
790 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
791 /* (((4 << 1) ^ 1) << 1) ^ 0x1000 */
792 /* test.exe test.txt test.zz */
793 expect_LayerValue(0, "SIGN.MEDIA=1012 test.exe", "TEST");
794 ok(wrapSdbSetPermLayerKeys2(drive
, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
797 ok(create_file(subdir
, "test.exe", 'a', 0x10203), "create_file error: %d\n", GetLastError());
799 if (!expect_files(subdir
, 1, "test.exe"))
801 skip("Skipping test, files are not returned in the expected order by the FS\n");
805 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
808 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST");
809 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
812 ok(create_file(subdir
, "test.bbb", 'a', 0), "create_file error: %d\n", GetLastError());
814 if (!expect_files(subdir
, 2, "test.bbb", "test.exe"))
816 skip("Skipping test, files are not returned in the expected order by the FS\n");
820 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
823 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST");
824 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
827 ok(create_file(subdir
, "TEST.txt", 'a', 0x30201), "create_file error: %d\n", GetLastError());
829 if (!expect_files(subdir
, 3, "test.bbb", "test.exe", "TEST.txt"))
831 skip("Skipping test, files are not returned in the expected order by the FS\n");
835 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
836 /* (0x10203 << 1) ^ 0x30201 */
837 /* test.exe TEST.txt */
838 expect_LayerValue(0, "SIGN.MEDIA=10607 sub\\test.exe", "TEST");
839 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
842 ok(create_file(subdir
, "TEST.aaa", 'a', 0x3a2a1), "create_file error: %d\n", GetLastError());
844 if (!expect_files(subdir
, 4, "TEST.aaa", "test.bbb", "test.exe", "TEST.txt"))
846 skip("Skipping test, files are not returned in the expected order by the FS\n");
850 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
851 /* (((0x3a2a1 << 1) ^ 0x10203) << 1) ^ 0x30201 */
852 /* TEST.aaa test.exe TEST.txt */
853 expect_LayerValue(0, "SIGN.MEDIA=F8C83 sub\\test.exe", "TEST");
854 ok(wrapSdbSetPermLayerKeys2(drive
, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n");
857 ret
= RestoreIat("apphelp.dll", "kernel32.dll", "GetDriveTypeW", (ULONG_PTR
)pGetDriveTypeW
);
858 ok(ret
, "Expected restore_iat to succeed\n");
860 ok(delete_file(subdir
, "test.bbb"), "delete_file error: %d\n", GetLastError());
861 ok(delete_file(subdir
, "TEST.aaa"), "delete_file error: %d\n", GetLastError());
862 ok(delete_file(subdir
, "TEST.txt"), "delete_file error: %d\n", GetLastError());
863 ok(delete_file(subdir
, "test.exe"), "delete_file error: %d\n", GetLastError());
864 ok(delete_file(workdir
, "test.zz"), "delete_file error: %d\n", GetLastError());
865 ok(delete_file(workdir
, "test.txt"), "delete_file error: %d\n", GetLastError());
866 ok(delete_file(workdir
, "test.exe"), "delete_file error: %d\n", GetLastError());
868 ret
= DefineDosDeviceA(DDD_REMOVE_DEFINITION
| DDD_NO_BROADCAST_SYSTEM
, drive
, NULL
);
869 ok(ret
, "DefineDosDeviceA error: %d\n", GetLastError());
871 ret
= RemoveDirectoryA(subdir
);
872 ok(ret
, "RemoveDirectoryA error: %d\n", GetLastError());
873 ret
= RemoveDirectoryA(workdir
);
874 ok(ret
, "RemoveDirectoryA error: %d\n", GetLastError());
880 /*SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");*/
881 hdll
= LoadLibraryA("apphelp.dll");
882 pAllowPermLayer
= (void *)GetProcAddress(hdll
, "AllowPermLayer");
883 pSdbSetPermLayerKeys
= (void *)GetProcAddress(hdll
, "SdbSetPermLayerKeys");
884 pSdbGetPermLayerKeys
= (void *)GetProcAddress(hdll
, "SdbGetPermLayerKeys");
885 pSetPermLayerState
= (void *)GetProcAddress(hdll
, "SetPermLayerState");
886 g_WinVersion
= get_host_winver();
888 if (!pAllowPermLayer
)
890 skip("Skipping tests with AllowPermLayer, function not found\n");
894 test_AllowPermLayer();
897 if (!pSdbSetPermLayerKeys
)
899 skip("Skipping tests with SdbSetPermLayerKeys, function not found\n");
903 if (!pSdbGetPermLayerKeys
)
905 skip("Skipping tests with SdbGetPermLayerKeys, function not found\n");
909 test_SdbGetPermLayerKeys();
912 if (!pSetPermLayerState
)
914 skip("Skipping tests with SetPermLayerState, function not found\n");