The `redirect_data->clrdata_len` [is unset in /dlls/ntdll/actctx.c#L4411-4412](https://gitlab.winehq.org/wine/wine/-/blob/master/dlls/ntdll/actctx.c?ref_ty...) when using registration-free COM in C# NET code.
Program.cs
```C# //...
Guid guid = Guid.Parse("COM clsid"); Type type = Type.GetTypeFromCLSID(guid, true); var instance = Activator.CreateInstance(type)); //...
```
App.manifest
```xml <assembly> <file name="ExampleCOM.dll"> <comClass description="ExampleCOM" progid="ExampleCOM" clsid="{COM clsid}" threadingModel="Free"/> </file> </assembly> ```
The above C# code gets this error on its second line.
```Shell System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. ```
This is because `len_name` is uninitialized when calling `memcpy(ret_strings, ptr_name, len_name);` in `SxsLookupClrGuid`, which is fixed in this MR.
-- v5: change for triggering the pipeline to run
From: Hans Chen hxchennz@gmail.com
--- dlls/sxs/sxs.c | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/dlls/sxs/sxs.c b/dlls/sxs/sxs.c index 150a49a322f..2b89bf369f0 100644 --- a/dlls/sxs/sxs.c +++ b/dlls/sxs/sxs.c @@ -97,7 +97,7 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff ACTCTX_SECTION_KEYED_DATA guid_info = { sizeof(ACTCTX_SECTION_KEYED_DATA) }; ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *assembly_info = NULL; SIZE_T bytes_assembly_info; - unsigned int len_version = 0, len_name, len_identity; + unsigned int len_version = 0, len_name = 0, len_identity = 0; const void *ptr_name, *ptr_version, *ptr_identity; SXS_GUID_INFORMATION_CLR *ret = buffer; BOOL retval = FALSE; @@ -160,12 +160,15 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff 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); + if(redirect_data->clrdata_len) + { + 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 { @@ -199,10 +202,15 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff ret->pcwszAssemblyIdentity = (WCHAR *)ret_strings; ret_strings += len_identity;
- memcpy(ret_strings, ptr_name, len_name); - ret->pcwszTypeName = (WCHAR *)ret_strings; - ret_strings += len_name; - + if(len_name > 0) + { + memcpy(ret_strings, ptr_name, len_name); + ret->pcwszTypeName = (WCHAR *)ret_strings; + ret_strings += len_name; + } + else + ret->pcwszTypeName = NULL; + if (len_version > 0) { memcpy(ret_strings, ptr_version, len_version);
From: Hans Chen hxchennz@gmail.com
--- dlls/sxs/tests/comtest_exe.manifest | 7 +++++++ dlls/sxs/tests/interfaces.idl | 5 +++++ dlls/sxs/tests/sxs.c | 12 ++++++++++++ 3 files changed, 24 insertions(+)
diff --git a/dlls/sxs/tests/comtest_exe.manifest b/dlls/sxs/tests/comtest_exe.manifest index bc9ce4c0457..362b408da07 100644 --- a/dlls/sxs/tests/comtest_exe.manifest +++ b/dlls/sxs/tests/comtest_exe.manifest @@ -8,4 +8,11 @@ type="win32"/> </dependentAssembly> </dependency> + <file name="comtest.dll"> + <comClass + clsid="{2e106e50-e7a4-4489-8538-83643f100fde}" + progid="comtest.COMClass" + threadingModel="Free" + /> + </file> </assembly> diff --git a/dlls/sxs/tests/interfaces.idl b/dlls/sxs/tests/interfaces.idl index f34660db75c..bc143fe0deb 100644 --- a/dlls/sxs/tests/interfaces.idl +++ b/dlls/sxs/tests/interfaces.idl @@ -38,3 +38,8 @@ coclass Test { interface ITest; }; uuid(2e106e50-e7a4-4489-8538-83643f100fdd), ] coclass SurrogateTest { interface ITest; }; + +[ + uuid(2e106e50-e7a4-4489-8538-83643f100fde), +] +coclass COMClassTest { interface ITest; }; diff --git a/dlls/sxs/tests/sxs.c b/dlls/sxs/tests/sxs.c index 9bcb85c69aa..6dfc2fb6aab 100644 --- a/dlls/sxs/tests/sxs.c +++ b/dlls/sxs/tests/sxs.c @@ -147,6 +147,18 @@ static void run_test(void) 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 %ld\n", GetLastError()); + + info = malloc(buffer_size); + SetLastError(0xdeadbeef); + ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_CLR_ANY, (GUID*)&CLSID_COMClassTest, NULL, info, buffer_size, &buffer_size); + ok(ret == TRUE, "Got %d\n", ret); + ok(GetLastError() == 0, "Got %ld\n", GetLastError()); + ok(info->dwFlags == SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS, "Got %ld\n", info->dwFlags); + ok(!lstrcmpW(info->pcwszTypeName, NULL), "Unexpected typename %s.\n", wine_dbgstr_w(info->pcwszTypeName)); + ok(!lstrcmpW(info->pcwszRuntimeVersion, NULL), "Unexpected runtime version %s.\n", + wine_dbgstr_w(info->pcwszRuntimeVersion)); + + free(info); }
static void prepare_and_run_test(void)
From: Hans Chen hxchennz@gmail.com
--- dlls/sxs/tests/sxs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/sxs/tests/sxs.c b/dlls/sxs/tests/sxs.c index 6dfc2fb6aab..30883e8506a 100644 --- a/dlls/sxs/tests/sxs.c +++ b/dlls/sxs/tests/sxs.c @@ -150,7 +150,7 @@ static void run_test(void)
info = malloc(buffer_size); SetLastError(0xdeadbeef); - ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_CLR_ANY, (GUID*)&CLSID_COMClassTest, NULL, info, buffer_size, &buffer_size); + ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_ANY, (GUID*)&CLSID_COMClassTest, NULL, info, buffer_size, &buffer_size); ok(ret == TRUE, "Got %d\n", ret); ok(GetLastError() == 0, "Got %ld\n", GetLastError()); ok(info->dwFlags == SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS, "Got %ld\n", info->dwFlags);
From: Hans Chen hxchennz@gmail.com
--- dlls/sxs/tests/sxs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/sxs/tests/sxs.c b/dlls/sxs/tests/sxs.c index 30883e8506a..485e9ef574b 100644 --- a/dlls/sxs/tests/sxs.c +++ b/dlls/sxs/tests/sxs.c @@ -153,6 +153,7 @@ static void run_test(void) ret = SxsLookupClrGuid(SXS_LOOKUP_CLR_GUID_FIND_ANY, (GUID*)&CLSID_COMClassTest, NULL, info, buffer_size, &buffer_size); ok(ret == TRUE, "Got %d\n", ret); ok(GetLastError() == 0, "Got %ld\n", GetLastError()); + ok(info->dwFlags == SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS, "Got %ld\n", info->dwFlags); ok(!lstrcmpW(info->pcwszTypeName, NULL), "Unexpected typename %s.\n", wine_dbgstr_w(info->pcwszTypeName)); ok(!lstrcmpW(info->pcwszRuntimeVersion, NULL), "Unexpected runtime version %s.\n",