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 typedef struct _SXS_GUID_INFORMATION_CLR
35 PCWSTR pcwszRuntimeVersion
;
37 PCWSTR pcwszAssemblyIdentity
;
38 } SXS_GUID_INFORMATION_CLR
, *PSXS_GUID_INFORMATION_CLR
;
40 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE 0x1
41 #define SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS 0x2
43 #define SXS_LOOKUP_CLR_GUID_USE_ACTCTX 0x00000001
44 #define SXS_LOOKUP_CLR_GUID_FIND_SURROGATE 0x00010000
45 #define SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS 0x00020000
46 #define SXS_LOOKUP_CLR_GUID_FIND_ANY (SXS_LOOKUP_CLR_GUID_FIND_SURROGATE | SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
48 struct comclassredirect_data
64 DWORD miscstatuscontent
;
65 DWORD miscstatusthumbnail
;
67 DWORD miscstatusdocprint
;
83 struct clrsurrogate_data
94 BOOL WINAPI
SxsLookupClrGuid(DWORD flags
, GUID
*clsid
, HANDLE actctx
, void *buffer
, SIZE_T buffer_len
,
95 SIZE_T
*buffer_len_required
)
97 ACTCTX_SECTION_KEYED_DATA guid_info
= { sizeof(ACTCTX_SECTION_KEYED_DATA
) };
98 ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION
*assembly_info
= NULL
;
99 SIZE_T bytes_assembly_info
;
100 unsigned int len_version
= 0, len_name
, len_identity
;
101 const void *ptr_name
, *ptr_version
, *ptr_identity
;
102 SXS_GUID_INFORMATION_CLR
*ret
= buffer
;
107 TRACE("%#x, %s, %p, %p, %lx, %p.\n", flags
, wine_dbgstr_guid(clsid
), actctx
,
108 buffer
, buffer_len
, buffer_len_required
);
110 if (flags
& SXS_LOOKUP_CLR_GUID_USE_ACTCTX
)
112 if (!ActivateActCtx(actctx
, &cookie
))
114 WARN("Failed to activate context.\n");
119 if (flags
& SXS_LOOKUP_CLR_GUID_FIND_SURROGATE
)
121 if ((retval
= FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
, NULL
,
122 ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES
, clsid
, &guid_info
)))
124 flags
&= ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
;
128 if (!retval
&& (flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
))
130 if ((retval
= FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX
, NULL
,
131 ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION
, clsid
, &guid_info
)))
133 flags
&= ~SXS_LOOKUP_CLR_GUID_FIND_SURROGATE
;
139 SetLastError(ERROR_NOT_FOUND
);
143 retval
= QueryActCtxW(0, guid_info
.hActCtx
, &guid_info
.ulAssemblyRosterIndex
,
144 AssemblyDetailedInformationInActivationContext
, NULL
, 0, &bytes_assembly_info
);
145 if (!retval
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
150 assembly_info
= heap_alloc(bytes_assembly_info
);
151 if (!(retval
= QueryActCtxW(0, guid_info
.hActCtx
, &guid_info
.ulAssemblyRosterIndex
,
152 AssemblyDetailedInformationInActivationContext
, assembly_info
,
153 bytes_assembly_info
, &bytes_assembly_info
)))
158 if (flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
)
160 const struct comclassredirect_data
*redirect_data
= guid_info
.lpData
;
161 const struct clrclass_data
*class_data
;
163 class_data
= (void *)((char *)redirect_data
+ redirect_data
->clrdata_offset
);
164 ptr_name
= (char *)class_data
+ class_data
->name_offset
;
165 ptr_version
= (char *)class_data
+ class_data
->version_offset
;
166 len_name
= class_data
->name_len
+ sizeof(WCHAR
);
167 if (class_data
->version_len
)
168 len_version
= class_data
->version_len
+ sizeof(WCHAR
);
172 const struct clrsurrogate_data
*surrogate
= guid_info
.lpData
;
173 ptr_name
= (char *)surrogate
+ surrogate
->name_offset
;
174 ptr_version
= (char *)surrogate
+ surrogate
->version_offset
;
175 len_name
= surrogate
->name_len
+ sizeof(WCHAR
);
176 if (surrogate
->version_len
)
177 len_version
= surrogate
->version_len
+ sizeof(WCHAR
);
180 ptr_identity
= assembly_info
->lpAssemblyEncodedAssemblyIdentity
;
181 len_identity
= assembly_info
->ulEncodedAssemblyIdentityLength
+ sizeof(WCHAR
);
183 *buffer_len_required
= sizeof(*ret
) + len_identity
+ len_version
+ len_name
;
184 if (!buffer
|| buffer_len
< *buffer_len_required
)
186 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
191 ret
->cbSize
= sizeof(*ret
);
192 ret
->dwFlags
= flags
& SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS
? SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS
:
193 SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE
;
195 /* Copy strings into buffer */
196 ret_strings
= (char *)ret
+ sizeof(*ret
);
198 memcpy(ret_strings
, ptr_identity
, len_identity
);
199 ret
->pcwszAssemblyIdentity
= (WCHAR
*)ret_strings
;
200 ret_strings
+= len_identity
;
202 memcpy(ret_strings
, ptr_name
, len_name
);
203 ret
->pcwszTypeName
= (WCHAR
*)ret_strings
;
204 ret_strings
+= len_name
;
208 memcpy(ret_strings
, ptr_version
, len_version
);
209 ret
->pcwszRuntimeVersion
= (WCHAR
*)ret_strings
;
212 ret
->pcwszRuntimeVersion
= NULL
;
217 ReleaseActCtx(guid_info
.hActCtx
);
219 if (flags
& SXS_LOOKUP_CLR_GUID_USE_ACTCTX
)
220 DeactivateActCtx(0, cookie
);
222 heap_free(assembly_info
);