* 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); r = MSI_IterateRecords(view, NULL, load_component, package);
msiobj_release(&view->hdr); msiobj_release(&view->hdr);
msi_destroy_assembly_caches( package );
return r; return r;
} }
@ -2390,13 +2389,17 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
return MSI_SetFeatureStates(package); return MSI_SetFeatureStates(package);
} }
/* OK this value is "interpreted" and then formatted based on the static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, DWORD *size)
first few characters */
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
DWORD *size)
{ {
LPSTR data = NULL; 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[0]=='#' && value[1]!='#' && value[1]!='%')
{ {
if (value[1]=='x') if (value[1]=='x')
@ -2554,12 +2557,13 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key
return ret; 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 WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'};
static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]); 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 )) root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
{ {
UINT size; UINT size;
@ -2574,18 +2578,54 @@ static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
strcatW( path_32node, path + len ); strcatW( path_32node, path + len );
return path_32node; return path_32node;
} }
return strdupW( path ); 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) static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{ {
MSIPACKAGE *package = param; MSIPACKAGE *package = param;
LPSTR value_data = NULL; LPSTR value;
HKEY root_key, hkey; HKEY root_key, hkey;
DWORD type,size; DWORD type,size;
LPWSTR deformated, uikey, keypath; LPWSTR deformated, uikey, keypath;
LPCWSTR szRoot, component, name, key, value; LPCWSTR szRoot, component, name, key;
MSICOMPONENT *comp; MSICOMPONENT *comp;
MSIRECORD * uirow; MSIRECORD * uirow;
INT root; INT root;
@ -2612,10 +2652,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
/* null values can have special meanings */ /* null values can have special meanings */
if (name[0]=='-' && name[1] == 0) if (name[0]=='-' && name[1] == 0)
return ERROR_SUCCESS; return ERROR_SUCCESS;
else if ((name[0]=='+' && name[1] == 0) || if ((name[0] == '+' || name[0] == '*') && !name[1])
(name[0] == '*' && name[1] == 0)) check_first = TRUE;
name = NULL;
check_first = TRUE;
} }
root = MSI_RecordGetInteger(row,2); root = MSI_RecordGetInteger(row,2);
@ -2631,49 +2669,42 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
strcpyW(uikey,szRoot); strcpyW(uikey,szRoot);
strcatW(uikey,deformated); strcatW(uikey,deformated);
keypath = get_keypath( package, root_key, deformated ); keypath = get_keypath( comp, root_key, deformated );
msi_free( 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)); ERR("Could not create key %s\n", debugstr_w(keypath));
msi_free(uikey); msi_free(uikey);
msi_free(keypath); msi_free(keypath);
return ERROR_SUCCESS; return ERROR_FUNCTION_FAILED;
} }
value = parse_value(package, MSI_RecordGetString(row, 5), &type, &size);
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;
}
deformat_string(package, name, &deformated); deformat_string(package, name, &deformated);
if (!check_first) if (!is_special_entry( name ))
{ {
TRACE("Setting value %s of %s\n",debugstr_w(deformated), if (!check_first)
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)
{ {
TRACE("value %s of %s checked already exists\n", TRACE("Setting value %s of %s\n", debugstr_w(deformated),
debugstr_w(deformated), debugstr_w(uikey)); debugstr_w(uikey));
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size);
} }
else else
{ {
TRACE("Checked and setting value %s of %s\n", DWORD sz = 0;
debugstr_w(deformated), debugstr_w(uikey)); rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
if (deformated || size) if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size); {
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); RegCloseKey(hkey);
@ -2682,11 +2713,11 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
MSI_RecordSetStringW(uirow,2,deformated); MSI_RecordSetStringW(uirow,2,deformated);
MSI_RecordSetStringW(uirow,1,uikey); MSI_RecordSetStringW(uirow,1,uikey);
if (type == REG_SZ || type == REG_EXPAND_SZ) 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 ); msi_ui_actiondata( package, szWriteRegistryValues, uirow );
msiobj_release( &uirow->hdr ); msiobj_release( &uirow->hdr );
msi_free(value_data); msi_free(value);
msi_free(deformated); msi_free(deformated);
msi_free(uikey); msi_free(uikey);
msi_free(keypath); msi_free(keypath);
@ -2711,35 +2742,68 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
return rc; 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; LONG res;
HKEY hkey; HKEY hkey;
DWORD num_subkeys, num_values; DWORD num_subkeys, num_values;
if (!(res = RegOpenKeyW( root, keypath, &hkey ))) if ((hkey = open_key( root, path, FALSE )))
{ {
if ((res = RegDeleteValueW( hkey, value ))) if ((res = RegDeleteValueW( hkey, value )))
{
TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res); TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res);
}
res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values, res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values,
NULL, NULL, NULL, NULL ); NULL, NULL, NULL, NULL );
RegCloseKey( hkey ); RegCloseKey( hkey );
if (!res && !num_subkeys && !num_values) if (!res && !num_subkeys && !num_values)
{ {
TRACE("removing empty key %s\n", debugstr_w(keypath)); TRACE("removing empty key %s\n", debugstr_w(path));
RegDeleteKeyW( root, keypath ); 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 ); LONG res;
if (res) TRACE("failed to delete key %s (%d)\n", debugstr_w(keypath), 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 ) 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]) if (name[0] == '+' && !name[1])
return ERROR_SUCCESS; return ERROR_SUCCESS;
else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1])) if ((name[0] == '-' || name[0] == '*') && !name[1])
{ {
delete_key = TRUE; delete_key = TRUE;
name = NULL; name = NULL;
@ -2795,10 +2859,10 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
deformat_string( package, name, &deformated_name ); 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 ); msi_free( deformated_key );
if (delete_key) delete_reg_key( hkey_root, keypath ); if (delete_key) delete_tree( hkey_root, keypath );
else delete_reg_value( hkey_root, keypath, deformated_name ); else delete_value( hkey_root, keypath, deformated_name );
msi_free( keypath ); msi_free( keypath );
uirow = MSI_CreateRecord( 2 ); uirow = MSI_CreateRecord( 2 );
@ -2860,10 +2924,10 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
deformat_string( package, name, &deformated_name ); 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 ); msi_free( deformated_key );
if (delete_key) delete_reg_key( hkey_root, keypath ); if (delete_key) delete_tree( hkey_root, keypath );
else delete_reg_value( hkey_root, keypath, deformated_name ); else delete_value( hkey_root, keypath, deformated_name );
msi_free( keypath ); msi_free( keypath );
uirow = MSI_CreateRecord( 2 ); uirow = MSI_CreateRecord( 2 );
@ -6981,23 +7045,51 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param ) 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; MSIPACKAGE *package = param;
const WCHAR *property = MSI_RecordGetString( rec, 1 ); const WCHAR *property = MSI_RecordGetString( rec, 7 );
WCHAR *value; 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( product );
msi_free( value ); 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; return ERROR_SUCCESS;
} }
static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package ) static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
{ {
static const WCHAR query[] = { static const WCHAR query[] = {
'S','E','L','E','C','T',' ','A','c','t','i','o','n','P','r','o','p','e','r','t','y',' ', 'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0};
'F','R','O','M',' ','U','p','g','r','a','d','e',0};
MSIQUERY *view; MSIQUERY *view;
UINT r; UINT r;
@ -7340,6 +7432,7 @@ UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UINT scrip
TRACE("Performing action (%s)\n", debugstr_w(action)); TRACE("Performing action (%s)\n", debugstr_w(action));
package->action_progress_increment = 0;
handled = ACTION_HandleStandardAction(package, action, &rc); handled = ACTION_HandleStandardAction(package, action, &rc);
if (!handled) if (!handled)

View file

@ -34,25 +34,41 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD ); static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * ); static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * ); 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 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 szVersion10[] = {'v','1','.','0','.','3','7','0','5',0};
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',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 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 (!hsxs && !(hsxs = LoadLibraryW( szSxs ))) return FALSE;
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" )))
if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE; {
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 */ 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 )) if (!pLoadLibraryShim( szFusion, szVersion10, NULL, &hfusion10 ))
pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" ); pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" );
@ -62,65 +78,32 @@ static BOOL init_function_pointers( void )
if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 )) if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 ))
pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" ); 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; 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 ) BOOL msi_init_assembly_caches( MSIPACKAGE *package )
{ {
if (!init_function_pointers()) return FALSE; 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 (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE;
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet10( &package->cache_net[CLR_VERSION_V10], 0 );
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V10], 0 );
if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 ); if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 );
if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 ); if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 );
if (pCreateAssemblyCacheNet40) pCreateAssemblyCacheNet40( &package->cache_net[CLR_VERSION_V40], 0 );
if (package->cache_net[CLR_VERSION_V10] || return TRUE;
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;
} }
void msi_destroy_assembly_caches( MSIPACKAGE *package ) void msi_destroy_assembly_caches( MSIPACKAGE *package )
{ {
UINT i; UINT i;
if (package->cache_sxs)
{
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
}
for (i = 0; i < CLR_VERSION_MAX; i++) for (i = 0; i < CLR_VERSION_MAX; i++)
{ {
if (package->cache_net[i]) if (package->cache_net[i])
@ -129,19 +112,22 @@ void msi_destroy_assembly_caches( MSIPACKAGE *package )
package->cache_net[i] = NULL; package->cache_net[i] = NULL;
} }
} }
if (package->cache_sxs)
{
IAssemblyCache_Release( package->cache_sxs );
package->cache_sxs = NULL;
}
pCreateAssemblyCacheNet10 = NULL; pCreateAssemblyCacheNet10 = NULL;
pCreateAssemblyCacheNet11 = NULL; pCreateAssemblyCacheNet11 = NULL;
pCreateAssemblyCacheNet20 = NULL; pCreateAssemblyCacheNet20 = NULL;
pCreateAssemblyCacheNet40 = NULL;
FreeLibrary( hfusion10 ); FreeLibrary( hfusion10 );
FreeLibrary( hfusion11 ); FreeLibrary( hfusion11 );
FreeLibrary( hfusion20 ); FreeLibrary( hfusion20 );
FreeLibrary( hfusion40 );
FreeLibrary( hmscoree ); FreeLibrary( hmscoree );
FreeLibrary( hsxs ); FreeLibrary( hsxs );
hfusion10 = NULL;
hfusion11 = NULL;
hfusion20 = NULL;
hfusion40 = NULL;
hmscoree = NULL;
hsxs = NULL;
} }
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp ) 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; HRESULT hr;
ASSEMBLY_INFO info; ASSEMBLY_INFO info;
if (!cache) return FALSE;
memset( &info, 0, sizeof(info) ); memset( &info, 0, sizeof(info) );
info.cbAssemblyInfo = sizeof(info); info.cbAssemblyInfo = sizeof(info);
hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, display_name, &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_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_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_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_unknown[] = {'u','n','k','n','o','w','n',0};
static const WCHAR *clr_version[] = static const WCHAR *clr_version[] =
{ {
clr_version_v10, clr_version_v10,
clr_version_v11, clr_version_v11,
clr_version_v20 clr_version_v20,
clr_version_v40
}; };
static const WCHAR *get_clr_version_str( enum clr_version version ) 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 ))); TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i )));
a->installed = TRUE; 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; manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath;
cache = package->cache_net[get_clr_version( manifest )]; cache = package->cache_net[get_clr_version( manifest )];
if (!cache) return ERROR_SUCCESS;
} }
TRACE("installing assembly %s\n", debugstr_w(manifest)); 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; if (!assembly->clr_version[i]) continue;
cache = package->cache_net[i]; cache = package->cache_net[i];
hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL ); if (cache)
if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr); {
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; 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); hr = create_list_enumerator(This->list, (LPVOID *)ppEnum);
if (FAILED(hr)) if (FAILED(hr))
{ {
if (*ppEnum) if (*ppEnum) IEnumVARIANT_Release(*ppEnum);
IUnknown_Release(*ppEnum);
return hr; return hr;
} }

View file

@ -935,13 +935,15 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source, static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
LPCWSTR target, const INT type, LPCWSTR action) LPCWSTR target, const INT type, LPCWSTR action)
{ {
const WCHAR *workingdir; const WCHAR *workingdir = NULL;
HANDLE handle; HANDLE handle;
WCHAR *cmd; WCHAR *cmd;
workingdir = msi_get_target_folder( package, source ); if (source)
if (!workingdir) return ERROR_FUNCTION_FAILED; {
workingdir = msi_get_target_folder( package, source );
if (!workingdir) return ERROR_FUNCTION_FAILED;
}
deformat_string( package, target, &cmd ); deformat_string( package, target, &cmd );
if (!cmd) return ERROR_FUNCTION_FAILED; if (!cmd) return ERROR_FUNCTION_FAILED;
@ -957,7 +959,7 @@ static DWORD ACTION_CallScript( const GUID *guid )
{ {
msi_custom_action_info *info; msi_custom_action_info *info;
MSIHANDLE hPackage; MSIHANDLE hPackage;
UINT r; UINT r = ERROR_FUNCTION_FAILED;
info = find_action_by_guid( guid ); info = find_action_by_guid( guid );
if (!info) if (!info)
@ -979,13 +981,13 @@ static DWORD ACTION_CallScript( const GUID *guid )
ERR("failed to create handle for %p\n", info->package ); ERR("failed to create handle for %p\n", info->package );
release_custom_action_data( info ); release_custom_action_data( info );
return S_OK; return r;
} }
static DWORD WINAPI ScriptThread( LPVOID arg ) static DWORD WINAPI ScriptThread( LPVOID arg )
{ {
LPGUID guid = arg; LPGUID guid = arg;
DWORD rc = 0; DWORD rc;
TRACE("custom action (%x) started\n", GetCurrentThreadId() ); TRACE("custom action (%x) started\n", GetCurrentThreadId() );
@ -1437,7 +1439,7 @@ static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) || if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemoteCustomAction ) ) IsEqualCLSID( riid, &IID_IWineMsiRemoteCustomAction ) )
{ {
IUnknown_AddRef( iface ); IWineMsiRemoteCustomAction_AddRef( iface );
*ppobj = iface; *ppobj = iface;
return S_OK; 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; if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
stream->stg = stg; stream->stg = stg;
IStream_AddRef( stg ); IStorage_AddRef( stg );
stream->stm = *stm; stream->stm = *stm;
IStream_AddRef( *stm ); IStream_AddRef( *stm );
list_add_tail( &db->streams, &stream->entry ); list_add_tail( &db->streams, &stream->entry );
@ -207,7 +207,7 @@ void msi_destroy_stream( MSIDATABASE *db, const WCHAR *stname )
list_remove( &stream->entry ); list_remove( &stream->entry );
IStream_Release( stream->stm ); IStream_Release( stream->stm );
IStream_Release( stream->stg ); IStorage_Release( stream->stg );
IStorage_DestroyElement( stream->stg, stname ); IStorage_DestroyElement( stream->stg, stname );
msi_free( stream ); msi_free( stream );
CoTaskMemFree( stat.pwcsName ); CoTaskMemFree( stat.pwcsName );
@ -224,7 +224,7 @@ static void free_streams( MSIDATABASE *db )
MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry); MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
list_remove( &s->entry ); list_remove( &s->entry );
IStream_Release( s->stm ); IStream_Release( s->stm );
IStream_Release( s->stg ); IStorage_Release( s->stg );
msi_free( s ); msi_free( s );
} }
} }
@ -2082,7 +2082,7 @@ static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) || if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemoteDatabase ) ) IsEqualCLSID( riid, &IID_IWineMsiRemoteDatabase ) )
{ {
IUnknown_AddRef( iface ); IWineMsiRemoteDatabase_AddRef( iface );
*ppobj = iface; *ppobj = iface;
return S_OK; 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); TRACE("progress: func %u val1 %u val2 %u\n", func, val1, val2);
units = val1 / 512;
switch (func) switch (func)
{ {
case 0: /* init */ case 0: /* init */
SendMessageW( ctrl->hwnd, PBM_SETRANGE, 0, MAKELPARAM(0,100) ); SendMessageW( ctrl->hwnd, PBM_SETRANGE, 0, MAKELPARAM(0,100) );
units = val1 / 512;
if (val2) if (val2)
{ {
ctrl->progress_max = units ? units : 100; 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 ); SendMessageW( ctrl->hwnd, PBM_SETPOS, 0, 0 );
} }
break; 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; break;
case 2: /* move */ case 2: /* move */
units = val1 / 512;
if (ctrl->progress_backwards) if (ctrl->progress_backwards)
{ {
if (units >= ctrl->progress_current) ctrl->progress_current -= units; 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 ); SendMessageW( ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0 );
break; break;
case 3: /* add */
ctrl->progress_max += units;
break;
default: default:
FIXME("Unknown progress message %u\n", func); FIXME("Unknown progress message %u\n", func);
break; break;

View file

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

View file

@ -4207,3 +4207,9 @@ UINT WINAPI MsiEndTransaction( DWORD state )
FIXME("%u\n", state); FIXME("%u\n", state);
return ERROR_SUCCESS; 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 233 stub MsiDeleteUserDataA
234 stub MsiDeleteUserDataW 234 stub MsiDeleteUserDataW
235 stub Migrate10CachedPackagesA 235 stub Migrate10CachedPackagesA
236 stub Migrate10CachedPackagesW 236 stdcall Migrate10CachedPackagesW(ptr ptr ptr long)
237 stub MsiRemovePatchesA 237 stub MsiRemovePatchesA
238 stub MsiRemovePatchesW 238 stub MsiRemovePatchesW
239 stdcall MsiApplyMultiplePatchesA(str str str) 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: case DLL_PROCESS_ATTACH:
msi_hInstance = hinstDLL; msi_hInstance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL); DisableThreadLibraryCalls(hinstDLL);
IsWow64Process( GetCurrentProcess(), &is_wow64 );
break; break;
case DLL_PROCESS_DETACH: case DLL_PROCESS_DETACH:
msi_dialog_unregister_class(); msi_dialog_unregister_class();

View file

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

View file

@ -344,9 +344,10 @@ static void free_package_structures( MSIPACKAGE *package )
static void MSI_FreePackage( MSIOBJECTHDR *arg) static void MSI_FreePackage( MSIOBJECTHDR *arg)
{ {
UINT i;
MSIPACKAGE *package = (MSIPACKAGE *)arg; MSIPACKAGE *package = (MSIPACKAGE *)arg;
msi_destroy_assembly_caches( package );
if( package->dialog ) if( package->dialog )
msi_dialog_destroy( package->dialog ); msi_dialog_destroy( package->dialog );
@ -354,10 +355,6 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
free_package_structures(package); free_package_structures(package);
CloseHandle( package->log_file ); 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 ); if (package->delete_on_close) DeleteFileW( package->localfile );
msi_free( package->localfile ); msi_free( package->localfile );
} }
@ -669,12 +666,11 @@ done:
static VOID set_installer_properties(MSIPACKAGE *package) static VOID set_installer_properties(MSIPACKAGE *package)
{ {
WCHAR pth[MAX_PATH];
WCHAR *ptr; WCHAR *ptr;
OSVERSIONINFOEXW OSVersion; OSVERSIONINFOEXW OSVersion;
MEMORYSTATUSEX msex; MEMORYSTATUSEX msex;
DWORD verval, len; DWORD verval, len;
WCHAR verstr[10], bufstr[20]; WCHAR pth[MAX_PATH], verstr[11], bufstr[22];
HDC dc; HDC dc;
HKEY hkey; HKEY hkey;
LPWSTR username, companyname; 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 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 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 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 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 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 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 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 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 szScreenX[] = {'S','c','r','e','e','n','X',0};
static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',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}; 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); sprintfW(verstr, szFormat, OSVersion.dwBuildNumber);
msi_set_property(package->db, szWindowsBuild, verstr); msi_set_property(package->db, szWindowsBuild, verstr);
/* just fudge this */ sprintfW(verstr, szFormat, OSVersion.wServicePackMajor);
msi_set_property(package->db, szServicePackLevel, szSix); msi_set_property(package->db, szServicePackLevel, verstr);
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION); sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
msi_set_property( package->db, szVersionMsi, bufstr ); 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 ) static UINT validate_package( MSIPACKAGE *package )
{ {
BOOL is_wow64;
UINT i; UINT i;
if (package->platform == PLATFORM_INTEL64) if (package->platform == PLATFORM_INTEL64)
@ -1348,7 +1342,6 @@ static UINT validate_package( MSIPACKAGE *package )
if (package->platform == PLATFORM_ARM) if (package->platform == PLATFORM_ARM)
return ERROR_INSTALL_PLATFORM_UNSUPPORTED; return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
#endif #endif
IsWow64Process( GetCurrentProcess(), &is_wow64 );
if (package->platform == PLATFORM_X64) if (package->platform == PLATFORM_X64)
{ {
if (!is_64bit && !is_wow64) if (!is_64bit && !is_wow64)
@ -1905,8 +1898,16 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
msi_free(deformated); msi_free(deformated);
ControlEvent_FireSubscribedEvent(package, szActionData, uirow); ControlEvent_FireSubscribedEvent(package, szActionData, uirow);
msiobj_release(&uirow->hdr); 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; break;
case INSTALLMESSAGE_ACTIONSTART: case INSTALLMESSAGE_ACTIONSTART:
@ -2360,7 +2361,7 @@ static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
if( IsEqualCLSID( riid, &IID_IUnknown ) || if( IsEqualCLSID( riid, &IID_IUnknown ) ||
IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) ) IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) )
{ {
IUnknown_AddRef( iface ); IWineMsiRemotePackage_AddRef( iface );
*ppobj = iface; *ppobj = iface;
return S_OK; return S_OK;
} }

View file

@ -81,7 +81,8 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
{ {
HRESULT hr; HRESULT hr;
IActiveScript *pActiveScript = NULL; IActiveScript *pActiveScript = NULL;
IActiveScriptParse *pActiveScriptParse = NULL; IActiveScriptParse32 *pActiveScriptParse32 = NULL;
IActiveScriptParse64 *pActiveScriptParse64 = NULL;
MsiActiveScriptSite *pActiveScriptSite = NULL; MsiActiveScriptSite *pActiveScriptSite = NULL;
IDispatch *pDispatch = NULL; IDispatch *pDispatch = NULL;
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0}; DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
@ -123,27 +124,41 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
goto done; goto done;
} }
/* Get the IActiveScriptParse engine interface */ if (type & msidbCustomActionType64BitScript)
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse); {
if (FAILED(hr)) goto done; 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);
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite); if (FAILED(hr)) goto done;
if (FAILED(hr)) goto done;
/* Initialize the script engine */ hr = IActiveScriptParse64_InitNew(pActiveScriptParse64);
hr = IActiveScriptParse64_InitNew(pActiveScriptParse); if (FAILED(hr)) goto done;
if (FAILED(hr)) goto done;
/* Add the session object */ hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS); if (FAILED(hr)) goto done;
if (FAILED(hr)) goto done;
/* Pass the script to the engine */ hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse64, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL); if (FAILED(hr)) goto done;
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); hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED);
if (FAILED(hr)) goto done; if (FAILED(hr)) goto done;
@ -176,17 +191,17 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
done: done:
/* Free everything that needs to be freed */
if (pDispatch) IDispatch_Release(pDispatch); if (pDispatch) IDispatch_Release(pDispatch);
if (pActiveScript) IActiveScriptSite_Release(pActiveScript); if (pActiveScript) IActiveScript_Release(pActiveScript);
if (pActiveScriptSite && if (pActiveScriptParse32) IActiveScriptParse32_Release(pActiveScriptParse32);
pActiveScriptSite->pSession) IUnknown_Release((IUnknown *)pActiveScriptSite->pSession); if (pActiveScriptParse64) IActiveScriptParse64_Release(pActiveScriptParse64);
if (pActiveScriptSite && if (pActiveScriptSite)
pActiveScriptSite->pInstaller) IUnknown_Release((IUnknown *)pActiveScriptSite->pInstaller); {
if (pActiveScriptSite) IUnknown_Release((IUnknown *)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 */ CoUninitialize(); /* must call even if CoInitialize failed */
return ret; return ret;
} }
@ -204,7 +219,7 @@ static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* ifac
if (IsEqualGUID(riid, &IID_IUnknown) || if (IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_IActiveScriptSite)) IsEqualGUID(riid, &IID_IActiveScriptSite))
{ {
IClassFactory_AddRef(iface); IActiveScriptSite_AddRef(iface);
*ppvObject = This; *ppvObject = This;
return S_OK; 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 * [in/out] sz - number of bytes available in the buffer on input
* number of bytes used on output * number of bytes used on output
* *
* The size includes the terminating nul character. Short buffers * Returned string is not nul terminated.
* will be filled, but not nul terminated.
*/ */
static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz ) static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz )
{ {
UINT len; UINT len, lenW;
const WCHAR *str; const WCHAR *str;
int n;
TRACE("Finding string %d of %d\n", id, st->maxcount); 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 ) if( !str )
return ERROR_FUNCTION_FAILED; return ERROR_FUNCTION_FAILED;
len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL ); lenW = strlenW( str );
len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL );
if( !buffer ) if( *sz < len )
{ {
*sz = len; *sz = len;
return ERROR_SUCCESS; return ERROR_MORE_DATA;
} }
*sz = WideCharToMultiByte( st->codepage, 0, str, lenW, buffer, *sz, NULL, NULL );
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 );
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
@ -588,7 +574,7 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
data = msi_alloc( datasize ); data = msi_alloc( datasize );
if( ! data ) if( ! data )
{ {
WARN("Failed to alloc data %d bytes\n", poolsize ); WARN("Failed to alloc data %d bytes\n", datasize );
goto err; 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"); ERR("failed to fetch string\n");
sz = 0; sz = 0;
} }
if( sz && (sz < (datasize - used ) ) )
sz--;
if (sz) if (sz)
pool[ n*2 + 1 ] = st->strings[i].persistent_refcount; 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; *tokenType = TK_DOT;
return 1; return 1;
} }
/* Fall thru into the next case */ /* Fall through */
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '5': case '6': case '7': case '8': case '9':
*tokenType = TK_INTEGER; *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/msgsm32.acm # Synced to Wine-1.5.4
reactos/dll/win32/mshtml # Autosync reactos/dll/win32/mshtml # Autosync
reactos/dll/win32/mshtml.tlb # 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/msimg32 # Synced to Wine-1.5.4
reactos/dll/win32/msimtf # 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 reactos/dll/win32/msisip # Synced to Wine-1.5.4