sxs: Implement surrogate data lookup in SxsLookupClrGuid().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
077e2a8e70
commit
fe2c271ecc
|
@ -60,6 +60,7 @@ typedef struct _SXS_GUID_INFORMATION_CLR
|
||||||
#define SXS_LOOKUP_CLR_GUID_USE_ACTCTX 0x00000001
|
#define SXS_LOOKUP_CLR_GUID_USE_ACTCTX 0x00000001
|
||||||
#define SXS_LOOKUP_CLR_GUID_FIND_SURROGATE 0x00010000
|
#define SXS_LOOKUP_CLR_GUID_FIND_SURROGATE 0x00010000
|
||||||
#define SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS 0x00020000
|
#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
|
struct comclassredirect_data
|
||||||
{
|
{
|
||||||
|
@ -96,27 +97,54 @@ struct clrclass_data
|
||||||
DWORD res2[2];
|
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,
|
BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buffer, SIZE_T buffer_len,
|
||||||
SIZE_T *buffer_len_required)
|
SIZE_T *buffer_len_required)
|
||||||
{
|
{
|
||||||
ACTCTX_SECTION_KEYED_DATA guid_info = { sizeof(ACTCTX_SECTION_KEYED_DATA) };
|
ACTCTX_SECTION_KEYED_DATA guid_info = { sizeof(ACTCTX_SECTION_KEYED_DATA) };
|
||||||
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *assembly_info;
|
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *assembly_info;
|
||||||
SIZE_T bytes_assembly_info;
|
SIZE_T bytes_assembly_info;
|
||||||
struct comclassredirect_data *redirect_data;
|
unsigned int len_version = 0, len_name, len_identity;
|
||||||
struct clrclass_data *class_data;
|
|
||||||
int len_version = 0, len_name, len_identity;
|
|
||||||
const void *ptr_name, *ptr_version, *ptr_identity;
|
const void *ptr_name, *ptr_version, *ptr_identity;
|
||||||
SXS_GUID_INFORMATION_CLR *ret = buffer;
|
SXS_GUID_INFORMATION_CLR *ret = buffer;
|
||||||
|
BOOL retval = FALSE;
|
||||||
char *ret_strings;
|
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);
|
buffer, buffer_len, buffer_len_required);
|
||||||
|
|
||||||
if (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_CLR_CLASS);
|
FIXME("Ignored flags: %x\n", flags & ~SXS_LOOKUP_CLR_GUID_FIND_ANY);
|
||||||
|
|
||||||
if (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
|
if (flags & SXS_LOOKUP_CLR_GUID_FIND_SURROGATE)
|
||||||
ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info))
|
{
|
||||||
|
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);
|
SetLastError(ERROR_NOT_FOUND);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -139,17 +167,30 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
redirect_data = guid_info.lpData;
|
if (flags & SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS)
|
||||||
class_data = (void *)((char*)redirect_data + redirect_data->clrdata_offset);
|
{
|
||||||
|
const struct comclassredirect_data *redirect_data = guid_info.lpData;
|
||||||
|
const struct clrclass_data *class_data;
|
||||||
|
|
||||||
ptr_identity = assembly_info->lpAssemblyEncodedAssemblyIdentity;
|
class_data = (void *)((char *)redirect_data + redirect_data->clrdata_offset);
|
||||||
ptr_name = (char *)class_data + class_data->name_offset;
|
ptr_name = (char *)class_data + class_data->name_offset;
|
||||||
ptr_version = (char *)class_data + class_data->version_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);
|
len_name = class_data->name_len + sizeof(WCHAR);
|
||||||
if (class_data->version_len > 0)
|
if (class_data->version_len)
|
||||||
len_version = class_data->version_len + sizeof(WCHAR);
|
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;
|
||||||
|
len_identity = assembly_info->ulEncodedAssemblyIdentityLength + sizeof(WCHAR);
|
||||||
|
|
||||||
*buffer_len_required = sizeof(SXS_GUID_INFORMATION_CLR) + len_identity + len_version + len_name;
|
*buffer_len_required = sizeof(SXS_GUID_INFORMATION_CLR) + len_identity + len_version + len_name;
|
||||||
if (!buffer || buffer_len < *buffer_len_required)
|
if (!buffer || buffer_len < *buffer_len_required)
|
||||||
|
@ -160,11 +201,12 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret->cbSize = sizeof(SXS_GUID_INFORMATION_CLR);
|
ret->cbSize = sizeof(*ret);
|
||||||
ret->dwFlags = SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS;
|
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 */
|
/* 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);
|
memcpy(ret_strings, ptr_identity, len_identity);
|
||||||
ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings;
|
ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings;
|
||||||
|
|
|
@ -11,6 +11,11 @@
|
||||||
name="DLL.Test"
|
name="DLL.Test"
|
||||||
runtimeVersion="v4.0.0.0">
|
runtimeVersion="v4.0.0.0">
|
||||||
</clrClass>
|
</clrClass>
|
||||||
|
<clrSurrogate
|
||||||
|
clsid="{2e106e50-e7a4-4489-8538-83643f100fdd}"
|
||||||
|
name="Surrogate.Test"
|
||||||
|
runtimeVersion="v4.0.0.1">
|
||||||
|
</clrSurrogate>
|
||||||
<file name="comtest.dll">
|
<file name="comtest.dll">
|
||||||
</file>
|
</file>
|
||||||
</assembly>
|
</assembly>
|
||||||
|
|
|
@ -33,3 +33,8 @@ interface ITest : IUnknown {
|
||||||
uuid(2e106e50-e7a4-4489-8538-83643f100fdc),
|
uuid(2e106e50-e7a4-4489-8538-83643f100fdc),
|
||||||
]
|
]
|
||||||
coclass Test { interface ITest; };
|
coclass Test { interface ITest; };
|
||||||
|
|
||||||
|
[
|
||||||
|
uuid(2e106e50-e7a4-4489-8538-83643f100fdd),
|
||||||
|
]
|
||||||
|
coclass SurrogateTest { interface ITest; };
|
||||||
|
|
|
@ -86,6 +86,10 @@ static void run_test(void)
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
SXS_GUID_INFORMATION_CLR *info;
|
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);
|
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(ret == FALSE, "Got %d\n", ret);
|
||||||
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Got %d\n", GetLastError());
|
||||||
|
@ -103,6 +107,29 @@ static void run_test(void)
|
||||||
wine_dbgstr_w(info->pcwszRuntimeVersion));
|
wine_dbgstr_w(info->pcwszRuntimeVersion));
|
||||||
|
|
||||||
heap_free(info);
|
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)
|
static void prepare_and_run_test(void)
|
||||||
|
@ -199,10 +226,16 @@ static void test_SxsLookupClrGuid(void)
|
||||||
SIZE_T buffer_size;
|
SIZE_T buffer_size;
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS, (GUID*)&CLSID_Test, NULL, NULL, 0, &buffer_size);
|
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(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||||
ok(GetLastError() == ERROR_NOT_FOUND, "Expected ERROR_NOT_FOUND, got %d\n", GetLastError());
|
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();
|
run_child_process();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue