From: Fabian Maurer Subject: [PATCH 6/6] Implement SxsLookupClrGuid Message-Id: <20180807174512.25597-6-dark.shadow4@web.de> Date: Tue, 7 Aug 2018 19:45:12 +0200 In-Reply-To: <20180807174512.25597-1-dark.shadow4@web.de> References: <20180807174512.25597-1-dark.shadow4@web.de> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43270 Signed-off-by: Fabian Maurer --- dlls/sxs/sxs.c | 135 +++++++++++++++++++++++++++++++++++++++++++ dlls/sxs/sxs.spec | 2 +- dlls/sxs/tests/sxs.c | 1 - 3 files changed, 136 insertions(+), 2 deletions(-) diff --git a/dlls/sxs/sxs.c b/dlls/sxs/sxs.c index 06e6672dbf..74a2450c68 100644 --- a/dlls/sxs/sxs.c +++ b/dlls/sxs/sxs.c @@ -23,6 +23,10 @@ #include "windef.h" #include "winbase.h" +#include "wine/heap.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(sxs); /*********************************************************************** * DllMain (SXS.@) @@ -40,3 +44,134 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) } return TRUE; } + +typedef struct _SXS_GUID_INFORMATION_CLR +{ + DWORD cbSize; + DWORD dwFlags; + PCWSTR pcwszRuntimeVersion; + PCWSTR pcwszTypeName; + PCWSTR pcwszAssemblyIdentity; +} SXS_GUID_INFORMATION_CLR, *PSXS_GUID_INFORMATION_CLR; + +#define SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE 0x1 +#define SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS 0x2 + +#define SXS_LOOKUP_CLR_GUID_USE_ACTCTX 0x00000001 +#define SXS_LOOKUP_CLR_GUID_FIND_SURROGATE 0x00010000 +#define SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS 0x00020000 + +struct comclassredirect_data +{ + ULONG size; + BYTE res; + BYTE miscmask; + BYTE res1[2]; + DWORD model; + GUID clsid; + GUID alias; + GUID clsid2; + GUID tlbid; + ULONG name_len; + ULONG name_offset; + ULONG progid_len; + ULONG progid_offset; + ULONG clrdata_len; + ULONG clrdata_offset; + DWORD miscstatus; + DWORD miscstatuscontent; + DWORD miscstatusthumbnail; + DWORD miscstatusicon; + DWORD miscstatusdocprint; +}; + +struct clrclass_data +{ + ULONG size; + DWORD res[2]; + ULONG module_len; + ULONG module_offset; + ULONG name_len; + ULONG name_offset; + ULONG version_len; + ULONG version_offset; + DWORD res2[2]; +}; + +BOOL WINAPI SxsLookupClrGuid(DWORD dwFlags, LPGUID pClsid, HANDLE hActCtx, PVOID pvOutputBuffer, SIZE_T cbOutputBuffer, PSIZE_T pcbOutputBuffer) +{ + ACTCTX_SECTION_KEYED_DATA guid_info = { sizeof(ACTCTX_SECTION_KEYED_DATA) }; + ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *assembly_info; + SIZE_T bytes_assembly_info; + struct comclassredirect_data *redirect_data; + struct clrclass_data *class_data; + int len_version = 0, len_name, len_identity; + const void *ptr_name, *ptr_version, *ptr_identity; + + SXS_GUID_INFORMATION_CLR *ret = pvOutputBuffer; + char *ret_strings = (char *)ret + sizeof(SXS_GUID_INFORMATION_CLR); + + TRACE("(%x, %s, %p, %p, %08lx, %p): stub\n", dwFlags, wine_dbgstr_guid(pClsid), hActCtx, pvOutputBuffer, cbOutputBuffer, pcbOutputBuffer); + + if (dwFlags & (~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)) + FIXME("Ignored flags: %x\n", dwFlags & (~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)); + + if (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, pClsid, &guid_info)) + { + DWORD error = GetLastError(); + if (error != ERROR_SXS_KEY_NOT_FOUND) + ERR("Failed to find guid: %d\n", error); + SetLastError(ERROR_NOT_FOUND); + return FALSE; + } + + QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex, AssemblyDetailedInformationInActivationContext, NULL, 0, &bytes_assembly_info); + assembly_info = heap_alloc(bytes_assembly_info); + if (!QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex, + AssemblyDetailedInformationInActivationContext, assembly_info, bytes_assembly_info, &bytes_assembly_info)) + { + ERR("QueryActCtxW failed: %d!\n", GetLastError()); + heap_free(assembly_info); + ReleaseActCtx(guid_info.hActCtx); + return FALSE; + } + + redirect_data = guid_info.lpData; + class_data = (void *)((char*)redirect_data + redirect_data->clrdata_offset); + + ptr_identity = assembly_info->lpAssemblyEncodedAssemblyIdentity; + ptr_name = (char *)class_data + class_data->name_offset; + ptr_version = (char *)class_data + class_data->version_offset; + + len_identity = (lstrlenW(ptr_identity) + 1) * sizeof(WCHAR); + len_name = (lstrlenW(ptr_name) + 1) * sizeof(WCHAR); + if (class_data->version_len > 0) + len_version = (lstrlenW(ptr_version) + 1) * sizeof(WCHAR); + + *pcbOutputBuffer = sizeof(SXS_GUID_INFORMATION_CLR) + len_identity + len_version + len_name; + if (!pvOutputBuffer || cbOutputBuffer < *pcbOutputBuffer) + { + SetLastError(ERROR_INSUFFICIENT_BUFFER); + heap_free(assembly_info); + ReleaseActCtx(guid_info.hActCtx); + return FALSE; + } + + ret->cbSize = sizeof(SXS_GUID_INFORMATION_CLR); + ret->dwFlags = SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS; + +#define copy_str(target, ptr, len) \ + target = len ? (void *)ret_strings : NULL; \ + memcpy(ret_strings, ptr, len); \ + ret_strings += len; + copy_str(ret->pcwszAssemblyIdentity, ptr_identity, len_identity); + copy_str(ret->pcwszTypeName , ptr_name, len_name); + copy_str(ret->pcwszRuntimeVersion, ptr_version, len_version); +#undef copy_str + + SetLastError(0); + + ReleaseActCtx(guid_info.hActCtx); + heap_free(assembly_info); + return TRUE; +} diff --git a/dlls/sxs/sxs.spec b/dlls/sxs/sxs.spec index 9766c4a791..99bc917161 100644 --- a/dlls/sxs/sxs.spec +++ b/dlls/sxs/sxs.spec @@ -6,7 +6,7 @@ @ stub SxsFindClrSurrogateInformation @ stub SxsGenerateActivationContext @ stub SxsInstallW -@ stub SxsLookupClrGuid +@ stdcall SxsLookupClrGuid(long ptr ptr ptr long ptr) @ stub SxsOleAut32MapConfiguredClsidToReferenceClsid @ stub SxsOleAut32MapIIDOrCLSIDToTypeLibrary @ stub SxsOleAut32MapIIDToProxyStubCLSID diff --git a/dlls/sxs/tests/sxs.c b/dlls/sxs/tests/sxs.c index a68876d422..7b70d43dad 100644 --- a/dlls/sxs/tests/sxs.c +++ b/dlls/sxs/tests/sxs.c @@ -221,7 +221,6 @@ START_TEST(sxs) return; } - todo_wine ok(SxsLookupClrGuid != NULL, "SxsLookupClrGuid doesn't exist\n"); if( SxsLookupClrGuid) test_SxsLookupClrGuid(); -- 2.18.0