Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=18889
-- v3: ntdll: Don't hard-code DLL manifest resource ID when looking up dependency assembly. kernel32/tests: Test loading assembly manifest resource inside dependencies.
From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/kernel32/tests/actctx.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index da351e70466..023a5ea0825 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -2800,8 +2800,12 @@ todo_wine { handle = CreateActCtxA(&actctx); ok(handle == INVALID_HANDLE_VALUE, "got handle %p\n", handle); todo_wine +#ifdef _WIN64 + ok(GetLastError() == ERROR_SXS_MANIFEST_TOO_BIG, "got error %ld\n", GetLastError()); +#else ok(GetLastError() == ERROR_SXS_CANT_GEN_ACTCTX || broken(GetLastError() == ERROR_NOT_ENOUGH_MEMORY) /* XP, win2k3 */, "got error %ld\n", GetLastError()); +#endif
/* create from HMODULE - resource doesn't exist, lpSource is set */ memset(&actctx, 0, sizeof(ACTCTXA));
From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/kernel32/tests/actctx.c | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index 023a5ea0825..bdd99b23e5f 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -3758,6 +3758,59 @@ static void test_manifest_in_module(void) ReleaseActCtx(handle); }
+static void test_manifest_resource_name_omitted(void) +{ + WCHAR pathbuf[MAX_PATH]; + HANDLE handle; + ACTCTXW ctx; + DWORD err, len; + + memset(&ctx, 0, sizeof(ctx)); + ctx.cbSize = sizeof(ctx); + ctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID; + ctx.hModule = GetModuleHandleW(NULL); + handle = CreateActCtxW(&ctx); + err = GetLastError(); + ok(handle == INVALID_HANDLE_VALUE, "CreateActCtxW shall fail\n"); + todo_wine + ok(err == ERROR_RESOURCE_TYPE_NOT_FOUND, "got %lu\n", err); + + memset(&ctx, 0, sizeof(ctx)); + ctx.cbSize = sizeof(ctx); + ctx.dwFlags = ACTCTX_FLAG_HMODULE_VALID | ACTCTX_FLAG_RESOURCE_NAME_VALID; + ctx.hModule = GetModuleHandleW(NULL); + ctx.lpResourceName = NULL; + handle = CreateActCtxW(&ctx); + err = GetLastError(); + ok(handle == INVALID_HANDLE_VALUE, "CreateActCtxW shall fail\n"); + todo_wine + ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err); + + len = GetModuleFileNameW(NULL, pathbuf, ARRAY_SIZE(pathbuf)); + ok(len > 0 && len < ARRAY_SIZE(pathbuf), "GetModuleFileNameW returned error %lu\n", GetLastError()); + + memset(&ctx, 0, sizeof(ctx)); + ctx.cbSize = sizeof(ctx); + ctx.lpSource = pathbuf; + ctx.dwFlags = 0; + handle = CreateActCtxW(&ctx); + err = GetLastError(); + ok(handle == INVALID_HANDLE_VALUE, "CreateActCtxW shall fail\n"); + todo_wine + ok(err == ERROR_RESOURCE_TYPE_NOT_FOUND, "got %lu\n", err); + + memset(&ctx, 0, sizeof(ctx)); + ctx.cbSize = sizeof(ctx); + ctx.lpSource = pathbuf; + ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID; + ctx.lpResourceName = NULL; + handle = CreateActCtxW(&ctx); + err = GetLastError(); + ok(handle == INVALID_HANDLE_VALUE, "CreateActCtxW shall fail\n"); + todo_wine + ok(err == ERROR_INVALID_PARAMETER, "got %lu\n", err); +} + START_TEST(actctx) { int argc; @@ -3785,6 +3838,7 @@ START_TEST(actctx) }
test_manifest_in_module(); + test_manifest_resource_name_omitted(); test_actctx(); test_create_fail(); test_CreateActCtx();
From: Jinoh Kang jinoh.kang.kr@gmail.com
This prevents passing NULL resource name to get_manifest_in_module(). --- dlls/ntdll/actctx.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index b275a7f5b49..f25fd10dfef 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -2951,8 +2951,6 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assemb hModule, debugstr_w(filename) ); }
- if (!resname) return STATUS_INVALID_PARAMETER; - info.Type = RT_MANIFEST; info.Language = lang; if (!((ULONG_PTR)resname >> 16)) @@ -5223,6 +5221,9 @@ NTSTATUS WINAPI RtlCreateActivationContext( HANDLE *handle, const void *ptr ) (pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL)) return STATUS_INVALID_PARAMETER;
+ if ((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && !pActCtx->lpResourceName) + return STATUS_INVALID_PARAMETER; + if (!(actctx = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*actctx) ))) return STATUS_NO_MEMORY;
From: Jinoh Kang jinoh.kang.kr@gmail.com
--- dlls/kernel32/tests/actctx.c | 383 +++++++++++++++++++++++++++++++++++ 1 file changed, 383 insertions(+)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index bdd99b23e5f..8417529841c 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -3386,6 +3386,39 @@ typedef struct void (WINAPI *get_path)(char *buffer, int buffer_size); } sxs_info;
+struct manifest_res_spec +{ + const char *name; + LANGID lang; + const char *override_manifest; +}; + +static void add_sxs_dll_manifest(const char *pathname, const struct manifest_res_spec *res_specs, size_t num_specs, const char *manifest) +{ + HANDLE update_h; + BOOL ret; + size_t i; + + update_h = BeginUpdateResourceA(pathname, FALSE); + ok(update_h != NULL, "BeginUpdateResourceA returned error %lu.\n", GetLastError()); + + for (i = 0; i < num_specs; i++) + { + const struct manifest_res_spec *res_spec = &res_specs[i]; + const char *cur_manifest = res_spec->override_manifest ? res_spec->override_manifest : manifest; + ret = UpdateResourceA(update_h, + MAKEINTRESOURCEA(RT_MANIFEST), + res_spec->name, + res_spec->lang, + (void *)cur_manifest, + strlen(cur_manifest)); + ok(ret, "UpdateResourceA returned error %lu.\n", GetLastError()); + } + + ret = EndUpdateResourceA(update_h, FALSE); + ok(ret, "EndUpdateResourceA returned error %lu.\n", GetLastError()); +} + static BOOL fill_sxs_info(sxs_info *info, const char *temp, const char *path_dll, const char *exe_manifest, const char *dll_manifest, BOOL do_load) { BOOL success; @@ -3683,6 +3716,353 @@ cleanup: } }
+#define subtest_manifest_res(d,e,r,n,l) subtest_manifest_res_(__LINE__,d,e,r,n,l) +static DWORD subtest_manifest_res_(int line, const char *manifest_exe, const char *manifest_dll, const struct manifest_res_spec *res_specs, size_t num_specs, LANGID lang) +{ + char path_tmp[MAX_PATH] = "", path_dll[MAX_PATH] = "", path_manifest_exe[MAX_PATH] = ""; + char path_tmp_lang[MAX_PATH] = ""; + static const char path_tmp_suffix[] = "winek32t\"; + WCHAR locale_name[LOCALE_NAME_MAX_LENGTH] = {0}; + DWORD err, prefix_len; + ACTCTXA actctx; + HANDLE handle; + BOOL ret; + int r; + + prefix_len = GetTempPathA(MAX_PATH - ARRAY_SIZE(path_tmp_suffix), path_tmp); + ok_(__FILE__, line)(prefix_len > 0, "GetTempPathA returned error %lu.\n", GetLastError()); + + memcpy(&path_tmp[prefix_len], path_tmp_suffix, sizeof(path_tmp_suffix) - sizeof(*path_tmp_suffix)); + ret = CreateDirectoryA(path_tmp, NULL); + ok_(__FILE__, line)(ret || GetLastError() == ERROR_ALREADY_EXISTS, + "CreateDirectoryA returned error %lu.\n", GetLastError()); + + if (lang) + { + r = LCIDToLocaleName(MAKELCID(lang, SORT_DEFAULT), + locale_name, ARRAY_SIZE(locale_name), LOCALE_ALLOW_NEUTRAL_NAMES); + ok(r > 0, "lang 0x%04x, error %lu.\n", lang, GetLastError()); + } + + if (locale_name[0]) + { + r = snprintf(path_tmp_lang, ARRAY_SIZE(path_tmp_lang), "%s%ls\", path_tmp, locale_name); + ok_(__FILE__, line)(r > 0 && r < ARRAY_SIZE(path_tmp_lang), "got %d\n", r); + + ret = CreateDirectoryA(path_tmp_lang, NULL); + ok_(__FILE__, line)(ret || GetLastError() == ERROR_ALREADY_EXISTS, + "CreateDirectoryA returned error %lu.\n", GetLastError()); + } + else + { + r = snprintf(path_tmp_lang, ARRAY_SIZE(path_tmp_lang), "%s", path_tmp); + ok_(__FILE__, line)(r > 0 && r < ARRAY_SIZE(path_tmp_lang), "got %d\n", r); + } + + r = snprintf(path_dll, ARRAY_SIZE(path_dll), "%s%s", path_tmp_lang, "sxs_dll.dll"); + ok_(__FILE__, line)(r > 0 && r < ARRAY_SIZE(path_dll), "got %d\n", r); + + r = snprintf(path_manifest_exe, ARRAY_SIZE(path_manifest_exe), "%s%s", path_tmp, "exe.manifest"); + ok_(__FILE__, line)(r > 0 && r < ARRAY_SIZE(path_manifest_exe), "got %d\n", r); + create_manifest_file(path_manifest_exe, manifest_exe, -1, NULL, NULL); + + extract_resource("dummy.dll", "TESTDLL", path_dll); + add_sxs_dll_manifest(path_dll, res_specs, num_specs, manifest_dll); + + memset(&actctx, 0, sizeof(actctx)); + actctx.cbSize = sizeof(actctx); + actctx.lpSource = path_manifest_exe; + actctx.lpAssemblyDirectory = path_tmp; + actctx.dwFlags = ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID; + + SetLastError(0xccccccccUL); + handle = CreateActCtxA(&actctx); + if (handle == INVALID_HANDLE_VALUE) + { + err = GetLastError(); + ok_(__FILE__, line)(err != ERROR_SUCCESS, "got %#lx.\n", err); + } + else + { + err = ERROR_SUCCESS; + ok_(__FILE__, line)(handle != NULL, "CreateActCtxA returned %p (error %lu)\n", handle, err); + ReleaseActCtx(handle); + } + + ret = DeleteFileA(path_manifest_exe); + ok_(__FILE__, line)(ret, "DeleteFileA(%s) returned error %lu\n.", debugstr_a(path_manifest_exe), GetLastError()); + + ret = DeleteFileA(path_dll); + ok_(__FILE__, line)(ret, "DeleteFileA(%s) returned error %lu\n.", debugstr_a(path_dll), GetLastError()); + + if (locale_name[0]) + { + ret = RemoveDirectoryA(path_tmp_lang); + ok_(__FILE__, line)(ret, "RemoveDirectoryA(%s) returned error %lu\n.", debugstr_a(path_tmp_lang), GetLastError()); + } + + ret = RemoveDirectoryA(path_tmp); + ok_(__FILE__, line)(ret, "RemoveDirectoryA(%s) returned error %lu %s\n.", debugstr_a(path_tmp), GetLastError(), debugstr_a(path_tmp_lang)); + + return err; +} + +/* Test loading DLL with dependency assembly in valid manifest resource */ +static void test_valid_manifest_resources(void) +{ + static const struct manifest_res_spec valid_specs_basic[] = { + /* Test arbitrary resource ID */ + { (char *)1 }, { (char *)2 }, { (char *)3 }, { (char *)4 }, + { (char *)5 }, { (char *)6 }, { (char *)7 }, { (char *)8 }, + { (char *)9 }, { (char *)10 }, { (char *)11 }, { (char *)12 }, + { (char *)13 }, { (char *)14 }, { (char *)15 }, { (char *)16 }, + { (char *)0x1234 }, { (char *)0x89ab }, { (char *)0xffff }, + + /* Test arbitrary LANGID */ + { (char *)2, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT) }, + { (char *)2, MAKELANGID(LANG_FRENCH,SUBLANG_DEFAULT) }, + { (char *)2, 0x1234 }, + { (char *)2, 0xffff }, + }; + static const struct manifest_res_spec multiple_resources[] = { + /* Test multiple manifest resources coexisting inside a module */ + { (char *)2, 0 }, + { (char *)2, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), wrong_manifest1 }, + { (char *)2, MAKELANGID(LANG_FRENCH,SUBLANG_DEFAULT), wrong_manifest1 }, + { (char *)3, 0, wrong_manifest1 }, + { (char *)0x1234, 0, wrong_manifest1 }, + }; + static const struct manifest_res_spec multiple_resources_lang_prio[] = { + /* Test language priority among multiple manifest resources */ + { (char *)2, MAKELANGID(LANG_INVARIANT,SUBLANG_NEUTRAL) }, + { (char *)3, 0, wrong_manifest1 }, + { (char *)3, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT), wrong_manifest1 }, + }; + static const struct manifest_res_spec multiple_resources_named[] = { + /* Test multiple manifest resources (ID / name) coexisting inside a module */ + { (char *)2, 0 }, + { "winetestdummy", 0, wrong_manifest1 }, + }; + DWORD err; + size_t i; + + for (i = 0; i < ARRAY_SIZE(valid_specs_basic); i++) + { + winetest_push_context("valid_specs_basic[%Iu]", i); + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, &valid_specs_basic[i], 1, 0); + todo_wine_if(valid_specs_basic[i].name != (char *)1 || valid_specs_basic[i].lang != 0) + ok(err == ERROR_SUCCESS, "got error %lu.\n", err); + winetest_pop_context(); + } + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources, ARRAY_SIZE(multiple_resources), 0); + todo_wine + ok(err == ERROR_SUCCESS, "got error %lu.\n", err); + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_lang_prio, ARRAY_SIZE(multiple_resources_lang_prio), 0); + todo_wine + ok(err == ERROR_SUCCESS, "got error %lu.\n", err); + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_named, ARRAY_SIZE(multiple_resources_named), 0); + todo_wine + ok(err == ERROR_SUCCESS, "got error %lu.\n", err); +} + +/* Test loading DLL with dependency assembly in invalid manifest resource */ +static void test_invalid_manifest_resources(void) +{ + static const struct manifest_res_spec named_resources[] = { + /* Test name-only RT_MANIFEST resources */ + { "winetestdummy" }, + { "winetestdummy", 0x1234 }, + }; + static const struct manifest_res_spec multiple_resources[] = { + /* Test multiple manifest resources coexisting inside a module */ + { (char *)2, 0, wrong_manifest1 }, + { (char *)2, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT) }, + { (char *)2, MAKELANGID(LANG_FRENCH,SUBLANG_DEFAULT) }, + { (char *)3, 0 }, + { (char *)0x1234, 0 }, + }; + static const struct manifest_res_spec multiple_resources_lang_prio[] = { + /* Test language priority among multiple manifest resources */ + { (char *)2, MAKELANGID(LANG_INVARIANT,SUBLANG_NEUTRAL), wrong_manifest1 }, + { (char *)3, 0 }, + { (char *)3, MAKELANGID(LANG_ENGLISH,SUBLANG_DEFAULT) }, + }; + static const struct manifest_res_spec multiple_resources_named[] = { + /* Test multiple manifest resources (ID / name) coexisting inside a module */ + { (char *)2, 0, wrong_manifest1 }, + { "winetestdummy", 0 }, + }; + DWORD err; + size_t i; + + for (i = 0; i < ARRAY_SIZE(named_resources); i++) + { + winetest_push_context("named_resources[%Iu]", i); + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, &named_resources[i], 1, 0); + ok(err == ERROR_SXS_CANT_GEN_ACTCTX, "got error %lu.\n", err); + winetest_pop_context(); + } + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources, ARRAY_SIZE(multiple_resources), 0); + ok(err == ERROR_SXS_CANT_GEN_ACTCTX, "got error %lu.\n", err); + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_lang_prio, ARRAY_SIZE(multiple_resources_lang_prio), 0); + ok(err == ERROR_SXS_CANT_GEN_ACTCTX, "got error %lu.\n", err); + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_named, ARRAY_SIZE(multiple_resources_named), 0); + ok(err == ERROR_SXS_CANT_GEN_ACTCTX, "got error %lu.\n", err); + + err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, NULL, 0, 0); + ok(err == ERROR_SXS_CANT_GEN_ACTCTX, "got error %lu.\n", err); +} + +struct u16_vec +{ + UINT16 *base; + UINT16 *end; + UINT16 *alloc_end; +}; + +static BOOL u16_vec_add_uniq(struct u16_vec *vec, UINT16 item) +{ + UINT16 *p; + + for (p = vec->base; p != vec->end; p++) + { + if (*p == item) return FALSE; + } + + if (vec->end == vec->alloc_end) + { + ok(0, "u16_vec full\n"); + return FALSE; + } + else + { + *vec->end++ = item; + return TRUE; + } +} + +static void subtest_valid_manifest_resources_locale(LANGID actctx_lang) +{ + static const char manifest_exe_fmt[] = + "<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">" + "<dependency>" + "<dependentAssembly>" + "<assemblyIdentity type="win32" name="sxs_dll" version="1.0.0.0"" + " processorArchitecture="" ARCH "" publicKeyToken="0000000000000000" language="%ls"/>" + "</dependentAssembly>" + "</dependency>" + "</assembly>"; + static const char manifest_dll_fmt[] = + "<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">" + "<assemblyIdentity type="win32" name="sxs_dll" version="1.0.0.0"" + " processorArchitecture="" ARCH "" publicKeyToken="0000000000000000" language="%ls"/>" + "</assembly>"; + static const char manifest_dll_nofmt[] = + "<assembly xmlns="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0">" + "<assemblyIdentity type="win32" name="sxs_dll" version="1.0.0.0"" + " processorArchitecture="" ARCH "" publicKeyToken="0000000000000000"/>" + "</assembly>"; + char manifest_exe[1024], manifest_dll[1024]; + WCHAR locale_name[LOCALE_NAME_MAX_LENGTH]; + UINT16 langs_arr[5], *it; + struct u16_vec langs; + LANGID user_ui_lang; + int ret; + + if (actctx_lang == MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)) + { + wcscpy(locale_name, L"*"); + strcpy(manifest_dll, manifest_dll_nofmt); + } + else + { + actctx_lang = ConvertDefaultLocale(actctx_lang); + ok(actctx_lang != MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + "unexpected neutral locale\n"); + ret = LCIDToLocaleName(MAKELCID(actctx_lang, SORT_DEFAULT), + locale_name, ARRAY_SIZE(locale_name), LOCALE_ALLOW_NEUTRAL_NAMES); + ok(ret > 0, "error %lu.\n", GetLastError()); + + ret = snprintf(manifest_dll, ARRAY_SIZE(manifest_dll), manifest_dll_fmt, locale_name); + ok(ret > 0 && ret < ARRAY_SIZE(manifest_dll), "ret %d.\n", ret); + } + + ret = snprintf(manifest_exe, ARRAY_SIZE(manifest_exe), manifest_exe_fmt, locale_name); + ok(ret > 0 && ret < ARRAY_SIZE(manifest_exe), "ret %d.\n", ret); + + langs.base = langs_arr; + langs.end = langs_arr; + langs.alloc_end = langs_arr + ARRAY_SIZE(langs_arr); + + user_ui_lang = GetUserDefaultUILanguage(); + u16_vec_add_uniq(&langs, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)); + u16_vec_add_uniq(&langs, user_ui_lang); + u16_vec_add_uniq(&langs, MAKELANGID(PRIMARYLANGID(user_ui_lang), SUBLANG_NEUTRAL)); + u16_vec_add_uniq(&langs, MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT)); + u16_vec_add_uniq(&langs, 0x1); /* least number that is a valid LANGID */ + + for (it = langs.base; it != langs.end; it++) + { + struct manifest_res_spec specs[ARRAY_SIZE(langs_arr) + 1]; + size_t num_specs; + UINT16 *it2; + DWORD err; + + winetest_push_context("langs[%Id:]", it - langs.base); + + num_specs = 0; + for (it2 = it; it2 != langs.end; it2++) + { + struct manifest_res_spec spec = {(char *)2}; + spec.lang = *it2; + if (it2 != it) spec.override_manifest = wrong_manifest1; + ok(num_specs < ARRAY_SIZE(specs), "overrun\n"); + specs[num_specs++] = spec; + } + + err = subtest_manifest_res(manifest_exe, manifest_dll, specs, num_specs, actctx_lang); + todo_wine + ok(err == ERROR_SUCCESS, "got error %lu.\n", err); + + if (winetest_debug > 1 && err != ERROR_SUCCESS) + { + for (it2 = langs.base; it2 != langs.end; it2++) + { + trace("langs[%Id] = 0x%04x %c\n", it2 - langs.base, *it2, it2 == it ? '<' : ' '); + } + } + + winetest_pop_context(); + } + +} + +static void test_valid_manifest_resources_locale(void) +{ + static const LANGID langs[] = { + MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT), + MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL), + MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), + MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(langs); i++) + { + winetest_push_context("[%Iu]lang=0x%04x", i, langs[i]); + subtest_valid_manifest_resources_locale(langs[i]); + winetest_pop_context(); + } +} + static void run_sxs_test(int run) { switch(run) @@ -3839,6 +4219,9 @@ START_TEST(actctx)
test_manifest_in_module(); test_manifest_resource_name_omitted(); + test_valid_manifest_resources(); + test_invalid_manifest_resources(); + test_valid_manifest_resources_locale(); test_actctx(); test_create_fail(); test_CreateActCtx();
From: Jinoh Kang jinoh.kang.kr@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=18889 --- dlls/kernel32/tests/actctx.c | 6 +----- dlls/ntdll/actctx.c | 26 ++++++++++++++++++++++++-- 2 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/tests/actctx.c b/dlls/kernel32/tests/actctx.c index 8417529841c..bd0cc57ed68 100644 --- a/dlls/kernel32/tests/actctx.c +++ b/dlls/kernel32/tests/actctx.c @@ -3850,21 +3850,17 @@ static void test_valid_manifest_resources(void) { winetest_push_context("valid_specs_basic[%Iu]", i); err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, &valid_specs_basic[i], 1, 0); - todo_wine_if(valid_specs_basic[i].name != (char *)1 || valid_specs_basic[i].lang != 0) ok(err == ERROR_SUCCESS, "got error %lu.\n", err); winetest_pop_context(); }
err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources, ARRAY_SIZE(multiple_resources), 0); - todo_wine ok(err == ERROR_SUCCESS, "got error %lu.\n", err);
err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_lang_prio, ARRAY_SIZE(multiple_resources_lang_prio), 0); - todo_wine ok(err == ERROR_SUCCESS, "got error %lu.\n", err);
err = subtest_manifest_res(two_dll_manifest_exe, two_dll_manifest_dll, multiple_resources_named, ARRAY_SIZE(multiple_resources_named), 0); - todo_wine ok(err == ERROR_SUCCESS, "got error %lu.\n", err); }
@@ -4027,7 +4023,7 @@ static void subtest_valid_manifest_resources_locale(LANGID actctx_lang) }
err = subtest_manifest_res(manifest_exe, manifest_dll, specs, num_specs, actctx_lang); - todo_wine + todo_wine_if(PRIMARYLANGID(actctx_lang) != LANG_NEUTRAL && PRIMARYLANGID(actctx_lang) != LANG_INVARIANT) ok(err == ERROR_SUCCESS, "got error %lu.\n", err);
if (winetest_debug > 1 && err != ERROR_SUCCESS) diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index f25fd10dfef..0e73c99962c 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -2929,6 +2929,23 @@ static NTSTATUS open_nt_file( HANDLE *handle, UNICODE_STRING *name ) FILE_SHARE_READ | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_ALERT ); }
+static NTSTATUS find_first_manifest_resource_in_module( HANDLE hModule, const WCHAR **resname ) +{ + static const LDR_RESOURCE_INFO manifest_res_info = { RT_MANIFEST }; + const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry; + const IMAGE_RESOURCE_DIRECTORY *resdir; + NTSTATUS status; + + status = LdrFindResourceDirectory_U( hModule, &manifest_res_info, 1, &resdir ); + if (status != STATUS_SUCCESS) return status; + + if (!resdir->NumberOfIdEntries) return STATUS_RESOURCE_NAME_NOT_FOUND; + entry = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1); + *resname = (const WCHAR *)(ULONG_PTR)entry->u.Id; + + return STATUS_SUCCESS; +} + static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assembly_identity* ai, LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE hModule, LPCWSTR resname, ULONG lang ) @@ -2951,6 +2968,12 @@ static NTSTATUS get_manifest_in_module( struct actctx_loader* acl, struct assemb hModule, debugstr_w(filename) ); }
+ if (!resname) + { + status = find_first_manifest_resource_in_module( hModule, &resname ); + if (status != STATUS_SUCCESS) return status; + } + info.Type = RT_MANIFEST; info.Language = lang; if (!((ULONG_PTR)resname >> 16)) @@ -3330,8 +3353,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl, status = open_nt_file( &file, &nameW ); if (!status) { - status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, FALSE, file, - (LPCWSTR)CREATEPROCESS_MANIFEST_RESOURCE_ID, 0 ); + status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, FALSE, file, NULL, 0 ); NtClose( file ); if (status == STATUS_SUCCESS) break;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=131425
Your paranoid android.
=== debian11 (32 bit report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit ar:MA report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit de report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit fr report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit he:IL report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit hi:IN report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit ja:JP report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11 (32 bit zh:CN report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11b (32 bit WoW report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.
=== debian11b (64 bit WoW report) ===
kernel32: actctx.c:4163: Test succeeded inside todo block: got 87 actctx.c:4187: Test succeeded inside todo block: got 87 actctx.c:3864: Test failed: got error 14001.