diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index af3dadf79a5..2cb856abb43 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -315,6 +315,57 @@ static const char wrong_depmanifest1[] = "" ""; +static const char compat_manifest_no_supportedOs[] = +"" +" " +" " +" " +" " +" " +""; + +static const char compat_manifest_vista[] = +"" +" " +" " +" " +" " /* Windows Vista */ +" " +" " +""; + +static const char compat_manifest_vista_7_8_10_81[] = +"" +" " +" " +" " +" " /* Windows Vista */ +" " /* Windows 7 */ +" " /* Windows 8 */ +" " /* Windows 10 */ +" " /* Windows 8.1 */ +" " +" " +""; + +static const char compat_manifest_other_guid[] = +"" +" " +" " +" " +" " +" " +" " +""; + +DEFINE_GUID(VISTA_COMPAT_GUID, 0xe2011457, 0x1546, 0x43c5, 0xa5, 0xfe, 0x00, 0x8d, 0xee, 0xe3, 0xd3, 0xf0); +DEFINE_GUID(WIN7_COMPAT_GUID, 0x35138b9a, 0x5d96, 0x4fbd, 0x8e, 0x2d, 0xa2, 0x44, 0x02, 0x25, 0xf9, 0x3a); +DEFINE_GUID(WIN8_COMPAT_GUID, 0x4a2f28e3, 0x53b9, 0x4441, 0xba, 0x9c, 0xd6, 0x9d, 0x4a, 0x4a, 0x6e, 0x38); +DEFINE_GUID(WIN81_COMPAT_GUID, 0x1f676c76, 0x80e1, 0x4239, 0x95, 0xbb, 0x83, 0xd0, 0xf6, 0xd0, 0xda, 0x78); +DEFINE_GUID(WIN10_COMPAT_GUID, 0x8e0f7a12, 0xbfb3, 0x4fe8, 0xb9, 0xa5, 0x48, 0xfd, 0x50, 0xa1, 0x5a, 0x9a); +DEFINE_GUID(OTHER_COMPAT_GUID, 0x12345566, 0x1111, 0x2222, 0x33, 0x33, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44); + + static const WCHAR testlib_dll[] = {'t','e','s','t','l','i','b','.','d','l','l',0}; static const WCHAR testlib2_dll[] = @@ -2487,6 +2538,183 @@ todo_wine pReleaseActCtx(handle); } +/* Test structure to verify alignment */ +typedef struct _test_act_ctx_compat_info { + DWORD ElementCount; + COMPATIBILITY_CONTEXT_ELEMENT Elements[10]; +} test_act_ctx_compat_info; + +static void test_no_compat(HANDLE handle, int line) +{ + test_act_ctx_compat_info compat_info; + SIZE_T size; + BOOL b; + + memset(&compat_info, 0, sizeof(compat_info)); + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, + CompatibilityInformationInActivationContext, &compat_info, + sizeof(compat_info), &size); + +todo_wine { + ok_(__FILE__, line)(b, "CompatibilityInformationInActivationContext failed\n"); + ok_(__FILE__, line)(size == sizeof(DWORD), "size mismatch (got %lu, expected 4)\n", size); +} + ok_(__FILE__, line)(compat_info.ElementCount == 0, "unexpected ElementCount %u\n", compat_info.ElementCount); +} + +static void test_with_compat(HANDLE handle, DWORD num_compat, const GUID* expected_compat[], int line) +{ + test_act_ctx_compat_info compat_info; + SIZE_T size; + SIZE_T expected = sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * num_compat + sizeof(DWORD); + DWORD n; + BOOL b; + + memset(&compat_info, 0, sizeof(compat_info)); + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, + CompatibilityInformationInActivationContext, &compat_info, + sizeof(compat_info), &size); + +todo_wine { + ok_(__FILE__, line)(b, "CompatibilityInformationInActivationContext failed\n"); + ok_(__FILE__, line)(size == expected, "size mismatch (got %lu, expected %lu)\n", size, expected); + ok_(__FILE__, line)(compat_info.ElementCount == num_compat, "unexpected ElementCount %u\n", compat_info.ElementCount); + + for (n = 0; n < num_compat; ++n) + { + ok_(__FILE__, line)(IsEqualGUID(&compat_info.Elements[n].Id, expected_compat[n]), + "got wrong clsid %s, expected %s for %u\n", + wine_dbgstr_guid(&compat_info.Elements[n].Id), + wine_dbgstr_guid(expected_compat[n]), + n); + ok_(__FILE__, line)(compat_info.Elements[n].Type == ACTCX_COMPATIBILITY_ELEMENT_TYPE_OS, + "Wrong type, got %u for %u\n", (DWORD)compat_info.Elements[n].Type, n); + } +} +} + +static void test_compatibility(void) +{ + HANDLE handle; + + /* No compat results returned */ + trace("manifest1\n"); + if(!create_manifest_file("test1.manifest", manifest1, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("test1.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("test1.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + char buffer[sizeof(COMPATIBILITY_CONTEXT_ELEMENT) * 2 + sizeof(DWORD)]; + SIZE_T size; + BOOL b; + + memset(buffer, 0, sizeof(buffer)); + b = pQueryActCtxW(QUERY_ACTCTX_FLAG_NO_ADDREF, handle, NULL, + CompatibilityInformationInActivationContext, buffer, + sizeof(buffer), &size); + + if (!b && GetLastError() == ERROR_INVALID_PARAMETER) + { + win_skip("CompatibilityInformationInActivationContext not supported.\n"); + pReleaseActCtx(handle); + return; + } + + test_basic_info(handle, __LINE__); + test_no_compat(handle, __LINE__); + pReleaseActCtx(handle); + } + + /* Still no compat results returned */ + trace("no_supportedOs\n"); + if(!create_manifest_file("no_supportedOs.manifest", compat_manifest_no_supportedOs, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("no_supportedOs.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("no_supportedOs.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + test_basic_info(handle, __LINE__); + test_no_compat(handle, __LINE__); + pReleaseActCtx(handle); + } + + /* Just one result returned */ + trace("manifest_vista\n"); + if(!create_manifest_file("manifest_vista.manifest", compat_manifest_vista, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("manifest_vista.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("manifest_vista.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + static const GUID* expect_manifest[] = + { + &VISTA_COMPAT_GUID + }; + test_basic_info(handle, __LINE__); + test_with_compat(handle, 1, expect_manifest, __LINE__); + pReleaseActCtx(handle); + } + + /* Show that the order is retained */ + trace("manifest_vista_7_8_10_81\n"); + if(!create_manifest_file("manifest_vista_7_8_10_81.manifest", compat_manifest_vista_7_8_10_81, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("manifest_vista_7_8_10_81.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("manifest_vista_7_8_10_81.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + static const GUID* expect_manifest[] = + { + &VISTA_COMPAT_GUID, + &WIN7_COMPAT_GUID, + &WIN8_COMPAT_GUID, + &WIN10_COMPAT_GUID, + &WIN81_COMPAT_GUID, + }; + test_basic_info(handle, __LINE__); + test_with_compat(handle, 5, expect_manifest, __LINE__); + pReleaseActCtx(handle); + } + + /* Show that even unknown GUID's are stored */ + trace("manifest_other_guid\n"); + if(!create_manifest_file("manifest_other_guid.manifest", compat_manifest_other_guid, -1, NULL, NULL)) + { + skip("Could not create manifest file\n"); + return; + } + handle = test_create("manifest_other_guid.manifest"); + ok(handle != INVALID_HANDLE_VALUE, "handle == INVALID_HANDLE_VALUE, error %u\n", GetLastError()); + DeleteFileA("manifest_other_guid.manifest"); + if(handle != INVALID_HANDLE_VALUE) + { + static const GUID* expect_manifest[] = + { + &OTHER_COMPAT_GUID, + }; + test_basic_info(handle, __LINE__); + test_with_compat(handle, 1, expect_manifest, __LINE__); + pReleaseActCtx(handle); + } +} + START_TEST(actctx) { int argc; @@ -2511,4 +2739,5 @@ START_TEST(actctx) test_findsectionstring(); test_ZombifyActCtx(); run_child_process(); + test_compatibility(); }