Author: fireball
Date: Fri Oct 22 13:18:11 2010
New Revision: 49219
URL:
http://svn.reactos.org/svn/reactos?rev=49219&view=rev
Log:
[MSI]
- Sync to Wine-1.3.5.
Modified:
trunk/reactos/dll/win32/msi/action.c
trunk/reactos/dll/win32/msi/appsearch.c
trunk/reactos/dll/win32/msi/classes.c
trunk/reactos/dll/win32/msi/cond.tab.c
trunk/reactos/dll/win32/msi/cond.y
trunk/reactos/dll/win32/msi/custom.c
trunk/reactos/dll/win32/msi/database.c
trunk/reactos/dll/win32/msi/join.c
trunk/reactos/dll/win32/msi/media.c
trunk/reactos/dll/win32/msi/msi.c
trunk/reactos/dll/win32/msi/msi.spec
trunk/reactos/dll/win32/msi/msi_Fi.rc
trunk/reactos/dll/win32/msi/msipriv.h
trunk/reactos/dll/win32/msi/msiquery.c
trunk/reactos/dll/win32/msi/package.c
trunk/reactos/dll/win32/msi/record.c
trunk/reactos/dll/win32/msi/registry.c
trunk/reactos/dll/win32/msi/storages.c
trunk/reactos/dll/win32/msi/string.c
trunk/reactos/dll/win32/msi/suminfo.c
trunk/reactos/dll/win32/msi/table.c
trunk/reactos/dll/win32/msi/version.rc
trunk/reactos/include/psdk/msi.h
Modified: trunk/reactos/dll/win32/msi/action.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/action.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/action.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/action.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -1785,7 +1785,7 @@
BOOL feature_state = ((feature->Level > 0) &&
(feature->Level <= level));
- if ((feature_state) && (feature->Action == INSTALLSTATE_UNKNOWN))
+ if (feature_state && feature->ActionRequest ==
INSTALLSTATE_UNKNOWN)
{
if (feature->Attributes & msidbFeatureAttributesFavorSource)
msi_feature_set_state(package, feature, INSTALLSTATE_SOURCE);
@@ -1814,7 +1814,7 @@
{
BOOL selected = feature->Level > 0 && feature->Level <=
level;
- if (selected && feature->Action == INSTALLSTATE_UNKNOWN)
+ if (selected && feature->ActionRequest == INSTALLSTATE_UNKNOWN)
{
msi_feature_set_state(package, feature, feature->Installed);
}
@@ -1839,7 +1839,7 @@
LIST_FOR_EACH_ENTRY( cl, &feature->Components, ComponentList, entry )
{
if (cl->component->ForceLocalState &&
- feature->Action == INSTALLSTATE_SOURCE)
+ feature->ActionRequest == INSTALLSTATE_SOURCE)
{
msi_feature_set_state(package, feature, INSTALLSTATE_LOCAL);
break;
@@ -1850,7 +1850,7 @@
{
component = cl->component;
- switch (feature->Action)
+ switch (feature->ActionRequest)
{
case INSTALLSTATE_ABSENT:
component->anyAbsent = 1;
@@ -2371,17 +2371,43 @@
return ret;
}
+static WCHAR *get_keypath( MSIPACKAGE *package, 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 &&
+ root == HKEY_LOCAL_MACHINE && !strncmpiW( path, prefixW, len ))
+ {
+ UINT size;
+ WCHAR *path_32node;
+
+ size = (strlenW( path ) + strlenW( szWow6432Node ) + 1) * sizeof(WCHAR);
+ path_32node = msi_alloc( size );
+ if (!path_32node)
+ return NULL;
+
+ memcpy( path_32node, path, len * sizeof(WCHAR) );
+ path_32node[len] = 0;
+ strcatW( path_32node, szWow6432Node );
+ strcatW( path_32node, szBackSlash );
+ strcatW( path_32node, path + len );
+ return path_32node;
+ }
+
+ return strdupW( path );
+}
+
static UINT ITERATE_WriteRegistryValues(MSIRECORD *row, LPVOID param)
{
MSIPACKAGE *package = param;
LPSTR value_data = NULL;
HKEY root_key, hkey;
DWORD type,size;
- LPWSTR deformated;
+ LPWSTR deformated, uikey, keypath;
LPCWSTR szRoot, component, name, key, value;
MSICOMPONENT *comp;
MSIRECORD * uirow;
- LPWSTR uikey;
INT root;
BOOL check_first = FALSE;
UINT rc;
@@ -2432,14 +2458,14 @@
strcpyW(uikey,szRoot);
strcatW(uikey,deformated);
- if (RegCreateKeyW( root_key, deformated, &hkey))
- {
- ERR("Could not create key %s\n",debugstr_w(deformated));
- msi_free(deformated);
+ keypath = get_keypath( package, root_key, deformated );
+ msi_free( deformated );
+ if (RegCreateKeyW( root_key, keypath, &hkey ))
+ {
+ ERR("Could not create key %s\n", debugstr_w(keypath));
msi_free(uikey);
return ERROR_SUCCESS;
}
- msi_free(deformated);
value = MSI_RecordGetString(row,5);
if (value)
@@ -2554,7 +2580,7 @@
{
MSIPACKAGE *package = param;
LPCWSTR component, name, key_str, root_key_str;
- LPWSTR deformated_key, deformated_name, ui_key_str;
+ LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
MSICOMPONENT *comp;
MSIRECORD *uirow;
BOOL delete_key = FALSE;
@@ -2610,8 +2636,10 @@
deformat_string( package, name, &deformated_name );
- delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
+ keypath = get_keypath( package, hkey_root, deformated_key );
msi_free( deformated_key );
+ delete_reg_key_or_value( hkey_root, keypath, deformated_name, delete_key );
+ msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, ui_key_str );
@@ -2629,7 +2657,7 @@
{
MSIPACKAGE *package = param;
LPCWSTR component, name, key_str, root_key_str;
- LPWSTR deformated_key, deformated_name, ui_key_str;
+ LPWSTR deformated_key, deformated_name, ui_key_str, keypath;
MSICOMPONENT *comp;
MSIRECORD *uirow;
BOOL delete_key = FALSE;
@@ -2682,8 +2710,10 @@
deformat_string( package, name, &deformated_name );
- delete_reg_key_or_value( hkey_root, deformated_key, deformated_name, delete_key );
+ keypath = get_keypath( package, hkey_root, deformated_key );
msi_free( deformated_key );
+ delete_reg_key_or_value( hkey_root, keypath, deformated_name, delete_key );
+ msi_free( keypath );
uirow = MSI_CreateRecord( 2 );
MSI_RecordSetStringW( uirow, 1, ui_key_str );
@@ -3891,7 +3921,7 @@
WCHAR *p, *all_patches = NULL;
DWORD len = 0;
- r = MSIREG_OpenProductKey( package->ProductCode, NULL, package->Context,
&product_key, FALSE );
+ r = MSIREG_OpenProductKey( package->ProductCode, NULL, package->Context,
&product_key, TRUE );
if (r != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
@@ -4759,7 +4789,7 @@
if (!msi_check_publish(package))
return ERROR_SUCCESS;
- rc = MSIREG_OpenUninstallKey(package->ProductCode, &hkey, TRUE);
+ rc = MSIREG_OpenUninstallKey(package, &hkey, TRUE);
if (rc != ERROR_SUCCESS)
return rc;
@@ -4839,7 +4869,7 @@
MSIREG_DeleteProductKey(package->ProductCode);
MSIREG_DeleteUserDataProductKey(package->ProductCode);
- MSIREG_DeleteUninstallKey(package->ProductCode);
+ MSIREG_DeleteUninstallKey(package);
if (package->Context == MSIINSTALLCONTEXT_MACHINE)
{
@@ -7498,7 +7528,7 @@
msi_clone_properties( package );
msi_parse_command_line( package, szCommandLine, FALSE );
- msi_adjust_allusers_property( package );
+ msi_adjust_privilege_properties( package );
msi_set_context( package );
if (needs_ui_sequence( package))
Modified: trunk/reactos/dll/win32/msi/appsearch.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/appsearch.c?…
==============================================================================
--- trunk/reactos/dll/win32/msi/appsearch.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/appsearch.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -89,7 +89,7 @@
'S','i','g','n','a','t','u','r','e','
',
'w','h','e','r','e','
','S','i','g','n','a','t','u','r','e','
','=',' ',
'\'','%','s','\'',0};
- LPWSTR minVersion, maxVersion;
+ LPWSTR minVersion, maxVersion, p;
MSIRECORD *row;
DWORD time;
@@ -106,6 +106,12 @@
/* get properties */
sig->File = msi_dup_record_field(row,2);
+ if ((p = strchrW(sig->File, '|')))
+ {
+ p++;
+ memmove(sig->File, p, (strlenW(p) + 1) * sizeof(WCHAR));
+ }
+
minVersion = msi_dup_record_field(row,3);
if (minVersion)
{
Modified: trunk/reactos/dll/win32/msi/classes.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/classes.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/classes.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/classes.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -804,12 +804,19 @@
UINT ACTION_RegisterClassInfo(MSIPACKAGE *package)
{
static const WCHAR szFileType_fmt[] =
{'F','i','l','e','T','y','p','e','\\','%','s','\\','%','i',0};
+ const WCHAR *keypath;
MSIRECORD *uirow;
HKEY hkey,hkey2,hkey3;
MSICLASS *cls;
load_classes_and_such(package);
- if (RegCreateKeyW(HKEY_CLASSES_ROOT, szCLSID, &hkey) != ERROR_SUCCESS)
+
+ if (is_64bit && package->platform == PLATFORM_INTEL)
+ keypath = szWow6432NodeCLSID;
+ else
+ keypath = szCLSID;
+
+ if (RegCreateKeyW(HKEY_CLASSES_ROOT, keypath, &hkey) != ERROR_SUCCESS)
return ERROR_FUNCTION_FAILED;
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
@@ -963,12 +970,19 @@
UINT ACTION_UnregisterClassInfo( MSIPACKAGE *package )
{
static const WCHAR szFileType[] =
{'F','i','l','e','T','y','p','e','\\',0};
+ const WCHAR *keypath;
MSIRECORD *uirow;
MSICLASS *cls;
HKEY hkey, hkey2;
load_classes_and_such( package );
- if (RegOpenKeyW( HKEY_CLASSES_ROOT, szCLSID, &hkey ) != ERROR_SUCCESS)
+
+ if (is_64bit && package->platform == PLATFORM_INTEL)
+ keypath = szWow6432NodeCLSID;
+ else
+ keypath = szCLSID;
+
+ if (RegOpenKeyW( HKEY_CLASSES_ROOT, keypath, &hkey ) != ERROR_SUCCESS)
return ERROR_SUCCESS;
LIST_FOR_EACH_ENTRY( cls, &package->classes, MSICLASS, entry )
@@ -1072,7 +1086,7 @@
if (clsid)
msi_reg_set_subkey_val( hkey, szCLSID, NULL, clsid );
else
- ERR("%s has no class\n", debugstr_w( progid->ProgID ) );
+ TRACE("%s has no class\n", debugstr_w( progid->ProgID ) );
if (progid->Description)
msi_reg_set_val_str( hkey, NULL, progid->Description );
Modified: trunk/reactos/dll/win32/msi/cond.tab.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/cond.tab.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/cond.tab.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/cond.tab.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -2329,11 +2329,21 @@
case COND_LHS:
return 0 == strncmpW( a, b, lstrlenW( b ) );
case COND_RHS:
- return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b );
+ {
+ int l = lstrlenW( a );
+ int r = lstrlenW( b );
+ if (r > l) return 0;
+ return 0 == lstrcmpW( a + (l - r), b );
+ }
case COND_ILHS:
return 0 == strncmpiW( a, b, lstrlenW( b ) );
case COND_IRHS:
- return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b );
+ {
+ int l = lstrlenW( a );
+ int r = lstrlenW( b );
+ if (r > l) return 0;
+ return 0 == lstrcmpiW( a + (l - r), b );
+ }
default:
ERR("invalid substring operator\n");
return 0;
Modified: trunk/reactos/dll/win32/msi/cond.y
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/cond.y?rev=4…
==============================================================================
--- trunk/reactos/dll/win32/msi/cond.y [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/cond.y [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -462,11 +462,21 @@
case COND_LHS:
return 0 == strncmpW( a, b, lstrlenW( b ) );
case COND_RHS:
- return 0 == lstrcmpW( a + (lstrlenW( a ) - lstrlenW( b )), b );
+ {
+ int l = lstrlenW( a );
+ int r = lstrlenW( b );
+ if (r > l) return 0;
+ return 0 == lstrcmpW( a + (l - r), b );
+ }
case COND_ILHS:
return 0 == strncmpiW( a, b, lstrlenW( b ) );
case COND_IRHS:
- return 0 == lstrcmpiW( a + (lstrlenW( a ) - lstrlenW( b )), b );
+ {
+ int l = lstrlenW( a );
+ int r = lstrlenW( b );
+ if (r > l) return 0;
+ return 0 == lstrcmpiW( a + (l - r), b );
+ }
default:
ERR("invalid substring operator\n");
return 0;
Modified: trunk/reactos/dll/win32/msi/custom.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/custom.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/custom.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -222,13 +222,6 @@
if (type & msidbCustomActionTypeNoImpersonate)
WARN("msidbCustomActionTypeNoImpersonate not handled\n");
- if (type & msidbCustomActionTypeRollback)
- {
- FIXME("Rollback only action... rollbacks not supported yet\n");
- schedule_action(package, ROLLBACK_SCRIPT, action);
- rc = ERROR_SUCCESS;
- goto end;
- }
if (!execute)
{
LPWSTR actiondata = msi_dup_property(package->db, action);
@@ -238,12 +231,17 @@
if (type & msidbCustomActionTypeCommit)
{
- TRACE("Deferring Commit Action!\n");
+ TRACE("Deferring commit action\n");
schedule_action(package, COMMIT_SCRIPT, deferred);
+ }
+ else if (type & msidbCustomActionTypeRollback)
+ {
+ FIXME("Deferring rollback only action... rollbacks not supported
yet\n");
+ schedule_action(package, ROLLBACK_SCRIPT, deferred);
}
else
{
- TRACE("Deferring Action!\n");
+ TRACE("Deferring action\n");
schedule_action(package, INSTALL_SCRIPT, deferred);
}
@@ -258,20 +256,14 @@
{
LPWSTR actiondata = msi_dup_property( package->db, action );
- switch (script)
- {
- case INSTALL_SCRIPT:
+ if (type & msidbCustomActionTypeInScript)
package->scheduled_action_running = TRUE;
- break;
- case COMMIT_SCRIPT:
+
+ if (type & msidbCustomActionTypeCommit)
package->commit_action_running = TRUE;
- break;
- case ROLLBACK_SCRIPT:
+
+ if (type & msidbCustomActionTypeRollback)
package->rollback_action_running = TRUE;
- break;
- default:
- break;
- }
if (deferred_data)
set_deferred_action_props(package, deferred_data);
Modified: trunk/reactos/dll/win32/msi/database.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/database.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/database.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/database.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -241,7 +241,7 @@
free_cached_tables( db );
free_streams( db );
free_transforms( db );
- msi_destroy_stringtable( db->strings );
+ if (db->strings) msi_destroy_stringtable( db->strings );
IStorage_Release( db->storage );
if (db->deletefile)
{
@@ -253,6 +253,43 @@
DeleteFileW( db->localfile );
msi_free( db->localfile );
}
+}
+
+static HRESULT db_initialize( IStorage *stg, const GUID *clsid )
+{
+ static const WCHAR szTables[] = {
'_','T','a','b','l','e','s',0 };
+ HRESULT hr;
+
+ hr = IStorage_SetClass( stg, clsid );
+ if (FAILED( hr ))
+ {
+ WARN("failed to set class id 0x%08x\n", hr);
+ return hr;
+ }
+
+ /* create the _Tables stream */
+ hr = write_stream_data( stg, szTables, NULL, 0, TRUE );
+ if (FAILED( hr ))
+ {
+ WARN("failed to create _Tables stream 0x%08x\n", hr);
+ return hr;
+ }
+
+ hr = msi_init_string_table( stg );
+ if (FAILED( hr ))
+ {
+ WARN("failed to initialize string table 0x%08x\n", hr);
+ return hr;
+ }
+
+ hr = IStorage_Commit( stg, 0 );
+ if (FAILED( hr ))
+ {
+ WARN("failed to commit changes 0x%08x\n", hr);
+ return hr;
+ }
+
+ return S_OK;
}
UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
@@ -266,8 +303,6 @@
BOOL created = FALSE, patch = FALSE;
WCHAR path[MAX_PATH];
- static const WCHAR szTables[] = {
'_','T','a','b','l','e','s',0 };
-
TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
if( !pdb )
@@ -298,28 +333,28 @@
r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
}
- else if( szPersist == MSIDBOPEN_CREATE || szPersist == MSIDBOPEN_CREATEDIRECT )
- {
- /* FIXME: MSIDBOPEN_CREATE should case STGM_TRANSACTED flag to be
- * used here: */
+ else if( szPersist == MSIDBOPEN_CREATE )
+ {
r = StgCreateDocfile( szDBPath,
- STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
- if( r == ERROR_SUCCESS )
- {
- IStorage_SetClass( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase
);
- /* create the _Tables stream */
- r = write_stream_data(stg, szTables, NULL, 0, TRUE);
- if (SUCCEEDED(r))
- r = msi_init_string_table( stg );
- }
+ STGM_CREATE|STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0,
&stg );
+
+ if( SUCCEEDED(r) )
+ r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase
);
created = TRUE;
}
+ else if( szPersist == MSIDBOPEN_CREATEDIRECT )
+ {
+ r = StgCreateDocfile( szDBPath,
+ STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg
);
+
+ if( SUCCEEDED(r) )
+ r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase
);
+ created = TRUE;
+ }
else if( szPersist == MSIDBOPEN_TRANSACT )
{
- /* FIXME: MSIDBOPEN_TRANSACT should case STGM_TRANSACTED flag to be
- * used here: */
r = StgOpenStorage( szDBPath, NULL,
- STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
+ STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
}
else if( szPersist == MSIDBOPEN_DIRECT )
{
Modified: trunk/reactos/dll/win32/msi/join.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/join.c?rev=4…
==============================================================================
--- trunk/reactos/dll/win32/msi/join.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/join.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -60,8 +60,6 @@
UINT cols = 0;
UINT prev_rows = 1;
- TRACE("%d, %d\n", row, col);
-
if (col == 0 || col > jv->columns)
return ERROR_FUNCTION_FAILED;
@@ -225,10 +223,12 @@
static UINT join_find_row( MSIJOINVIEW *jv, MSIRECORD *rec, UINT *row )
{
LPCWSTR str;
- UINT i, id, data;
+ UINT r, i, id, data;
str = MSI_RecordGetString( rec, 1 );
- msi_string2idW( jv->db->strings, str, &id );
+ r = msi_string2idW( jv->db->strings, str, &id );
+ if (r != ERROR_SUCCESS)
+ return r;
for (i = 0; i < jv->rows; i++)
{
Modified: trunk/reactos/dll/win32/msi/media.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/media.c?rev=…
==============================================================================
--- trunk/reactos/dll/win32/msi/media.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/media.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -211,9 +211,6 @@
UINT r;
IStream *stm;
- if (oflag)
- WARN("ignoring open flags 0x%08x\n", oflag);
-
r = db_get_raw_stream( cab_stream.db, cab_stream.name, &stm );
if (r != ERROR_SUCCESS)
{
@@ -356,6 +353,40 @@
msi_free(cab);
msi_free(cabinet_file);
return res;
+}
+
+static INT_PTR cabinet_next_cabinet_stream( FDINOTIFICATIONTYPE fdint,
+ PFDINOTIFICATION pfdin )
+{
+ MSICABDATA *data = pfdin->pv;
+ MSIMEDIAINFO *mi = data->mi;
+ UINT rc;
+
+ msi_free( mi->disk_prompt );
+ msi_free( mi->cabinet );
+ msi_free( mi->volume_label );
+ mi->disk_prompt = NULL;
+ mi->cabinet = NULL;
+ mi->volume_label = NULL;
+
+ mi->disk_id++;
+ mi->is_continuous = TRUE;
+
+ rc = msi_media_get_disk_info( data->package, mi );
+ if (rc != ERROR_SUCCESS)
+ {
+ ERR("Failed to get next cabinet information: %u\n", rc);
+ return -1;
+ }
+
+ msi_free( cab_stream.name );
+ cab_stream.name = encode_streamname( FALSE, mi->cabinet + 1 );
+ if (!cab_stream.name)
+ return -1;
+
+ TRACE("next cabinet is %s\n", debugstr_w(mi->cabinet));
+
+ return 0;
}
static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
@@ -494,6 +525,12 @@
{
switch (fdint)
{
+ case fdintPARTIAL_FILE:
+ return cabinet_partial_file( fdint, pfdin );
+
+ case fdintNEXT_CABINET:
+ return cabinet_next_cabinet_stream( fdint, pfdin );
+
case fdintCOPY_FILE:
return cabinet_copy_file( fdint, pfdin );
Modified: trunk/reactos/dll/win32/msi/msi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.c?rev=49…
==============================================================================
--- trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msi.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -3779,3 +3779,44 @@
FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent),
eInstallState);
return ERROR_SUCCESS;
}
+
+/***********************************************************************
+ * MsiBeginTransactionA [MSI.@]
+ */
+UINT WINAPI MsiBeginTransactionA( LPCSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event
)
+{
+ WCHAR *nameW;
+ UINT r;
+
+ FIXME("%s %u %p %p\n", debugstr_a(name), attrs, id, event);
+
+ nameW = strdupAtoW( name );
+ if (name && !nameW)
+ return ERROR_OUTOFMEMORY;
+
+ r = MsiBeginTransactionW( nameW, attrs, id, event );
+ msi_free( nameW );
+ return r;
+}
+
+/***********************************************************************
+ * MsiBeginTransactionW [MSI.@]
+ */
+UINT WINAPI MsiBeginTransactionW( LPCWSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event
)
+{
+ FIXME("%s %u %p %p\n", debugstr_w(name), attrs, id, event);
+
+ *id = (MSIHANDLE)0xdeadbeef;
+ *event = (HANDLE)0xdeadbeef;
+
+ return ERROR_SUCCESS;
+}
+
+/***********************************************************************
+ * MsiEndTransaction [MSI.@]
+ */
+UINT WINAPI MsiEndTransaction( DWORD state )
+{
+ FIXME("%u\n", state);
+ return ERROR_SUCCESS;
+}
Modified: trunk/reactos/dll/win32/msi/msi.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi.spec?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/msi.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msi.spec [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -174,7 +174,7 @@
178 stdcall MsiGetPatchInfoA(str str ptr ptr)
179 stdcall MsiGetPatchInfoW(wstr wstr ptr ptr)
180 stdcall MsiEnumPatchesA(str long ptr ptr ptr)
-181 stdcall MsiEnumPatchesW(str long ptr ptr ptr)
+181 stdcall MsiEnumPatchesW(wstr long ptr ptr ptr)
182 stdcall -private DllGetVersion(ptr)
183 stub MsiGetProductCodeFromPackageCodeA
184 stub MsiGetProductCodeFromPackageCodeW
@@ -214,7 +214,7 @@
218 stdcall MsiGetFileHashA(str long ptr)
219 stdcall MsiGetFileHashW(wstr long ptr)
220 stub MsiEnumComponentCostsA
-221 stdcall MsiEnumComponentCostsW(long str long long ptr ptr ptr ptr)
+221 stdcall MsiEnumComponentCostsW(long wstr long long ptr ptr ptr ptr)
222 stdcall MsiCreateAndVerifyInstallerDirectory(long)
223 stdcall MsiGetFileSignatureInformationA(str long ptr ptr ptr)
224 stdcall MsiGetFileSignatureInformationW(wstr long ptr ptr ptr)
@@ -277,9 +277,9 @@
281 stdcall MsiSetExternalUIRecord(ptr long ptr ptr)
282 stub MsiGetPatchFileListA
283 stub MsiGetPatchFileListW
-284 stub MsiBeginTransactionA
-285 stub MsiBeginTransactionW
-286 stub MsiEndTransaction
+284 stdcall MsiBeginTransactionA(str long ptr ptr)
+285 stdcall MsiBeginTransactionW(wstr long ptr ptr)
+286 stdcall MsiEndTransaction(long)
287 stub MsiJoinTransaction
288 stub MsiSetOfflineContextW
289 stub MsiEnumComponentsExA
Modified: trunk/reactos/dll/win32/msi/msi_Fi.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msi_Fi.rc?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/msi_Fi.rc [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msi_Fi.rc [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -24,39 +24,39 @@
STRINGTABLE
{
- 4 "The specified installation package could not be opened. Please check the file
path and try again."
+ 4 "Annettua asennuspakettia ei voitu avata. Tarkista tiedoston polku ja yritä
uudelleen."
5 "Polkua %s ei löydy."
9 "Anna levy %s"
10 "Windows Installer %s\n\n" \
- "Usage:\n" \
- "msiexec command {required parameter} [optional parammeter]\n\n" \
- "Install a product:\n" \
- "\t/i {package|productcode} [property]\n" \
- "\t/package {package|productcode} [property]\n" \
- "\t/a package [property]\n" \
- "Repair an installation:\n" \
- "\t/f[p|o|e|d|c|a|u|m|s|v] {package|productcode}\n" \
- "Uninstall a product:\n" \
- "\t/uninstall {package|productcode} [property]\n" \
- "\t/x {package|productcode} [property]\n" \
- "Advertise a product:\n" \
- "\t/j[u|m] package [/t transform] [/g languageid]\n" \
- "Apply a patch:\n" \
- "\t/p patchpackage [property]\n" \
- "\t/p patchpackage /a package [property]\n" \
- "Log and UI Modifiers for above commands:\n" \
- "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] logfile\n" \
+ "Käyttö:\n" \
+ "msiexec komento {pakollinen parametri} [valinnainen parametri]\n\n" \
+ "Asenna tuote:\n" \
+ "\t/i {paketti|tuotekoodi} [ominaisuus]\n" \
+ "\t/package {paketti|tuotekoodi} [ominaisuus]\n" \
+ "\t/a {paketti} [ominaisuus]\n" \
+ "Korjaa asennus:\n" \
+ "\t/f[p|o|e|d|c|a|u|m|s|v] {paketti|tuotekoodi}\n" \
+ "Poista tuote:\n" \
+ "\t/uninstall {paketti|tuotekoodi} [ominaisuus]\n" \
+ "\t/x {paketti|tuotekoodi} [ominaisuus]\n" \
+ "Mainosta (advertise) tuotetta:\n" \
+ "\t/j[u|m] paketti [/t muunnos] [/g kielitunnus]\n" \
+ "Asenna korjaus:\n" \
+ "\t/p korjauspaketti [ominaisuus]\n" \
+ "\t/p korjauspaketti /a paketti [ominaisuus]\n" \
+ "Loki- ja käyttöliittymäasetukset edellisille komennoille:\n" \
+ "\t/l[*][i|w|e|a|r|u|c|m|o|p|v|][+|!] lokitiedosto\n" \
"\t/q{|n|b|r|f|n+|b+|b-}\n" \
- "Register MSI Service:\n" \
+ "Rekisteröi MSI-palvelu:\n" \
"\t/y\n" \
- "Unregister MSI Service:\n" \
+ "Peru MSI-palvelun rekisteröinti:\n" \
"\t/z\n" \
- "Display this help:\n" \
+ "Näytä tämä ohje:\n" \
"\t/help\n" \
"\t/?\n"
- 11 "Anna kansio, joka sisältää %s"
+ 11 "Anna kansio, jossa on %s"
12 "Ominaisuuden asennuslähde puuttuu."
13 "Ominaisuuden verkkolevy puuttuu."
14 "Ominaisuus:"
- 15 "Valitse kansio, joka sisältää %s"
+ 15 "Valitse kansio, jossa on %s"
}
Modified: trunk/reactos/dll/win32/msi/msipriv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msipriv.h?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msipriv.h [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -29,12 +29,15 @@
#include "fdi.h"
#include "msi.h"
#include "msiquery.h"
+#include "msidefs.h"
#include "objbase.h"
#include "objidl.h"
#include "winnls.h"
#include "winver.h"
#include "wine/list.h"
#include "wine/debug.h"
+
+static const BOOL is_64bit = sizeof(void *) > sizeof(int);
#define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100
@@ -45,6 +48,7 @@
#define MSITYPE_TEMPORARY 0x4000
#define MAX_STREAM_NAME_LEN 62
+#define LONG_STR_BYTES 3
/* Install UI level mask for AND operation to exclude flags */
#define INSTALLUILEVEL_MASK 0x0007
@@ -103,6 +107,7 @@
union
{
INT iVal;
+ INT_PTR pVal;
LPWSTR szwVal;
IStream *stream;
} u;
@@ -303,10 +308,21 @@
struct msi_dialog_tag;
typedef struct msi_dialog_tag msi_dialog;
+enum platform
+{
+ PLATFORM_INTEL,
+ PLATFORM_INTEL64,
+ PLATFORM_X64
+};
+
typedef struct tagMSIPACKAGE
{
MSIOBJECTHDR hdr;
MSIDATABASE *db;
+ INT version;
+ enum platform platform;
+ UINT num_langids;
+ LANGID *langids;
struct list patches;
struct list components;
struct list features;
@@ -388,7 +404,6 @@
typedef struct tagMSICOMPONENT
{
struct list entry;
- DWORD magic;
LPWSTR Component;
LPWSTR ComponentId;
LPWSTR Directory;
@@ -595,9 +610,9 @@
#define MSIHANDLETYPE_PACKAGE 5
#define MSIHANDLETYPE_PREVIEW 6
-#define MSI_MAJORVERSION 3
-#define MSI_MINORVERSION 1
-#define MSI_BUILDNUMBER 4000
+#define MSI_MAJORVERSION 4
+#define MSI_MINORVERSION 5
+#define MSI_BUILDNUMBER 6001
#define GUID_SIZE 39
#define SQUISH_GUID_SIZE 33
@@ -672,7 +687,7 @@
extern const WCHAR *msi_string_lookup_id( const string_table *st, UINT id );
extern HRESULT msi_init_string_table( IStorage *stg );
extern string_table *msi_load_string_table( IStorage *stg, UINT *bytes_per_strref );
-extern UINT msi_save_string_table( const string_table *st, IStorage *storage );
+extern UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT
*bytes_per_strref );
extern BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name );
extern MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table );
@@ -709,11 +724,13 @@
extern const WCHAR *MSI_RecordGetString( const MSIRECORD *, UINT );
extern MSIRECORD *MSI_CreateRecord( UINT );
extern UINT MSI_RecordSetInteger( MSIRECORD *, UINT, int );
+extern UINT MSI_RecordSetIntPtr( MSIRECORD *, UINT, INT_PTR );
extern UINT MSI_RecordSetStringW( MSIRECORD *, UINT, LPCWSTR );
extern BOOL MSI_RecordIsNull( MSIRECORD *, UINT );
extern UINT MSI_RecordGetStringW( MSIRECORD * , UINT, LPWSTR, LPDWORD);
extern UINT MSI_RecordGetStringA( MSIRECORD *, UINT, LPSTR, LPDWORD);
extern int MSI_RecordGetInteger( MSIRECORD *, UINT );
+extern INT_PTR MSI_RecordGetIntPtr( MSIRECORD *, UINT );
extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD);
extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *);
extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec );
@@ -765,7 +782,7 @@
extern UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR,
LPWSTR);
extern UINT msi_clone_properties(MSIPACKAGE *);
extern UINT msi_set_context(MSIPACKAGE *);
-extern void msi_adjust_allusers_property(MSIPACKAGE *);
+extern void msi_adjust_privilege_properties(MSIPACKAGE *);
extern UINT MSI_GetFeatureCost(MSIPACKAGE *, MSIFEATURE *, MSICOSTTREE, INSTALLSTATE,
LPINT);
/* for deformating */
@@ -776,8 +793,8 @@
extern BOOL squash_guid(LPCWSTR in, LPWSTR out);
extern BOOL encode_base85_guid(GUID *,LPWSTR);
extern BOOL decode_base85_guid(LPCWSTR,GUID*);
-extern UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create);
-extern UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct);
+extern UINT MSIREG_OpenUninstallKey(MSIPACKAGE *package, HKEY *key, BOOL create);
+extern UINT MSIREG_DeleteUninstallKey(MSIPACKAGE *package);
extern UINT MSIREG_OpenProductKey(LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT context, HKEY* key, BOOL create);
extern UINT MSIREG_OpenFeaturesKey(LPCWSTR szProduct, MSIINSTALLCONTEXT context,
@@ -843,6 +860,7 @@
/* summary information */
extern MSISUMMARYINFO *MSI_GetSummaryInformationW( IStorage *stg, UINT uiUpdateCount );
extern LPWSTR msi_suminfo_dup_string( MSISUMMARYINFO *si, UINT uiProperty );
+extern INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty );
extern LPWSTR msi_get_suminfo_product( IStorage *stg );
extern UINT msi_add_suminfo( MSIDATABASE *db, LPWSTR **records, int num_records, int
num_columns );
@@ -914,6 +932,10 @@
{
feature->ActionRequest = state;
feature->Action = state;
+ }
+ if (feature->Attributes & msidbFeatureAttributesUIDisallowAbsent)
+ {
+ feature->Action = INSTALLSTATE_UNKNOWN;
}
}
@@ -1123,6 +1145,12 @@
static const WCHAR szLocalPackage[] =
{'L','o','c','a','l','P','a','c','k','a','g','e',0};
static const WCHAR szOriginalDatabase[] =
{'O','r','i','g','i','n','a','l','D','a','t','a','b','a','s','e',0};
static const WCHAR szUpgradeCode[] =
{'U','p','g','r','a','d','e','C','o','d','e',0};
+static const WCHAR szAdminUser[] =
{'A','d','m','i','n','U','s','e','r',0};
+static const WCHAR szIntel[] =
{'I','n','t','e','l',0};
+static const WCHAR szIntel64[] =
{'I','n','t','e','l','6','4',0};
+static const WCHAR szX64[] = {'x','6','4',0};
+static const WCHAR szWow6432NodeCLSID[] =
{'W','o','w','6','4','3','2','N','o','d','e','\\','C','L','S','I','D',0};
+static const WCHAR szWow6432Node[] =
{'W','o','w','6','4','3','2','N','o','d','e',0};
/* memory allocation macro functions */
static void *msi_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
Modified: trunk/reactos/dll/win32/msi/msiquery.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/msiquery.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/msiquery.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -382,7 +382,7 @@
if (r == ERROR_SUCCESS)
{
query->row ++;
- MSI_RecordSetInteger(*prec, 0, (int)query);
+ MSI_RecordSetIntPtr(*prec, 0, (INT_PTR)query);
}
return r;
@@ -617,7 +617,7 @@
if ( !view || !view->ops->modify)
return ERROR_FUNCTION_FAILED;
- if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetInteger( rec, 0 ) != (int)query
)
+ if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetIntPtr( rec, 0 ) !=
(INT_PTR)query )
return ERROR_FUNCTION_FAILED;
r = view->ops->modify( view, mode, rec, query->row );
@@ -901,6 +901,9 @@
MSIQUERY *query = NULL;
UINT r;
+ if (!TABLE_Exists( db, table ))
+ return ERROR_INVALID_TABLE;
+
r = MSI_OpenQuery( db, &query, sql, table );
if( r != ERROR_SUCCESS )
return r;
Modified: trunk/reactos/dll/win32/msi/package.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/package.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/package.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/package.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -280,6 +280,7 @@
msi_free( package->ProductCode );
msi_free( package->ActionFormat );
msi_free( package->LastAction );
+ msi_free( package->langids );
/* cleanup control event subscriptions */
ControlEvent_CleanupSubscriptions( package );
@@ -417,7 +418,7 @@
HKEY hkey = 0;
UINT r;
- r = MSIREG_OpenUninstallKey( package->ProductCode, &hkey, FALSE );
+ r = MSIREG_OpenUninstallKey( package, &hkey, FALSE );
if (r == ERROR_SUCCESS)
{
RegCloseKey( hkey );
@@ -618,72 +619,49 @@
SYSTEMTIME systemtime;
LANGID langid;
- static const WCHAR CFF[] =
-{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
- static const WCHAR PFF[] =
-{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
- static const WCHAR CADF[] =
-{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR FaF[] =
-{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
- static const WCHAR FoF[] =
-{'F','o','n','t','s','F','o','l','d','e','r',0};
- static const WCHAR SendTF[] =
-{'S','e','n','d','T','o','F','o','l','d','e','r',0};
- static const WCHAR SMF[] =
-{'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
- static const WCHAR StF[] =
-{'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
- static const WCHAR TemplF[] =
-{'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
- static const WCHAR DF[] =
-{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
- static const WCHAR PMF[] =
-{'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
- static const WCHAR ATF[] =
-{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
- static const WCHAR ADF[] =
-{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR SF[] =
-{'S','y','s','t','e','m','F','o','l','d','e','r',0};
- static const WCHAR SF16[] =
-{'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
- static const WCHAR LADF[] =
-{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
- static const WCHAR MPF[] =
-{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
- static const WCHAR PF[] =
-{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
- static const WCHAR WF[] =
-{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
- static const WCHAR WV[] =
-{'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
- static const WCHAR TF[]=
-{'T','e','m','p','F','o','l','d','e','r',0};
- static const WCHAR szAdminUser[] =
-{'A','d','m','i','n','U','s','e','r',0};
- static const WCHAR szPriv[] =
-{'P','r','i','v','i','l','e','g','e','d',0};
- static const WCHAR v9x[] = {
'V','e','r','s','i','o','n','9','X',0
};
- static const WCHAR vNT[] = {
'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 szCommonFilesFolder[] =
{'C','o','m','m','o','n','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR szProgramFilesFolder[] =
{'P','r','o','g','r','a','m','F','i','l','e','s','F','o','l','d','e','r',0};
+ static const WCHAR szCommonAppDataFolder[] =
{'C','o','m','m','o','n','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR szFavoritesFolder[] =
{'F','a','v','o','r','i','t','e','s','F','o','l','d','e','r',0};
+ static const WCHAR szFontsFolder[] =
{'F','o','n','t','s','F','o','l','d','e','r',0};
+ static const WCHAR szSendToFolder[] =
{'S','e','n','d','T','o','F','o','l','d','e','r',0};
+ static const WCHAR szStartMenuFolder[] =
{'S','t','a','r','t','M','e','n','u','F','o','l','d','e','r',0};
+ static const WCHAR szStartupFolder[] =
{'S','t','a','r','t','u','p','F','o','l','d','e','r',0};
+ static const WCHAR szTemplateFolder[] =
{'T','e','m','p','l','a','t','e','F','o','l','d','e','r',0};
+ static const WCHAR szDesktopFolder[] =
{'D','e','s','k','t','o','p','F','o','l','d','e','r',0};
+ static const WCHAR szProgramMenuFolder[] =
{'P','r','o','g','r','a','m','M','e','n','u','F','o','l','d','e','r',0};
+ static const WCHAR szAdminToolsFolder[] =
{'A','d','m','i','n','T','o','o','l','s','F','o','l','d','e','r',0};
+ static const WCHAR szAppDataFolder[] =
{'A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR szSystemFolder[] =
{'S','y','s','t','e','m','F','o','l','d','e','r',0};
+ static const WCHAR szSystem16Folder[] =
{'S','y','s','t','e','m','1','6','F','o','l','d','e','r',0};
+ static const WCHAR szLocalAppDataFolder[] =
{'L','o','c','a','l','A','p','p','D','a','t','a','F','o','l','d','e','r',0};
+ static const WCHAR szMyPicturesFolder[] =
{'M','y','P','i','c','t','u','r','e','s','F','o','l','d','e','r',0};
+ static const WCHAR szPersonalFolder[] =
{'P','e','r','s','o','n','a','l','F','o','l','d','e','r',0};
+ static const WCHAR szWindowsFolder[] =
{'W','i','n','d','o','w','s','F','o','l','d','e','r',0};
+ static const WCHAR szWindowsVolume[] =
{'W','i','n','d','o','w','s','V','o','l','u','m','e',0};
+ static const WCHAR szTempFolder[]=
{'T','e','m','p','F','o','l','d','e','r',0};
+ static const WCHAR szPrivileged[] =
{'P','r','i','v','i','l','e','g','e','d',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 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 szWinBuild[] =
-{'W','i','n','d','o','w','s','B','u','i','l','d',
0 };
- static const WCHAR szSPL[] =
-{'S','e','r','v','i','c','e','P','a','c','k','L','e','v','e','l',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};
-/* Screen properties */
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};
static const WCHAR szIntFormat[] = {'%','d',0};
- static const WCHAR szIntel[] = {
'I','n','t','e','l',0 };
+ static const WCHAR szMsiAMD64[] = {
'M','s','i','A','M','D','6','4',0
};
+ static const WCHAR szMsix64[] = {
'M','s','i','x','6','4',0 };
+ static const WCHAR szSystem64Folder[] = {
'S','y','s','t','e','m','6','4','F','o','l','d','e','r',0
};
+ static const WCHAR szCommonFiles64Folder[] = {
'C','o','m','m','o','n','F','i','l','e','s','6','4','F','o','l','d','e','r',0
};
+ static const WCHAR szProgramFiles64Folder[] = {
'P','r','o','g','r','a','m','F','i','l','e','s','6','4','F','o','l','d','e','r',0
};
+ static const WCHAR szVersionNT64[] = {
'V','e','r','s','i','o','n','N','T','6','4',0
};
static const WCHAR szUserInfo[] = {
'S','O','F','T','W','A','R','E','\\',
'M','i','c','r','o','s','o','f','t','\\',
@@ -699,17 +677,20 @@
'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0
};
static const WCHAR szRegisteredUser[] =
{'R','e','g','i','s','t','e','r','e','d','O','w','n','e','r',0};
- static const WCHAR szRegisteredOrg[] = {
+ static const WCHAR szRegisteredOrganization[] = {
'R','e','g','i','s','t','e','r','e','d','O','r','g','a','n','i','z','a','t','i','o','n',0
};
static const WCHAR szUSERNAME[] =
{'U','S','E','R','N','A','M','E',0};
static const WCHAR szCOMPANYNAME[] =
{'C','O','M','P','A','N','Y','N','A','M','E',0};
static const WCHAR szDate[] = {'D','a','t','e',0};
static const WCHAR szTime[] = {'T','i','m','e',0};
- static const WCHAR szUserLangID[] =
{'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
+ static const WCHAR szUserLanguageID[] =
{'U','s','e','r','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szSystemLangID[] =
{'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',0};
static const WCHAR szProductState[] =
{'P','r','o','d','u','c','t','S','t','a','t','e',0};
static const WCHAR szLogonUser[] =
{'L','o','g','o','n','U','s','e','r',0};
+ static const WCHAR szNetHoodFolder[] =
{'N','e','t','H','o','o','d','F','o','l','d','e','r',0};
+ static const WCHAR szPrintHoodFolder[] =
{'P','r','i','n','t','H','o','o','d','F','o','l','d','e','r',0};
+ static const WCHAR szRecentFolder[] =
{'R','e','c','e','n','t','F','o','l','d','e','r',0};
/*
* Other things that probably should be set:
@@ -720,130 +701,175 @@
* RedirectedDllSupport
*/
- SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES_COMMON,NULL,0,pth);
+ SHGetFolderPathW(NULL, CSIDL_COMMON_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, CFF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_PROGRAM_FILES,NULL,0,pth);
+ msi_set_property(package->db, szCommonAppDataFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_FAVORITES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, PFF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_COMMON_APPDATA,NULL,0,pth);
+ msi_set_property(package->db, szFavoritesFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_FONTS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, CADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_FAVORITES,NULL,0,pth);
+ msi_set_property(package->db, szFontsFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_SENDTO, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, FaF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_FONTS,NULL,0,pth);
+ msi_set_property(package->db, szSendToFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, FoF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_SENDTO,NULL,0,pth);
+ msi_set_property(package->db, szStartMenuFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_STARTUP, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, SendTF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_STARTMENU,NULL,0,pth);
+ msi_set_property(package->db, szStartupFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_TEMPLATES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, SMF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_STARTUP,NULL,0,pth);
+ msi_set_property(package->db, szTemplateFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, StF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_TEMPLATES,NULL,0,pth);
+ msi_set_property(package->db, szDesktopFolder, pth);
+
+ /* FIXME: set to AllUsers profile path if ALLUSERS is set */
+ SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, TemplF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_DESKTOP,NULL,0,pth);
+ msi_set_property(package->db, szProgramMenuFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, DF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_PROGRAMS,NULL,0,pth);
+ msi_set_property(package->db, szAdminToolsFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, PMF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_ADMINTOOLS,NULL,0,pth);
+ msi_set_property(package->db, szAppDataFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, ATF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_APPDATA,NULL,0,pth);
+ msi_set_property(package->db, szSystemFolder, pth);
+ msi_set_property(package->db, szSystem16Folder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, ADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_SYSTEM,NULL,0,pth);
+ msi_set_property(package->db, szLocalAppDataFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, SF, pth);
- msi_set_property(package->db, SF16, pth);
-
- SHGetFolderPathW(NULL,CSIDL_LOCAL_APPDATA,NULL,0,pth);
+ msi_set_property(package->db, szMyPicturesFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, LADF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_MYPICTURES,NULL,0,pth);
+ msi_set_property(package->db, szPersonalFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, MPF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_PERSONAL,NULL,0,pth);
+ msi_set_property(package->db, szWindowsFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, PF, pth);
-
- SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
+ msi_set_property(package->db, szPrintHoodFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, 0, pth);
strcatW(pth, szBackSlash);
- msi_set_property(package->db, WF, pth);
-
+ msi_set_property(package->db, szNetHoodFolder, pth);
+
+ SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, 0, pth);
+ strcatW(pth, szBackSlash);
+ msi_set_property(package->db, szRecentFolder, pth);
+
/* Physical Memory is specified in MB. Using total amount. */
msex.dwLength = sizeof(msex);
GlobalMemoryStatusEx( &msex );
- sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys/1024/1024));
+ sprintfW( bufstr, szIntFormat, (int)(msex.ullTotalPhys / 1024 / 1024) );
msi_set_property(package->db, szPhysicalMemory, bufstr);
- SHGetFolderPathW(NULL,CSIDL_WINDOWS,NULL,0,pth);
+ SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, pth);
ptr = strchrW(pth,'\\');
- if (ptr)
- *(ptr+1) = 0;
- msi_set_property(package->db, WV, pth);
+ if (ptr) *(ptr + 1) = 0;
+ msi_set_property(package->db, szWindowsVolume, pth);
GetTempPathW(MAX_PATH,pth);
- msi_set_property(package->db, TF, pth);
-
+ msi_set_property(package->db, szTempFolder, pth);
/* in a wine environment the user is always admin and privileged */
msi_set_property(package->db, szAdminUser, szOne);
- msi_set_property(package->db, szPriv, szOne);
+ msi_set_property(package->db, szPrivileged, szOne);
/* set the os things */
OSVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
GetVersionExW((OSVERSIONINFOW *)&OSVersion);
- verval = OSVersion.dwMinorVersion+OSVersion.dwMajorVersion*100;
- sprintfW(verstr,szFormat,verval);
+ verval = OSVersion.dwMinorVersion + OSVersion.dwMajorVersion * 100;
+ sprintfW(verstr, szFormat, verval);
switch (OSVersion.dwPlatformId)
{
case VER_PLATFORM_WIN32_WINDOWS:
- msi_set_property(package->db, v9x, verstr);
+ msi_set_property(package->db, szVersion9x, verstr);
break;
case VER_PLATFORM_WIN32_NT:
- msi_set_property(package->db, vNT, verstr);
- sprintfW(verstr,szFormat,OSVersion.wProductType);
+ msi_set_property(package->db, szVersionNT, verstr);
+ sprintfW(verstr, szFormat,OSVersion.wProductType);
msi_set_property(package->db, szMsiNTProductType, verstr);
break;
}
- sprintfW(verstr,szFormat,OSVersion.dwBuildNumber);
- msi_set_property(package->db, szWinBuild, verstr);
+ sprintfW(verstr, szFormat, OSVersion.dwBuildNumber);
+ msi_set_property(package->db, szWindowsBuild, verstr);
/* just fudge this */
- msi_set_property(package->db, szSPL, szSix);
+ msi_set_property(package->db, szServicePackLevel, szSix);
sprintfW( bufstr, szFormat2, MSI_MAJORVERSION, MSI_MINORVERSION);
msi_set_property( package->db, szVersionMsi, bufstr );
sprintfW( bufstr, szFormat, MSI_MAJORVERSION * 100);
msi_set_property( package->db, szVersionDatabase, bufstr );
- GetSystemInfo( &sys_info );
+ GetNativeSystemInfo( &sys_info );
+ sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL)
{
- sprintfW( bufstr, szIntFormat, sys_info.wProcessorLevel );
msi_set_property( package->db, szIntel, bufstr );
+
+ GetSystemDirectoryW( pth, MAX_PATH );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szSystemFolder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szProgramFilesFolder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szCommonFilesFolder, pth );
+ }
+ else if (sys_info.u.s.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
+ {
+ msi_set_property( package->db, szMsiAMD64, bufstr );
+ msi_set_property( package->db, szMsix64, bufstr );
+ msi_set_property( package->db, szVersionNT64, verstr );
+
+ GetSystemDirectoryW( pth, MAX_PATH );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szSystem64Folder, pth );
+
+ GetSystemWow64DirectoryW( pth, MAX_PATH );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szSystemFolder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szProgramFiles64Folder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILESX86, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szProgramFilesFolder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMON, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szCommonFiles64Folder, pth );
+
+ SHGetFolderPathW( NULL, CSIDL_PROGRAM_FILES_COMMONX86, NULL, 0, pth );
+ PathAddBackslashW( pth );
+ msi_set_property( package->db, szCommonFilesFolder, pth );
}
/* Screen properties. */
@@ -878,7 +904,7 @@
(username = msi_reg_get_val_str( hkey, szRegisteredUser )))
msi_set_property( package->db, szUSERNAME, username );
if (!companyname &&
- (companyname = msi_reg_get_val_str( hkey, szRegisteredOrg )))
+ (companyname = msi_reg_get_val_str( hkey, szRegisteredOrganization )))
msi_set_property( package->db, szCOMPANYNAME, companyname );
CloseHandle( hkey );
}
@@ -908,7 +934,7 @@
langid = GetUserDefaultLangID();
sprintfW(bufstr, szIntFormat, langid);
- msi_set_property( package->db, szUserLangID, bufstr );
+ msi_set_property( package->db, szUserLanguageID, bufstr );
langid = GetSystemDefaultLangID();
sprintfW(bufstr, szIntFormat, langid);
@@ -1042,7 +1068,7 @@
return r;
}
-void msi_adjust_allusers_property( MSIPACKAGE *package )
+void msi_adjust_privilege_properties( MSIPACKAGE *package )
{
/* FIXME: this should depend on the user's privileges */
if (msi_get_property_int( package->db, szAllUsers, 0 ) == 2)
@@ -1050,6 +1076,7 @@
TRACE("resetting ALLUSERS property from 2 to 1\n");
msi_set_property( package->db, szAllUsers, szOne );
}
+ msi_set_property( package->db, szAdminUser, szOne );
}
MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
@@ -1074,7 +1101,7 @@
create_temp_property_table( package );
msi_clone_properties( package );
- msi_adjust_allusers_property( package );
+ msi_adjust_privilege_properties( package );
package->ProductCode = msi_dup_property( package->db, szProductCode );
package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
@@ -1119,7 +1146,10 @@
if( !CopyFileW( szPackage, filename, FALSE ) )
{
UINT error = GetLastError();
- ERR("failed to copy package %s to %s (%u)\n", debugstr_w(szPackage),
debugstr_w(filename), error);
+ if ( error == ERROR_FILE_NOT_FOUND )
+ ERR("can't find %s\n", debugstr_w(szPackage));
+ else
+ ERR("failed to copy package %s to %s (%u)\n",
debugstr_w(szPackage), debugstr_w(filename), error);
DeleteFileW( filename );
return error;
}
@@ -1257,6 +1287,92 @@
return r;
}
+static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
+{
+ WCHAR *template, *p, *q;
+ DWORD i, count;
+
+ package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
+ TRACE("version: %d\n", package->version);
+
+ template = msi_suminfo_dup_string( si, PID_TEMPLATE );
+ if (!template)
+ return ERROR_SUCCESS; /* native accepts missing template property */
+
+ TRACE("template: %s\n", debugstr_w(template));
+
+ p = strchrW( template, ';' );
+ if (!p)
+ {
+ WARN("invalid template string %s\n", debugstr_w(template));
+ msi_free( template );
+ return ERROR_PATCH_PACKAGE_INVALID;
+ }
+ *p = 0;
+ if (!template[0] || !strcmpW( template, szIntel ))
+ package->platform = PLATFORM_INTEL;
+ else if (!strcmpW( template, szIntel64 ))
+ package->platform = PLATFORM_INTEL64;
+ else if (!strcmpW( template, szX64 ))
+ package->platform = PLATFORM_X64;
+ else
+ {
+ WARN("unknown platform %s\n", debugstr_w(template));
+ msi_free( template );
+ return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
+ }
+
+ count = 1;
+ for (q = ++p; (q = strchrW( q, ',' )); q++) count++;
+
+ package->langids = msi_alloc( count * sizeof(LANGID) );
+ if (!package->langids)
+ {
+ msi_free( template );
+ return ERROR_OUTOFMEMORY;
+ }
+
+ i = 0;
+ while (*p)
+ {
+ q = strchrW( p, ',' );
+ if (q) *q = 0;
+ package->langids[i] = atoiW( p );
+ if (!q) break;
+ p = q + 1;
+ i++;
+ }
+ package->num_langids = i + 1;
+
+ msi_free( template );
+ return ERROR_SUCCESS;
+}
+
+static UINT validate_package( MSIPACKAGE *package )
+{
+ BOOL is_wow64;
+ UINT i;
+
+ IsWow64Process( GetCurrentProcess(), &is_wow64 );
+ if (package->platform == PLATFORM_X64)
+ {
+ if (!is_64bit && !is_wow64)
+ return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
+ if (package->version < 200)
+ return ERROR_INSTALL_PACKAGE_INVALID;
+ }
+ if (!package->num_langids)
+ {
+ return ERROR_SUCCESS;
+ }
+ for (i = 0; i < package->num_langids; i++)
+ {
+ if (!package->langids[i] || IsValidLocale( package->langids[i],
LCID_INSTALLED ))
+ return ERROR_SUCCESS;
+ }
+ return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
+}
+
UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
{
static const WCHAR Database[] =
{'D','A','T','A','B','A','S','E',0};
@@ -1269,6 +1385,7 @@
WCHAR temppath[MAX_PATH], localfile[MAX_PATH], cachefile[MAX_PATH];
LPCWSTR file = szPackage;
DWORD index = 0;
+ MSISUMMARYINFO *si;
TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
@@ -1339,7 +1456,7 @@
* read/write, which is safe because we always create a copy that is thrown
* away when we're done.
*/
- r = MSI_OpenDatabaseW( file, MSIDBOPEN_DIRECT, &db );
+ r = MSI_OpenDatabaseW( file, MSIDBOPEN_TRANSACT, &db );
if( r != ERROR_SUCCESS )
{
if (file != szPackage)
@@ -1368,6 +1485,29 @@
if( file != szPackage )
track_tempfile( package, file );
+ si = MSI_GetSummaryInformationW( db->storage, 0 );
+ if (!si)
+ {
+ WARN("failed to load summary info %u\n", r);
+ msiobj_release( &package->hdr );
+ return ERROR_INSTALL_PACKAGE_INVALID;
+ }
+
+ r = msi_parse_summary( si, package );
+ msiobj_release( &si->hdr );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("failed to parse summary info %u\n", r);
+ msiobj_release( &package->hdr );
+ return r;
+ }
+
+ r = validate_package( package );
+ if (r != ERROR_SUCCESS)
+ {
+ msiobj_release( &package->hdr );
+ return r;
+ }
msi_set_property( package->db, Database, db->path );
if( UrlIsW( szPackage, URLIS_URL ) )
@@ -1398,7 +1538,7 @@
if (r != ERROR_SUCCESS)
{
ERR("registered patch failed to apply %u\n", r);
- MSI_FreePackage( (MSIOBJECTHDR *)package );
+ msiobj_release( &package->hdr );
return r;
}
@@ -1408,7 +1548,7 @@
if (index)
{
msi_clone_properties( package );
- msi_adjust_allusers_property( package );
+ msi_adjust_privilege_properties( package );
}
*pPackage = package;
Modified: trunk/reactos/dll/win32/msi/record.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/record.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/record.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/record.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -45,6 +45,7 @@
#define MSIFIELD_INT 1
#define MSIFIELD_WSTR 3
#define MSIFIELD_STREAM 4
+#define MSIFIELD_INTPTR 5
static void MSI_FreeField( MSIFIELD *field )
{
@@ -52,6 +53,7 @@
{
case MSIFIELD_NULL:
case MSIFIELD_INT:
+ case MSIFIELD_INTPTR:
break;
case MSIFIELD_WSTR:
msi_free( field->u.szwVal);
@@ -176,6 +178,9 @@
break;
case MSIFIELD_INT:
out->u.iVal = in->u.iVal;
+ break;
+ case MSIFIELD_INTPTR:
+ out->u.pVal = in->u.pVal;
break;
case MSIFIELD_WSTR:
str = strdupW( in->u.szwVal );
@@ -200,19 +205,47 @@
return r;
}
-int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField)
-{
- int ret = 0;
-
- TRACE("%p %d\n", rec, iField );
-
- if( iField > rec->count )
- return MSI_NULL_INTEGER;
+INT_PTR MSI_RecordGetIntPtr( MSIRECORD *rec, UINT iField )
+{
+ int ret;
+
+ TRACE( "%p %d\n", rec, iField );
+
+ if( iField > rec->count )
+ return MININT_PTR;
switch( rec->fields[iField].type )
{
case MSIFIELD_INT:
return rec->fields[iField].u.iVal;
+ case MSIFIELD_INTPTR:
+ return rec->fields[iField].u.pVal;
+ case MSIFIELD_WSTR:
+ if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
+ return ret;
+ return MININT_PTR;
+ default:
+ break;
+ }
+
+ return MININT_PTR;
+}
+
+int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField)
+{
+ int ret = 0;
+
+ TRACE("%p %d\n", rec, iField );
+
+ if( iField > rec->count )
+ return MSI_NULL_INTEGER;
+
+ switch( rec->fields[iField].type )
+ {
+ case MSIFIELD_INT:
+ return rec->fields[iField].u.iVal;
+ case MSIFIELD_INTPTR:
+ return rec->fields[iField].u.pVal;
case MSIFIELD_WSTR:
if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
return ret;
@@ -263,6 +296,20 @@
}
msiobj_unlock( &rec->hdr );
msiobj_release( &rec->hdr );
+
+ return ERROR_SUCCESS;
+}
+
+UINT MSI_RecordSetIntPtr( MSIRECORD *rec, UINT iField, INT_PTR pVal )
+{
+ TRACE("%p %u %ld\n", rec, iField, pVal);
+
+ if( iField > rec->count )
+ return ERROR_INVALID_PARAMETER;
+
+ MSI_FreeField( &rec->fields[iField] );
+ rec->fields[iField].type = MSIFIELD_INTPTR;
+ rec->fields[iField].u.pVal = pVal;
return ERROR_SUCCESS;
}
Modified: trunk/reactos/dll/win32/msi/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/registry.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/registry.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -40,7 +40,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
/*
* This module will be all the helper functions for registry access by the
* installer bits.
@@ -97,6 +96,15 @@
static const WCHAR szUninstall_fmt[] = {
'S','o','f','t','w','a','r','e','\\',
+'M','i','c','r','o','s','o','f','t','\\',
+'W','i','n','d','o','w','s','\\',
+'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+'U','n','i','n','s','t','a','l','l','\\',
+'%','s',0 };
+
+static const WCHAR szUninstall_32node_fmt[] = {
+'S','o','f','t','w','a','r','e','\\',
+'W','o','w','6','4','3','2','N','o','d','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s','\\',
'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
@@ -509,28 +517,36 @@
return ERROR_SUCCESS;
}
-UINT MSIREG_OpenUninstallKey(LPCWSTR szProduct, HKEY* key, BOOL create)
+UINT MSIREG_OpenUninstallKey(MSIPACKAGE *package, HKEY *key, BOOL create)
{
UINT rc;
WCHAR keypath[0x200];
- TRACE("%s\n",debugstr_w(szProduct));
-
- sprintfW(keypath,szUninstall_fmt,szProduct);
+
+ TRACE("%s\n", debugstr_w(package->ProductCode));
+
+ if (is_64bit && package->platform == PLATFORM_INTEL)
+ sprintfW(keypath, szUninstall_32node_fmt, package->ProductCode);
+ else
+ sprintfW(keypath, szUninstall_fmt, package->ProductCode);
if (create)
- rc = RegCreateKeyW(HKEY_LOCAL_MACHINE, keypath, key);
- else
- rc = RegOpenKeyW(HKEY_LOCAL_MACHINE, keypath, key);
+ rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, NULL, 0, KEY_ALL_ACCESS,
NULL, key, NULL);
+ else
+ rc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keypath, 0, KEY_ALL_ACCESS, key);
return rc;
}
-UINT MSIREG_DeleteUninstallKey(LPCWSTR szProduct)
-{
- WCHAR keypath[0x200];
- TRACE("%s\n",debugstr_w(szProduct));
-
- sprintfW(keypath,szUninstall_fmt,szProduct);
+UINT MSIREG_DeleteUninstallKey(MSIPACKAGE *package)
+{
+ WCHAR keypath[0x200];
+
+ TRACE("%s\n", debugstr_w(package->ProductCode));
+
+ if (is_64bit && package->platform == PLATFORM_INTEL)
+ sprintfW(keypath, szUninstall_32node_fmt, package->ProductCode);
+ else
+ sprintfW(keypath, szUninstall_fmt, package->ProductCode);
return RegDeleteTreeW(HKEY_LOCAL_MACHINE, keypath);
}
Modified: trunk/reactos/dll/win32/msi/storages.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/storages.c?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/storages.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -334,10 +334,12 @@
static UINT storages_find_row(MSISTORAGESVIEW *sv, MSIRECORD *rec, UINT *row)
{
LPCWSTR str;
- UINT i, id, data;
+ UINT r, i, id, data;
str = MSI_RecordGetString(rec, 1);
- msi_string2idW(sv->db->strings, str, &id);
+ r = msi_string2idW(sv->db->strings, str, &id);
+ if (r != ERROR_SUCCESS)
+ return r;
for (i = 0; i < sv->num_rows; i++)
{
Modified: trunk/reactos/dll/win32/msi/string.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/string.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/msi/string.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/string.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -3,6 +3,7 @@
*
* Copyright 2002-2004, Mike McCormack for CodeWeavers
* Copyright 2007 Robert Shearman for CodeWeavers
+ * Copyright 2010 Hans Leidekker for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,8 +41,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
-#define LONG_STR_BYTES 3
-
typedef struct _msistring
{
USHORT persistent_refcount;
@@ -564,7 +563,7 @@
return st;
}
-UINT msi_save_string_table( const string_table *st, IStorage *storage )
+UINT msi_save_string_table( const string_table *st, IStorage *storage, UINT
*bytes_per_strref )
{
UINT i, datasize = 0, poolsize = 0, sz, used, r, codepage, n;
UINT ret = ERROR_FUNCTION_FAILED;
@@ -593,8 +592,16 @@
used = 0;
codepage = st->codepage;
- pool[0]=codepage&0xffff;
- pool[1]=(codepage>>16);
+ pool[0] = codepage & 0xffff;
+ pool[1] = codepage >> 16;
+ if (st->maxcount > 0xffff)
+ {
+ pool[1] |= 0x8000;
+ *bytes_per_strref = LONG_STR_BYTES;
+ }
+ else
+ *bytes_per_strref = sizeof(USHORT);
+
n = 1;
for( i=1; i<st->maxcount; i++ )
{
Modified: trunk/reactos/dll/win32/msi/suminfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/suminfo.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/suminfo.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -469,7 +469,7 @@
if( !pHandle )
return ERROR_INVALID_PARAMETER;
- if( szDatabase )
+ if( szDatabase && szDatabase[0] )
{
LPCWSTR persist = uiUpdateCount ? MSIDBOPEN_TRANSACT : MSIDBOPEN_READONLY;
@@ -644,6 +644,18 @@
return strdupAtoW( prop->u.pszVal );
}
+INT msi_suminfo_get_int32( MSISUMMARYINFO *si, UINT uiProperty )
+{
+ PROPVARIANT *prop;
+
+ if ( uiProperty >= MSI_MAX_PROPS )
+ return -1;
+ prop = &si->property[uiProperty];
+ if( prop->vt != VT_I4 )
+ return -1;
+ return prop->u.lVal;
+}
+
LPWSTR msi_get_suminfo_product( IStorage *stg )
{
MSISUMMARYINFO *si;
Modified: trunk/reactos/dll/win32/msi/table.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/table.c?rev=…
==============================================================================
--- trunk/reactos/dll/win32/msi/table.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/table.c [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -42,7 +42,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(msidb);
#define MSITABLE_HASH_TABLE_SIZE 37
-#define LONG_STR_BYTES 3
typedef struct tagMSICOLUMNHASHENTRY
{
@@ -117,13 +116,13 @@
LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz);
static void msi_free_colinfo( MSICOLUMNINFO *colinfo, UINT count );
-static inline UINT bytes_per_column( MSIDATABASE *db, const MSICOLUMNINFO *col )
+static inline UINT bytes_per_column( MSIDATABASE *db, const MSICOLUMNINFO *col, UINT
bytes_per_strref )
{
if( MSITYPE_IS_BINARY(col->type) )
return 2;
if( col->type & MSITYPE_STRING )
- return db->bytes_per_strref;
+ return bytes_per_strref;
if( (col->type & 0xff) <= 2)
return 2;
@@ -399,24 +398,33 @@
msi_free( table );
}
-static UINT msi_table_get_row_size( MSIDATABASE *db,const MSICOLUMNINFO *cols,
- UINT count )
-{
- const MSICOLUMNINFO *last_col = &cols[count-1];
+static UINT msi_table_get_row_size( MSIDATABASE *db, const MSICOLUMNINFO *cols, UINT
count, UINT bytes_per_strref )
+{
+ const MSICOLUMNINFO *last_col;
+
if (!count)
return 0;
- return last_col->offset + bytes_per_column( db, last_col );
+
+ if (bytes_per_strref != LONG_STR_BYTES)
+ {
+ UINT i, size = 0;
+ for (i = 0; i < count; i++) size += bytes_per_column( db, &cols[i],
bytes_per_strref );
+ return size;
+ }
+ last_col = &cols[count - 1];
+ return last_col->offset + bytes_per_column( db, last_col, bytes_per_strref );
}
/* add this table to the list of cached tables in the database */
static UINT read_table_from_storage( MSIDATABASE *db, MSITABLE *t, IStorage *stg )
{
BYTE *rawdata = NULL;
- UINT rawsize = 0, i, j, row_size = 0;
+ UINT rawsize = 0, i, j, row_size, row_size_mem;
TRACE("%s\n",debugstr_w(t->name));
- row_size = msi_table_get_row_size( db, t->colinfo, t->col_count );
+ row_size = msi_table_get_row_size( db, t->colinfo, t->col_count,
db->bytes_per_strref );
+ row_size_mem = msi_table_get_row_size( db, t->colinfo, t->col_count,
LONG_STR_BYTES );
/* if we can't read the table, just assume that it's empty */
read_stream_data( stg, t->name, TRUE, &rawdata, &rawsize );
@@ -441,17 +449,19 @@
/* transpose all the data */
TRACE("Transposing data from %d rows\n", t->row_count );
- for( i=0; i<t->row_count; i++ )
- {
- t->data[i] = msi_alloc( row_size );
+ for (i = 0; i < t->row_count; i++)
+ {
+ UINT ofs = 0, ofs_mem = 0;
+
+ t->data[i] = msi_alloc( row_size_mem );
if( !t->data[i] )
goto err;
t->data_persistent[i] = TRUE;
- for( j=0; j<t->col_count; j++ )
- {
- UINT ofs = t->colinfo[j].offset;
- UINT n = bytes_per_column( db, &t->colinfo[j] );
+ for (j = 0; j < t->col_count; j++)
+ {
+ UINT m = bytes_per_column( db, &t->colinfo[j], LONG_STR_BYTES );
+ UINT n = bytes_per_column( db, &t->colinfo[j], db->bytes_per_strref
);
UINT k;
if ( n != 2 && n != 3 && n != 4 )
@@ -459,9 +469,23 @@
ERR("oops - unknown column width %d\n", n);
goto err;
}
-
- for ( k = 0; k < n; k++ )
- t->data[i][ofs + k] = rawdata[ofs*t->row_count + i * n + k];
+ if (t->colinfo[j].type & MSITYPE_STRING && n < m)
+ {
+ for (k = 0; k < m; k++)
+ {
+ if (k < n)
+ t->data[i][ofs_mem + k] = rawdata[ofs * t->row_count + i *
n + k];
+ else
+ t->data[i][ofs_mem + k] = 0;
+ }
+ }
+ else
+ {
+ for (k = 0; k < n; k++)
+ t->data[i][ofs_mem + k] = rawdata[ofs * t->row_count + i * n +
k];
+ }
+ ofs_mem += m;
+ ofs += n;
}
}
@@ -729,10 +753,20 @@
return ERROR_SUCCESS;
}
-static UINT save_table( MSIDATABASE *db, const MSITABLE *t )
-{
- BYTE *rawdata = NULL, *p;
- UINT rawsize, r, i, j, row_size;
+static UINT read_table_int(BYTE *const *data, UINT row, UINT col, UINT bytes)
+{
+ UINT ret = 0, i;
+
+ for (i = 0; i < bytes; i++)
+ ret += data[row][col + i] << i * 8;
+
+ return ret;
+}
+
+static UINT save_table( MSIDATABASE *db, const MSITABLE *t, UINT bytes_per_strref )
+{
+ BYTE *rawdata = NULL;
+ UINT rawsize, r, i, j, row_size, row_count;
/* Nothing to do for non-persistent tables */
if( t->persistent == MSICONDITION_FALSE )
@@ -740,9 +774,17 @@
TRACE("Saving %s\n", debugstr_w( t->name ) );
- row_size = msi_table_get_row_size( db, t->colinfo, t->col_count );
-
- rawsize = t->row_count * row_size;
+ row_size = msi_table_get_row_size( db, t->colinfo, t->col_count,
bytes_per_strref );
+ row_count = t->row_count;
+ for (i = 0; i < t->row_count; i++)
+ {
+ if (!t->data_persistent[i])
+ {
+ row_count = 1; /* yes, this is bizarre */
+ break;
+ }
+ }
+ rawsize = row_count * row_size;
rawdata = msi_alloc_zero( rawsize );
if( !rawdata )
{
@@ -751,25 +793,41 @@
}
rawsize = 0;
- p = rawdata;
- for( i=0; i<t->col_count; i++ )
- {
- for( j=0; j<t->row_count; j++ )
- {
- UINT offset = t->colinfo[i].offset;
-
- if (!t->data_persistent[j]) continue;
- if (i == 0)
- rawsize += row_size;
-
- *p++ = t->data[j][offset];
- *p++ = t->data[j][offset + 1];
- if( 4 == bytes_per_column( db, &t->colinfo[i] ) )
+ for (i = 0; i < t->row_count; i++)
+ {
+ UINT ofs = 0, ofs_mem = 0;
+
+ if (!t->data_persistent[i]) break;
+
+ for (j = 0; j < t->col_count; j++)
+ {
+ UINT m = bytes_per_column( db, &t->colinfo[j], LONG_STR_BYTES );
+ UINT n = bytes_per_column( db, &t->colinfo[j], bytes_per_strref );
+ UINT k;
+
+ if (n != 2 && n != 3 && n != 4)
{
- *p++ = t->data[j][offset + 2];
- *p++ = t->data[j][offset + 3];
+ ERR("oops - unknown column width %d\n", n);
+ goto err;
}
- }
+ if (t->colinfo[j].type & MSITYPE_STRING && n < m)
+ {
+ UINT id = read_table_int( t->data, i, ofs_mem, LONG_STR_BYTES );
+ if (id > 1 << bytes_per_strref * 8)
+ {
+ ERR("string id %u out of range\n", id);
+ r = ERROR_FUNCTION_FAILED;
+ goto err;
+ }
+ }
+ for (k = 0; k < n; k++)
+ {
+ rawdata[ofs * row_count + i * n + k] = t->data[i][ofs_mem + k];
+ }
+ ofs_mem += m;
+ ofs += n;
+ }
+ rawsize += row_size;
}
TRACE("writing %d bytes\n", rawsize);
@@ -777,12 +835,10 @@
err:
msi_free( rawdata );
-
return r;
}
-static void table_calc_column_offsets( MSIDATABASE *db, MSICOLUMNINFO *colinfo,
- DWORD count )
+static void table_calc_column_offsets( MSIDATABASE *db, MSICOLUMNINFO *colinfo, DWORD
count )
{
DWORD i;
@@ -791,7 +847,7 @@
assert( (i+1) == colinfo[ i ].number );
if (i)
colinfo[i].offset = colinfo[ i - 1 ].offset
- + bytes_per_column( db, &colinfo[ i - 1 ] );
+ + bytes_per_column( db, &colinfo[ i - 1 ],
LONG_STR_BYTES );
else
colinfo[i].offset = 0;
TRACE("column %d is [%s] with type %08x ofs %d\n",
@@ -855,16 +911,6 @@
return strdupW(msi_string_lookup_id( db->strings, stringid ));
}
-static UINT read_table_int(BYTE *const *data, UINT row, UINT col, UINT bytes)
-{
- UINT ret = 0, i;
-
- for (i = 0; i < bytes; i++)
- ret += (data[row][col + i] << i * 8);
-
- return ret;
-}
-
static UINT get_tablecolumns( MSIDATABASE *db,
LPCWSTR szTableName, MSICOLUMNINFO *colinfo, UINT *sz)
{
@@ -902,11 +948,11 @@
count = table->row_count;
for( i=0; i<count; i++ )
{
- if( read_table_int(table->data, i, 0, db->bytes_per_strref) != table_id )
+ if( read_table_int(table->data, i, 0, LONG_STR_BYTES) != table_id )
continue;
if( colinfo )
{
- UINT id = read_table_int(table->data, i, table->colinfo[2].offset,
db->bytes_per_strref);
+ UINT id = read_table_int(table->data, i, table->colinfo[2].offset,
LONG_STR_BYTES);
UINT col = read_table_int(table->data, i, table->colinfo[1].offset,
sizeof(USHORT)) - (1<<15);
/* check the column number is in range */
@@ -971,7 +1017,7 @@
if (!table->col_count)
goto done;
- size = msi_table_get_row_size( db, table->colinfo, table->col_count );
+ size = msi_table_get_row_size( db, table->colinfo, table->col_count,
LONG_STR_BYTES );
offset = table->colinfo[table->col_count - 1].offset;
for ( n = 0; n < table->row_count; n++ )
@@ -988,8 +1034,8 @@
/* try to find the table name in the _Tables table */
BOOL TABLE_Exists( MSIDATABASE *db, LPCWSTR name )
{
- UINT r, table_id = 0, i, count;
- MSITABLE *table = NULL;
+ UINT r, table_id, i;
+ MSITABLE *table;
static const WCHAR szStreams[] =
{'_','S','t','r','e','a','m','s',0};
static const WCHAR szStorages[] =
{'_','S','t','o','r','a','g','e','s',0};
@@ -1012,10 +1058,11 @@
return FALSE;
}
- count = table->row_count;
- for( i=0; i<count; i++ )
- if( table->data[ i ][ 0 ] == table_id )
+ for( i = 0; i < table->row_count; i++ )
+ {
+ if( read_table_int( table->data, i, 0, LONG_STR_BYTES ) == table_id )
return TRUE;
+ }
return FALSE;
}
@@ -1059,7 +1106,7 @@
if (tv->order)
row = tv->order->reorder[row];
- n = bytes_per_column( tv->db, &tv->columns[col-1] );
+ n = bytes_per_column( tv->db, &tv->columns[col - 1], LONG_STR_BYTES );
if (n != 2 && n != 3 && n != 4)
{
ERR("oops! what is %d bytes per column?\n", n );
@@ -1116,7 +1163,7 @@
{
static const WCHAR fmt[] = { '%','d',0 };
WCHAR number[0x20];
- UINT n = bytes_per_column( tv->db, &tv->columns[i] );
+ UINT n = bytes_per_column( tv->db, &tv->columns[i],
LONG_STR_BYTES );
switch( n )
{
@@ -1213,7 +1260,7 @@
msi_free( tv->columns[col-1].hash_table );
tv->columns[col-1].hash_table = NULL;
- n = bytes_per_column( tv->db, &tv->columns[col-1] );
+ n = bytes_per_column( tv->db, &tv->columns[col - 1], LONG_STR_BYTES );
if ( n != 2 && n != 3 && n != 4 )
{
ERR("oops! what is %d bytes per column?\n", n );
@@ -1304,7 +1351,7 @@
if (r != ERROR_SUCCESS)
return ERROR_NOT_FOUND;
}
- else if ( 2 == bytes_per_column( tv->db, &columninfo ) )
+ else if ( bytes_per_column( tv->db, &columninfo, LONG_STR_BYTES ) == 2 )
{
*pvalue = 0x8000 + MSI_RecordGetInteger( rec, iField );
if ( *pvalue & 0xffff0000 )
@@ -1577,39 +1624,60 @@
return ERROR_SUCCESS;
}
-static UINT find_insert_index( MSITABLEVIEW *tv, MSIRECORD *rec, UINT *pidx )
-{
- UINT r, idx, j, ivalue, x;
-
- TRACE("%p %p %p\n", tv, rec, pidx);
-
- for (idx = 0; idx < tv->table->row_count; idx++)
- {
- for (j = 0; j < tv->num_cols; j++ )
- {
- r = get_table_value_from_record (tv, rec, j+1, &ivalue);
- if (r != ERROR_SUCCESS)
- break;
-
- r = TABLE_fetch_int(&tv->view, idx, j + 1, &x);
- if (r != ERROR_SUCCESS)
- return r;
-
- if (ivalue > x)
- break;
- else if (ivalue == x)
- continue;
- else {
- TRACE("Found %d.\n", idx);
- *pidx = idx;
- return ERROR_SUCCESS;
- }
- }
- }
-
- TRACE("Found %d.\n", idx);
- *pidx = idx;
- return ERROR_SUCCESS;
+static int compare_record( MSITABLEVIEW *tv, UINT row, MSIRECORD *rec )
+{
+ UINT r, i, ivalue, x;
+
+ for (i = 0; i < tv->num_cols; i++ )
+ {
+ r = get_table_value_from_record( tv, rec, i + 1, &ivalue );
+ if (r != ERROR_SUCCESS)
+ return 1;
+
+ r = TABLE_fetch_int( &tv->view, row, i + 1, &x );
+ if (r != ERROR_SUCCESS)
+ {
+ WARN("TABLE_fetch_int should not fail here %u\n", r);
+ return -1;
+ }
+ if (ivalue > x)
+ {
+ return 1;
+ }
+ else if (ivalue == x)
+ {
+ if (i < tv->num_cols - 1) continue;
+ return 0;
+ }
+ else
+ return -1;
+ }
+ return 1;
+}
+
+static int find_insert_index( MSITABLEVIEW *tv, MSIRECORD *rec )
+{
+ int idx, c, low = 0, high = tv->table->row_count - 1;
+
+ TRACE("%p %p\n", tv, rec);
+
+ while (low <= high)
+ {
+ idx = (low + high) / 2;
+ c = compare_record( tv, idx, rec );
+
+ if (c < 0)
+ high = idx - 1;
+ else if (c > 0)
+ low = idx + 1;
+ else
+ {
+ TRACE("found %u\n", idx);
+ return idx;
+ }
+ }
+ TRACE("found %u\n", high + 1);
+ return high + 1;
}
static UINT TABLE_insert_row( struct tagMSIVIEW *view, MSIRECORD *rec, UINT row, BOOL
temporary )
@@ -1625,11 +1693,7 @@
return ERROR_FUNCTION_FAILED;
if (row == -1)
- {
- r = find_insert_index(tv, rec, &row);
- if( r != ERROR_SUCCESS )
- return ERROR_FUNCTION_FAILED;
- }
+ row = find_insert_index( tv, rec );
r = table_create_new_row( view, &row, temporary );
TRACE("insert_row returned %08x\n", r);
@@ -2306,7 +2370,7 @@
tv->db = db;
tv->columns = tv->table->colinfo;
tv->num_cols = tv->table->col_count;
- tv->row_size = msi_table_get_row_size( db, tv->table->colinfo,
tv->table->col_count );
+ tv->row_size = msi_table_get_row_size( db, tv->table->colinfo,
tv->table->col_count, LONG_STR_BYTES );
TRACE("%s one row is %d bytes\n", debugstr_w(name), tv->row_size );
@@ -2318,12 +2382,13 @@
UINT MSI_CommitTables( MSIDATABASE *db )
{
- UINT r;
+ UINT r, bytes_per_strref;
+ HRESULT hr;
MSITABLE *table = NULL;
TRACE("%p\n",db);
- r = msi_save_string_table( db->strings, db->storage );
+ r = msi_save_string_table( db->strings, db->storage, &bytes_per_strref );
if( r != ERROR_SUCCESS )
{
WARN("failed to save string table r=%08x\n",r);
@@ -2332,7 +2397,7 @@
LIST_FOR_EACH_ENTRY( table, &db->tables, MSITABLE, entry )
{
- r = save_table( db, table );
+ r = save_table( db, table, bytes_per_strref );
if( r != ERROR_SUCCESS )
{
WARN("failed to save table %s (r=%08x)\n",
@@ -2344,7 +2409,13 @@
/* force everything to reload next time */
free_cached_tables( db );
- return ERROR_SUCCESS;
+ hr = IStorage_Commit( db->storage, 0 );
+ if (FAILED( hr ))
+ {
+ WARN("failed to commit changes 0x%08x\n", hr);
+ r = ERROR_FUNCTION_FAILED;
+ }
+ return r;
}
MSICONDITION MSI_DatabaseIsTablePersistent( MSIDATABASE *db, LPCWSTR table )
@@ -2463,7 +2534,7 @@
IStream *stm = NULL;
UINT r;
- ofs += bytes_per_column( tv->db, &columns[i] );
+ ofs += bytes_per_column( tv->db, &columns[i], bytes_per_strref );
r = msi_record_encoded_stream_name( tv, rec, &encname );
if ( r != ERROR_SUCCESS )
@@ -2490,7 +2561,7 @@
}
else
{
- UINT n = bytes_per_column( tv->db, &columns[i] );
+ UINT n = bytes_per_column( tv->db, &columns[i], bytes_per_strref );
switch( n )
{
case 2:
@@ -2704,7 +2775,7 @@
! MSITYPE_IS_BINARY(tv->columns[i].type) )
sz += bytes_per_strref;
else
- sz += bytes_per_column( tv->db, &tv->columns[i] );
+ sz += bytes_per_column( tv->db, &tv->columns[i],
bytes_per_strref );
}
}
else
@@ -2726,7 +2797,7 @@
! MSITYPE_IS_BINARY(tv->columns[i].type) )
sz += bytes_per_strref;
else
- sz += bytes_per_column( tv->db, &tv->columns[i] );
+ sz += bytes_per_column( tv->db, &tv->columns[i],
bytes_per_strref );
}
}
}
Modified: trunk/reactos/dll/win32/msi/version.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msi/version.rc?r…
==============================================================================
--- trunk/reactos/dll/win32/msi/version.rc [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msi/version.rc [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -18,9 +18,9 @@
#define WINE_FILEDESCRIPTION_STR "Wine MSI dll"
#define WINE_FILENAME_STR "msi.dll"
-#define WINE_FILEVERSION 3,1,4000,2435
-#define WINE_FILEVERSION_STR "3.1.4000.2435"
-#define WINE_PRODUCTVERSION 3,1,4000,2435
-#define WINE_PRODUCTVERSION_STR "3.1.4000.2435"
+#define WINE_FILEVERSION 4,5,6001,22159
+#define WINE_FILEVERSION_STR "4.5.6001.22159"
+#define WINE_PRODUCTVERSION 4,5,6001,22159
+#define WINE_PRODUCTVERSION_STR "4.5.6001.22159"
#include "wine/wine_common_ver.rc"
Modified: trunk/reactos/include/psdk/msi.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/msi.h?rev=492…
==============================================================================
--- trunk/reactos/include/psdk/msi.h [iso-8859-1] (original)
+++ trunk/reactos/include/psdk/msi.h [iso-8859-1] Fri Oct 22 13:18:11 2010
@@ -19,12 +19,12 @@
#ifndef __WINE_MSI_H
#define __WINE_MSI_H
+#ifndef _MSI_NO_CRYPTO
+#include <wincrypt.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
-#endif
-
-#ifndef _MSI_NO_CRYPTO
-#include <wincrypt.h>
#endif
typedef ULONG MSIHANDLE;
@@ -663,6 +663,12 @@
UINT WINAPI MsiApplyMultiplePatchesW(LPCWSTR, LPCWSTR, LPCWSTR);
#define MsiApplyMultiplePatches WINELIB_NAME_AW(MsiApplyMultiplePatches)
+UINT WINAPI MsiBeginTransactionA(LPCSTR, DWORD, MSIHANDLE *, HANDLE *);
+UINT WINAPI MsiBeginTransactionW(LPCWSTR, DWORD, MSIHANDLE *, HANDLE *);
+#define MsiBeginTransaction WINELIB_NAME_AW(MsiBeginTransaction)
+
+UINT WINAPI MsiEndTransaction(DWORD);
+
/* Non Unicode */
UINT WINAPI MsiCloseHandle(MSIHANDLE);
UINT WINAPI MsiCloseAllHandles(void);