mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 02:41:22 +00:00
[MSI]
* Sync to Wine 1.5.10 svn path=/trunk/; revision=57070
This commit is contained in:
parent
d73b1daf7f
commit
8939969e21
16 changed files with 319 additions and 220 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue