From: Dmitry Timoshkov <dmitry@baikal.ru> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58578 Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> --- dlls/msi/assembly.c | 96 ++++++++++++++++++++++++++++++++++++++++++++- dlls/msi/msi.c | 8 ---- include/msi.h | 3 ++ 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/dlls/msi/assembly.c b/dlls/msi/assembly.c index a751ded9b45..ff0e8b44f72 100644 --- a/dlls/msi/assembly.c +++ b/dlls/msi/assembly.c @@ -251,11 +251,10 @@ WCHAR *msi_get_assembly_path( const WCHAR *displayname ) return info.pszCurrentAssemblyPathBuf; } -IAssemblyEnum *msi_create_assembly_enum( const WCHAR *displayname ) +static IAssemblyName *msi_create_assembly_name( const WCHAR *displayname ) { HRESULT hr; IAssemblyName *name; - IAssemblyEnum *ret; WCHAR *str; DWORD len = 0; @@ -284,6 +283,18 @@ IAssemblyEnum *msi_create_assembly_enum( const WCHAR *displayname ) free( str ); if (FAILED( hr )) return NULL; + return name; +} + +IAssemblyEnum *msi_create_assembly_enum( const WCHAR *displayname ) +{ + HRESULT hr; + IAssemblyName *name; + IAssemblyEnum *ret; + + if (!(name = msi_create_assembly_name( displayname ))) + return NULL; + hr = pCreateAssemblyEnum( &ret, NULL, name, ASM_CACHE_GAC, NULL ); IAssemblyName_Release( name ); if (FAILED( hr )) return NULL; @@ -710,3 +721,84 @@ UINT ACTION_MsiUnpublishAssemblies( MSIPACKAGE *package ) } return ERROR_SUCCESS; } + +UINT WINAPI MsiProvideAssemblyW( const WCHAR *assembly, const WCHAR *application, DWORD mode, + DWORD info, WCHAR *path, DWORD *len ) +{ + UINT res; + IAssemblyName *asm_name; + BOOL win32 = info & MSIASSEMBLYINFO_WIN32ASSEMBLY, found = FALSE; + DWORD idx; + HKEY hkey; + + TRACE( "%s, %s, %#lx, %#lx, %p, %p\n", debugstr_w(assembly), debugstr_w(application), mode, info, path, len ); + + if (!assembly || !len) + return ERROR_INVALID_PARAMETER; + + if (application) + FIXME( "application context %s ignored\n", debugstr_w(application) ); + + if (!(asm_name = msi_create_assembly_name( assembly ))) + return ERROR_INVALID_PARAMETER; + + if ((res = open_global_assembly_key( MSIINSTALLCONTEXT_MACHINE /* FIXME */, win32, &hkey ))) + { + WARN( "failed to open global assembly key %u\n", res ); + goto done; + } + + idx = 0; + for (;;) + { + WCHAR *name; + WCHAR val[20 + MAX_FEATURE_CHARS + 1 + 20 + 2]; /* base85_GUID + feaure + '>' + base85_GUID + 2 terminating NULLs */ + DWORD name_sz, val_sz, type; + IAssemblyName *asm_name_enum; + + name_sz = 1024; + name = malloc( name_sz ); + val_sz = ARRAY_SIZE( val ); + while ((res = RegEnumValueW( hkey, idx, name, &name_sz, NULL, &type, (BYTE *)val, &val_sz )) == ERROR_MORE_DATA) + { + if (val_sz > ARRAY_SIZE( val )) + { + FIXME( "value storage overflow (need %lu bytes)\n", val_sz ); + break; + } + name = realloc( name, name_sz ); + } + + if (res != ERROR_SUCCESS || type != REG_MULTI_SZ) + { + free( name ); + break; + } + + if ((asm_name_enum = msi_create_assembly_name( name ))) + { + if (IAssemblyName_IsEqual( asm_name, asm_name_enum, ASM_CMPF_IL_ALL ) == S_OK) + { + WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1]; + DWORD size; + + found = TRUE; + + if (!(res = MsiDecomposeDescriptorW( val, product, feature, component, &size ))) + res = MsiProvideComponentW( product, feature, component, INSTALLMODE_NODETECTION /* FIXME */, path, len ); + } + + IAssemblyName_Release( asm_name_enum ); + } + + free( name ); + if (found) break; + idx++; + } + + RegCloseKey( hkey ); + +done: + IAssemblyName_Release( asm_name ); + return found ? res : ERROR_UNKNOWN_COMPONENT; +} diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 164d798c81f..0c73bf5920f 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -2486,14 +2486,6 @@ UINT WINAPI MsiProvideAssemblyA( const char *szAssemblyName, const char *szAppCo return ERROR_CALL_NOT_IMPLEMENTED; } -UINT WINAPI MsiProvideAssemblyW( const WCHAR *szAssemblyName, const WCHAR *szAppContext, DWORD dwInstallMode, - DWORD dwAssemblyInfo, WCHAR *lpPathBuf, DWORD *pcchPathBuf ) -{ - FIXME( "%s, %s, %#lx, %#lx, %p, %p\n", debugstr_w(szAssemblyName), debugstr_w(szAppContext), dwInstallMode, - dwAssemblyInfo, lpPathBuf, pcchPathBuf ); - return ERROR_CALL_NOT_IMPLEMENTED; -} - UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor, LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs ) { diff --git a/include/msi.h b/include/msi.h index 4012d365579..2d4846f9310 100644 --- a/include/msi.h +++ b/include/msi.h @@ -256,6 +256,9 @@ typedef struct tagMSIPATCHSEQUENCEINFOW #define ERROR_PATCH_TARGET_NOT_FOUND 1642 +#define MSIASSEMBLYINFO_NETASSEMBLY 0 +#define MSIASSEMBLYINFO_WIN32ASSEMBLY 1 + /* Strings defined in msi.h */ /* Advertised Information */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9748