mirror of
https://github.com/reactos/reactos.git
synced 2025-05-06 18:31:26 +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);
|
||||
msiobj_release(&view->hdr);
|
||||
msi_destroy_assembly_caches( package );
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2390,13 +2389,17 @@ static UINT ACTION_CostFinalize(MSIPACKAGE *package)
|
|||
return MSI_SetFeatureStates(package);
|
||||
}
|
||||
|
||||
/* OK this value is "interpreted" and then formatted based on the
|
||||
first few characters */
|
||||
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type,
|
||||
DWORD *size)
|
||||
static LPSTR parse_value(MSIPACKAGE *package, LPCWSTR value, DWORD *type, DWORD *size)
|
||||
{
|
||||
LPSTR data = NULL;
|
||||
|
||||
if (!value)
|
||||
{
|
||||
data = (LPSTR)strdupW(szEmpty);
|
||||
*size = sizeof(szEmpty);
|
||||
*type = REG_SZ;
|
||||
return data;
|
||||
}
|
||||
if (value[0]=='#' && value[1]!='#' && value[1]!='%')
|
||||
{
|
||||
if (value[1]=='x')
|
||||
|
@ -2554,12 +2557,13 @@ static const WCHAR *get_root_key( MSIPACKAGE *package, INT root, HKEY *root_key
|
|||
return ret;
|
||||
}
|
||||
|
||||
static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
|
||||
static WCHAR *get_keypath( MSICOMPONENT *comp, HKEY root, const WCHAR *path )
|
||||
{
|
||||
static const WCHAR prefixW[] = {'S','O','F','T','W','A','R','E','\\'};
|
||||
static const UINT len = sizeof(prefixW) / sizeof(prefixW[0]);
|
||||
|
||||
if (is_64bit && package->platform == PLATFORM_INTEL &&
|
||||
if ((is_64bit || is_wow64) &&
|
||||
!(comp->Attributes & msidbComponentAttributes64bit) &&
|
||||
root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
|
||||
{
|
||||
UINT size;
|
||||
|
@ -2574,18 +2578,54 @@ static WCHAR *get_keypath( MSIPACKAGE *package, HKEY root, const WCHAR *path )
|
|||
strcatW( path_32node, path + len );
|
||||
return path_32node;
|
||||
}
|
||||
|
||||
return strdupW( path );
|
||||
}
|
||||
|
||||
static HKEY open_key( HKEY root, const WCHAR *path, BOOL create )
|
||||
{
|
||||
REGSAM access = KEY_ALL_ACCESS;
|
||||
WCHAR *subkey, *p, *q;
|
||||
HKEY hkey, ret = NULL;
|
||||
LONG res;
|
||||
|
||||
if (is_wow64) access |= KEY_WOW64_64KEY;
|
||||
|
||||
if (!(subkey = strdupW( path ))) return NULL;
|
||||
p = subkey;
|
||||
if ((q = strchrW( p, '\\' ))) *q = 0;
|
||||
if (create)
|
||||
res = RegCreateKeyExW( root, subkey, 0, NULL, 0, access, NULL, &hkey, NULL );
|
||||
else
|
||||
res = RegOpenKeyExW( root, subkey, 0, access, &hkey );
|
||||
if (res)
|
||||
{
|
||||
TRACE("failed to open key %s (%d)\n", debugstr_w(subkey), res);
|
||||
msi_free( subkey );
|
||||
return NULL;
|
||||
}
|
||||
if (q && q[1])
|
||||
{
|
||||
ret = open_key( hkey, q + 1, create );
|
||||
RegCloseKey( hkey );
|
||||
}
|
||||
else ret = hkey;
|
||||
msi_free( subkey );
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL is_special_entry( const WCHAR *name )
|
||||
{
|
||||
return (name && (name[0] == '*' || name[0] == '+') && !name[1]);
|
||||
}
|
||||
|
||||
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
|
||||
{
|
||||
MSIPACKAGE *package = param;
|
||||
LPSTR value_data = NULL;
|
||||
LPSTR value;
|
||||
HKEY root_key, hkey;
|
||||
DWORD type,size;
|
||||
LPWSTR deformated, uikey, keypath;
|
||||
LPCWSTR szRoot, component, name, key, value;
|
||||
LPCWSTR szRoot, component, name, key;
|
||||
MSICOMPONENT *comp;
|
||||
MSIRECORD * uirow;
|
||||
INT root;
|
||||
|
@ -2612,10 +2652,8 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
|
|||
/* null values can have special meanings */
|
||||
if (name[0]=='-' && name[1] == 0)
|
||||
return ERROR_SUCCESS;
|
||||
else if ((name[0]=='+' && name[1] == 0) ||
|
||||
(name[0] == '*' && name[1] == 0))
|
||||
name = NULL;
|
||||
check_first = TRUE;
|
||||
if ((name[0] == '+' || name[0] == '*') && !name[1])
|
||||
check_first = TRUE;
|
||||
}
|
||||
|
||||
root = MSI_RecordGetInteger(row,2);
|
||||
|
@ -2631,49 +2669,42 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
|
|||
strcpyW(uikey,szRoot);
|
||||
strcatW(uikey,deformated);
|
||||
|
||||
keypath = get_keypath( package, root_key, deformated );
|
||||
keypath = get_keypath( comp, root_key, deformated );
|
||||
msi_free( deformated );
|
||||
if (RegCreateKeyW( root_key, keypath, &hkey ))
|
||||
if (!(hkey = open_key( root_key, keypath, TRUE )))
|
||||
{
|
||||
ERR("Could not create key %s\n", debugstr_w(keypath));
|
||||
msi_free(uikey);
|
||||
msi_free(keypath);
|
||||
return ERROR_SUCCESS;
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
value = MSI_RecordGetString(row,5);
|
||||
if (value)
|
||||
value_data = parse_value(package, value, &type, &size);
|
||||
else
|
||||
{
|
||||
value_data = (LPSTR)strdupW(szEmpty);
|
||||
size = sizeof(szEmpty);
|
||||
type = REG_SZ;
|
||||
}
|
||||
|
||||
value = parse_value(package, MSI_RecordGetString(row, 5), &type, &size);
|
||||
deformat_string(package, name, &deformated);
|
||||
|
||||
if (!check_first)
|
||||
if (!is_special_entry( name ))
|
||||
{
|
||||
TRACE("Setting value %s of %s\n",debugstr_w(deformated),
|
||||
debugstr_w(uikey));
|
||||
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value_data, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWORD sz = 0;
|
||||
rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
|
||||
if (!check_first)
|
||||
{
|
||||
TRACE("value %s of %s checked already exists\n",
|
||||
debugstr_w(deformated), debugstr_w(uikey));
|
||||
TRACE("Setting value %s of %s\n", debugstr_w(deformated),
|
||||
debugstr_w(uikey));
|
||||
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Checked and setting value %s of %s\n",
|
||||
debugstr_w(deformated), debugstr_w(uikey));
|
||||
if (deformated || size)
|
||||
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE) value_data, size);
|
||||
DWORD sz = 0;
|
||||
rc = RegQueryValueExW(hkey, deformated, NULL, NULL, NULL, &sz);
|
||||
if (rc == ERROR_SUCCESS || rc == ERROR_MORE_DATA)
|
||||
{
|
||||
TRACE("value %s of %s checked already exists\n", debugstr_w(deformated),
|
||||
debugstr_w(uikey));
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE("Checked and setting value %s of %s\n", debugstr_w(deformated),
|
||||
debugstr_w(uikey));
|
||||
if (deformated || size)
|
||||
RegSetValueExW(hkey, deformated, 0, type, (LPBYTE)value, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
RegCloseKey(hkey);
|
||||
|
@ -2682,11 +2713,11 @@ static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
|
|||
MSI_RecordSetStringW(uirow,2,deformated);
|
||||
MSI_RecordSetStringW(uirow,1,uikey);
|
||||
if (type == REG_SZ || type == REG_EXPAND_SZ)
|
||||
MSI_RecordSetStringW(uirow,3,(LPWSTR)value_data);
|
||||
MSI_RecordSetStringW(uirow, 3, (LPWSTR)value);
|
||||
msi_ui_actiondata( package, szWriteRegistryValues, uirow );
|
||||
msiobj_release( &uirow->hdr );
|
||||
|
||||
msi_free(value_data);
|
||||
msi_free(value);
|
||||
msi_free(deformated);
|
||||
msi_free(uikey);
|
||||
msi_free(keypath);
|
||||
|
@ -2711,35 +2742,68 @@ static UINT ACTION_WriteRegistryValues(MSIPACKAGE *package)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void delete_reg_value( HKEY root, const WCHAR *keypath, const WCHAR *value )
|
||||
static void delete_key( HKEY root, const WCHAR *path )
|
||||
{
|
||||
REGSAM access = 0;
|
||||
WCHAR *subkey, *p;
|
||||
HKEY hkey;
|
||||
LONG res;
|
||||
|
||||
if (is_wow64) access |= KEY_WOW64_64KEY;
|
||||
|
||||
if (!(subkey = strdupW( path ))) return;
|
||||
for (;;)
|
||||
{
|
||||
if ((p = strrchrW( subkey, '\\' ))) *p = 0;
|
||||
hkey = open_key( root, subkey, FALSE );
|
||||
if (!hkey) break;
|
||||
if (p && p[1])
|
||||
res = RegDeleteKeyExW( hkey, p + 1, access, 0 );
|
||||
else
|
||||
res = RegDeleteKeyExW( root, subkey, access, 0 );
|
||||
if (res)
|
||||
{
|
||||
TRACE("failed to delete key %s (%d)\n", debugstr_w(subkey), res);
|
||||
break;
|
||||
}
|
||||
if (p && p[1]) RegCloseKey( hkey );
|
||||
else break;
|
||||
}
|
||||
msi_free( subkey );
|
||||
}
|
||||
|
||||
static void delete_value( HKEY root, const WCHAR *path, const WCHAR *value )
|
||||
{
|
||||
LONG res;
|
||||
HKEY hkey;
|
||||
DWORD num_subkeys, num_values;
|
||||
|
||||
if (!(res = RegOpenKeyW( root, keypath, &hkey )))
|
||||
if ((hkey = open_key( root, path, FALSE )))
|
||||
{
|
||||
if ((res = RegDeleteValueW( hkey, value )))
|
||||
{
|
||||
TRACE("failed to delete value %s (%d)\n", debugstr_w(value), res);
|
||||
}
|
||||
|
||||
res = RegQueryInfoKeyW( hkey, NULL, NULL, NULL, &num_subkeys, NULL, NULL, &num_values,
|
||||
NULL, NULL, NULL, NULL );
|
||||
RegCloseKey( hkey );
|
||||
if (!res && !num_subkeys && !num_values)
|
||||
{
|
||||
TRACE("removing empty key %s\n", debugstr_w(keypath));
|
||||
RegDeleteKeyW( root, keypath );
|
||||
TRACE("removing empty key %s\n", debugstr_w(path));
|
||||
delete_key( root, path );
|
||||
}
|
||||
return;
|
||||
}
|
||||
TRACE("failed to open key %s (%d)\n", debugstr_w(keypath), res);
|
||||
}
|
||||
|
||||
static void delete_reg_key( HKEY root, const WCHAR *keypath )
|
||||
static void delete_tree( HKEY root, const WCHAR *path )
|
||||
{
|
||||
LONG res = RegDeleteTreeW( root, keypath );
|
||||
if (res) TRACE("failed to delete key %s (%d)\n", debugstr_w(keypath), res);
|
||||
LONG res;
|
||||
HKEY hkey;
|
||||
|
||||
if (!(hkey = open_key( root, path, FALSE ))) return;
|
||||
res = RegDeleteTreeW( hkey, NULL );
|
||||
if (res) TRACE("failed to delete subtree of %s (%d)\n", debugstr_w(path), res);
|
||||
delete_key( root, path );
|
||||
RegCloseKey( hkey );
|
||||
}
|
||||
|
||||
static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID param )
|
||||
|
@ -2773,7 +2837,7 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
|
|||
{
|
||||
if (name[0] == '+' && !name[1])
|
||||
return ERROR_SUCCESS;
|
||||
else if ((name[0] == '-' && !name[1]) || (name[0] == '*' && !name[1]))
|
||||
if ((name[0] == '-' || name[0] == '*') && !name[1])
|
||||
{
|
||||
delete_key = TRUE;
|
||||
name = NULL;
|
||||
|
@ -2795,10 +2859,10 @@ static UINT ITERATE_RemoveRegistryValuesOnUninstall( MSIRECORD *row, LPVOID para
|
|||
|
||||
deformat_string( package, name, &deformated_name );
|
||||
|
||||
keypath = get_keypath( package, hkey_root, deformated_key );
|
||||
keypath = get_keypath( comp, hkey_root, deformated_key );
|
||||
msi_free( deformated_key );
|
||||
if (delete_key) delete_reg_key( hkey_root, keypath );
|
||||
else delete_reg_value( hkey_root, keypath, deformated_name );
|
||||
if (delete_key) delete_tree( hkey_root, keypath );
|
||||
else delete_value( hkey_root, keypath, deformated_name );
|
||||
msi_free( keypath );
|
||||
|
||||
uirow = MSI_CreateRecord( 2 );
|
||||
|
@ -2860,10 +2924,10 @@ static UINT ITERATE_RemoveRegistryValuesOnInstall( MSIRECORD *row, LPVOID param
|
|||
|
||||
deformat_string( package, name, &deformated_name );
|
||||
|
||||
keypath = get_keypath( package, hkey_root, deformated_key );
|
||||
keypath = get_keypath( comp, hkey_root, deformated_key );
|
||||
msi_free( deformated_key );
|
||||
if (delete_key) delete_reg_key( hkey_root, keypath );
|
||||
else delete_reg_value( hkey_root, keypath, deformated_name );
|
||||
if (delete_key) delete_tree( hkey_root, keypath );
|
||||
else delete_value( hkey_root, keypath, deformated_name );
|
||||
msi_free( keypath );
|
||||
|
||||
uirow = MSI_CreateRecord( 2 );
|
||||
|
@ -6981,23 +7045,51 @@ static UINT ACTION_SetODBCFolders( MSIPACKAGE *package )
|
|||
|
||||
static UINT ITERATE_RemoveExistingProducts( MSIRECORD *rec, LPVOID param )
|
||||
{
|
||||
static const WCHAR fmtW[] =
|
||||
{'m','s','i','e','x','e','c',' ','/','i',' ','%','s',' ','R','E','M','O','V','E','=','%','s',0};
|
||||
MSIPACKAGE *package = param;
|
||||
const WCHAR *property = MSI_RecordGetString( rec, 1 );
|
||||
WCHAR *value;
|
||||
const WCHAR *property = MSI_RecordGetString( rec, 7 );
|
||||
UINT len = sizeof(fmtW)/sizeof(fmtW[0]);
|
||||
WCHAR *product, *features, *cmd;
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION info;
|
||||
BOOL ret;
|
||||
|
||||
if ((value = msi_dup_property( package->db, property )))
|
||||
if (!(product = msi_dup_property( package->db, property ))) return ERROR_SUCCESS;
|
||||
|
||||
deformat_string( package, MSI_RecordGetString( rec, 6 ), &features );
|
||||
|
||||
len += strlenW( product );
|
||||
if (features)
|
||||
len += strlenW( features );
|
||||
else
|
||||
len += sizeof(szAll) / sizeof(szAll[0]);
|
||||
|
||||
if (!(cmd = msi_alloc( len * sizeof(WCHAR) )))
|
||||
{
|
||||
FIXME("remove %s\n", debugstr_w(value));
|
||||
msi_free( value );
|
||||
msi_free( product );
|
||||
msi_free( features );
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
sprintfW( cmd, fmtW, product, features ? features : szAll );
|
||||
msi_free( product );
|
||||
msi_free( features );
|
||||
|
||||
memset( &si, 0, sizeof(STARTUPINFOW) );
|
||||
ret = CreateProcessW( NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &info );
|
||||
msi_free( cmd );
|
||||
if (!ret) return GetLastError();
|
||||
CloseHandle( info.hThread );
|
||||
|
||||
WaitForSingleObject( info.hProcess, INFINITE );
|
||||
CloseHandle( info.hProcess );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static UINT ACTION_RemoveExistingProducts( MSIPACKAGE *package )
|
||||
{
|
||||
static const WCHAR query[] = {
|
||||
'S','E','L','E','C','T',' ','A','c','t','i','o','n','P','r','o','p','e','r','t','y',' ',
|
||||
'F','R','O','M',' ','U','p','g','r','a','d','e',0};
|
||||
'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','U','p','g','r','a','d','e',0};
|
||||
MSIQUERY *view;
|
||||
UINT r;
|
||||
|
||||
|
@ -7340,6 +7432,7 @@ UINT ACTION_PerformUIAction(MSIPACKAGE *package, const WCHAR *action, UINT scrip
|
|||
|
||||
TRACE("Performing action (%s)\n", debugstr_w(action));
|
||||
|
||||
package->action_progress_increment = 0;
|
||||
handled = ACTION_HandleStandardAction(package, action, &rc);
|
||||
|
||||
if (!handled)
|
||||
|
|
|
@ -34,25 +34,41 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
|
|||
static HRESULT (WINAPI *pCreateAssemblyCacheNet10)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheNet11)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheNet20)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheNet40)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pCreateAssemblyCacheSxs)( IAssemblyCache **, DWORD );
|
||||
static HRESULT (WINAPI *pLoadLibraryShim)( LPCWSTR, LPCWSTR, LPVOID, HMODULE * );
|
||||
static HRESULT (WINAPI *pGetFileVersion)( LPCWSTR, LPWSTR, DWORD, DWORD * );
|
||||
|
||||
static HMODULE hfusion10, hfusion11, hfusion20, hmscoree, hsxs;
|
||||
static HMODULE hfusion10, hfusion11, hfusion20, hfusion40, hmscoree, hsxs;
|
||||
|
||||
static BOOL init_function_pointers( void )
|
||||
{
|
||||
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
|
||||
static const WCHAR szFusion[] = {'f','u','s','i','o','n','.','d','l','l',0};
|
||||
static const WCHAR szMscoree[] = {'\\','m','s','c','o','r','e','e','.','d','l','l',0};
|
||||
static const WCHAR szSxs[] = {'s','x','s','.','d','l','l',0};
|
||||
static const WCHAR szVersion10[] = {'v','1','.','0','.','3','7','0','5',0};
|
||||
static const WCHAR szVersion11[] = {'v','1','.','1','.','4','3','2','2',0};
|
||||
static const WCHAR szVersion20[] = {'v','2','.','0','.','5','0','7','2','7',0};
|
||||
static const WCHAR szVersion40[] = {'v','4','.','0','.','3','0','3','1','9',0};
|
||||
WCHAR path[MAX_PATH];
|
||||
DWORD len = GetSystemDirectoryW( path, MAX_PATH );
|
||||
|
||||
if (pCreateAssemblyCacheNet10 || pCreateAssemblyCacheNet11 || pCreateAssemblyCacheNet20) return TRUE;
|
||||
|
||||
if (!(hmscoree = LoadLibraryA( "mscoree.dll" ))) return FALSE;
|
||||
if (!hsxs && !(hsxs = LoadLibraryW( szSxs ))) return FALSE;
|
||||
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" )))
|
||||
{
|
||||
FreeLibrary( hsxs );
|
||||
hsxs = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
strcpyW( path + len, szMscoree );
|
||||
if (hmscoree || !(hmscoree = LoadLibraryW( path ))) return TRUE;
|
||||
pGetFileVersion = (void *)GetProcAddress( hmscoree, "GetFileVersion" ); /* missing from v1.0.3705 */
|
||||
if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" ))) goto error;
|
||||
|
||||
if (!(pLoadLibraryShim = (void *)GetProcAddress( hmscoree, "LoadLibraryShim" )))
|
||||
{
|
||||
FreeLibrary( hmscoree );
|
||||
hmscoree = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
if (!pLoadLibraryShim( szFusion, szVersion10, NULL, &hfusion10 ))
|
||||
pCreateAssemblyCacheNet10 = (void *)GetProcAddress( hfusion10, "CreateAssemblyCache" );
|
||||
|
||||
|
@ -62,65 +78,32 @@ static BOOL init_function_pointers( void )
|
|||
if (!pLoadLibraryShim( szFusion, szVersion20, NULL, &hfusion20 ))
|
||||
pCreateAssemblyCacheNet20 = (void *)GetProcAddress( hfusion20, "CreateAssemblyCache" );
|
||||
|
||||
if (!pCreateAssemblyCacheNet10 && !pCreateAssemblyCacheNet11 && !pCreateAssemblyCacheNet20) goto error;
|
||||
if (!pLoadLibraryShim( szFusion, szVersion40, NULL, &hfusion40 ))
|
||||
pCreateAssemblyCacheNet40 = (void *)GetProcAddress( hfusion40, "CreateAssemblyCache" );
|
||||
|
||||
if (!(hsxs = LoadLibraryA( "sxs.dll" ))) goto error;
|
||||
if (!(pCreateAssemblyCacheSxs = (void *)GetProcAddress( hsxs, "CreateAssemblyCache" ))) goto error;
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
pCreateAssemblyCacheNet10 = NULL;
|
||||
pCreateAssemblyCacheNet11 = NULL;
|
||||
pCreateAssemblyCacheNet20 = NULL;
|
||||
FreeLibrary( hfusion10 );
|
||||
FreeLibrary( hfusion11 );
|
||||
FreeLibrary( hfusion20 );
|
||||
FreeLibrary( hmscoree );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL msi_init_assembly_caches( MSIPACKAGE *package )
|
||||
{
|
||||
if (!init_function_pointers()) return FALSE;
|
||||
if (package->cache_net[CLR_VERSION_V10] ||
|
||||
package->cache_net[CLR_VERSION_V11] ||
|
||||
package->cache_net[CLR_VERSION_V20]) return TRUE;
|
||||
if (pCreateAssemblyCacheSxs( &package->cache_sxs, 0 ) != S_OK) return FALSE;
|
||||
|
||||
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V10], 0 );
|
||||
if (pCreateAssemblyCacheNet10) pCreateAssemblyCacheNet10( &package->cache_net[CLR_VERSION_V10], 0 );
|
||||
if (pCreateAssemblyCacheNet11) pCreateAssemblyCacheNet11( &package->cache_net[CLR_VERSION_V11], 0 );
|
||||
if (pCreateAssemblyCacheNet20) pCreateAssemblyCacheNet20( &package->cache_net[CLR_VERSION_V20], 0 );
|
||||
|
||||
if (package->cache_net[CLR_VERSION_V10] ||
|
||||
package->cache_net[CLR_VERSION_V11] ||
|
||||
package->cache_net[CLR_VERSION_V20])
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (package->cache_net[CLR_VERSION_V10])
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V10] );
|
||||
package->cache_net[CLR_VERSION_V10] = NULL;
|
||||
}
|
||||
if (package->cache_net[CLR_VERSION_V11])
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V11] );
|
||||
package->cache_net[CLR_VERSION_V11] = NULL;
|
||||
}
|
||||
if (package->cache_net[CLR_VERSION_V20])
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_net[CLR_VERSION_V20] );
|
||||
package->cache_net[CLR_VERSION_V20] = NULL;
|
||||
}
|
||||
IAssemblyCache_Release( package->cache_sxs );
|
||||
package->cache_sxs = NULL;
|
||||
return FALSE;
|
||||
if (pCreateAssemblyCacheNet40) pCreateAssemblyCacheNet40( &package->cache_net[CLR_VERSION_V40], 0 );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void msi_destroy_assembly_caches( MSIPACKAGE *package )
|
||||
{
|
||||
UINT i;
|
||||
|
||||
if (package->cache_sxs)
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_sxs );
|
||||
package->cache_sxs = NULL;
|
||||
}
|
||||
for (i = 0; i < CLR_VERSION_MAX; i++)
|
||||
{
|
||||
if (package->cache_net[i])
|
||||
|
@ -129,19 +112,22 @@ void msi_destroy_assembly_caches( MSIPACKAGE *package )
|
|||
package->cache_net[i] = NULL;
|
||||
}
|
||||
}
|
||||
if (package->cache_sxs)
|
||||
{
|
||||
IAssemblyCache_Release( package->cache_sxs );
|
||||
package->cache_sxs = NULL;
|
||||
}
|
||||
pCreateAssemblyCacheNet10 = NULL;
|
||||
pCreateAssemblyCacheNet11 = NULL;
|
||||
pCreateAssemblyCacheNet20 = NULL;
|
||||
pCreateAssemblyCacheNet40 = NULL;
|
||||
FreeLibrary( hfusion10 );
|
||||
FreeLibrary( hfusion11 );
|
||||
FreeLibrary( hfusion20 );
|
||||
FreeLibrary( hfusion40 );
|
||||
FreeLibrary( hmscoree );
|
||||
FreeLibrary( hsxs );
|
||||
hfusion10 = NULL;
|
||||
hfusion11 = NULL;
|
||||
hfusion20 = NULL;
|
||||
hfusion40 = NULL;
|
||||
hmscoree = NULL;
|
||||
hsxs = NULL;
|
||||
}
|
||||
|
||||
static MSIRECORD *get_assembly_record( MSIPACKAGE *package, const WCHAR *comp )
|
||||
|
@ -260,6 +246,8 @@ static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_n
|
|||
HRESULT hr;
|
||||
ASSEMBLY_INFO info;
|
||||
|
||||
if (!cache) return FALSE;
|
||||
|
||||
memset( &info, 0, sizeof(info) );
|
||||
info.cbAssemblyInfo = sizeof(info);
|
||||
hr = IAssemblyCache_QueryAssemblyInfo( cache, 0, display_name, &info );
|
||||
|
@ -274,13 +262,15 @@ static BOOL is_assembly_installed( IAssemblyCache *cache, const WCHAR *display_n
|
|||
static const WCHAR clr_version_v10[] = {'v','1','.','0','.','3','7','0','5',0};
|
||||
static const WCHAR clr_version_v11[] = {'v','1','.','1','.','4','3','2','2',0};
|
||||
static const WCHAR clr_version_v20[] = {'v','2','.','0','.','5','0','7','2','7',0};
|
||||
static const WCHAR clr_version_v40[] = {'v','4','.','0','.','3','0','3','1','9',0};
|
||||
static const WCHAR clr_version_unknown[] = {'u','n','k','n','o','w','n',0};
|
||||
|
||||
static const WCHAR *clr_version[] =
|
||||
{
|
||||
clr_version_v10,
|
||||
clr_version_v11,
|
||||
clr_version_v20
|
||||
clr_version_v20,
|
||||
clr_version_v40
|
||||
};
|
||||
|
||||
static const WCHAR *get_clr_version_str( enum clr_version version )
|
||||
|
@ -347,6 +337,7 @@ MSIASSEMBLY *msi_load_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
|
|||
{
|
||||
TRACE("runtime version %s\n", debugstr_w(get_clr_version_str( i )));
|
||||
a->installed = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +402,7 @@ UINT msi_install_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
|
|||
{
|
||||
manifest = msi_get_loaded_file( package, comp->KeyPath )->TargetPath;
|
||||
cache = package->cache_net[get_clr_version( manifest )];
|
||||
if (!cache) return ERROR_SUCCESS;
|
||||
}
|
||||
TRACE("installing assembly %s\n", debugstr_w(manifest));
|
||||
|
||||
|
@ -455,8 +447,11 @@ UINT msi_uninstall_assembly( MSIPACKAGE *package, MSICOMPONENT *comp )
|
|||
{
|
||||
if (!assembly->clr_version[i]) continue;
|
||||
cache = package->cache_net[i];
|
||||
hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
|
||||
if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
|
||||
if (cache)
|
||||
{
|
||||
hr = IAssemblyCache_UninstallAssembly( cache, 0, assembly->display_name, NULL, NULL );
|
||||
if (FAILED( hr )) WARN("failed to uninstall assembly 0x%08x\n", hr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (feature) feature->Action = INSTALLSTATE_ABSENT;
|
||||
|
|
|
@ -609,8 +609,7 @@ static HRESULT WINAPI ListEnumerator_Clone(IEnumVARIANT* iface, IEnumVARIANT **p
|
|||
hr = create_list_enumerator(This->list, (LPVOID *)ppEnum);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (*ppEnum)
|
||||
IUnknown_Release(*ppEnum);
|
||||
if (*ppEnum) IEnumVARIANT_Release(*ppEnum);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
@ -935,13 +935,15 @@ static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
|
|||
static UINT HANDLE_CustomType34(MSIPACKAGE *package, LPCWSTR source,
|
||||
LPCWSTR target, const INT type, LPCWSTR action)
|
||||
{
|
||||
const WCHAR *workingdir;
|
||||
const WCHAR *workingdir = NULL;
|
||||
HANDLE handle;
|
||||
WCHAR *cmd;
|
||||
|
||||
workingdir = msi_get_target_folder( package, source );
|
||||
if (!workingdir) return ERROR_FUNCTION_FAILED;
|
||||
|
||||
if (source)
|
||||
{
|
||||
workingdir = msi_get_target_folder( package, source );
|
||||
if (!workingdir) return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
deformat_string( package, target, &cmd );
|
||||
if (!cmd) return ERROR_FUNCTION_FAILED;
|
||||
|
||||
|
@ -957,7 +959,7 @@ static DWORD ACTION_CallScript( const GUID *guid )
|
|||
{
|
||||
msi_custom_action_info *info;
|
||||
MSIHANDLE hPackage;
|
||||
UINT r;
|
||||
UINT r = ERROR_FUNCTION_FAILED;
|
||||
|
||||
info = find_action_by_guid( guid );
|
||||
if (!info)
|
||||
|
@ -979,13 +981,13 @@ static DWORD ACTION_CallScript( const GUID *guid )
|
|||
ERR("failed to create handle for %p\n", info->package );
|
||||
|
||||
release_custom_action_data( info );
|
||||
return S_OK;
|
||||
return r;
|
||||
}
|
||||
|
||||
static DWORD WINAPI ScriptThread( LPVOID arg )
|
||||
{
|
||||
LPGUID guid = arg;
|
||||
DWORD rc = 0;
|
||||
DWORD rc;
|
||||
|
||||
TRACE("custom action (%x) started\n", GetCurrentThreadId() );
|
||||
|
||||
|
@ -1437,7 +1439,7 @@ static HRESULT WINAPI mcr_QueryInterface( IWineMsiRemoteCustomAction *iface,
|
|||
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
|
||||
IsEqualCLSID( riid, &IID_IWineMsiRemoteCustomAction ) )
|
||||
{
|
||||
IUnknown_AddRef( iface );
|
||||
IWineMsiRemoteCustomAction_AddRef( iface );
|
||||
*ppobj = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ UINT msi_get_raw_stream( MSIDATABASE *db, LPCWSTR stname, IStream **stm )
|
|||
|
||||
if (!(stream = msi_alloc( sizeof(MSISTREAM) ))) return ERROR_NOT_ENOUGH_MEMORY;
|
||||
stream->stg = stg;
|
||||
IStream_AddRef( stg );
|
||||
IStorage_AddRef( stg );
|
||||
stream->stm = *stm;
|
||||
IStream_AddRef( *stm );
|
||||
list_add_tail( &db->streams, &stream->entry );
|
||||
|
@ -207,7 +207,7 @@ void msi_destroy_stream( MSIDATABASE *db, const WCHAR *stname )
|
|||
|
||||
list_remove( &stream->entry );
|
||||
IStream_Release( stream->stm );
|
||||
IStream_Release( stream->stg );
|
||||
IStorage_Release( stream->stg );
|
||||
IStorage_DestroyElement( stream->stg, stname );
|
||||
msi_free( stream );
|
||||
CoTaskMemFree( stat.pwcsName );
|
||||
|
@ -224,7 +224,7 @@ static void free_streams( MSIDATABASE *db )
|
|||
MSISTREAM *s = LIST_ENTRY(list_head( &db->streams ), MSISTREAM, entry);
|
||||
list_remove( &s->entry );
|
||||
IStream_Release( s->stm );
|
||||
IStream_Release( s->stg );
|
||||
IStorage_Release( s->stg );
|
||||
msi_free( s );
|
||||
}
|
||||
}
|
||||
|
@ -2082,7 +2082,7 @@ static HRESULT WINAPI mrd_QueryInterface( IWineMsiRemoteDatabase *iface,
|
|||
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
|
||||
IsEqualCLSID( riid, &IID_IWineMsiRemoteDatabase ) )
|
||||
{
|
||||
IUnknown_AddRef( iface );
|
||||
IWineMsiRemoteDatabase_AddRef( iface );
|
||||
*ppobj = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -644,11 +644,11 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
|||
|
||||
TRACE("progress: func %u val1 %u val2 %u\n", func, val1, val2);
|
||||
|
||||
units = val1 / 512;
|
||||
switch (func)
|
||||
{
|
||||
case 0: /* init */
|
||||
SendMessageW( ctrl->hwnd, PBM_SETRANGE, 0, MAKELPARAM(0,100) );
|
||||
units = val1 / 512;
|
||||
if (val2)
|
||||
{
|
||||
ctrl->progress_max = units ? units : 100;
|
||||
|
@ -664,10 +664,11 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
|||
SendMessageW( ctrl->hwnd, PBM_SETPOS, 0, 0 );
|
||||
}
|
||||
break;
|
||||
case 1: /* FIXME: not sure what this is supposed to do */
|
||||
case 1: /* action data increment */
|
||||
if (val2) dialog->package->action_progress_increment = val1;
|
||||
else dialog->package->action_progress_increment = 0;
|
||||
break;
|
||||
case 2: /* move */
|
||||
units = val1 / 512;
|
||||
if (ctrl->progress_backwards)
|
||||
{
|
||||
if (units >= ctrl->progress_current) ctrl->progress_current -= units;
|
||||
|
@ -680,6 +681,9 @@ void msi_dialog_handle_event( msi_dialog* dialog, LPCWSTR control,
|
|||
}
|
||||
SendMessageW( ctrl->hwnd, PBM_SETPOS, MulDiv(100, ctrl->progress_current, ctrl->progress_max), 0 );
|
||||
break;
|
||||
case 3: /* add */
|
||||
ctrl->progress_max += units;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unknown progress message %u\n", func);
|
||||
break;
|
||||
|
|
|
@ -399,7 +399,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
|||
goto done;
|
||||
}
|
||||
}
|
||||
msi_init_assembly_caches( package );
|
||||
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||
{
|
||||
comp->Action = msi_get_component_action( package, comp );
|
||||
|
@ -414,7 +413,6 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
|||
}
|
||||
}
|
||||
}
|
||||
msi_destroy_assembly_caches( package );
|
||||
|
||||
done:
|
||||
msi_free_media_info(mi);
|
||||
|
@ -1309,7 +1307,6 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
|||
msiobj_release( &uirow->hdr );
|
||||
}
|
||||
|
||||
msi_init_assembly_caches( package );
|
||||
LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
|
||||
{
|
||||
comp->Action = msi_get_component_action( package, comp );
|
||||
|
@ -1328,6 +1325,5 @@ UINT ACTION_RemoveFiles( MSIPACKAGE *package )
|
|||
remove_folder( folder );
|
||||
}
|
||||
}
|
||||
msi_destroy_assembly_caches( package );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -4207,3 +4207,9 @@ UINT WINAPI MsiEndTransaction( DWORD state )
|
|||
FIXME("%u\n", state);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
UINT WINAPI Migrate10CachedPackagesW(void* a, void* b, void* c, DWORD d)
|
||||
{
|
||||
FIXME("%p,%p,%p,%08x\n", a, b, c, d);
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -229,7 +229,7 @@
|
|||
233 stub MsiDeleteUserDataA
|
||||
234 stub MsiDeleteUserDataW
|
||||
235 stub Migrate10CachedPackagesA
|
||||
236 stub Migrate10CachedPackagesW
|
||||
236 stdcall Migrate10CachedPackagesW(ptr ptr ptr long)
|
||||
237 stub MsiRemovePatchesA
|
||||
238 stub MsiRemovePatchesW
|
||||
239 stdcall MsiApplyMultiplePatchesA(str str str)
|
||||
|
|
|
@ -73,6 +73,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|||
case DLL_PROCESS_ATTACH:
|
||||
msi_hInstance = hinstDLL;
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
IsWow64Process( GetCurrentProcess(), &is_wow64 );
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
msi_dialog_unregister_class();
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "wine/debug.h"
|
||||
|
||||
static const BOOL is_64bit = sizeof(void *) > sizeof(int);
|
||||
BOOL is_wow64;
|
||||
|
||||
#define MSI_DATASIZEMASK 0x00ff
|
||||
#define MSITYPE_VALID 0x0100
|
||||
|
@ -347,6 +348,7 @@ enum clr_version
|
|||
CLR_VERSION_V10,
|
||||
CLR_VERSION_V11,
|
||||
CLR_VERSION_V20,
|
||||
CLR_VERSION_V40,
|
||||
CLR_VERSION_MAX
|
||||
};
|
||||
|
||||
|
@ -369,6 +371,7 @@ typedef struct tagMSIPACKAGE
|
|||
struct list cabinet_streams;
|
||||
LPWSTR ActionFormat;
|
||||
LPWSTR LastAction;
|
||||
UINT action_progress_increment;
|
||||
HANDLE log_file;
|
||||
IAssemblyCache *cache_net[CLR_VERSION_MAX];
|
||||
IAssemblyCache *cache_sxs;
|
||||
|
|
|
@ -344,9 +344,10 @@ static void free_package_structures( MSIPACKAGE *package )
|
|||
|
||||
static void MSI_FreePackage( MSIOBJECTHDR *arg)
|
||||
{
|
||||
UINT i;
|
||||
MSIPACKAGE *package = (MSIPACKAGE *)arg;
|
||||
|
||||
msi_destroy_assembly_caches( package );
|
||||
|
||||
if( package->dialog )
|
||||
msi_dialog_destroy( package->dialog );
|
||||
|
||||
|
@ -354,10 +355,6 @@ static void MSI_FreePackage( MSIOBJECTHDR *arg)
|
|||
free_package_structures(package);
|
||||
CloseHandle( package->log_file );
|
||||
|
||||
for (i = 0; i < CLR_VERSION_MAX; i++)
|
||||
if (package->cache_net[i]) IAssemblyCache_Release( package->cache_net[i] );
|
||||
if (package->cache_sxs) IAssemblyCache_Release( package->cache_sxs );
|
||||
|
||||
if (package->delete_on_close) DeleteFileW( package->localfile );
|
||||
msi_free( package->localfile );
|
||||
}
|
||||
|
@ -669,12 +666,11 @@ done:
|
|||
|
||||
static VOID set_installer_properties(MSIPACKAGE *package)
|
||||
{
|
||||
WCHAR pth[MAX_PATH];
|
||||
WCHAR *ptr;
|
||||
OSVERSIONINFOEXW OSVersion;
|
||||
MEMORYSTATUSEX msex;
|
||||
DWORD verval, len;
|
||||
WCHAR verstr[10], bufstr[20];
|
||||
WCHAR pth[MAX_PATH], verstr[11], bufstr[22];
|
||||
HDC dc;
|
||||
HKEY hkey;
|
||||
LPWSTR username, companyname;
|
||||
|
@ -704,14 +700,13 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
|||
static const WCHAR szVersion9x[] = {'V','e','r','s','i','o','n','9','X',0};
|
||||
static const WCHAR szVersionNT[] = {'V','e','r','s','i','o','n','N','T',0};
|
||||
static const WCHAR szMsiNTProductType[] = {'M','s','i','N','T','P','r','o','d','u','c','t','T','y','p','e',0};
|
||||
static const WCHAR szFormat[] = {'%','l','i',0};
|
||||
static const WCHAR szFormat[] = {'%','u',0};
|
||||
static const WCHAR szFormat2[] = {'%','u','.','%','u',0};
|
||||
static const WCHAR szWindowsBuild[] = {'W','i','n','d','o','w','s','B','u','i','l','d',0};
|
||||
static const WCHAR szServicePackLevel[] = {'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',0};
|
||||
static const WCHAR szSix[] = {'6',0 };
|
||||
static const WCHAR szVersionMsi[] = { 'V','e','r','s','i','o','n','M','s','i',0 };
|
||||
static const WCHAR szVersionDatabase[] = { 'V','e','r','s','i','o','n','D','a','t','a','b','a','s','e',0 };
|
||||
static const WCHAR szPhysicalMemory[] = { 'P','h','y','s','i','c','a','l','M','e','m','o','r','y',0 };
|
||||
static const WCHAR szFormat2[] = {'%','l','i','.','%','l','i',0};
|
||||
static const WCHAR szScreenX[] = {'S','c','r','e','e','n','X',0};
|
||||
static const WCHAR szScreenY[] = {'S','c','r','e','e','n','Y',0};
|
||||
static const WCHAR szColorBits[] = {'C','o','l','o','r','B','i','t','s',0};
|
||||
|
@ -874,8 +869,8 @@ static VOID set_installer_properties(MSIPACKAGE *package)
|
|||
}
|
||||
sprintfW(verstr, szFormat, OSVersion.dwBuildNumber);
|
||||
msi_set_property(package->db, szWindowsBuild, verstr);
|
||||
/* just fudge this */
|
||||
msi_set_property(package->db, szServicePackLevel, szSix);
|
||||
sprintfW(verstr, szFormat, OSVersion.wServicePackMajor);
|
||||
msi_set_property(package->db, szServicePackLevel, verstr);
|
||||
|
||||
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
|
||||
msi_set_property( package->db, szVersionMsi, bufstr );
|
||||
|
@ -1339,7 +1334,6 @@ static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
|
|||
|
||||
static UINT validate_package( MSIPACKAGE *package )
|
||||
{
|
||||
BOOL is_wow64;
|
||||
UINT i;
|
||||
|
||||
if (package->platform == PLATFORM_INTEL64)
|
||||
|
@ -1348,7 +1342,6 @@ static UINT validate_package( MSIPACKAGE *package )
|
|||
if (package->platform == PLATFORM_ARM)
|
||||
return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
|
||||
#endif
|
||||
IsWow64Process( GetCurrentProcess(), &is_wow64 );
|
||||
if (package->platform == PLATFORM_X64)
|
||||
{
|
||||
if (!is_64bit && !is_wow64)
|
||||
|
@ -1905,8 +1898,16 @@ INT MSI_ProcessMessage( MSIPACKAGE *package, INSTALLMESSAGE eMessageType, MSIREC
|
|||
msi_free(deformated);
|
||||
|
||||
ControlEvent_FireSubscribedEvent(package, szActionData, uirow);
|
||||
|
||||
msiobj_release(&uirow->hdr);
|
||||
|
||||
if (package->action_progress_increment)
|
||||
{
|
||||
uirow = MSI_CreateRecord(2);
|
||||
MSI_RecordSetInteger(uirow, 1, 2);
|
||||
MSI_RecordSetInteger(uirow, 2, package->action_progress_increment);
|
||||
ControlEvent_FireSubscribedEvent(package, szSetProgress, uirow);
|
||||
msiobj_release(&uirow->hdr);
|
||||
}
|
||||
break;
|
||||
|
||||
case INSTALLMESSAGE_ACTIONSTART:
|
||||
|
@ -2360,7 +2361,7 @@ static HRESULT WINAPI mrp_QueryInterface( IWineMsiRemotePackage *iface,
|
|||
if( IsEqualCLSID( riid, &IID_IUnknown ) ||
|
||||
IsEqualCLSID( riid, &IID_IWineMsiRemotePackage ) )
|
||||
{
|
||||
IUnknown_AddRef( iface );
|
||||
IWineMsiRemotePackage_AddRef( iface );
|
||||
*ppobj = iface;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,8 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
|
|||
{
|
||||
HRESULT hr;
|
||||
IActiveScript *pActiveScript = NULL;
|
||||
IActiveScriptParse *pActiveScriptParse = NULL;
|
||||
IActiveScriptParse32 *pActiveScriptParse32 = NULL;
|
||||
IActiveScriptParse64 *pActiveScriptParse64 = NULL;
|
||||
MsiActiveScriptSite *pActiveScriptSite = NULL;
|
||||
IDispatch *pDispatch = NULL;
|
||||
DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
|
||||
|
@ -123,27 +124,41 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Get the IActiveScriptParse engine interface */
|
||||
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse, (void **)&pActiveScriptParse);
|
||||
if (FAILED(hr)) goto done;
|
||||
if (type & msidbCustomActionType64BitScript)
|
||||
{
|
||||
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse64, (void **)&pActiveScriptParse64);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
/* Give our host to the engine */
|
||||
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
|
||||
if (FAILED(hr)) goto done;
|
||||
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
/* Initialize the script engine */
|
||||
hr = IActiveScriptParse64_InitNew(pActiveScriptParse);
|
||||
if (FAILED(hr)) goto done;
|
||||
hr = IActiveScriptParse64_InitNew(pActiveScriptParse64);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
/* Add the session object */
|
||||
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
|
||||
if (FAILED(hr)) goto done;
|
||||
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
/* Pass the script to the engine */
|
||||
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
|
||||
if (FAILED(hr)) goto done;
|
||||
hr = IActiveScriptParse64_ParseScriptText(pActiveScriptParse64, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
|
||||
if (FAILED(hr)) goto done;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = IActiveScript_QueryInterface(pActiveScript, &IID_IActiveScriptParse32, (void **)&pActiveScriptParse32);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
hr = IActiveScript_SetScriptSite(pActiveScript, (IActiveScriptSite *)pActiveScriptSite);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
hr = IActiveScriptParse32_InitNew(pActiveScriptParse32);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
hr = IActiveScript_AddNamedItem(pActiveScript, szSession, SCRIPTITEM_GLOBALMEMBERS);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
hr = IActiveScriptParse32_ParseScriptText(pActiveScriptParse32, script, NULL, NULL, NULL, 0, 0, 0L, NULL, NULL);
|
||||
if (FAILED(hr)) goto done;
|
||||
}
|
||||
|
||||
/* Start processing the script */
|
||||
hr = IActiveScript_SetScriptState(pActiveScript, SCRIPTSTATE_CONNECTED);
|
||||
if (FAILED(hr)) goto done;
|
||||
|
||||
|
@ -176,17 +191,17 @@ DWORD call_script(MSIHANDLE hPackage, INT type, LPCWSTR script, LPCWSTR function
|
|||
|
||||
done:
|
||||
|
||||
/* Free everything that needs to be freed */
|
||||
if (pDispatch) IDispatch_Release(pDispatch);
|
||||
if (pActiveScript) IActiveScriptSite_Release(pActiveScript);
|
||||
if (pActiveScriptSite &&
|
||||
pActiveScriptSite->pSession) IUnknown_Release((IUnknown *)pActiveScriptSite->pSession);
|
||||
if (pActiveScriptSite &&
|
||||
pActiveScriptSite->pInstaller) IUnknown_Release((IUnknown *)pActiveScriptSite->pInstaller);
|
||||
if (pActiveScriptSite) IUnknown_Release((IUnknown *)pActiveScriptSite);
|
||||
|
||||
if (pActiveScript) IActiveScript_Release(pActiveScript);
|
||||
if (pActiveScriptParse32) IActiveScriptParse32_Release(pActiveScriptParse32);
|
||||
if (pActiveScriptParse64) IActiveScriptParse64_Release(pActiveScriptParse64);
|
||||
if (pActiveScriptSite)
|
||||
{
|
||||
if (pActiveScriptSite->pSession) IDispatch_Release(pActiveScriptSite->pSession);
|
||||
if (pActiveScriptSite->pInstaller) IDispatch_Release(pActiveScriptSite->pInstaller);
|
||||
IActiveScriptSite_Release((IActiveScriptSite *)pActiveScriptSite);
|
||||
}
|
||||
CoUninitialize(); /* must call even if CoInitialize failed */
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -204,7 +219,7 @@ static HRESULT WINAPI MsiActiveScriptSite_QueryInterface(IActiveScriptSite* ifac
|
|||
if (IsEqualGUID(riid, &IID_IUnknown) ||
|
||||
IsEqualGUID(riid, &IID_IActiveScriptSite))
|
||||
{
|
||||
IClassFactory_AddRef(iface);
|
||||
IActiveScriptSite_AddRef(iface);
|
||||
*ppvObject = This;
|
||||
return S_OK;
|
||||
}
|
||||
|
|
|
@ -357,14 +357,12 @@ const WCHAR *msi_string_lookup_id( const string_table *st, UINT id )
|
|||
* [in/out] sz - number of bytes available in the buffer on input
|
||||
* number of bytes used on output
|
||||
*
|
||||
* The size includes the terminating nul character. Short buffers
|
||||
* will be filled, but not nul terminated.
|
||||
* Returned string is not nul terminated.
|
||||
*/
|
||||
static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT *sz )
|
||||
{
|
||||
UINT len;
|
||||
UINT len, lenW;
|
||||
const WCHAR *str;
|
||||
int n;
|
||||
|
||||
TRACE("Finding string %d of %d\n", id, st->maxcount);
|
||||
|
||||
|
@ -372,26 +370,14 @@ static UINT msi_id2stringA( const string_table *st, UINT id, LPSTR buffer, UINT
|
|||
if( !str )
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
|
||||
len = WideCharToMultiByte( st->codepage, 0, str, -1, NULL, 0, NULL, NULL );
|
||||
|
||||
if( !buffer )
|
||||
lenW = strlenW( str );
|
||||
len = WideCharToMultiByte( st->codepage, 0, str, lenW, NULL, 0, NULL, NULL );
|
||||
if( *sz < len )
|
||||
{
|
||||
*sz = len;
|
||||
return ERROR_SUCCESS;
|
||||
return ERROR_MORE_DATA;
|
||||
}
|
||||
|
||||
if( len > *sz )
|
||||
{
|
||||
n = strlenW( str ) + 1;
|
||||
while( n && (len > *sz) )
|
||||
len = WideCharToMultiByte( st->codepage, 0,
|
||||
str, --n, NULL, 0, NULL, NULL );
|
||||
}
|
||||
else
|
||||
n = -1;
|
||||
|
||||
*sz = WideCharToMultiByte( st->codepage, 0, str, n, buffer, len, NULL, NULL );
|
||||
|
||||
*sz = WideCharToMultiByte( st->codepage, 0, str, lenW, buffer, *sz, NULL, NULL );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -588,7 +574,7 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
|
|||
data = msi_alloc( datasize );
|
||||
if( ! data )
|
||||
{
|
||||
WARN("Failed to alloc data %d bytes\n", poolsize );
|
||||
WARN("Failed to alloc data %d bytes\n", datasize );
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -622,8 +608,6 @@ UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT *byt
|
|||
ERR("failed to fetch string\n");
|
||||
sz = 0;
|
||||
}
|
||||
if( sz && (sz < (datasize - used ) ) )
|
||||
sz--;
|
||||
|
||||
if (sz)
|
||||
pool[ n*2 + 1 ] = st->strings[i].persistent_refcount;
|
||||
|
|
|
@ -266,7 +266,7 @@ int sqliteGetToken(const WCHAR *z, int *tokenType, int *skip){
|
|||
*tokenType = TK_DOT;
|
||||
return 1;
|
||||
}
|
||||
/* Fall thru into the next case */
|
||||
/* Fall through */
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
*tokenType = TK_INTEGER;
|
||||
|
|
|
@ -106,7 +106,7 @@ reactos/dll/win32/msg711.acm # Synced to Wine-1.5.4
|
|||
reactos/dll/win32/msgsm32.acm # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/mshtml # Autosync
|
||||
reactos/dll/win32/mshtml.tlb # Autosync
|
||||
reactos/dll/win32/msi # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/msi # Synced to Wine-1.5.10
|
||||
reactos/dll/win32/msimg32 # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/msimtf # Synced to Wine-1.5.4
|
||||
reactos/dll/win32/msisip # Synced to Wine-1.5.4
|
||||
|
|
Loading…
Reference in a new issue