#include "windef.h"
#include "winbase.h"
+#include "wine/heap.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(sxs);
/***********************************************************************
* DllMain (SXS.@)
}
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 flags, GUID *clsid, HANDLE actctx, void *buffer, SIZE_T buffer_len,
+ SIZE_T *buffer_len_required)
+{
+ 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 = buffer;
+ char *ret_strings;
+
+ TRACE("(%x, %s, %p, %p, %08lx, %p): stub\n", flags, wine_dbgstr_guid(clsid), actctx,
+ buffer, buffer_len, buffer_len_required);
+
+ if (flags & ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
+ FIXME("Ignored flags: %x\n", flags & ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS);
+
+ if (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
+ ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info))
+ {
+ SetLastError(ERROR_NOT_FOUND);
+ return FALSE;
+ }
+
+ QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex,
+ AssemblyDetailedInformationInActivationContext, NULL, 0, &bytes_assembly_info);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ReleaseActCtx(guid_info.hActCtx);
+ return FALSE;
+ }
+ 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))
+ {
+ 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 = assembly_info->ulEncodedAssemblyIdentityLength + sizeof(WCHAR);
+ len_name = class_data->name_len + sizeof(WCHAR);
+ if (class_data->version_len > 0)
+ len_version = class_data->version_len + sizeof(WCHAR);
+
+ *buffer_len_required = sizeof(SXS_GUID_INFORMATION_CLR) + len_identity + len_version + len_name;
+ if (!buffer || buffer_len < *buffer_len_required)
+ {
+ 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;
+
+ /* Copy strings into buffer */
+ ret_strings = (char *)ret + sizeof(SXS_GUID_INFORMATION_CLR);
+
+ memcpy(ret_strings, ptr_identity, len_identity);
+ ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings;
+ ret_strings += len_identity;
+
+ memcpy(ret_strings, ptr_name, len_name);
+ ret->pcwszTypeName = (WCHAR *)ret_strings;
+ ret_strings += len_name;
+
+ if (len_version > 0)
+ {
+ memcpy(ret_strings, ptr_version, len_version);
+ ret->pcwszRuntimeVersion = (WCHAR *)ret_strings;
+ }
+ else
+ ret->pcwszRuntimeVersion = NULL;
+
+ SetLastError(0);
+
+ ReleaseActCtx(guid_info.hActCtx);
+ heap_free(assembly_info);
+ return TRUE;
+}