1 /* 2 * PROJECT: apphelp_apitest 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Tests for (registry)layer manipulation api's 5 * COPYRIGHT: Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org) 6 */ 7 8 #include <ntstatus.h> 9 #define WIN32_NO_STATUS 10 #include <windows.h> 11 #include <shlwapi.h> 12 #include <winnt.h> 13 #ifdef __REACTOS__ 14 #include <ntndk.h> 15 #else 16 #include <winternl.h> 17 #endif 18 #include <winerror.h> 19 #include <stdio.h> 20 #include <strsafe.h> 21 22 #include "wine/test.h" 23 #include "apitest_iathook.h" 24 #include "apphelp_apitest.h" 25 26 #define GPLK_USER 1 27 #define GPLK_MACHINE 2 28 #define MAX_LAYER_LENGTH 256 29 #define LAYER_APPLY_TO_SYSTEM_EXES 1 30 31 32 static HMODULE hdll; 33 static BOOL(WINAPI *pAllowPermLayer)(PCWSTR path); 34 static BOOL(WINAPI *pSdbSetPermLayerKeys)(PCWSTR wszPath, PCWSTR wszLayers, BOOL bMachine); 35 static BOOL(WINAPI *pSdbGetPermLayerKeys)(PCWSTR wszPath, PWSTR pwszLayers, PDWORD pdwBytes, DWORD dwFlags); 36 static BOOL(WINAPI *pSetPermLayerState)(PCWSTR wszPath, PCWSTR wszLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable); 37 38 39 /* Helper function to disable Wow64 redirection on an os that reports it being enabled. */ 40 static DWORD g_QueryFlag = 0xffffffff; 41 static DWORD QueryFlag(void) 42 { 43 if (g_QueryFlag == 0xffffffff) 44 { 45 ULONG_PTR wow64_ptr = 0; 46 NTSTATUS status = NtQueryInformationProcess(NtCurrentProcess(), ProcessWow64Information, &wow64_ptr, sizeof(wow64_ptr), NULL); 47 g_QueryFlag = (NT_SUCCESS(status) && wow64_ptr != 0) ? KEY_WOW64_64KEY : 0; 48 } 49 return g_QueryFlag; 50 } 51 52 /* Helper function to prepare the registry key with a value. */ 53 static BOOL setLayerValue(BOOL bMachine, const char* valueName, const char* value) 54 { 55 HKEY key = NULL; 56 LSTATUS lstatus = RegCreateKeyExA(bMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, 57 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL, 0, QueryFlag() | KEY_SET_VALUE, NULL, &key, NULL); 58 if (lstatus == ERROR_SUCCESS) 59 { 60 if (value) 61 lstatus = RegSetValueExA(key, valueName, 0, REG_SZ, (const BYTE*)value, (DWORD)strlen(value)+1); 62 else 63 { 64 lstatus = RegDeleteValueA(key, valueName); 65 lstatus = (lstatus == ERROR_FILE_NOT_FOUND ? ERROR_SUCCESS : lstatus); 66 } 67 RegCloseKey(key); 68 } 69 return lstatus == ERROR_SUCCESS; 70 } 71 72 73 static void expect_LayerValue_imp(BOOL bMachine, const char* valueName, const char* value) 74 { 75 HKEY key = NULL; 76 LSTATUS lstatus = RegCreateKeyExA(bMachine ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, 77 "Software\\Microsoft\\Windows NT\\CurrentVersion\\AppCompatFlags\\Layers", 0, NULL, 0, QueryFlag() | KEY_QUERY_VALUE, NULL, &key, NULL); 78 winetest_ok(lstatus == ERROR_SUCCESS, "Expected to be able to open a registry key\n"); 79 if (lstatus == ERROR_SUCCESS) 80 { 81 char data[512] = { 0 }; 82 DWORD dwType = 0; 83 DWORD dwDataLen = sizeof(data); 84 lstatus = RegQueryValueExA(key, valueName, NULL, &dwType, (LPBYTE)data, &dwDataLen); 85 if (value) 86 { 87 winetest_ok(lstatus == ERROR_SUCCESS, "Expected to get a valid value, err: %u\n", lstatus); 88 if (lstatus == ERROR_SUCCESS) 89 { 90 winetest_ok(dwType == REG_SZ, "Expected the type to be REG_SZ, was: %u\n", dwType); 91 winetest_ok(!strcmp(data, value), "Expected the data to be: '%s', was: '%s'\n", value, data); 92 } 93 } 94 else 95 { 96 winetest_ok(lstatus == ERROR_FILE_NOT_FOUND, "Expected not to find the value %s\n", valueName); 97 } 98 RegCloseKey(key); 99 } 100 } 101 102 static void expect_LayerValue_imp2(BOOL bMachine, const char* valueName, const char* value, int use_alt, const char* alt_value) 103 { 104 expect_LayerValue_imp(bMachine, valueName, use_alt ? alt_value : value); 105 } 106 107 108 void expect_Sdb_imp(PCSTR path, DWORD type, BOOL result, DWORD lenResult, PCSTR stringResult) 109 { 110 WCHAR pathW[MAX_PATH], buffer[MAX_LAYER_LENGTH] = { 0 }; 111 char resultBuffer[MAX_LAYER_LENGTH] = { 0 }; 112 DWORD dwBufSize = sizeof(buffer); 113 114 /* In case of a failure, the buffer size is sometimes set to 0, and sometimes not touched, 115 depending on the version. Either case is fine, since the function returns FALSE anyway. */ 116 117 MultiByteToWideChar(CP_ACP, 0, path, -1, pathW, MAX_PATH); 118 119 winetest_ok(pSdbGetPermLayerKeys(pathW, buffer, &dwBufSize, type) == result, "Expected pSdbGetPermLayerKeys to %s\n", (result ? "succeed" : "fail")); 120 if (!result && lenResult == 0xffffffff) 121 winetest_ok(dwBufSize == 0 || dwBufSize == sizeof(buffer), "Expected dwBufSize to be 0 or %u, was %u\n", sizeof(buffer), dwBufSize); 122 else 123 winetest_ok(dwBufSize == lenResult || 124 /* W2k3 is off by 2 when concatenating user / machine */ 125 broken(g_WinVersion < WINVER_VISTA && type == (GPLK_MACHINE|GPLK_USER) && (lenResult + 2) == dwBufSize), 126 "Expected dwBufSize to be %u, was %u\n", lenResult, dwBufSize); 127 if (result) 128 { 129 winetest_ok(lstrlenW(buffer) * sizeof(WCHAR) + sizeof(WCHAR) == lenResult, "Expected lstrlenW(buffer)*2+2 to be %u, was %u\n", 130 lenResult, lstrlenW(buffer) * sizeof(WCHAR) + sizeof(WCHAR)); 131 } 132 WideCharToMultiByte(CP_ACP, 0, buffer, -1, resultBuffer, sizeof(resultBuffer), NULL, NULL); 133 winetest_ok(!strcmp(stringResult, resultBuffer), "Expected the result to be '%s', was '%s'\n", stringResult, resultBuffer); 134 135 if (result) 136 { 137 UNICODE_STRING pathNT; 138 139 if (RtlDosPathNameToNtPathName_U(pathW, &pathNT, NULL, NULL)) 140 { 141 memset(buffer, 0, sizeof(buffer)); 142 dwBufSize = sizeof(buffer); 143 winetest_ok(pSdbGetPermLayerKeys(pathNT.Buffer, buffer, &dwBufSize, type) == FALSE, "Expected pSdbGetPermLayerKeys to fail for NT path\n"); 144 145 RtlFreeUnicodeString(&pathNT); 146 } 147 } 148 149 } 150 151 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 156 157 158 BOOL wrapAllowPermLayer(const char* str) 159 { 160 WCHAR buf[100]; 161 MultiByteToWideChar(CP_ACP, 0, str, -1, buf, 100); 162 return pAllowPermLayer(buf); 163 } 164 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...) 169 */ 170 static void test_AllowPermLayer(void) 171 { 172 char buf[20]; 173 char drive_letter; 174 UINT drivetype = 0; 175 ok(pAllowPermLayer(NULL) == FALSE, "Expected AllowPermLayer to fail for NULL\n"); 176 if (g_WinVersion < WINVER_WIN8) 177 { 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"); 182 } 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) 186 { 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); 190 } 191 } 192 193 static BOOL wrapSdbSetPermLayerKeys(PCWSTR wszPath, PCSTR szLayers, BOOL bMachine) 194 { 195 WCHAR wszLayers[MAX_LAYER_LENGTH]; 196 MultiByteToWideChar(CP_ACP, 0, szLayers, -1, wszLayers, MAX_LAYER_LENGTH); 197 return pSdbSetPermLayerKeys(wszPath, wszLayers, bMachine); 198 } 199 200 static void test_SdbSetPermLayerKeysLevel(BOOL bMachine, const char* file) 201 { 202 WCHAR fileW[MAX_PATH+20]; 203 WCHAR emptyString[1] = { 0 }; 204 205 MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH+20); 206 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"); 213 214 /* Basic tests */ 215 ok(wrapSdbSetPermLayerKeys(fileW, "TEST1", bMachine), "Expected SdbSetPermLayerKeys to succeed\n"); 216 expect_LayerValue(bMachine, file, "TEST1"); 217 218 ok(wrapSdbSetPermLayerKeys(fileW, "TEST1 TEST2", bMachine), "Expected SdbSetPermLayerKeys to succeed\n"); 219 expect_LayerValue(bMachine, file, "TEST1 TEST2"); 220 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"); 224 225 ok(wrapSdbSetPermLayerKeys(fileW, "!#$% TEST1 TEST2", bMachine), "Expected SdbSetPermLayerKeys to succeed\n"); 226 expect_LayerValue(bMachine, file, "!#$% TEST1 TEST2"); 227 228 ok(pSdbSetPermLayerKeys(fileW, NULL, bMachine) == TRUE, "Expected SdbSetPermLayerKeys to succeed\n"); 229 expect_LayerValue(bMachine, file, NULL); 230 231 ok(wrapSdbSetPermLayerKeys(fileW, " ", bMachine), "Expected SdbSetPermLayerKeys to succeed\n"); 232 expect_LayerValue(bMachine, file, " "); 233 234 ok(pSdbSetPermLayerKeys(fileW, NULL, bMachine) == TRUE, "Expected SdbSetPermLayerKeys to fail\n"); 235 expect_LayerValue(bMachine, file, NULL); 236 } 237 238 static void test_SdbGetPermLayerKeys(void) 239 { 240 WCHAR pathW[MAX_PATH], buffer[MAX_LAYER_LENGTH] = { 0 }; 241 char file[MAX_PATH + 20], tmp[MAX_PATH + 20]; 242 BOOL bUser, bMachine; 243 HANDLE hfile; 244 DWORD dwBufSize = sizeof(buffer); 245 246 GetTempPathA(MAX_PATH, tmp); 247 GetLongPathNameA(tmp, file, sizeof(file)); 248 PathCombineA(tmp, file, "notexist.exe"); 249 PathAppendA(file, "test_file.exe"); 250 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"); 255 if (!bUser) 256 { 257 skip("Cannot do any tests if I cannot set some values\n"); 258 return; 259 } 260 bMachine = setLayerValue(TRUE, file, "WINXPSP3 WINXPSP2"); 261 if (bMachine) 262 { 263 expect_LayerValue(TRUE, file, "WINXPSP3 WINXPSP2"); 264 } 265 266 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) 270 { 271 skip("Running these tests is useless without a file present\n"); 272 return; 273 } 274 CloseHandle(hfile); 275 276 MultiByteToWideChar(CP_ACP, 0, file, -1, pathW, MAX_PATH); 277 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); 284 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"); 290 291 if (bMachine) 292 { 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"); 297 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"); 308 } 309 else 310 { 311 skip("Skipping tests for HKLM, cannot alter the registry\n"); 312 } 313 /* Fail from these paths */ 314 StringCbPrintfA(tmp, sizeof(tmp), "\\?\\%s", file); 315 expect_Sdb(tmp, GPLK_USER, FALSE, 0xffffffff, ""); 316 StringCbPrintfA(tmp, sizeof(tmp), "\\??\\%s", file); 317 expect_Sdb(tmp, GPLK_USER, FALSE, 0xffffffff, ""); 318 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 "); 322 323 324 /* Cleanup */ 325 ok(DeleteFileA(file), "DeleteFile failed....\n"); 326 setLayerValue(FALSE, file, NULL); 327 setLayerValue(TRUE, file, NULL); 328 } 329 330 331 static BOOL wrapSetPermLayerState(PCWSTR wszPath, PCSTR szLayer, DWORD dwFlags, BOOL bMachine, BOOL bEnable) 332 { 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); 336 } 337 338 static void test_SetPermLayerStateLevel(BOOL bMachine, const char* file) 339 { 340 WCHAR fileW[MAX_PATH+20]; 341 WCHAR emptyString[1] = { 0 }; 342 DWORD dwFlag; 343 344 MultiByteToWideChar(CP_ACP, 0, file, -1, fileW, MAX_PATH+20); 345 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); 349 350 ok(pSetPermLayerState(fileW, NULL, 0, bMachine, 1) == FALSE, "Expected SetPermLayerState to fail\n"); 351 expect_LayerValue(bMachine, file, NULL); 352 353 ok(wrapSetPermLayerState(fileW, "", 0, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 354 expect_LayerValue(bMachine, file, NULL); 355 356 ok(wrapSetPermLayerState(fileW, "", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 357 expect_LayerValue(bMachine, file, NULL); 358 359 ok(wrapSetPermLayerState(NULL, NULL, 0, bMachine, 0) == FALSE, "Expected SetPermLayerState to fail\n"); 360 expect_LayerValue(bMachine, NULL, NULL); 361 362 ok(wrapSetPermLayerState(NULL, NULL, 0, bMachine, 1) == FALSE, "Expected SetPermLayerState to fail\n"); 363 expect_LayerValue(bMachine, NULL, NULL); 364 365 ok(wrapSetPermLayerState(emptyString, "", 0, bMachine, 0) == FALSE, "Expected SetPermLayerState to fail\n"); 366 expect_LayerValue(bMachine, NULL, NULL); 367 368 ok(wrapSetPermLayerState(emptyString, "", 0, bMachine, 1) == FALSE, "Expected SetPermLayerState to fail\n"); 369 expect_LayerValue(bMachine, NULL, NULL); 370 371 ok(wrapSetPermLayerState(emptyString, "TEST", 0, bMachine, 0) == FALSE, "Expected SetPermLayerState to fail\n"); 372 expect_LayerValue(bMachine, NULL, NULL); 373 374 if (g_WinVersion <= WINVER_WIN8) 375 { 376 ok(wrapSetPermLayerState(emptyString, "TEST", 0, bMachine, 1) == FALSE, "Expected SetPermLayerState to fail\n"); 377 expect_LayerValue(bMachine, NULL, NULL); 378 } 379 380 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); 385 386 ok(wrapSetPermLayerState(fileW, "TEST", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 387 expect_LayerValue(bMachine, file, "TEST"); 388 389 ok(wrapSetPermLayerState(fileW, "", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 390 expect_LayerValue(bMachine, file, "TEST"); 391 392 ok(wrapSetPermLayerState(fileW, "test", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 393 expect_LayerValue(bMachine, file, "test"); 394 395 ok(wrapSetPermLayerState(fileW, "TEST", 0, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 396 expect_LayerValue(bMachine, file, NULL); 397 398 ok(wrapSetPermLayerState(fileW, "TEST", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 399 expect_LayerValue(bMachine, file, "TEST"); 400 401 ok(wrapSetPermLayerState(fileW, "TEST1", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 402 expect_LayerValue2(bMachine, file, "TEST TEST1", g_WinVersion >= WINVER_WIN8, "TEST1 TEST"); 403 404 ok(wrapSetPermLayerState(fileW, "TEST2", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 405 expect_LayerValue2(bMachine, file, "TEST TEST1 TEST2", g_WinVersion >= WINVER_WIN8, "TEST2 TEST1 TEST"); 406 407 ok(wrapSetPermLayerState(fileW, "TEST1", 0, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 408 expect_LayerValue2(bMachine, file, "TEST TEST2", g_WinVersion >= WINVER_WIN8, "TEST2 TEST"); 409 410 ok(wrapSetPermLayerState(fileW, "TEST", 0, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 411 expect_LayerValue(bMachine, file, "TEST2"); 412 413 ok(wrapSetPermLayerState(fileW, "TEST2", 0, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 414 expect_LayerValue(bMachine, file, NULL); 415 416 /* Valid flags until win8: !# */ 417 /* Key is empty, now play around with the flags. */ 418 for (dwFlag = ((g_WinVersion >= WINVER_WIN8) ? 6 : 2); dwFlag < 32; ++dwFlag) 419 { 420 ok(wrapSetPermLayerState(fileW, "TEST", (1<<dwFlag), bMachine, 1) == FALSE, "Expected SetPermLayerState to fail on 0x%x\n", (1<<dwFlag)); 421 } 422 expect_LayerValue(bMachine, file, NULL); 423 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"); 427 428 ok(wrapSetPermLayerState(fileW, "TEST2", 2, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 429 expect_LayerValue2(bMachine, file, "!# TEST TEST2", g_WinVersion >= WINVER_WIN8, "!# TEST2 TEST"); 430 431 ok(wrapSetPermLayerState(fileW, "TEST", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 432 expect_LayerValue2(bMachine, file, "!# TEST2 TEST", g_WinVersion >= WINVER_WIN8, "!# TEST TEST2"); 433 434 ok(wrapSetPermLayerState(fileW, "TEST3", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 435 expect_LayerValue2(bMachine, file, "!# TEST2 TEST TEST3", g_WinVersion >= WINVER_WIN8, "!# TEST3 TEST TEST2"); 436 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_WinVersion >= WINVER_WIN8, "# TEST3 TEST"); 440 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_WinVersion >= WINVER_WIN8, "TEST3 TEST"); 443 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_WinVersion >= WINVER_WIN8, "!# TEST3 TEST"); 446 447 ok(wrapSetPermLayerState(fileW, "TEST3", LAYER_APPLY_TO_SYSTEM_EXES, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 448 expect_LayerValue(bMachine, file, "! TEST"); 449 450 ok(wrapSetPermLayerState(fileW, "TEST", 2, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 451 expect_LayerValue(bMachine, file, NULL); 452 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); 456 457 ok(wrapSetPermLayerState(fileW, "TEST2", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 458 expect_LayerValue(bMachine, file, "TEST2"); 459 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"); 463 464 ok(wrapSetPermLayerState(fileW, "!", 0, bMachine, 1) == FALSE, "Expected SetPermLayerState to fail\n"); 465 expect_LayerValue(bMachine, file, "TEST2"); 466 467 /* Now we prepare the registry with some crap to see how data is validated. */ 468 setLayerValue(bMachine, file, "!#!# TEST2 TEST2 !# TEST "); 469 470 ok(wrapSetPermLayerState(fileW, "TEST1", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 471 expect_LayerValue2(bMachine, file, "!# TEST2 TEST2 !# TEST TEST1", g_WinVersion >= WINVER_WIN8, "!# TEST1 TEST2 TEST2 !# TEST"); 472 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_WinVersion >= WINVER_WIN8, "!# TEST1 !# TEST"); 476 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_WinVersion >= WINVER_WIN8, "!# TEST1 !# TEST"); 480 481 if(g_WinVersion < WINVER_WIN8) 482 { 483 ok(wrapSetPermLayerState(fileW, "$%$%^^", 0, bMachine, 1) == TRUE, "Expected SetPermLayerState to succeed\n"); 484 expect_LayerValue(bMachine, file, "!# TEST TEST1 $%$%^^"); 485 } 486 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"); 490 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_WinVersion >= WINVER_WIN8, "!# TEST2 !# TEST"); 495 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_WinVersion >= WINVER_WIN8, "!# TEST2 \n !# \r\n TEST"); 500 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"); 505 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"); 509 510 ok(wrapSetPermLayerState(fileW, "", LAYER_APPLY_TO_SYSTEM_EXES, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 511 expect_LayerValue(bMachine, file, "! TEST2 !# TEST"); 512 513 ok(wrapSetPermLayerState(fileW, "", 2, bMachine, 0) == TRUE, "Expected SetPermLayerState to succeed\n"); 514 expect_LayerValue(bMachine, file, "TEST2 !# TEST"); 515 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"); 519 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"); 523 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); 527 } 528 529 static void test_SetPermLayer(void) 530 { 531 char file[MAX_PATH + 20], tmp[MAX_PATH + 20]; 532 HANDLE hfile; 533 534 GetTempPathA(MAX_PATH, tmp); 535 GetLongPathNameA(tmp, file, sizeof(file)); 536 PathAppendA(file, "test_file.exe"); 537 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) 541 { 542 skip("Running these tests is useless without a file present\n"); 543 return; 544 } 545 CloseHandle(hfile); 546 547 if (setLayerValue(FALSE, file, NULL)) 548 { 549 test_SdbSetPermLayerKeysLevel(FALSE, file); 550 test_SetPermLayerStateLevel(FALSE, file); 551 } 552 else 553 { 554 skip("Skipping SetPermLayerStateLevel tests for User, because I cannot prepare the environment\n"); 555 } 556 if (setLayerValue(TRUE, file, NULL)) 557 { 558 test_SdbSetPermLayerKeysLevel(TRUE, file); 559 test_SetPermLayerStateLevel(TRUE, file); 560 } 561 else 562 { 563 skip("Skipping SetPermLayerStateLevel tests for Machine (HKLM), because I cannot prepare the environment\n"); 564 } 565 ok(DeleteFileA(file), "DeleteFile failed....\n"); 566 } 567 568 static BOOL create_file(LPCSTR dir, LPCSTR name, int filler, DWORD size) 569 { 570 char target[MAX_PATH], *tmp; 571 HANDLE file; 572 PathCombineA(target, dir, name); 573 574 tmp = malloc(size); 575 memset(tmp, filler, size); 576 577 file = CreateFileA(target, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 578 if(file == INVALID_HANDLE_VALUE) 579 return FALSE; 580 581 WriteFile(file, tmp, size, &size, NULL); 582 CloseHandle(file); 583 free(tmp); 584 return TRUE; 585 } 586 587 static BOOL delete_file(LPCSTR dir, LPCSTR name) 588 { 589 char target[MAX_PATH]; 590 PathCombineA(target, dir, name); 591 return DeleteFileA(target); 592 } 593 594 static char g_FakeDrive = 0; 595 596 UINT (WINAPI *pGetDriveTypeW)(LPCWSTR target) = NULL; 597 UINT WINAPI mGetDriveTypeW(LPCWSTR target) 598 { 599 UINT uRet = pGetDriveTypeW(target); 600 if(g_FakeDrive && target && (char)*target == g_FakeDrive) 601 return DRIVE_CDROM; 602 return uRet; 603 } 604 605 static BOOL wrapSdbSetPermLayerKeys2(LPCSTR dir, LPCSTR name, PCSTR szLayers, BOOL bMachine) 606 { 607 char szPath[MAX_PATH]; 608 WCHAR wszPath[MAX_PATH], wszLayers[MAX_LAYER_LENGTH]; 609 PathCombineA(szPath, dir, name); 610 MultiByteToWideChar(CP_ACP, 0, szLayers, -1, wszLayers, MAX_LAYER_LENGTH); 611 MultiByteToWideChar(CP_ACP, 0, szPath, -1, wszPath, MAX_PATH); 612 return pSdbSetPermLayerKeys(wszPath, wszLayers, bMachine); 613 } 614 615 616 BOOL expect_files(const char* dir, int num, ...) 617 { 618 char finddir[MAX_PATH + 20]; 619 va_list args; 620 WIN32_FIND_DATAA find = { 0 }; 621 HANDLE hFind; 622 int cmp = 0; 623 624 va_start(args, num); 625 626 PathCombineA(finddir, dir, "*"); 627 hFind = FindFirstFileA(finddir, &find); 628 if (hFind != INVALID_HANDLE_VALUE) 629 { 630 const char* file; 631 do 632 { 633 if (!(find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 634 { 635 if (--num < 0) 636 break; 637 file = va_arg(args, const char*); 638 cmp = strcmp(file, find.cFileName); 639 } 640 } while (cmp == 0 && FindNextFileA(hFind, &find)); 641 FindClose(hFind); 642 } 643 va_end(args); 644 return cmp == 0 && num == 0; 645 } 646 647 648 static void test_Sign_Media(void) 649 { 650 char workdir[MAX_PATH], subdir[MAX_PATH], drive[5] = "Z:"; 651 BOOL ret; 652 653 DWORD logical_drives = GetLogicalDrives(); 654 g_FakeDrive = 0; 655 for (drive[0] = 'D'; drive[0] <= 'Z'; drive[0]++) 656 { 657 DWORD idx = 1 << (drive[0] - 'D' + 3); 658 if (!(logical_drives & idx)) 659 { 660 g_FakeDrive = drive[0]; 661 break; 662 } 663 } 664 if (!g_FakeDrive) 665 { 666 skip("Unable to find a free drive\n"); 667 return; 668 } 669 670 ret = GetTempPathA(MAX_PATH, workdir); 671 ok(ret, "GetTempPathA error: %d\n", GetLastError()); 672 PathAppendA(workdir, "apphelp_test"); 673 674 ret = CreateDirectoryA(workdir, NULL); 675 ok(ret, "CreateDirectoryA error: %d\n", GetLastError()); 676 677 PathCombineA(subdir, workdir, "sub"); 678 ret = CreateDirectoryA(subdir, NULL); 679 ok(ret, "CreateDirectoryA error: %d\n", GetLastError()); 680 681 ret = DefineDosDeviceA(DDD_NO_BROADCAST_SYSTEM, drive, workdir); 682 ok(ret, "DefineDosDeviceA error: %d\n", GetLastError()); 683 if(ret) 684 { 685 ret = RedirectIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW", 686 (ULONG_PTR)mGetDriveTypeW, (ULONG_PTR*)&pGetDriveTypeW); 687 if (g_WinVersion < WINVER_WIN8) 688 ok(ret, "Expected redirect_iat to succeed\n"); 689 if(ret) 690 { 691 ret = create_file(workdir, "test.exe", 'a', 4); 692 ok(ret, "create_file error: %d\n", GetLastError()); 693 694 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 695 /* 4 */ 696 /* test.exe */ 697 expect_LayerValue(0, "SIGN.MEDIA=4 test.exe", "TEST"); 698 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 699 700 ret = create_file(workdir, "test.txt", 'a', 1); 701 ok(ret, "create_file error: %d\n", GetLastError()); 702 703 if (!expect_files(workdir, 2, "test.exe", "test.txt")) 704 { 705 skip("Skipping test, files are not returned in the expected order by the FS\n"); 706 } 707 else 708 { 709 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 710 /* (4 << 1) ^ 1 */ 711 /* test.exe test.txt */ 712 expect_LayerValue(0, "SIGN.MEDIA=9 test.exe", "TEST"); 713 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 714 } 715 716 ret = create_file(workdir, "test.zz", 'a', 0x1000); 717 ok(ret, "create_file error: %d\n", GetLastError()); 718 719 if (!expect_files(workdir, 3, "test.exe", "test.txt", "test.zz")) 720 { 721 skip("Skipping test, files are not returned in the expected order by the FS\n"); 722 } 723 else 724 { 725 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 726 /* (((4 << 1) ^ 1) << 1) ^ 0x1000 */ 727 /* test.exe test.txt test.zz */ 728 expect_LayerValue(0, "SIGN.MEDIA=1012 test.exe", "TEST"); 729 ok(wrapSdbSetPermLayerKeys2(drive, "test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 730 } 731 732 ret = create_file(subdir, "test.exe", 'a', 0x10203); 733 ok(ret, "create_file error: %d\n", GetLastError()); 734 735 if (!expect_files(subdir, 1, "test.exe")) 736 { 737 skip("Skipping test, files are not returned in the expected order by the FS\n"); 738 } 739 else 740 { 741 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 742 /* 0x10203 */ 743 /* test.exe */ 744 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST"); 745 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 746 } 747 748 ret = create_file(subdir, "test.bbb", 'a', 0); 749 ok(ret, "create_file error: %d\n", GetLastError()); 750 751 if (!expect_files(subdir, 2, "test.bbb", "test.exe")) 752 { 753 skip("Skipping test, files are not returned in the expected order by the FS\n"); 754 } 755 else 756 { 757 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 758 /* 0x10203 */ 759 /* test.exe */ 760 expect_LayerValue(0, "SIGN.MEDIA=10203 sub\\test.exe", "TEST"); 761 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 762 } 763 764 ret = create_file(subdir, "TEST.txt", 'a', 0x30201); 765 ok(ret, "create_file error: %d\n", GetLastError()); 766 767 if (!expect_files(subdir, 3, "test.bbb", "test.exe", "TEST.txt")) 768 { 769 skip("Skipping test, files are not returned in the expected order by the FS\n"); 770 } 771 else 772 { 773 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 774 /* (0x10203 << 1) ^ 0x30201 */ 775 /* test.exe TEST.txt */ 776 expect_LayerValue(0, "SIGN.MEDIA=10607 sub\\test.exe", "TEST"); 777 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 778 } 779 780 ret = create_file(subdir, "TEST.aaa", 'a', 0x3a2a1); 781 ok(ret, "create_file error: %d\n", GetLastError()); 782 783 if (!expect_files(subdir, 4, "TEST.aaa", "test.bbb", "test.exe", "TEST.txt")) 784 { 785 skip("Skipping test, files are not returned in the expected order by the FS\n"); 786 } 787 else 788 { 789 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "TEST", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 790 /* (((0x3a2a1 << 1) ^ 0x10203) << 1) ^ 0x30201 */ 791 /* TEST.aaa test.exe TEST.txt */ 792 expect_LayerValue(0, "SIGN.MEDIA=F8C83 sub\\test.exe", "TEST"); 793 ok(wrapSdbSetPermLayerKeys2(drive, "sub\\test.exe", "", 0), "Expected wrapSdbSetPermLayerKeys2 to succeed\n"); 794 } 795 796 ret = RestoreIat(GetModuleHandleA("apphelp.dll"), "kernel32.dll", "GetDriveTypeW", (ULONG_PTR)pGetDriveTypeW); 797 ok(ret, "Expected restore_iat to succeed\n"); 798 799 ret = delete_file(subdir, "test.bbb"); 800 ok(ret, "delete_file error: %d\n", GetLastError()); 801 ret = delete_file(subdir, "TEST.aaa"); 802 ok(ret, "delete_file error: %d\n", GetLastError()); 803 ret = delete_file(subdir, "TEST.txt"); 804 ok(ret, "delete_file error: %d\n", GetLastError()); 805 ret = delete_file(subdir, "test.exe"); 806 ok(ret, "delete_file error: %d\n", GetLastError()); 807 ret = delete_file(workdir, "test.zz"); 808 ok(ret, "delete_file error: %d\n", GetLastError()); 809 ret = delete_file(workdir, "test.txt"); 810 ok(ret, "delete_file error: %d\n", GetLastError()); 811 ret = delete_file(workdir, "test.exe"); 812 ok(ret, "delete_file error: %d\n", GetLastError()); 813 } 814 ret = DefineDosDeviceA(DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM, drive, NULL); 815 ok(ret, "DefineDosDeviceA error: %d\n", GetLastError()); 816 } 817 ret = RemoveDirectoryA(subdir); 818 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError()); 819 ret = RemoveDirectoryA(workdir); 820 ok(ret, "RemoveDirectoryA error: %d\n", GetLastError()); 821 } 822 823 824 START_TEST(layerapi) 825 { 826 silence_debug_output(); 827 /*SetEnvironmentVariable("SHIM_DEBUG_LEVEL", "4");*/ 828 hdll = LoadLibraryA("apphelp.dll"); 829 pAllowPermLayer = (void *)GetProcAddress(hdll, "AllowPermLayer"); 830 pSdbSetPermLayerKeys = (void *)GetProcAddress(hdll, "SdbSetPermLayerKeys"); 831 pSdbGetPermLayerKeys = (void *)GetProcAddress(hdll, "SdbGetPermLayerKeys"); 832 pSetPermLayerState = (void *)GetProcAddress(hdll, "SetPermLayerState"); 833 g_WinVersion = get_host_winver(); 834 835 if (!pAllowPermLayer) 836 { 837 skip("Skipping tests with AllowPermLayer, function not found\n"); 838 } 839 else 840 { 841 test_AllowPermLayer(); 842 } 843 844 if (!pSdbSetPermLayerKeys) 845 { 846 skip("Skipping tests with SdbSetPermLayerKeys, function not found\n"); 847 } 848 else 849 { 850 if (!pSdbGetPermLayerKeys) 851 { 852 skip("Skipping tests with SdbGetPermLayerKeys, function not found\n"); 853 } 854 else 855 { 856 test_SdbGetPermLayerKeys(); 857 } 858 859 if (!pSetPermLayerState) 860 { 861 skip("Skipping tests with SetPermLayerState, function not found\n"); 862 } 863 else 864 { 865 test_SetPermLayer(); 866 test_Sign_Media(); 867 } 868 } 869 } 870