[ros-diffs] [janderwald] 49924: - Merge from trunk - Hackfixed to build

janderwald at svn.reactos.org janderwald at svn.reactos.org
Fri Dec 3 13:37:10 UTC 2010


Author: janderwald
Date: Fri Dec  3 13:37:09 2010
New Revision: 49924

URL: http://svn.reactos.org/svn/reactos?rev=49924&view=rev
Log:
- Merge from trunk
- Hackfixed to build

Modified:
    branches/audio-bringup/dll/win32/msi/action.c
    branches/audio-bringup/dll/win32/msi/appsearch.c
    branches/audio-bringup/dll/win32/msi/classes.c
    branches/audio-bringup/dll/win32/msi/cond.tab.c
    branches/audio-bringup/dll/win32/msi/cond.y
    branches/audio-bringup/dll/win32/msi/custom.c
    branches/audio-bringup/dll/win32/msi/database.c
    branches/audio-bringup/dll/win32/msi/join.c
    branches/audio-bringup/dll/win32/msi/media.c
    branches/audio-bringup/dll/win32/msi/msi.c
    branches/audio-bringup/dll/win32/msi/msi.spec
    branches/audio-bringup/dll/win32/msi/msi_Fi.rc
    branches/audio-bringup/dll/win32/msi/msipriv.h
    branches/audio-bringup/dll/win32/msi/msiquery.c
    branches/audio-bringup/dll/win32/msi/package.c
    branches/audio-bringup/dll/win32/msi/record.c
    branches/audio-bringup/dll/win32/msi/registry.c
    branches/audio-bringup/dll/win32/msi/storages.c
    branches/audio-bringup/dll/win32/msi/string.c
    branches/audio-bringup/dll/win32/msi/suminfo.c
    branches/audio-bringup/dll/win32/msi/table.c
    branches/audio-bringup/dll/win32/msi/version.rc

Modified: branches/audio-bringup/dll/win32/msi/action.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/action.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/action.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/action.c [iso-8859-1] Fri Dec  3 13:37:09 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;
@@ -1985,7 +1985,7 @@
 VS_FIXEDFILEINFO *msi_get_disk_file_version( LPCWSTR filename )
 {
     static const WCHAR name[] = {'\\',0};
-    VS_FIXEDFILEINFO *ret;
+    VS_FIXEDFILEINFO *ptr, *ret;
     LPVOID version;
     DWORD versize, handle;
     UINT sz;
@@ -2002,11 +2002,14 @@
 
     GetFileVersionInfoW( filename, 0, versize, version );
 
-    if (!VerQueryValueW( version, name, (LPVOID *)&ret, &sz ))
+    if (!VerQueryValueW( version, name, (LPVOID *)&ptr, &sz ))
     {
         msi_free( version );
         return NULL;
     }
+
+    ret = msi_alloc( sz );
+    memcpy( ret, ptr, sz );
 
     msi_free( version );
     return ret;
@@ -2371,17 +2374,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 +2461,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 +2583,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 +2639,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 +2660,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 +2713,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 +3924,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 +4792,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 +4872,7 @@
 
     MSIREG_DeleteProductKey(package->ProductCode);
     MSIREG_DeleteUserDataProductKey(package->ProductCode);
-    MSIREG_DeleteUninstallKey(package->ProductCode);
+    MSIREG_DeleteUninstallKey(package);
 
     if (package->Context == MSIINSTALLCONTEXT_MACHINE)
     {
@@ -7498,7 +7531,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: branches/audio-bringup/dll/win32/msi/appsearch.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/appsearch.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/appsearch.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/appsearch.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/classes.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/classes.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/classes.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/classes.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/cond.tab.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/cond.tab.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/cond.tab.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/cond.tab.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/cond.y
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/cond.y?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/cond.y [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/cond.y [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/custom.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/custom.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/custom.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/custom.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/database.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/database.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/database.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/database.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/join.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/join.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/join.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/join.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/media.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/media.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/media.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/media.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/msi.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/msi.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/msi.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/msi.c [iso-8859-1] Fri Dec  3 13:37:09 2010
@@ -3779,3 +3779,45 @@
     FIXME("(%s %s %d\n", debugstr_w(szProduct), debugstr_w(szComponent), eInstallState);
     return ERROR_SUCCESS;
 }
+
+UINT WINAPI MsiBeginTransactionW( LPCWSTR name, DWORD attrs, MSIHANDLE *id, HANDLE *event );
+/***********************************************************************
+ * 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: branches/audio-bringup/dll/win32/msi/msi.spec
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/msi.spec?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/msi.spec [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/msi.spec [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/msi_Fi.rc
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/msi_Fi.rc?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/msi_Fi.rc [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/msi_Fi.rc [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/msipriv.h
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/msipriv.h?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/msipriv.h [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/msipriv.h [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/msiquery.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/msiquery.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/msiquery.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/msiquery.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/package.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/package.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/package.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/package.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/record.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/record.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/record.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/record.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/registry.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/registry.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/registry.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/registry.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/storages.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/storages.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/storages.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/storages.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/string.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/string.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/string.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/string.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/suminfo.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/suminfo.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/suminfo.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/suminfo.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/table.c
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/table.c?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/table.c [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/table.c [iso-8859-1] Fri Dec  3 13:37:09 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: branches/audio-bringup/dll/win32/msi/version.rc
URL: http://svn.reactos.org/svn/reactos/branches/audio-bringup/dll/win32/msi/version.rc?rev=49924&r1=49923&r2=49924&view=diff
==============================================================================
--- branches/audio-bringup/dll/win32/msi/version.rc [iso-8859-1] (original)
+++ branches/audio-bringup/dll/win32/msi/version.rc [iso-8859-1] Fri Dec  3 13:37:09 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"




More information about the Ros-diffs mailing list