* Sync to Wine 1.5.10

svn path=/trunk/; revision=57070
This commit is contained in:
Amine Khaldi 2012-08-13 16:17:18 +00:00
parent d73b1daf7f
commit 8939969e21
16 changed files with 319 additions and 220 deletions

View file

@ -1017,7 +1017,6 @@ UINT msi_load_all_components( MSIPACKAGE *package )
r = MSI_IterateRecords(view, NULL, load_component, package);
msiobj_release(&view->hdr);
msi_destroy_assembly_caches( package );
return r;
}
@ -2390,13 +2389,17 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
return MSI_SetFeatureStates(package);
}
/* OK this value is "interpreted" and then formatted based on the
first few characters */
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
DWORD *size)
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, DWORD *size)
{
LPSTR data = NULL;
if (!value)
{
data = (LPSTR)strdupW(szEmpty);
*size = sizeof(szEmpty);
*type = REG_SZ;
return data;
}
if (value[0]=='#' && value[1]!='#' && value[1]!='%')
{
if (value[1]=='x')
@ -2554,12 +2557,13 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key
return ret;
}
static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
static WCHAR *get_keypath( MSICOMPONENT *comp, HKEY root, const WCHAR *path )
{
static const WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'};
static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]);
if (is_64bit && package->platform == PLATFORM_INTEL &&
if ((is_64bit || is_wow64) &&
!(comp->Attributes & msidbComponentAttributes64bit) &&
root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
{
UINT size;
@ -2574,18 +2578,54 @@ static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
strcatW( path_32node, path + len );
return path_32node;
}
return strdupW( path );
}
static HKEY open_key( HKEY root, const WCHAR *path, BOOL create )
{
REGSAM access = KEY_ALL_ACCESS;
WCHAR *subkey, *p, *q;
HKEY hkey, ret = NULL;
LONG res;
if (is_wow64) access |= KEY_WOW64_64KEY;
if (!(subkey = strdupW( path ))) return NULL;
p = subkey;
if ((q = strchrW( p, '\\' ))) *q = 0;
if (create)
res = RegCreateKeyExW( root, subkey, 0, NULL, 0, access, NULL, &hkey, NULL );
else
res = RegOpenKeyExW( root, subkey, 0, access, &hkey );
if (res)
{
TRACE("failed to open key %s (%d)\n", debugstr_w(subkey), res);
msi_free( subkey );
return NULL;
}
if (q && q[1])
{
ret = open_key( hkey, q + 1, create );
RegCloseKey( hkey );
}
else ret = hkey;
msi_free( subkey );
return ret;
}
static BOOL is_special_entry( const WCHAR *name )
{
return (name && (name[0] == '*' || name[0] == '+') && !name[1]);
}
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = param;
LPSTR value_data = NULL;
LPSTR value;
HKEY root_key, hkey;
DWORD type,size;
LPWSTR deformated, uikey, keypath;
LPCWSTR szRoot, component, name, key, value;
LPCWSTR szRoot, component, name, key;
MSICOMPONENT *comp;
MSIRECORD * uirow;
INT root;
@ -2612,10 +2652,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
/* null values can have special meanings */
if (name[0]=='-' && name[1] == 0)
return ERROR_SUCCESS;
else if ((name[0]=='+' && name[1] == 0) ||
(name[0] == '*' && name[1] == 0))
name = NULL;
check_first = TRUE;
if ((name[0] == '+' || name[0] == '*') && !name[1])
check_first = TRUE;
}
root = MSI_RecordGetInteger(row,2);
@ -2631,49 +2669,42 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
strcpyW(uikey,szRoot);
strcatW(uikey,deformated);
keypath = get_keypath( package, root_key, deformated );
keypath = get_keypath( comp, root_key, deformated );
msi_free( deformated );
if (RegCreateKeyW( root_key, keypath, &hkey ))
if (!(hkey = open_key( root_key, keypath, TRUE )))
{
ERR("Could not create key %s\n", debugstr_w(keypath));
msi_free(uikey);
msi_free(keypath);
return ERROR_SUCCESS;
return ERROR_FUNCTION_FAILED;
}
value = MSI_RecordGetString(row,5);
if (value)
value_data = parse_value(package, value, &type, &size);
else
{
value_data = (LPSTR)strdupW(szEmpty);
size = sizeof(szEmpty);
type = REG_SZ;
}
value = parse_value(package, MSI_RecordGetString(row, 5), &type, &size);
deformat_string(package, name, &deformated);
if (!check_first)
if (!is_special_entry( name ))
{
TRACE("Setting value %s of %s\n",debugstr_w(deformated),
debugstr_w(uikey));
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size);
}
else
{
DWORD sz = 0;
rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
if (!check_first)
{
TRACE("value %s of %s checked already exists\n",
debugstr_w(deformated), debugstr_w(uikey));
TRACE("Setting value %s of %s\n", debugstr_w(deformated),
debugstr_w(uikey));
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size);
}
else
{
TRACE("Checked and setting value %s of %s\n",
debugstr_w(deformated), debugstr_w(uikey));
if (deformated || size)
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size);
DWORD sz = 0;
rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
{
TRACE("value %s of %s checked already exists\n", debugstr_w(deformated),
debugstr_w(uikey));
}
else
{
TRACE("Checked and setting value %s of %s\n", debugstr_w(deformated),
debugstr_w(uikey));
if (deformated || size)
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size);
}
}
}
RegCloseKey(hkey);
@ -2682,11 +2713,11 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
MSI_RecordSetStringW(uirow,2,deformated);
MSI_RecordSetStringW(uirow,1,uikey);
if (type == REG_SZ || type == REG_EXPAND_SZ)
MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data);
MSI_RecordSetStringW(uirow, 3, (LPWSTR)value);
msi_ui_actiondata( package, szWriteRegistryValues, uirow );
msiobj_release( &uirow->hdr );
msi_free(value_data);
msi_free(value);
msi_free(deformated);
msi_free(uikey);
msi_free(keypath);
@ -2711,35 +2742,68 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
return rc;
}
static void delete_reg_value( HKEY root, const WCHAR *keypath, const WCHAR *value )
static void delete_key( HKEY root, const WCHAR *path )
{
REGSAM access = 0;
WCHAR *subkey, *p;
HKEY hkey;
LONG res;
if (is_wow64) access |= KEY_WOW64_64KEY;
if (!(subkey = strdupW( path ))) return;
for (;;)
{
if ((p = strrchrW( subkey, '\\' ))) *p = 0;
hkey = open_key( root, subkey, FALSE );
if (!hkey) break;
if (p && p[1])
res = RegDeleteKeyExW( hkey, p + 1, access, 0 );
else
res = RegDeleteKeyExW( root, subkey, access, 0 );
if (res)
{
TRACE("failed to delete key %s (%d)\n", debugstr_w(subkey), res);
break;
}
if (p && p[1]) RegCloseKey( hkey );
else break;
}
msi_free( subkey );
}
static void delete_value( HKEY root, const WCHAR *path, const WCHAR *value )
{
LONG res;
HKEY hkey;
DWORD num_subkeys, num_values;
if (!(res = RegOpenKeyW( root, keypath, &hkey )))
if ((hkey = open_key( root, path, FALSE )))
{
if ((res = RegDeleteValueW( hkey, value )))
{
TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res);
}
res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values,
NULL, NULL, NULL, NULL );
RegCloseKey( hkey );
if (!res && !num_subkeys && !num_values)
{
TRACE("removing empty key %s\n", debugstr_w(keypath));
RegDeleteKeyW( root, keypath );
TRACE("removing empty key %s\n", debugstr_w(path));
delete_key( root, path );
}
return;
}
TRACE("failed to open key %s (%d)\n", debugstr_w(keypath), res);
}
static void delete_reg_key( HKEY root, const WCHAR *keypath )
static void delete_tree( HKEY root, const WCHAR *path )
{
LONG res = RegDeleteTreeW( root, keypath );
if (res) TRACE("failed to delete key %s (%d)\n", debugstr_w(keypath), res);
LONG res;
HKEY hkey;
if (!(hkey = open_key( root, path, FALSE ))) return;
res = RegDeleteTreeW( hkey, NULL );
if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(path), res);
delete_key( root, path );
RegCloseKey( hkey );
}
static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID param )
@ -2773,7 +2837,7 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
{
if (name[0] == '+' && !name[1])
return ERROR_SUCCESS;
else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1]))
if ((name[0] == '-' || name[0] == '*') && !name[1])
{
delete_key = TRUE;
name = NULL;
@ -2795,10 +2859,10 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
deformat_string( package, name, &deformated_name );
keypath = get_keypath( package, hkey_root, deformated_key );
keypath = get_keypath( comp, hkey_root, deformated_key );
msi_free( deformated_key );
if (delete_key) delete_reg_key( hkey_root, keypath );
else delete_reg_value( hkey_root, keypath, deformated_name );
if (delete_key) delete_tree( hkey_root, keypath );
else delete_value( hkey_root, keypath, deformated_name );
msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
@ -2860,10 +2924,10 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
deformat_string( package, name, &deformated_name );
keypath = get_keypath( package, hkey_root, deformated_key );
keypath = get_keypath( comp, hkey_root, deformated_key );
msi_free( deformated_key );
if (delete_key) delete_reg_key( hkey_root, keypath );
else delete_reg_value( hkey_root, keypath, deformated_name );
if (delete_key) delete_tree( hkey_root, keypath );
else delete_value( hkey_root, keypath, deformated_name );
msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
@ -6981,23 +7045,51 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
{
static const WCHAR fmtW[] =
{'m','s','i','e','x','e','c',' ','/','i',' ','%','s',' ','R','E','M','O','V','E','=','%','s',0};
MSIPACKAGE *package = param;
const WCHAR *property = MSI_RecordGetString( rec, 1 );
WCHAR *value;
const WCHAR *property = MSI_RecordGetString( rec, 7 );
UINT len = sizeof(fmtW)/sizeof(fmtW[0]);
WCHAR *product, *features, *cmd;
STARTUPINFOW si;
PROCESS_INFORMATION info;
BOOL ret;
if ((value = msi_dup_property( package->db, property )))
if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS;
deformat_string( package, MSI_RecordGetString( rec, 6 ), &features );
len += strlenW( product );
if (features)
len += strlenW( features );
else
len += sizeof(szAll) / sizeof(szAll[0]);
if (!(cmd = msi_alloc( len * sizeof(WCHAR) )))
{
FIXME("remove %s\n", debugstr_w(value));
msi_free( value );
msi_free( product );
msi_free( features );
return ERROR_OUTOFMEMORY;
}
sprintfW( cmd, fmtW, product, features ? features : szAll );
msi_free( product );
msi_free( features );
memset( &si, 0, sizeof(STARTUPINFOW) );
ret = CreateProcessW( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info );
msi_free( cmd );
if (!ret) return GetLastError();
CloseHandle( info.hThread );
WaitForSingleObject( info.hProcess, INFINITE );
CloseHandle( info.hProcess );
return ERROR_SUCCESS;
}
static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
{
static const WCHAR query[] = {
'S','E','L','E','C','T',' ','A','c','t','i','o','n','P','r','o','p','e','r','t','y',' ',
'F','R','O','M',' ','U','p','g','r','a','d','e',0};
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0};
MSIQUERY *view;
UINT r;
@ -7340,6 +7432,7 @@ UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UINT scrip
TRACE("Performing action (%s)\n", debugstr_w(action));
package->action_progress_increment = 0;
handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled)

View file

@ -34,25 +34,41 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
static HMODULE hfusion10, hfusion11, hfusion20, hmscoree, hsxs;
static HMODULE hfusion10, hfusion11, hfusion20, hfusion40, hmscoree, hsxs;
static BOOL init_function_pointers( void )
{
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
static const WCHAR szMscoree[] = {'\\','m','s','c','o','r','e','e','.','d','l','l',0};
static const WCHAR szSxs[] = {'s','x','s','.','d','l','l',0};
static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0};
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0};
WCHAR path[MAX_PATH];
DWORD len = GetSystemDirectoryW( path, MAX_PATH );
if (pCreateAssemblyCacheNet10 || pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE;
if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE;
if (!hsxs && !(hsxs = LoadLibraryW( szSxs ))) return FALSE;
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" )))
{
FreeLibrary( hsxs );
hsxs = NULL;
return FALSE;
}
strcpyW( path + len, szMscoree );
if (hmscoree || !(hmscoree = LoadLibraryW( path ))) return TRUE;
pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */
if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) goto error;
if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" )))
{
FreeLibrary( hmscoree );
hmscoree = NULL;
return TRUE;
}
if (!pLoadLibraryShim( szFusion, szVersion10, NULL, &hfusion10 ))
pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" );
@ -62,65 +78,32 @@ static BOOL init_function_pointers( void )
if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 ))
pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" );
if (!pCreateAssemblyCacheNet10 && !pCreateAssemblyCacheNet11 && !pCreateAssemblyCacheNet20) goto error;
if (!pLoadLibraryShim( szFusion, szVersion40, NULL, &hfusion40 ))
pCreateAssemblyCacheNet40 = (void *)GetProcAddress( hfusion40, "CreateAssemblyCache" );
if (!(hsxs = LoadLibraryA( "sxs.dll" ))) goto error;
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) goto error;
return TRUE;
error:
pCreateAssemblyCacheNet10 = NULL;
pCreateAssemblyCacheNet11 = NULL;
pCreateAssemblyCacheNet20 = NULL;
FreeLibrary( hfusion10 );
FreeLibrary( hfusion11 );
FreeLibrary( hfusion20 );
FreeLibrary( hmscoree );
return FALSE;
}
BOOL msi_init_assembly_caches( MSIPACKAGE *package )
{
if (!init_function_pointers()) return FALSE;
if (package->cache_net[CLR_VERSION_V10] ||
package->cache_net[CLR_VERSION_V11] ||
package->cache_net[CLR_VERSION_V20]) return TRUE;
if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE;
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V10], 0 );
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet10( &package->cache_net[CLR_VERSION_V10], 0 );
if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 );
if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 );
if (package->cache_net[CLR_VERSION_V10] ||
package->cache_net[CLR_VERSION_V11] ||
package->cache_net[CLR_VERSION_V20])
{
return TRUE;
}
if (package->cache_net[CLR_VERSION_V10])
{
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V10] );
package->cache_net[CLR_VERSION_V10] = NULL;
}
if (package->cache_net[CLR_VERSION_V11])
{
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V11] );
package->cache_net[CLR_VERSION_V11] = NULL;
}
if (package->cache_net[CLR_VERSION_V20])
{
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V20] );
package->cache_net[CLR_VERSION_V20] = NULL;
}
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
return FALSE;
if (pCreateAssemblyCacheNet40) pCreateAssemblyCacheNet40( &package->cache_net[CLR_VERSION_V40], 0 );
return TRUE;
}
void msi_destroy_assembly_caches( MSIPACKAGE *package )
{
UINT i;
if (package->cache_sxs)
{
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
}
for (i = 0; i < CLR_VERSION_MAX; i++)
{
if (package->cache_net[i])
@ -129,19 +112,22 @@ void msi_destroy_assembly_caches( MSIPACKAGE *package )
package->cache_net[i] = NULL;
}
}
if (package->cache_sxs)
{
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
}
pCreateAssemblyCacheNet10 = NULL;
pCreateAssemblyCacheNet11 = NULL;
pCreateAssemblyCacheNet20 = NULL;
pCreateAssemblyCacheNet40 = NULL;
FreeLibrary( hfusion10 );
FreeLibrary( hfusion11 );
FreeLibrary( hfusion20 );
FreeLibrary( hfusion40 );
FreeLibrary( hmscoree );
FreeLibrary( hsxs );
hfusion10 = NULL;
hfusion11 = NULL;
hfusion20 = NULL;
hfusion40 = NULL;
hmscoree = NULL;
hsxs = NULL;
}
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
@ -260,6 +246,8 @@ static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_n
HRESULT hr;
ASSEMBLY_INFO info;
if (!cache) return FALSE;
memset( &info, 0, sizeof(info) );
info.cbAssemblyInfo = sizeof(info);
hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, display_name, &info );
@ -274,13 +262,15 @@ static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_n
static const WCHAR clr_version_v10[] = {'v','1','.','0','.','3','7','0','5',0};
static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0};
static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0};
static const WCHAR clr_version_v40[] = {'v','4','.','0','.','3','0','3','1','9',0};
static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0};
static const WCHAR *clr_version[] =
{
clr_version_v10,
clr_version_v11,
clr_version_v20
clr_version_v20,
clr_version_v40
};
static const WCHAR *get_clr_version_str( enum clr_version version )
@ -347,6 +337,7 @@ MSIASSEMBLY *msi_load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{
TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i )));
a->installed = TRUE;
break;
}
}
}
@ -411,6 +402,7 @@ UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{
manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath;
cache = package->cache_net[get_clr_version( manifest )];
if (!cache) return ERROR_SUCCESS;
}
TRACE("installing assembly %s\n", debugstr_w(manifest));
@ -455,8 +447,11 @@ UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
{
if (!assembly->clr_version[i]) continue;
cache = package->cache_net[i];
hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
if (cache)
{
hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
}
}
}
if (feature) feature->Action = INSTALLSTATE_ABSENT;

View file

@ -609,8 +609,7 @@ static HRESULT WINAPI ListEnumerator_Clone(IEnumVARIANT* iface, IEnumVARIANT **p
hr = create_list_enumerator(This->list, (LPVOID *)ppEnum);
if (FAILED(hr))
{
if (*ppEnum)
IUnknown_Release(*ppEnum);
if (*ppEnum) IEnumVARIANT_Release(*ppEnum);
return hr;
}

View file

@ -935,13 +935,15 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action)
{
const WCHAR *workingdir;
const WCHAR *workingdir = NULL;
HANDLE handle;
WCHAR *cmd;
workingdir = msi_get_target_folder( package, source );
if (!workingdir) return ERROR_FUNCTION_FAILED;
if (source)
{
workingdir = msi_get_target_folder( package, source );
if (!workingdir) return ERROR_FUNCTION_FAILED;
}
deformat_string( package, target, &cmd );
if (!cmd) return ERROR_FUNCTION_FAILED;
@ -957,7 +959,7 @@ static DWORD ACTION_CallScript( const GUID *guid )
{
msi_custom_action_info *info;
MSIHANDLE hPackage;
UINT r;
UINT r = ERROR_FUNCTION_FAILED;
info = find_action_by_guid( guid );
if (!info)
@ -979,13 +981,13 @@ static DWORD ACTION_CallScript( const GUID *guid )
ERR("failed to create handle for %p\n", info->package );
release_custom_action_data( info );
return S_OK;
return r;
}
static DWORD WINAPI ScriptThread( LPVOID arg )
{
LPGUID guid = arg;
DWORD rc = 0;
DWORD rc;
TRACE("custom action (%x) started\n", GetCurrentThreadId() );
@ -1437,7 +1439,7 @@ static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemoteCustomAction ) )
{
IUnknown_AddRef( iface );
IWineMsiRemoteCustomAction_AddRef( iface );
*ppobj = iface;
return S_OK;
}

View file

@ -164,7 +164,7 @@ UINT msi_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
stream->stg = stg;
IStream_AddRef( stg );
IStorage_AddRef( stg );
stream->stm = *stm;
IStream_AddRef( *stm );
list_add_tail( &db->streams, &stream->entry );
@ -207,7 +207,7 @@ void msi_destroy_stream( MSIDATABASE *db, const WCHAR *stname )
list_remove( &stream->entry );
IStream_Release( stream->stm );
IStream_Release( stream->stg );
IStorage_Release( stream->stg );
IStorage_DestroyElement( stream->stg, stname );
msi_free( stream );
CoTaskMemFree( stat.pwcsName );
@ -224,7 +224,7 @@ static void free_streams( MSIDATABASE *db )
MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
list_remove( &s->entry );
IStream_Release( s->stm );
IStream_Release( s->stg );
IStorage_Release( s->stg );
msi_free( s );
}
}
@ -2082,7 +2082,7 @@ static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemoteDatabase ) )
{
IUnknown_AddRef( iface );
IWineMsiRemoteDatabase_AddRef( iface );
*ppobj = iface;
return S_OK;
}

View file

@ -644,11 +644,11 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
TRACE("progress: func %u val1 %u val2 %u\n", func, val1, val2);
units = val1 / 512;
switch (func)
{
case 0: /* init */
SendMessageW( ctrl->hwnd, PBM_SETRANGE, 0, MAKELPARAM(0,100) );
units = val1 / 512;
if (val2)
{
ctrl->progress_max = units ? units : 100;
@ -664,10 +664,11 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
SendMessageW( ctrl->hwnd, PBM_SETPOS, 0, 0 );
}
break;
case 1: /* FIXME: not sure what this is supposed to do */
case 1: /* action data increment */
if (val2) dialog->package->action_progress_increment = val1;
else dialog->package->action_progress_increment = 0;
break;
case 2: /* move */
units = val1 / 512;
if (ctrl->progress_backwards)
{
if (units >= ctrl->progress_current) ctrl->progress_current -= units;
@ -680,6 +681,9 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
}
SendMessageW( ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0 );
break;
case 3: /* add */
ctrl->progress_max += units;
break;
default:
FIXME("Unknown progress message %u\n", func);
break;

View file

@ -399,7 +399,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
goto done;
}
}
msi_init_assembly_caches( package );
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
comp->Action = msi_get_component_action( package, comp );
@ -414,7 +413,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
}
}
}
msi_destroy_assembly_caches( package );
done:
msi_free_media_info(mi);
@ -1309,7 +1307,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
msiobj_release( &uirow->hdr );
}
msi_init_assembly_caches( package );
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
{
comp->Action = msi_get_component_action( package, comp );
@ -1328,6 +1325,5 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
remove_folder( folder );
}
}
msi_destroy_assembly_caches( package );
return ERROR_SUCCESS;
}

View file

@ -4207,3 +4207,9 @@ UINT WINAPI MsiEndTransaction( DWORD state )
FIXME("%u\n", state);
return ERROR_SUCCESS;
}
UINT WINAPI Migrate10CachedPackagesW(void* a, void* b, void* c, DWORD d)
{
FIXME("%p,%p,%p,%08x\n", a, b, c, d);
return ERROR_SUCCESS;
}

View file

@ -229,7 +229,7 @@
233 stub MsiDeleteUserDataA
234 stub MsiDeleteUserDataW
235 stub Migrate10CachedPackagesA
236 stub Migrate10CachedPackagesW
236 stdcall Migrate10CachedPackagesW(ptr ptr ptr long)
237 stub MsiRemovePatchesA
238 stub MsiRemovePatchesW
239 stdcall MsiApplyMultiplePatchesA(str str str)

View file

@ -73,6 +73,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
case DLL_PROCESS_ATTACH:
msi_hInstance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
IsWow64Process( GetCurrentProcess(), &is_wow64 );
break;
case DLL_PROCESS_DETACH:
msi_dialog_unregister_class();

View file

@ -39,6 +39,7 @@
#include "wine/debug.h"
static const BOOL is_64bit = sizeof(void *) > sizeof(int);
BOOL is_wow64;
#define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100
@ -347,6 +348,7 @@ enum clr_version
CLR_VERSION_V10,
CLR_VERSION_V11,
CLR_VERSION_V20,
CLR_VERSION_V40,
CLR_VERSION_MAX
};
@ -369,6 +371,7 @@ typedef struct tagMSIPACKAGE
struct list cabinet_streams;
LPWSTR ActionFormat;
LPWSTR LastAction;
UINT action_progress_increment;
HANDLE log_file;
IAssemblyCache *cache_net[CLR_VERSION_MAX];
IAssemblyCache *cache_sxs;

View file

@ -344,9 +344,10 @@ static void free_package_structures( MSIPACKAGE *package )
static void MSI_FreePackage( MSIOBJECTHDR *arg)
{
UINT i;
MSIPACKAGE *package = (MSIPACKAGE *)arg;
msi_destroy_assembly_caches( package );
if( package->dialog )
msi_dialog_destroy( package->dialog );
@ -354,10 +355,6 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
free_package_structures(package);
CloseHandle( package->log_file );
for (i = 0; i < CLR_VERSION_MAX; i++)
if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] );
if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs );
if (package->delete_on_close) DeleteFileW( package->localfile );
msi_free( package->localfile );
}
@ -669,12 +666,11 @@ done:
static VOID set_installer_properties(MSIPACKAGE *package)
{
WCHAR pth[MAX_PATH];
WCHAR *ptr;
OSVERSIONINFOEXW OSVersion;
MEMORYSTATUSEX msex;
DWORD verval, len;
WCHAR verstr[10], bufstr[20];
WCHAR pth[MAX_PATH], verstr[11], bufstr[22];
HDC dc;
HKEY hkey;
LPWSTR username, companyname;
@ -704,14 +700,13 @@ static VOID set_installer_properties(MSIPACKAGE *package)
static const WCHAR szVersion9x[] = {'V','e','r','s','i','o','n','9','X',0};
static const WCHAR szVersionNT[] = {'V','e','r','s','i','o','n','N','T',0};
static const WCHAR szMsiNTProductType[] = {'M','s','i','N','T','P','r','o','d','u','c','t','T','y','p','e',0};
static const WCHAR szFormat[] = {'%','l','i',0};
static const WCHAR szFormat[] = {'%','u',0};
static const WCHAR szFormat2[] = {'%','u','.','%','u',0};
static const WCHAR szWindowsBuild[] = {'W','i','n','d','o','w','s','B','u','i','l','d',0};
static const WCHAR szServicePackLevel[] = {'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0};
static const WCHAR szSix[] = {'6',0 };
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
static const WCHAR szVersionDatabase[] = { 'V','e','r','s','i','o','n','D','a','t','a','b','a','s','e',0 };
static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 };
static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0};
static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
@ -874,8 +869,8 @@ static VOID set_installer_properties(MSIPACKAGE *package)
}
sprintfW(verstr, szFormat, OSVersion.dwBuildNumber);
msi_set_property(package->db, szWindowsBuild, verstr);
/* just fudge this */
msi_set_property(package->db, szServicePackLevel, szSix);
sprintfW(verstr, szFormat, OSVersion.wServicePackMajor);
msi_set_property(package->db, szServicePackLevel, verstr);
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
msi_set_property( package->db, szVersionMsi, bufstr );
@ -1339,7 +1334,6 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
static UINT validate_package( MSIPACKAGE *package )
{
BOOL is_wow64;
UINT i;
if (package->platform == PLATFORM_INTEL64)
@ -1348,7 +1342,6 @@ static UINT validate_package( MSIPACKAGE *package )
if (package->platform == PLATFORM_ARM)
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
#endif
IsWow64Process( GetCurrentProcess(), &is_wow64 );
if (package->platform == PLATFORM_X64)
{
if (!is_64bit && !is_wow64)
@ -1905,8 +1898,16 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
msi_free(deformated);
ControlEvent_FireSubscribedEvent(package, szActionData, uirow);
msiobj_release(&uirow->hdr);
if (package->action_progress_increment)
{
uirow = MSI_CreateRecord(2);
MSI_RecordSetInteger(uirow, 1, 2);
MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
ControlEvent_FireSubscribedEvent(package, szSetProgress, uirow);
msiobj_release(&uirow->hdr);
}
break;
case INSTALLMESSAGE_ACTIONSTART:
@ -2360,7 +2361,7 @@ static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) )
{
IUnknown_AddRef( iface );
IWineMsiRemotePackage_AddRef( iface );
*ppobj = iface;
return S_OK;
}

View file

@ -81,7 +81,8 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
{
HRESULT hr;
IActiveScript *pActiveScript = NULL;
IActiveScriptParse *pActiveScriptParse = NULL;
IActiveScriptParse32 *pActiveScriptParse32 = NULL;
IActiveScriptParse64 *pActiveScriptParse64 = NULL;
MsiActiveScriptSite *pActiveScriptSite = NULL;
IDispatch *pDispatch = NULL;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
@ -123,27 +124,41 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
goto done;
}
/* Get the IActiveScriptParse engine interface */
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse);
if (FAILED(hr)) goto done;
if (type & msidbCustomActionType64BitScript)
{
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse64, (void **)&pActiveScriptParse64);
if (FAILED(hr)) goto done;
/* Give our host to the engine */
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
if (FAILED(hr)) goto done;
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
if (FAILED(hr)) goto done;
/* Initialize the script engine */
hr = IActiveScriptParse64_InitNew(pActiveScriptParse);
if (FAILED(hr)) goto done;
hr = IActiveScriptParse64_InitNew(pActiveScriptParse64);
if (FAILED(hr)) goto done;
/* Add the session object */
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
if (FAILED(hr)) goto done;
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
if (FAILED(hr)) goto done;
/* Pass the script to the engine */
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
if (FAILED(hr)) goto done;
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse64, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
if (FAILED(hr)) goto done;
}
else
{
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse32, (void **)&pActiveScriptParse32);
if (FAILED(hr)) goto done;
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
if (FAILED(hr)) goto done;
hr = IActiveScriptParse32_InitNew(pActiveScriptParse32);
if (FAILED(hr)) goto done;
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
if (FAILED(hr)) goto done;
hr = IActiveScriptParse32_ParseScriptText(pActiveScriptParse32, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
if (FAILED(hr)) goto done;
}
/* Start processing the script */
hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED);
if (FAILED(hr)) goto done;
@ -176,17 +191,17 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
done:
/* Free everything that needs to be freed */
if (pDispatch) IDispatch_Release(pDispatch);
if (pActiveScript) IActiveScriptSite_Release(pActiveScript);
if (pActiveScriptSite &&
pActiveScriptSite->pSession) IUnknown_Release((IUnknown *)pActiveScriptSite->pSession);
if (pActiveScriptSite &&
pActiveScriptSite->pInstaller) IUnknown_Release((IUnknown *)pActiveScriptSite->pInstaller);
if (pActiveScriptSite) IUnknown_Release((IUnknown *)pActiveScriptSite);
if (pActiveScript) IActiveScript_Release(pActiveScript);
if (pActiveScriptParse32) IActiveScriptParse32_Release(pActiveScriptParse32);
if (pActiveScriptParse64) IActiveScriptParse64_Release(pActiveScriptParse64);
if (pActiveScriptSite)
{
if (pActiveScriptSite->pSession) IDispatch_Release(pActiveScriptSite->pSession);
if (pActiveScriptSite->pInstaller) IDispatch_Release(pActiveScriptSite->pInstaller);
IActiveScriptSite_Release((IActiveScriptSite *)pActiveScriptSite);
}
CoUninitialize(); /* must call even if CoInitialize failed */
return ret;
}
@ -204,7 +219,7 @@ static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* ifac
if (IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IActiveScriptSite))
{
IClassFactory_AddRef(iface);
IActiveScriptSite_AddRef(iface);
*ppvObject = This;
return S_OK;
}

View file

@ -357,14 +357,12 @@ const WCHAR *msi_string_lookup_id( const string_table *st, UINT id )
* [in/out] sz - number of bytes available in the buffer on input
* number of bytes used on output
*
* The size includes the terminating nul character. Short buffers
* will be filled, but not nul terminated.
* Returned string is not nul terminated.
*/
static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz )
{
UINT len;
UINT len, lenW;
const WCHAR *str;
int n;
TRACE("Finding string %d of %d\n", id, st->maxcount);
@ -372,26 +370,14 @@ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT
if( !str )
return ERROR_FUNCTION_FAILED;
len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL );
if( !buffer )
lenW = strlenW( str );
len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL );
if( *sz < len )
{
*sz = len;
return ERROR_SUCCESS;
return ERROR_MORE_DATA;
}
if( len > *sz )
{
n = strlenW( str ) + 1;
while( n && (len > *sz) )
len = WideCharToMultiByte( st->codepage, 0,
str, --n, NULL, 0, NULL, NULL );
}
else
n = -1;
*sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL );
*sz = WideCharToMultiByte( st->codepage, 0, str, lenW, buffer, *sz, NULL, NULL );
return ERROR_SUCCESS;
}
@ -588,7 +574,7 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
data = msi_alloc( datasize );
if( ! data )
{
WARN("Failed to alloc data %d bytes\n", poolsize );
WARN("Failed to alloc data %d bytes\n", datasize );
goto err;
}
@ -622,8 +608,6 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
ERR("failed to fetch string\n");
sz = 0;
}
if( sz && (sz < (datasize - used ) ) )
sz--;
if (sz)
pool[ n*2 + 1 ] = st->strings[i].persistent_refcount;

View file

@ -266,7 +266,7 @@ int sqliteGetToken(const WCHAR *z, int *tokenType, int *skip){
*tokenType = TK_DOT;
return 1;
}
/* Fall thru into the next case */
/* Fall through */
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
*tokenType = TK_INTEGER;

View file

@ -106,7 +106,7 @@ reactos/dll/win32/msg711.acm # Synced to Wine-1.5.4
reactos/dll/win32/msgsm32.acm # Synced to Wine-1.5.4
reactos/dll/win32/mshtml # Autosync
reactos/dll/win32/mshtml.tlb # Autosync
reactos/dll/win32/msi # Synced to Wine-1.5.4
reactos/dll/win32/msi # Synced to Wine-1.5.10
reactos/dll/win32/msimg32 # Synced to Wine-1.5.4
reactos/dll/win32/msimtf # Synced to Wine-1.5.4
reactos/dll/win32/msisip # Synced to Wine-1.5.4