https://git.reactos.org/?p=reactos.git;a=commitdiff;h=58895b70d0b0a266043f7…
commit 58895b70d0b0a266043f7fc9e8722cff4845abc0
Author: Amine Khaldi <amine.khaldi(a)reactos.org>
AuthorDate: Sat Nov 30 14:56:42 2019 +0100
Commit: Amine Khaldi <amine.khaldi(a)reactos.org>
CommitDate: Sat Nov 30 14:56:42 2019 +0100
[SXS] Sync with Wine Staging 4.18. CORE-16441
---
dll/win32/sxs/cache.c | 116 +++++++++++++++++-----------------
dll/win32/sxs/name.c | 34 +++++-----
dll/win32/sxs/precomp.h | 2 +-
dll/win32/sxs/sxs.c | 150 ++++++++++++++++++++++++++++++++++++++++++++
dll/win32/sxs/sxs.spec | 1 +
dll/win32/sxs/sxs_private.h | 4 +-
media/doc/README.WINE | 2 +-
7 files changed, 231 insertions(+), 78 deletions(-)
diff --git a/dll/win32/sxs/cache.c b/dll/win32/sxs/cache.c
index 3cc26f29e8c..361c05789fb 100644
--- a/dll/win32/sxs/cache.c
+++ b/dll/win32/sxs/cache.c
@@ -19,6 +19,9 @@
*/
#include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
#define COBJMACROS
#define INITGUID
@@ -31,7 +34,6 @@
#include "wine/debug.h"
#include "wine/list.h"
-#include "wine/unicode.h"
#include "sxs_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(sxs);
@@ -112,16 +114,15 @@ static WCHAR *build_assembly_name( const WCHAR *arch, const WCHAR
*name, const W
static const WCHAR fmtW[] =
{'%','s','_','%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
unsigned int buflen = ARRAY_SIZE(fmtW);
- WCHAR *ret, *p;
+ WCHAR *ret;
- buflen += strlenW( arch );
- buflen += strlenW( name );
- buflen += strlenW( token );
- buflen += strlenW( version );
+ buflen += lstrlenW( arch );
+ buflen += lstrlenW( name );
+ buflen += lstrlenW( token );
+ buflen += lstrlenW( version );
if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
- *len = sprintfW( ret, fmtW, arch, name, token, version );
- for (p = ret; *p; p++) *p = tolowerW( *p );
- return ret;
+ *len = swprintf( ret, fmtW, arch, name, token, version );
+ return _wcslwr( ret );
}
static WCHAR *build_manifest_path( const WCHAR *arch, const WCHAR *name, const WCHAR
*token,
@@ -140,7 +141,7 @@ static WCHAR *build_manifest_path( const WCHAR *arch, const WCHAR
*name, const W
HeapFree( GetProcessHeap(), 0, path );
return NULL;
}
- sprintfW( ret, fmtW, sxsdir, path );
+ swprintf( ret, fmtW, sxsdir, path );
HeapFree( GetProcessHeap(), 0, path );
return ret;
}
@@ -151,15 +152,14 @@ static WCHAR *build_policy_name( const WCHAR *arch, const WCHAR
*name, const WCH
static const WCHAR fmtW[] =
{'%','s','_','%','s','_','%','s','_','n','o','n','e','_','d','e','a','d','b','e','e','f',0};
unsigned int buflen = ARRAY_SIZE(fmtW);
- WCHAR *ret, *p;
+ WCHAR *ret;
- buflen += strlenW( arch );
- buflen += strlenW( name );
- buflen += strlenW( token );
+ buflen += lstrlenW( arch );
+ buflen += lstrlenW( name );
+ buflen += lstrlenW( token );
if (!(ret = HeapAlloc( GetProcessHeap(), 0, buflen * sizeof(WCHAR) ))) return NULL;
- *len = sprintfW( ret, fmtW, arch, name, token );
- for (p = ret; *p; p++) *p = tolowerW( *p );
- return ret;
+ *len = swprintf( ret, fmtW, arch, name, token );
+ return _wcslwr( ret );
}
static WCHAR *build_policy_path( const WCHAR *arch, const WCHAR *name, const WCHAR
*token,
@@ -173,13 +173,13 @@ static WCHAR *build_policy_path( const WCHAR *arch, const WCHAR
*name, const WCH
if (!(path = build_policy_name( arch, name, token, &len ))) return NULL;
len += ARRAY_SIZE(fmtW);
len += build_sxs_path( sxsdir );
- len += strlenW( version );
+ len += lstrlenW( version );
if (!(ret = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
{
HeapFree( GetProcessHeap(), 0, path );
return NULL;
}
- sprintfW( ret, fmtW, sxsdir, path, version );
+ swprintf( ret, fmtW, sxsdir, path, version );
HeapFree( GetProcessHeap(), 0, path );
return ret;
}
@@ -235,8 +235,8 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
}
cache_lock( cache );
- if (!strcmpW( type, win32W )) path = build_manifest_path( arch, name, token, version
);
- else if (!strcmpW( type, win32_policyW )) path = build_policy_path( arch, name,
token, version );
+ if (!wcscmp( type, win32W )) path = build_manifest_path( arch, name, token, version
);
+ else if (!wcscmp( type, win32_policyW )) path = build_policy_path( arch, name, token,
version );
else
{
hr = HRESULT_FROM_WIN32( ERROR_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE );
@@ -253,8 +253,8 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
info->dwAssemblyFlags = ASSEMBLYINFO_FLAG_INSTALLED;
TRACE("assembly is installed\n");
}
- if ((p = strrchrW( path, '\\' ))) *p = 0;
- len = strlenW( path ) + 1;
+ if ((p = wcsrchr( path, '\\' ))) *p = 0;
+ len = lstrlenW( path ) + 1;
if (info->pszCurrentAssemblyPathBuf)
{
if (info->cchBuf < len)
@@ -262,7 +262,7 @@ static HRESULT WINAPI cache_QueryAssemblyInfo(
info->cchBuf = len;
hr = HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
}
- else strcpyW( info->pszCurrentAssemblyPathBuf, path );
+ else lstrcpyW( info->pszCurrentAssemblyPathBuf, path );
}
done:
@@ -473,14 +473,14 @@ static HRESULT parse_assembly( IXMLDOMDocument *doc, struct assembly
**assembly
a->arch = get_attribute_value( attrs, architectureW );
a->token = get_attribute_value( attrs, tokenW );
- if (!a->type || (strcmpW( a->type, win32W ) && strcmpW( a->type,
win32_policyW )) ||
+ if (!a->type || (wcscmp( a->type, win32W ) && wcscmp( a->type,
win32_policyW )) ||
!a->name || !a->version || !a->arch || !a->token)
{
WARN("invalid win32 assembly\n");
hr = ERROR_SXS_MANIFEST_FORMAT_ERROR;
goto done;
}
- if (!strcmpW( a->type, win32W )) hr = parse_files( doc, a );
+ if (!wcscmp( a->type, win32W )) hr = parse_files( doc, a );
done:
if (attrs) IXMLDOMNamedNodeMap_Release( attrs );
@@ -502,21 +502,21 @@ static WCHAR *build_policy_filename( const WCHAR *arch, const WCHAR
*name, const
if (!(fullname = build_policy_name( arch, name, token, &len ))) return NULL;
len += build_sxs_path( sxsdir );
len += ARRAY_SIZE(policiesW) - 1;
- len += strlenW( version );
+ len += lstrlenW( version );
len += ARRAY_SIZE(suffixW) - 1;
if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
{
HeapFree( GetProcessHeap(), 0, fullname );
return NULL;
}
- strcpyW( ret, sxsdir );
- strcatW( ret, policiesW );
+ lstrcpyW( ret, sxsdir );
+ lstrcatW( ret, policiesW );
CreateDirectoryW( ret, NULL );
- strcatW( ret, name );
+ lstrcatW( ret, name );
CreateDirectoryW( ret, NULL );
- strcatW( ret, backslashW );
- strcatW( ret, version );
- strcatW( ret, suffixW );
+ lstrcatW( ret, backslashW );
+ lstrcatW( ret, version );
+ lstrcatW( ret, suffixW );
HeapFree( GetProcessHeap(), 0, fullname );
return ret;
@@ -549,16 +549,16 @@ static WCHAR *build_source_filename( const WCHAR *manifest, struct
file *file )
const WCHAR *p;
int len;
- p = strrchrW( manifest, '\\' );
- if (!p) p = strrchrW( manifest, '/' );
+ p = wcsrchr( manifest, '\\' );
+ if (!p) p = wcsrchr( manifest, '/' );
if (!p) return strdupW( manifest );
len = p - manifest + 1;
- if (!(src = HeapAlloc( GetProcessHeap(), 0, (len + strlenW( file->name ) + 1) *
sizeof(WCHAR) )))
+ if (!(src = HeapAlloc( GetProcessHeap(), 0, (len + lstrlenW( file->name ) + 1) *
sizeof(WCHAR) )))
return NULL;
memcpy( src, manifest, len * sizeof(WCHAR) );
- strcpyW( src + len, file->name );
+ lstrcpyW( src + len, file->name );
return src;
}
@@ -579,10 +579,10 @@ static WCHAR *build_manifest_filename( const WCHAR *arch, const
WCHAR *name, con
HeapFree( GetProcessHeap(), 0, fullname );
return NULL;
}
- strcpyW( ret, sxsdir );
- strcatW( ret, manifestsW );
- strcatW( ret, fullname );
- strcatW( ret, suffixW );
+ lstrcpyW( ret, sxsdir );
+ lstrcatW( ret, manifestsW );
+ lstrcatW( ret, fullname );
+ lstrcatW( ret, suffixW );
HeapFree( GetProcessHeap(), 0, fullname );
return ret;
@@ -639,19 +639,19 @@ static HRESULT install_assembly( const WCHAR *manifest, struct
assembly *assembl
{
if (!(src = build_source_filename( manifest, file ))) goto done;
- len = len_sxsdir + len_name + strlenW( file->name );
+ len = len_sxsdir + len_name + lstrlenW( file->name );
if (!(dst = HeapAlloc( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR) )))
{
HeapFree( GetProcessHeap(), 0, src );
goto done;
}
- strcpyW( dst, sxsdir );
- strcatW( dst, name );
+ lstrcpyW( dst, sxsdir );
+ lstrcatW( dst, name );
CreateDirectoryW( dst, NULL );
- strcatW( dst, backslashW );
- strcatW( dst, file->name );
- for (p = dst; *p; p++) *p = tolowerW( *p );
+ lstrcatW( dst, backslashW );
+ lstrcatW( dst, file->name );
+ for (p = dst; *p; p++) *p = towlower( *p );
ret = CopyFileW( src, dst, FALSE );
HeapFree( GetProcessHeap(), 0, src );
@@ -695,7 +695,7 @@ static HRESULT WINAPI cache_InstallAssembly(
/* FIXME: verify name attributes */
- if (!strcmpW( assembly->type, win32_policyW ))
+ if (!wcscmp( assembly->type, win32_policyW ))
hr = install_policy( path, assembly );
else
hr = install_assembly( path, assembly );
@@ -720,16 +720,16 @@ static HRESULT uninstall_assembly( struct assembly *assembly )
if (!name) return E_OUTOFMEMORY;
if (!(dirname = HeapAlloc( GetProcessHeap(), 0, (len_sxsdir + len_name + 1) *
sizeof(WCHAR) )))
goto done;
- strcpyW( dirname, sxsdir );
- strcpyW( dirname + len_sxsdir, name );
+ lstrcpyW( dirname, sxsdir );
+ lstrcpyW( dirname + len_sxsdir, name );
LIST_FOR_EACH_ENTRY( file, &assembly->files, struct file, entry )
{
- len = len_sxsdir + len_name + 1 + strlenW( file->name );
+ len = len_sxsdir + len_name + 1 + lstrlenW( file->name );
if (!(filename = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
goto done;
- strcpyW( filename, dirname );
- strcatW( filename, backslashW );
- strcatW( filename, file->name );
+ lstrcpyW( filename, dirname );
+ lstrcatW( filename, backslashW );
+ lstrcatW( filename, file->name );
if (!DeleteFileW( filename )) WARN( "failed to delete file %u\n",
GetLastError() );
HeapFree( GetProcessHeap(), 0, filename );
@@ -782,8 +782,8 @@ static HRESULT WINAPI cache_UninstallAssembly(
hr = E_INVALIDARG;
goto done;
}
- if (!strcmpW( type, win32W )) path = build_manifest_filename( arch, name, token,
version );
- else if (!strcmpW( type, win32_policyW )) path = build_policy_filename( arch, name,
token, version );
+ if (!wcscmp( type, win32W )) path = build_manifest_filename( arch, name, token,
version );
+ else if (!wcscmp( type, win32_policyW )) path = build_policy_filename( arch, name,
token, version );
else
{
hr = E_INVALIDARG;
@@ -798,12 +798,12 @@ static HRESULT WINAPI cache_UninstallAssembly(
if ((hr = parse_assembly( doc, &assembly )) != S_OK) goto done;
if (!DeleteFileW( path )) WARN( "unable to remove manifest file %u\n",
GetLastError() );
- else if ((p = strrchrW( path, '\\' )))
+ else if ((p = wcsrchr( path, '\\' )))
{
*p = 0;
RemoveDirectoryW( path );
}
- if (!strcmpW( assembly->type, win32W )) hr = uninstall_assembly( assembly );
+ if (!wcscmp( assembly->type, win32W )) hr = uninstall_assembly( assembly );
done:
if (name_obj) IAssemblyName_Release( name_obj );
diff --git a/dll/win32/sxs/name.c b/dll/win32/sxs/name.c
index e1090140b26..a4634a06b8a 100644
--- a/dll/win32/sxs/name.c
+++ b/dll/win32/sxs/name.c
@@ -19,6 +19,9 @@
*/
#include <stdarg.h>
+#ifdef __REACTOS__
+#include <wchar.h>
+#endif
#define COBJMACROS
@@ -28,7 +31,6 @@
#include "winsxs.h"
#include "wine/debug.h"
-#include "wine/unicode.h"
#include "sxs_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(sxs);
@@ -143,22 +145,22 @@ static HRESULT WINAPI name_GetDisplayName(
if (!buflen || flags) return E_INVALIDARG;
- len = strlenW( name->name ) + 1;
- if (name->arch) len += strlenW( archW ) + strlenW( name->arch ) + 4;
- if (name->token) len += strlenW( tokenW ) + strlenW( name->token ) + 4;
- if (name->type) len += strlenW( typeW ) + strlenW( name->type ) + 4;
- if (name->version) len += strlenW( versionW ) + strlenW( version ) + 4;
+ len = lstrlenW( name->name ) + 1;
+ if (name->arch) len += lstrlenW( archW ) + lstrlenW( name->arch ) + 4;
+ if (name->token) len += lstrlenW( tokenW ) + lstrlenW( name->token ) + 4;
+ if (name->type) len += lstrlenW( typeW ) + lstrlenW( name->type ) + 4;
+ if (name->version) len += lstrlenW( versionW ) + lstrlenW( version ) + 4;
if (len > *buflen)
{
*buflen = len;
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
}
- strcpyW( buffer, name->name );
- len = strlenW( buffer );
- if (name->arch) len += sprintfW( buffer + len, fmtW, archW, name->arch );
- if (name->token) len += sprintfW( buffer + len, fmtW, tokenW, name->token );
- if (name->type) len += sprintfW( buffer + len, fmtW, typeW, name->type );
- if (name->version) len += sprintfW( buffer + len, fmtW, versionW, name->version
);
+ lstrcpyW( buffer, name->name );
+ len = lstrlenW( buffer );
+ if (name->arch) len += swprintf( buffer + len, fmtW, archW, name->arch );
+ if (name->token) len += swprintf( buffer + len, fmtW, tokenW, name->token );
+ if (name->type) len += swprintf( buffer + len, fmtW, typeW, name->type );
+ if (name->version) len += swprintf( buffer + len, fmtW, versionW, name->version
);
return S_OK;
}
@@ -211,13 +213,13 @@ static HRESULT WINAPI name_GetName(
if (!buflen || !buffer) return E_INVALIDARG;
name = get_name_attribute( iface, NAME_ATTR_ID_NAME );
- len = strlenW( name ) + 1;
+ len = lstrlenW( name ) + 1;
if (len > *buflen)
{
*buflen = len;
return HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER );
}
- strcpyW( buffer, name );
+ lstrcpyW( buffer, name );
*buflen = len + 3;
return S_OK;
}
@@ -232,9 +234,9 @@ static HRESULT parse_version( WCHAR *version, DWORD *high, DWORD *low
)
for (i = 0, p = version; i < 4; i++)
{
if (!*p) break;
- q = strchrW( p, '.' );
+ q = wcschr( p, '.' );
if (q) *q = 0;
- ver[i] = atolW( p );
+ ver[i] = wcstol( p, NULL, 10 );
if (!q && i < 3) break;
p = q + 1;
}
diff --git a/dll/win32/sxs/precomp.h b/dll/win32/sxs/precomp.h
index 52a823b3d20..fad16879610 100644
--- a/dll/win32/sxs/precomp.h
+++ b/dll/win32/sxs/precomp.h
@@ -3,6 +3,7 @@
#define _SXS_PRECOMP_H_
#include <stdarg.h>
+#include <wchar.h>
#define WIN32_NO_STATUS
#define _INC_WINDOWS
@@ -16,7 +17,6 @@
#include <winsxs.h>
#include <wine/debug.h>
-#include <wine/unicode.h>
#include "sxs_private.h"
diff --git a/dll/win32/sxs/sxs.c b/dll/win32/sxs/sxs.c
index 06e6672dbf7..5b2db1d997c 100644
--- a/dll/win32/sxs/sxs.c
+++ b/dll/win32/sxs/sxs.c
@@ -23,6 +23,10 @@
#include "windef.h"
#include "winbase.h"
+#include "wine/heap.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(sxs);
/***********************************************************************
* DllMain (SXS.@)
@@ -40,3 +44,149 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID
lpvReserved)
}
return TRUE;
}
+
+typedef struct _SXS_GUID_INFORMATION_CLR
+{
+ DWORD cbSize;
+ DWORD dwFlags;
+ PCWSTR pcwszRuntimeVersion;
+ PCWSTR pcwszTypeName;
+ PCWSTR pcwszAssemblyIdentity;
+} SXS_GUID_INFORMATION_CLR, *PSXS_GUID_INFORMATION_CLR;
+
+#define SXS_GUID_INFORMATION_CLR_FLAG_IS_SURROGATE 0x1
+#define SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS 0x2
+
+#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
+
+struct comclassredirect_data
+{
+ ULONG size;
+ BYTE res;
+ BYTE miscmask;
+ BYTE res1[2];
+ DWORD model;
+ GUID clsid;
+ GUID alias;
+ GUID clsid2;
+ GUID tlbid;
+ ULONG name_len;
+ ULONG name_offset;
+ ULONG progid_len;
+ ULONG progid_offset;
+ ULONG clrdata_len;
+ ULONG clrdata_offset;
+ DWORD miscstatus;
+ DWORD miscstatuscontent;
+ DWORD miscstatusthumbnail;
+ DWORD miscstatusicon;
+ DWORD miscstatusdocprint;
+};
+
+struct clrclass_data
+{
+ ULONG size;
+ DWORD res[2];
+ ULONG module_len;
+ ULONG module_offset;
+ ULONG name_len;
+ ULONG name_offset;
+ ULONG version_len;
+ ULONG version_offset;
+ DWORD res2[2];
+};
+
+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;
+ const void *ptr_name, *ptr_version, *ptr_identity;
+ SXS_GUID_INFORMATION_CLR *ret = buffer;
+ char *ret_strings;
+
+ TRACE("(%x, %s, %p, %p, %08lx, %p): stub\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 (!FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, 0,
+ ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid,
&guid_info))
+ {
+ SetLastError(ERROR_NOT_FOUND);
+ return FALSE;
+ }
+
+ QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex,
+ AssemblyDetailedInformationInActivationContext, NULL, 0,
&bytes_assembly_info);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ {
+ ReleaseActCtx(guid_info.hActCtx);
+ return FALSE;
+ }
+ assembly_info = heap_alloc(bytes_assembly_info);
+ if(!QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex,
+ AssemblyDetailedInformationInActivationContext, assembly_info,
+ bytes_assembly_info, &bytes_assembly_info))
+ {
+ heap_free(assembly_info);
+ ReleaseActCtx(guid_info.hActCtx);
+ return FALSE;
+ }
+
+ redirect_data = guid_info.lpData;
+ class_data = (void *)((char*)redirect_data + redirect_data->clrdata_offset);
+
+ 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)
+ {
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ heap_free(assembly_info);
+ ReleaseActCtx(guid_info.hActCtx);
+ return FALSE;
+ }
+
+ ret->cbSize = sizeof(SXS_GUID_INFORMATION_CLR);
+ ret->dwFlags = SXS_GUID_INFORMATION_CLR_FLAG_IS_CLASS;
+
+ /* Copy strings into buffer */
+ ret_strings = (char *)ret + sizeof(SXS_GUID_INFORMATION_CLR);
+
+ memcpy(ret_strings, ptr_identity, len_identity);
+ 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_version > 0)
+ {
+ memcpy(ret_strings, ptr_version, len_version);
+ ret->pcwszRuntimeVersion = (WCHAR *)ret_strings;
+ }
+ else
+ ret->pcwszRuntimeVersion = NULL;
+
+ SetLastError(0);
+
+ ReleaseActCtx(guid_info.hActCtx);
+ heap_free(assembly_info);
+ return TRUE;
+}
diff --git a/dll/win32/sxs/sxs.spec b/dll/win32/sxs/sxs.spec
index 2a273134279..138d68f7d73 100644
--- a/dll/win32/sxs/sxs.spec
+++ b/dll/win32/sxs/sxs.spec
@@ -1,2 +1,3 @@
@ stdcall CreateAssemblyCache(ptr long)
@ stdcall CreateAssemblyNameObject(ptr wstr long ptr)
+@ stdcall SxsLookupClrGuid(long ptr ptr ptr long ptr)
diff --git a/dll/win32/sxs/sxs_private.h b/dll/win32/sxs/sxs_private.h
index 1ceab265e33..006eb67f90d 100644
--- a/dll/win32/sxs/sxs_private.h
+++ b/dll/win32/sxs/sxs_private.h
@@ -34,7 +34,7 @@ static inline WCHAR *strdupW( const WCHAR *src )
WCHAR *dst;
if (!src) return NULL;
- dst = HeapAlloc( GetProcessHeap(), 0, (strlenW( src ) + 1) * sizeof(WCHAR) );
- if (dst) strcpyW( dst, src );
+ dst = HeapAlloc( GetProcessHeap(), 0, (lstrlenW( src ) + 1) * sizeof(WCHAR) );
+ if (dst) lstrcpyW( dst, src );
return dst;
}
diff --git a/media/doc/README.WINE b/media/doc/README.WINE
index 623e539443d..a5878eb06ef 100644
--- a/media/doc/README.WINE
+++ b/media/doc/README.WINE
@@ -182,7 +182,7 @@ dll/win32/softpub # Synced to WineStaging-2.9
dll/win32/stdole2.tlb # Synced to WineStaging-3.3
dll/win32/stdole32.tlb # Synced to WineStaging-3.3
dll/win32/sti # Synced to WineStaging-4.18
-dll/win32/sxs # Synced to WineStaging-4.0
+dll/win32/sxs # Synced to WineStaging-4.18
dll/win32/t2embed # Synced to WineStaging-4.0
dll/win32/tapi32 # Synced to WineStaging-3.3
dll/win32/traffic # Synced to WineStaging-3.3