4 * Copyright 2007 EA Durbin
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.
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.
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
26 #include "wine/heap.h"
27 #include "wine/debug.h"
29 WINE_DEFAULT_DEBUG_CHANNEL(sxs
);
31 /***********************************************************************
35 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
39 case DLL_WINE_PREATTACH
:
40 return FALSE
; /* prefer native version */
41 case DLL_PROCESS_ATTACH
:
42 DisableThreadLibraryCalls( hinstDLL
);
48 typedef struct _SXS_GUID_INFORMATION_CLR
52 PCWSTR pcwszRuntimeVersion
;
54 PCWSTR pcwszAssemblyIdentity
;
55 } SXS_GUID_INFORMATION_CLR
, *PSXS_GUID_INFORMATION_CLR
;
57 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE 0x1
58 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS 0x2
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 #define SXS_LOOKUP_CLR_GUID_FIND_ANY (SXS_LOOKUP_CLR_GUID_FIND_SURROGATE | SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
65 struct comclassredirect_data
81 DWORD miscstatuscontent
;
82 DWORD miscstatusthumbnail
;
84 DWORD miscstatusdocprint
;
100 struct clrsurrogate_data
105 ULONG version_offset
;
111 BOOL WINAPI
SxsLookupClrGuid(DWORD flags
, GUID
*clsid
, HANDLE actctx
, void *buffer
, SIZE_T buffer_len
,
112 SIZE_T
*buffer_len_required
)
114 ACTCTX_SECTION_KEYED_DATA guid_info
= { sizeof(ACTCTX_SECTION_KEYED_DATA
) };
115 ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION
*assembly_info
= NULL
;
116 SIZE_T bytes_assembly_info
;
117 unsigned int len_version
= 0, len_name
, len_identity
;
118 const void *ptr_name
, *ptr_version
, *ptr_identity
;
119 SXS_GUID_INFORMATION_CLR
*ret
= buffer
;
124 TRACE("%#x, %s, %p, %p, %lx, %p.\n", flags
, wine_dbgstr_guid(clsid
), actctx
,
125 buffer
, buffer_len
, buffer_len_required
);
127 if (flags
& SXS_LOOKUP_CLR_GUID_USE_ACTCTX
)
129 if (!ActivateActCtx(actctx
, &cookie
))
131 WARN("Failed to activate context.\n");
136 if (flags
& SXS_LOOKUP_CLR_GUID_FIND_SURROGATE
)
138 if ((retval
= FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
, NULL
,
139 ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES
, clsid
, &guid_info
)))
141 flags
&= ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
;
145 if (!retval
&& (flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
))
147 if ((retval
= FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
, NULL
,
148 ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
, clsid
, &guid_info
)))
150 flags
&= ~SXS_LOOKUP_CLR_GUID_FIND_SURROGATE
;
156 SetLastError(ERROR_NOT_FOUND
);
160 retval
= QueryActCtxW(0, guid_info
.hActCtx
, &guid_info
.ulAssemblyRosterIndex
,
161 AssemblyDetailedInformationInActivationContext
, NULL
, 0, &bytes_assembly_info
);
162 if (!retval
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
167 assembly_info
= heap_alloc(bytes_assembly_info
);
168 if (!(retval
= QueryActCtxW(0, guid_info
.hActCtx
, &guid_info
.ulAssemblyRosterIndex
,
169 AssemblyDetailedInformationInActivationContext
, assembly_info
,
170 bytes_assembly_info
, &bytes_assembly_info
)))
175 if (flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
)
177 const struct comclassredirect_data
*redirect_data
= guid_info
.lpData
;
178 const struct clrclass_data
*class_data
;
180 class_data
= (void *)((char *)redirect_data
+ redirect_data
->clrdata_offset
);
181 ptr_name
= (char *)class_data
+ class_data
->name_offset
;
182 ptr_version
= (char *)class_data
+ class_data
->version_offset
;
183 len_name
= class_data
->name_len
+ sizeof(WCHAR
);
184 if (class_data
->version_len
)
185 len_version
= class_data
->version_len
+ sizeof(WCHAR
);
189 const struct clrsurrogate_data
*surrogate
= guid_info
.lpData
;
190 ptr_name
= (char *)surrogate
+ surrogate
->name_offset
;
191 ptr_version
= (char *)surrogate
+ surrogate
->version_offset
;
192 len_name
= surrogate
->name_len
+ sizeof(WCHAR
);
193 if (surrogate
->version_len
)
194 len_version
= surrogate
->version_len
+ sizeof(WCHAR
);
197 ptr_identity
= assembly_info
->lpAssemblyEncodedAssemblyIdentity
;
198 len_identity
= assembly_info
->ulEncodedAssemblyIdentityLength
+ sizeof(WCHAR
);
200 *buffer_len_required
= sizeof(*ret
) + len_identity
+ len_version
+ len_name
;
201 if (!buffer
|| buffer_len
< *buffer_len_required
)
203 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
208 ret
->cbSize
= sizeof(*ret
);
209 ret
->dwFlags
= flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
? SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS
:
210 SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE
;
212 /* Copy strings into buffer */
213 ret_strings
= (char *)ret
+ sizeof(*ret
);
215 memcpy(ret_strings
, ptr_identity
, len_identity
);
216 ret
->pcwszAssemblyIdentity
= (WCHAR
*)ret_strings
;
217 ret_strings
+= len_identity
;
219 memcpy(ret_strings
, ptr_name
, len_name
);
220 ret
->pcwszTypeName
= (WCHAR
*)ret_strings
;
221 ret_strings
+= len_name
;
225 memcpy(ret_strings
, ptr_version
, len_version
);
226 ret
->pcwszRuntimeVersion
= (WCHAR
*)ret_strings
;
229 ret
->pcwszRuntimeVersion
= NULL
;
234 ReleaseActCtx(guid_info
.hActCtx
);
236 if (flags
& SXS_LOOKUP_CLR_GUID_USE_ACTCTX
)
237 DeactivateActCtx(0, cookie
);
239 heap_free(assembly_info
);