[PATCH 2/3] sxs: Implement surrogate data lookup in SxsLookupClrGuid().
Nikolay Sivov
nsivov at codeweavers.com
Tue Jul 21 07:03:28 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/sxs/sxs.c | 80 ++++++++++++++++++++++-------
dlls/sxs/tests/comtest_dll.manifest | 5 ++
dlls/sxs/tests/interfaces.idl | 5 ++
dlls/sxs/tests/sxs.c | 33 ++++++++++++
4 files changed, 104 insertions(+), 19 deletions(-)
diff --git a/dlls/sxs/sxs.c b/dlls/sxs/sxs.c
index 0b59eb5d2e9..92ba18ab0ea 100644
--- a/dlls/sxs/sxs.c
+++ b/dlls/sxs/sxs.c
@@ -60,6 +60,7 @@ typedef struct _SXS_GUID_INFORMATION_CLR
#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
+#define SXS_LOOKUP_CLR_GUID_FIND_ANY (SXS_LOOKUP_CLR_GUID_FIND_SURROGATE | SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
struct comclassredirect_data
{
@@ -96,27 +97,54 @@ struct clrclass_data
DWORD res2[2];
};
+struct clrsurrogate_data
+{
+ ULONG size;
+ DWORD res;
+ GUID clsid;
+ ULONG version_offset;
+ ULONG version_len;
+ ULONG name_offset;
+ ULONG name_len;
+};
+
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;
+ unsigned int len_version = 0, len_name, len_identity;
const void *ptr_name, *ptr_version, *ptr_identity;
SXS_GUID_INFORMATION_CLR *ret = buffer;
+ BOOL retval = FALSE;
char *ret_strings;
- TRACE("(%x, %s, %p, %p, %08lx, %p): stub\n", flags, wine_dbgstr_guid(clsid), actctx,
+ TRACE("%#x, %s, %p, %p, %lx, %p.\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 (flags & ~SXS_LOOKUP_CLR_GUID_FIND_ANY)
+ FIXME("Ignored flags: %x\n", flags & ~SXS_LOOKUP_CLR_GUID_FIND_ANY);
- if (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
- ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info))
+ if (flags & SXS_LOOKUP_CLR_GUID_FIND_SURROGATE)
+ {
+ if ((retval = FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
+ ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, clsid, &guid_info)))
+ {
+ flags &= ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS;
+ }
+ }
+
+ if (!retval && (flags & SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS))
+ {
+ if ((retval = FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
+ ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info)))
+ {
+ flags &= ~SXS_LOOKUP_CLR_GUID_FIND_SURROGATE;
+ }
+ }
+
+ if (!retval)
{
SetLastError(ERROR_NOT_FOUND);
return FALSE;
@@ -139,17 +167,30 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
return FALSE;
}
- redirect_data = guid_info.lpData;
- class_data = (void *)((char*)redirect_data + redirect_data->clrdata_offset);
+ if (flags & SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
+ {
+ const struct comclassredirect_data *redirect_data = guid_info.lpData;
+ const struct clrclass_data *class_data;
+
+ class_data = (void *)((char *)redirect_data + redirect_data->clrdata_offset);
+ ptr_name = (char *)class_data + class_data->name_offset;
+ ptr_version = (char *)class_data + class_data->version_offset;
+ len_name = class_data->name_len + sizeof(WCHAR);
+ if (class_data->version_len)
+ len_version = class_data->version_len + sizeof(WCHAR);
+ }
+ else
+ {
+ const struct clrsurrogate_data *surrogate = guid_info.lpData;
+ ptr_name = (char *)surrogate + surrogate->name_offset;
+ ptr_version = (char *)surrogate + surrogate->version_offset;
+ len_name = surrogate->name_len + sizeof(WCHAR);
+ if (surrogate->version_len)
+ len_version = surrogate->version_len + sizeof(WCHAR);
+ }
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)
@@ -160,11 +201,12 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
return FALSE;
}
- ret->cbSize = sizeof(SXS_GUID_INFORMATION_CLR);
- ret->dwFlags = SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS;
+ ret->cbSize = sizeof(*ret);
+ ret->dwFlags = flags & SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS ? SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS :
+ SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE;
/* Copy strings into buffer */
- ret_strings = (char *)ret + sizeof(SXS_GUID_INFORMATION_CLR);
+ ret_strings = (char *)ret + sizeof(*ret);
memcpy(ret_strings, ptr_identity, len_identity);
ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings;
diff --git a/dlls/sxs/tests/comtest_dll.manifest b/dlls/sxs/tests/comtest_dll.manifest
index ef6924de9e8..b3273457edf 100644
--- a/dlls/sxs/tests/comtest_dll.manifest
+++ b/dlls/sxs/tests/comtest_dll.manifest
@@ -11,6 +11,11 @@
name="DLL.Test"
runtimeVersion="v4.0.0.0">
</clrClass>
+ <clrSurrogate
+ clsid="{2e106e50-e7a4-4489-8538-83643f100fdd}"
+ name="Surrogate.Test"
+ runtimeVersion="v4.0.0.1">
+ </clrSurrogate>
<file name="comtest.dll">
</file>
</assembly>
diff --git a/dlls/sxs/tests/interfaces.idl b/dlls/sxs/tests/interfaces.idl
index 6f8ac615bf2..f34660db75c 100644
--- a/dlls/sxs/tests/interfaces.idl
+++ b/dlls/sxs/tests/interfaces.idl
@@ -33,3 +33,8 @@ interface ITest : IUnknown {
uuid(2e106e50-e7a4-4489-8538-83643f100fdc),
]
coclass Test { interface ITest; };
+
+[
+ uuid(2e106e50-e7a4-4489-8538-83643f100fdd),
+]
+coclass SurrogateTest { interface ITest; };
diff --git a/dlls/sxs/tests/sxs.c b/dlls/sxs/tests/sxs.c
index 4215c5045bd..9887871422a 100644
--- a/dlls/sxs/tests/sxs.c
+++ b/dlls/sxs/tests/sxs.c
@@ -86,6 +86,10 @@ static void run_test(void)
BOOL ret;
SXS_GUID_INFORMATION_CLR *info;
+ ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_ANY, (GUID*)&CLSID_Test, NULL, NULL, 0, &buffer_size);
+ ok(!ret, "Unexpected return value %d.\n", ret);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
+
ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS, (GUID*)&CLSID_Test, NULL, NULL, 0, &buffer_size);
ok(ret == FALSE, "Got %d\n", ret);
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
@@ -103,6 +107,29 @@ static void run_test(void)
wine_dbgstr_w(info->pcwszRuntimeVersion));
heap_free(info);
+
+ ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_SURROGATE, (GUID *)&CLSID_SurrogateTest, NULL, NULL, 0, &buffer_size);
+ ok(!ret, "Unexpected return value %d.\n", ret);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
+
+ info = heap_alloc(buffer_size);
+ ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_SURROGATE, (GUID *)&CLSID_SurrogateTest, NULL, info,
+ buffer_size, &buffer_size);
+ ok(ret, "Unexpected return value %d.\n", ret);
+ ok(GetLastError() == 0, "Got %d\n", GetLastError());
+
+ ok(info->dwFlags == SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE, "Unexpected flags %#x.\n", info->dwFlags);
+ ok(!lstrcmpW(info->pcwszTypeName, L"Surrogate.Test"), "Unexpected typename %s.\n", wine_dbgstr_w(info->pcwszTypeName));
+ ok(!lstrcmpW(info->pcwszAssemblyIdentity, L"comtest,type=\"win32\",version=\"1.0.0.0\""),
+ "Unexpected assembly identity %s.\n", wine_dbgstr_w(info->pcwszAssemblyIdentity));
+ ok(!lstrcmpW(info->pcwszRuntimeVersion, L"v4.0.0.1"), "Unexpected runtime version %s.\n",
+ wine_dbgstr_w(info->pcwszRuntimeVersion));
+
+ heap_free(info);
+
+ ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_ANY, (GUID *)&CLSID_SurrogateTest, NULL, NULL, 0, &buffer_size);
+ ok(!ret, "Unexpected return value %d.\n", ret);
+ ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
}
static void prepare_and_run_test(void)
@@ -199,10 +226,16 @@ static void test_SxsLookupClrGuid(void)
SIZE_T buffer_size;
BOOL ret;
+ SetLastError(0xdeadbeef);
ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS, (GUID*)&CLSID_Test, NULL, NULL, 0, &buffer_size);
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
ok(GetLastError() == ERROR_NOT_FOUND, "Expected ERROR_NOT_FOUND, got %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_SURROGATE, (GUID *)&CLSID_Test, NULL, NULL, 0, &buffer_size);
+ ok(!ret, "Unexpected return value %d.\n", ret);
+ ok(GetLastError() == ERROR_NOT_FOUND, "Expected ERROR_NOT_FOUND, got %d\n", GetLastError());
+
run_child_process();
}
--
2.27.0
More information about the wine-devel
mailing list