1 /* 2 * sxs main 3 * 4 * Copyright 2007 EA Durbin 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdarg.h> 22 23 #include "windef.h" 24 #include "winbase.h" 25 26 #include "wine/heap.h" 27 #include "wine/debug.h" 28 29 WINE_DEFAULT_DEBUG_CHANNEL(sxs); 30 31 /*********************************************************************** 32 * DllMain (SXS.@) 33 * 34 */ 35 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 36 { 37 switch(fdwReason) 38 { 39 case DLL_WINE_PREATTACH: 40 return FALSE; /* prefer native version */ 41 case DLL_PROCESS_ATTACH: 42 DisableThreadLibraryCalls( hinstDLL ); 43 break; 44 } 45 return TRUE; 46 } 47 48 typedef struct _SXS_GUID_INFORMATION_CLR 49 { 50 DWORD cbSize; 51 DWORD dwFlags; 52 PCWSTR pcwszRuntimeVersion; 53 PCWSTR pcwszTypeName; 54 PCWSTR pcwszAssemblyIdentity; 55 } SXS_GUID_INFORMATION_CLR, *PSXS_GUID_INFORMATION_CLR; 56 57 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE 0x1 58 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS 0x2 59 60 #define SXS_LOOKUP_CLR_GUID_USE_ACTCTX 0x00000001 61 #define SXS_LOOKUP_CLR_GUID_FIND_SURROGATE 0x00010000 62 #define SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS 0x00020000 63 64 struct comclassredirect_data 65 { 66 ULONG size; 67 BYTE res; 68 BYTE miscmask; 69 BYTE res1[2]; 70 DWORD model; 71 GUID clsid; 72 GUID alias; 73 GUID clsid2; 74 GUID tlbid; 75 ULONG name_len; 76 ULONG name_offset; 77 ULONG progid_len; 78 ULONG progid_offset; 79 ULONG clrdata_len; 80 ULONG clrdata_offset; 81 DWORD miscstatus; 82 DWORD miscstatuscontent; 83 DWORD miscstatusthumbnail; 84 DWORD miscstatusicon; 85 DWORD miscstatusdocprint; 86 }; 87 88 struct clrclass_data 89 { 90 ULONG size; 91 DWORD res[2]; 92 ULONG module_len; 93 ULONG module_offset; 94 ULONG name_len; 95 ULONG name_offset; 96 ULONG version_len; 97 ULONG version_offset; 98 DWORD res2[2]; 99 }; 100 101 BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buffer, SIZE_T buffer_len, 102 SIZE_T *buffer_len_required) 103 { 104 ACTCTX_SECTION_KEYED_DATA guid_info = { sizeof(ACTCTX_SECTION_KEYED_DATA) }; 105 ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *assembly_info; 106 SIZE_T bytes_assembly_info; 107 struct comclassredirect_data *redirect_data; 108 struct clrclass_data *class_data; 109 int len_version = 0, len_name, len_identity; 110 const void *ptr_name, *ptr_version, *ptr_identity; 111 SXS_GUID_INFORMATION_CLR *ret = buffer; 112 char *ret_strings; 113 114 TRACE("(%x, %s, %p, %p, %08lx, %p): stub\n", flags, wine_dbgstr_guid(clsid), actctx, 115 buffer, buffer_len, buffer_len_required); 116 117 if (flags & ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS) 118 FIXME("Ignored flags: %x\n", flags & ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS); 119 120 if (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0, 121 ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info)) 122 { 123 SetLastError(ERROR_NOT_FOUND); 124 return FALSE; 125 } 126 127 QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex, 128 AssemblyDetailedInformationInActivationContext, NULL, 0, &bytes_assembly_info); 129 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 130 { 131 ReleaseActCtx(guid_info.hActCtx); 132 return FALSE; 133 } 134 assembly_info = heap_alloc(bytes_assembly_info); 135 if(!QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex, 136 AssemblyDetailedInformationInActivationContext, assembly_info, 137 bytes_assembly_info, &bytes_assembly_info)) 138 { 139 heap_free(assembly_info); 140 ReleaseActCtx(guid_info.hActCtx); 141 return FALSE; 142 } 143 144 redirect_data = guid_info.lpData; 145 class_data = (void *)((char*)redirect_data + redirect_data->clrdata_offset); 146 147 ptr_identity = assembly_info->lpAssemblyEncodedAssemblyIdentity; 148 ptr_name = (char *)class_data + class_data->name_offset; 149 ptr_version = (char *)class_data + class_data->version_offset; 150 151 len_identity = assembly_info->ulEncodedAssemblyIdentityLength + sizeof(WCHAR); 152 len_name = class_data->name_len + sizeof(WCHAR); 153 if (class_data->version_len > 0) 154 len_version = class_data->version_len + sizeof(WCHAR); 155 156 *buffer_len_required = sizeof(SXS_GUID_INFORMATION_CLR) + len_identity + len_version + len_name; 157 if (!buffer || buffer_len < *buffer_len_required) 158 { 159 SetLastError(ERROR_INSUFFICIENT_BUFFER); 160 heap_free(assembly_info); 161 ReleaseActCtx(guid_info.hActCtx); 162 return FALSE; 163 } 164 165 ret->cbSize = sizeof(SXS_GUID_INFORMATION_CLR); 166 ret->dwFlags = SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS; 167 168 /* Copy strings into buffer */ 169 ret_strings = (char *)ret + sizeof(SXS_GUID_INFORMATION_CLR); 170 171 memcpy(ret_strings, ptr_identity, len_identity); 172 ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings; 173 ret_strings += len_identity; 174 175 memcpy(ret_strings, ptr_name, len_name); 176 ret->pcwszTypeName = (WCHAR *)ret_strings; 177 ret_strings += len_name; 178 179 if (len_version > 0) 180 { 181 memcpy(ret_strings, ptr_version, len_version); 182 ret->pcwszRuntimeVersion = (WCHAR *)ret_strings; 183 } 184 else 185 ret->pcwszRuntimeVersion = NULL; 186 187 SetLastError(0); 188 189 ReleaseActCtx(guid_info.hActCtx); 190 heap_free(assembly_info); 191 return TRUE; 192 } 193