From: Bolan Chen <bolanchen123@gmail.com> --- dlls/ntdll/actctx.c | 104 +++++++++++++++++++++++++++++++------------- 1 file changed, 73 insertions(+), 31 deletions(-) diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 705ef85ade5..1bf503eba91 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -3365,7 +3365,7 @@ static void parse_assembly_binding_elem( xmlbuf_t *xmlbuf, const struct xml_elem } } -static void parse_runtime_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent, WCHAR **private_path ) +static void parse_windows_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent, WCHAR **private_path ) { struct xml_attr attr; struct xml_elem elem; @@ -3388,12 +3388,14 @@ static NTSTATUS parse_config_file( xmlbuf_t *xmlbuf, WCHAR **private_path ) { struct xml_elem elem; struct xml_elem parent = {}; + struct xml_elem configuration_root = {}; BOOL end = FALSE; xmlbuf->error = FALSE; xmlbuf->ns_pos = 0; *private_path = NULL; + if (!next_xml_elem( xmlbuf, &elem, &parent )) return STATUS_SXS_ASSEMBLY_NOT_FOUND; if (xmlstr_cmp( &elem.name, L"?xml" ) && @@ -3407,12 +3409,14 @@ static NTSTATUS parse_config_file( xmlbuf_t *xmlbuf, WCHAR **private_path ) } parse_expect_no_attr( xmlbuf, &end ); + + configuration_root = elem; if (!end) { - while (next_xml_elem( xmlbuf, &elem, &parent )) + while (next_xml_elem( xmlbuf, &elem, &configuration_root )) { - if (xmlstr_cmp( &elem.name, L"runtime" ) && !elem.ns.len) - parse_runtime_elem( xmlbuf, &elem, private_path ); + if (xmlstr_cmp( &elem.name, L"windows" ) && !elem.ns.len) + parse_windows_elem( xmlbuf, &elem, private_path ); else parse_unknown_elem( xmlbuf, &elem ); } @@ -3510,7 +3514,6 @@ static NTSTATUS open_config_file( LPCWSTR filename, HANDLE file, WCHAR **private RtlFreeHeap( GetProcessHeap(), 0, new_buff ); } } - done: NtUnmapViewOfSection( GetCurrentProcess(), base ); return status; @@ -3625,14 +3628,16 @@ static NTSTATUS probe_private_path( struct actctx_loader *acl, struct assembly_i SIZE_T path_len = end ? end - path : wcslen( path ); if (path_len) { - memcpy( buffer, acl->actctx->appdir.info, len * sizeof(WCHAR) ); - p = buffer + len; - memcpy ( p, path, path_len * sizeof(WCHAR) ); - p += path_len; + p = buffer + swprintf( buffer, total, L"%s%.*s", acl->actctx->appdir.info, + (int)path_len, path); if (p > buffer && p[-1] != '\\') *p++ = '\\'; *p = 0; status = open_manifest_file( acl, ai, lang, directory, buffer, total ); if (status != STATUS_SXS_ASSEMBLY_NOT_FOUND) break; + swprintf( buffer, total, L"%s%.*s\\%s\\", acl->actctx->appdir.info, + (int)path_len, path, ai->name ); + status = open_manifest_file( acl, ai, lang, directory, buffer, total ); + if (status != STATUS_SXS_ASSEMBLY_NOT_FOUND) break; } if (!end) break; path = end + 1; @@ -3701,7 +3706,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl, status = open_manifest_file( acl, ai, lang, directory, buffer, total ); } - if ((status = probe_private_path( acl, ai )) != STATUS_SXS_ASSEMBLY_NOT_FOUND) return status; + if ((status = probe_private_path( acl, ai )) != STATUS_SXS_ASSEMBLY_NOT_FOUND) goto done; done: RtlFreeHeap( GetProcessHeap(), 0, directory ); @@ -5541,6 +5546,62 @@ static const WCHAR *find_app_settings( ACTIVATION_CONTEXT *actctx, const WCHAR * return NULL; } +static NTSTATUS probe_config_path( ACTIVATION_CONTEXT *actctx ) +{ + struct assembly *root; + WCHAR *path; + UNICODE_STRING nt_name; + HANDLE file; + size_t len; + static const WCHAR manifest_ext[] = L".manifest"; + static const WCHAR config_ext[] = L".config"; + size_t manifest_ext_len = ARRAY_SIZE(manifest_ext) - 1; + size_t config_ext_len = ARRAY_SIZE(config_ext) - 1; + + if (!actctx->num_assemblies) return STATUS_SUCCESS; + + root = &actctx->assemblies[0]; + if (root->manifest.type != ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE || !root->manifest.info) + return STATUS_SUCCESS; + + len = wcslen( root->manifest.info ); + if (len > manifest_ext_len && + !wcsicmp( root->manifest.info + len - manifest_ext_len, manifest_ext )) + { + if (!(path = RtlAllocateHeap( GetProcessHeap(), 0, (len - manifest_ext_len + config_ext_len + 1) * sizeof(WCHAR) ))) return STATUS_NO_MEMORY; + + memcpy( path, root->manifest.info, (len - manifest_ext_len) * sizeof(WCHAR) ); + memcpy( path + len - manifest_ext_len, config_ext, (config_ext_len + 1) * sizeof(WCHAR) ); + } + else + { + if (!(path = RtlAllocateHeap( GetProcessHeap(), 0, (len + config_ext_len + 1) * sizeof(WCHAR) ))) return STATUS_NO_MEMORY; + + memcpy( path, root->manifest.info, len * sizeof(WCHAR) ); + memcpy( path + len, config_ext, (config_ext_len + 1) * sizeof(WCHAR) ); + } + + if (!RtlDosPathNameToNtPathName_U( path, &nt_name, NULL, NULL )) + { + RtlFreeHeap( GetProcessHeap(), 0, path ); + return STATUS_SUCCESS; + } + + if (!open_nt_file( &file, &nt_name )) + { + NtClose( file ); + actctx->config.info = path; + actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; + } + else + { + RtlFreeHeap( GetProcessHeap(), 0, path ); + } + + RtlFreeUnicodeString( &nt_name ); + return STATUS_SUCCESS; +} + /* initialize the activation context for the current process */ void actctx_init(void) { @@ -5558,7 +5619,6 @@ void actctx_init(void) NtCurrentTeb()->Peb->ActivationContextData = process_actctx; } - /*********************************************************************** * RtlCreateActivationContext (NTDLL.@) * @@ -5571,10 +5631,6 @@ NTSTATUS WINAPI RtlCreateActivationContext( ACTIVATION_CONTEXT **new_actctx, con const ACTCTXW *pActCtx = ptr; /* FIXME: not the right structure */ const WCHAR *directory = NULL; ACTIVATION_CONTEXT *actctx; - HANDLE config_file = 0; - HMODULE config_module; - UNICODE_STRING config_name; - UNICODE_STRING config_nameW; UNICODE_STRING nameW; ULONG lang = 0; NTSTATUS status = STATUS_NO_MEMORY; @@ -5605,22 +5661,6 @@ NTSTATUS WINAPI RtlCreateActivationContext( ACTIVATION_CONTEXT **new_actctx, con actctx->ref_count = 1; actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_NONE; actctx->config.info = NULL; - config_module = NtCurrentTeb()->Peb->ImageBaseAddress; - if ((status = get_module_filename( config_module, &config_name, sizeof(L".config") ))) - goto error; - wcscat( config_name.Buffer, L".config" ); - config_nameW.Buffer = NULL; - if (RtlDosPathNameToNtPathName_U( config_name.Buffer, &config_nameW, NULL, NULL )) { - if (!open_nt_file( &config_file, &config_nameW )) { - actctx->config.info = config_name.Buffer; - actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; - NtClose(config_file); - } else - RtlFreeUnicodeString(&config_name); - } else - RtlFreeUnicodeString(&config_name); - RtlFreeUnicodeString(&config_nameW); - actctx->appdir.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE; if (pActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID) { @@ -5719,6 +5759,8 @@ NTSTATUS WINAPI RtlCreateActivationContext( ACTIVATION_CONTEXT **new_actctx, con if (file) NtClose( file ); RtlFreeUnicodeString( &nameW ); + if (status == STATUS_SUCCESS) status = probe_config_path(actctx); + if (status == STATUS_SUCCESS) status = parse_depend_manifests(&acl); free_depend_manifests( &acl ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10753