/* * sxs main * * Copyright 2007 EA Durbin * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include "windef.h" #include "winbase.h" #include "wine/heap.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(sxs); /*********************************************************************** * DllMain (SXS.@) * */ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch(fdwReason) { case DLL_WINE_PREATTACH: return FALSE; /* prefer native version */ case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( hinstDLL ); break; } 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; ULONG flags; 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; }