sync msi to wine 1.1.31
authorChristoph von Wittich <christoph_vw@reactos.org>
Sat, 17 Oct 2009 21:16:57 +0000 (21:16 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Sat, 17 Oct 2009 21:16:57 +0000 (21:16 +0000)
svn path=/trunk/; revision=43546

reactos/dll/win32/msi/action.c
reactos/dll/win32/msi/custom.c
reactos/dll/win32/msi/files.c
reactos/dll/win32/msi/media.c
reactos/dll/win32/msi/msi.c
reactos/dll/win32/msi/msipriv.h
reactos/dll/win32/msi/msiserver.idl
reactos/dll/win32/msi/package.c
reactos/dll/win32/msi/suminfo.c
reactos/dll/win32/msi/table.c
reactos/include/psdk/msi.h

index c824904..46249c2 100644 (file)
@@ -501,7 +501,7 @@ static UINT msi_apply_substorage_transform( MSIPACKAGE *package,
     return ERROR_SUCCESS;
 }
 
     return ERROR_SUCCESS;
 }
 
-static UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
+UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si )
 {
     static const WCHAR szProdCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
     LPWSTR guid_list, *guids, product_code;
 {
     static const WCHAR szProdCode[] = { 'P','r','o','d','u','c','t','C','o','d','e',0 };
     LPWSTR guid_list, *guids, product_code;
@@ -789,6 +789,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
     static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
     static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
     static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
     static const WCHAR szUILevel[] = {'U','I','L','e','v','e','l',0};
     static const WCHAR szAction[] = {'A','C','T','I','O','N',0};
     static const WCHAR szInstall[] = {'I','N','S','T','A','L','L',0};
+    static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
+    static const WCHAR szInstalled[] = {'I','n','s','t','a','l','l','e','d',0};
+    static const WCHAR szAll[] = {'A','L','L',0};
 
     MSI_SetPropertyW(package, szAction, szInstall);
 
 
     MSI_SetPropertyW(package, szAction, szInstall);
 
@@ -837,6 +840,12 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
     msi_apply_transforms( package );
     msi_apply_patches( package );
 
     msi_apply_transforms( package );
     msi_apply_patches( package );
 
+    if (!szCommandLine && msi_get_property_int( package, szInstalled, 0 ))
+    {
+        TRACE("setting reinstall property\n");
+        MSI_SetPropertyW( package, szReinstall, szAll );
+    }
+
     /* properties may have been added by a transform */
     msi_clone_properties( package );
     msi_set_context( package );
     /* properties may have been added by a transform */
     msi_clone_properties( package );
     msi_set_context( package );
@@ -871,6 +880,9 @@ UINT MSI_InstallPackage( MSIPACKAGE *package, LPCWSTR szPackagePath,
     /* finish up running custom actions */
     ACTION_FinishCustomActions(package);
     
     /* finish up running custom actions */
     ACTION_FinishCustomActions(package);
     
+    if (rc == ERROR_SUCCESS && package->need_reboot)
+        return ERROR_SUCCESS_REBOOT_REQUIRED;
+
     return rc;
 }
 
     return rc;
 }
 
@@ -3378,16 +3390,12 @@ static UINT ACTION_CreateShortcuts(MSIPACKAGE *package)
         return ERROR_SUCCESS;
 
     res = CoInitialize( NULL );
         return ERROR_SUCCESS;
 
     res = CoInitialize( NULL );
-    if (FAILED (res))
-    {
-        ERR("CoInitialize failed\n");
-        return ERROR_FUNCTION_FAILED;
-    }
 
     rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package);
     msiobj_release(&view->hdr);
 
 
     rc = MSI_IterateRecords(view, NULL, ITERATE_CreateShortcuts, package);
     msiobj_release(&view->hdr);
 
-    CoUninitialize();
+    if (SUCCEEDED(res))
+        CoUninitialize();
 
     return rc;
 }
 
     return rc;
 }
@@ -5308,8 +5316,7 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
         }
     }
 
         }
     }
 
-    if (!*flags ||
-        check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
+    if (check_flag_combo(*flags, ENV_ACT_SETALWAYS | ENV_ACT_SETABSENT) ||
         check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
         check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) ||
         check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK))
         check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETABSENT) ||
         check_flag_combo(*flags, ENV_ACT_REMOVEMATCH | ENV_ACT_SETALWAYS) ||
         check_flag_combo(*flags, ENV_ACT_SETABSENT | ENV_MOD_MASK))
@@ -5318,6 +5325,9 @@ static LONG env_set_flags( LPCWSTR *name, LPCWSTR *value, DWORD *flags )
         return ERROR_FUNCTION_FAILED;
     }
 
         return ERROR_FUNCTION_FAILED;
     }
 
+    if (!*flags)
+        *flags = ENV_ACT_SETALWAYS | ENV_ACT_REMOVE;
+
     return ERROR_SUCCESS;
 }
 
     return ERROR_SUCCESS;
 }
 
@@ -5345,6 +5355,8 @@ static UINT ITERATE_WriteEnvironmentString( MSIRECORD *rec, LPVOID param )
     name = MSI_RecordGetString(rec, 2);
     value = MSI_RecordGetString(rec, 3);
 
     name = MSI_RecordGetString(rec, 2);
     value = MSI_RecordGetString(rec, 3);
 
+    TRACE("name %s value %s\n", debugstr_w(name), debugstr_w(value));
+
     res = env_set_flags(&name, &value, &flags);
     if (res != ERROR_SUCCESS)
        goto done;
     res = env_set_flags(&name, &value, &flags);
     if (res != ERROR_SUCCESS)
        goto done;
index 3476f0d..5ac9c1b 100644 (file)
@@ -679,7 +679,7 @@ static DWORD ACTION_CallDllFunction( const GUID *guid )
     hModule = LoadLibraryW( dll );
     if (!hModule)
     {
     hModule = LoadLibraryW( dll );
     if (!hModule)
     {
-        ERR("failed to load dll %s\n", debugstr_w( dll ) );
+        ERR("failed to load dll %s (%u)\n", debugstr_w( dll ), GetLastError() );
         return r;
     }
 
         return r;
     }
 
@@ -1046,15 +1046,16 @@ static UINT HANDLE_CustomType19(MSIPACKAGE *package, LPCWSTR source,
     if( row )
     {
         LPCWSTR error = MSI_RecordGetString( row, 1 );
     if( row )
     {
         LPCWSTR error = MSI_RecordGetString( row, 1 );
-        MessageBoxW( NULL, error, NULL, MB_OK );
+        if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
+            MessageBoxW( NULL, error, NULL, MB_OK );
         msiobj_release( &row->hdr );
     }
         msiobj_release( &row->hdr );
     }
-    else
+    else if ((gUILevel & INSTALLUILEVEL_MASK) != INSTALLUILEVEL_NONE)
         MessageBoxW( NULL, deformated, NULL, MB_OK );
 
     msi_free( deformated );
 
         MessageBoxW( NULL, deformated, NULL, MB_OK );
 
     msi_free( deformated );
 
-    return ERROR_FUNCTION_FAILED;
+    return ERROR_INSTALL_FAILURE;
 }
 
 static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
 }
 
 static UINT HANDLE_CustomType50(MSIPACKAGE *package, LPCWSTR source,
index 01a80b7..d9cc0ff 100644 (file)
@@ -139,7 +139,7 @@ static UINT copy_file(MSIFILE *file, LPWSTR source)
     return ERROR_SUCCESS;
 }
 
     return ERROR_SUCCESS;
 }
 
-static UINT copy_install_file(MSIFILE *file, LPWSTR source)
+static UINT copy_install_file(MSIPACKAGE *package, MSIFILE *file, LPWSTR source)
 {
     UINT gle;
 
 {
     UINT gle;
 
@@ -153,7 +153,7 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source)
     if (gle == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite)
     {
         TRACE("overwriting existing file\n");
     if (gle == ERROR_ALREADY_EXISTS && file->state == msifs_overwrite)
     {
         TRACE("overwriting existing file\n");
-        gle = ERROR_SUCCESS;
+        return ERROR_SUCCESS;
     }
     else if (gle == ERROR_ACCESS_DENIED)
     {
     }
     else if (gle == ERROR_ACCESS_DENIED)
     {
@@ -162,6 +162,39 @@ static UINT copy_install_file(MSIFILE *file, LPWSTR source)
         gle = copy_file(file, source);
         TRACE("Overwriting existing file: %d\n", gle);
     }
         gle = copy_file(file, source);
         TRACE("Overwriting existing file: %d\n", gle);
     }
+    if (gle == ERROR_SHARING_VIOLATION)
+    {
+        static const WCHAR msiW[] = {'m','s','i',0};
+        static const WCHAR slashW[] = {'\\',0};
+        WCHAR tmpfileW[MAX_PATH], *pathW, *p;
+        DWORD len;
+
+        TRACE("file in use, scheduling rename operation\n");
+
+        GetTempFileNameW(slashW, msiW, 0, tmpfileW);
+        len = strlenW(file->TargetPath) + strlenW(tmpfileW) + 1;
+        if (!(pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
+            return ERROR_OUTOFMEMORY;
+
+        strcpyW(pathW, file->TargetPath);
+        if ((p = strrchrW(pathW, '\\'))) *p = 0;
+        strcatW(pathW, tmpfileW);
+
+        if (CopyFileW(source, pathW, FALSE) &&
+            MoveFileExW(file->TargetPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) &&
+            MoveFileExW(pathW, file->TargetPath, MOVEFILE_DELAY_UNTIL_REBOOT))
+        {
+            file->state = msifs_installed;
+            package->need_reboot = 1;
+            gle = ERROR_SUCCESS;
+        }
+        else
+        {
+            gle = GetLastError();
+            WARN("failed to schedule rename operation: %d)\n", gle);
+        }
+        HeapFree(GetProcessHeap(), 0, pathW);
+    }
 
     return gle;
 }
 
     return gle;
 }
@@ -296,7 +329,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
                   debugstr_w(file->TargetPath));
 
             msi_file_update_ui(package, file, szInstallFiles);
                   debugstr_w(file->TargetPath));
 
             msi_file_update_ui(package, file, szInstallFiles);
-            rc = copy_install_file(file, source);
+            rc = copy_install_file(package, file, source);
             if (rc != ERROR_SUCCESS)
             {
                 ERR("Failed to copy %s to %s (%d)\n", debugstr_w(source),
             if (rc != ERROR_SUCCESS)
             {
                 ERR("Failed to copy %s to %s (%d)\n", debugstr_w(source),
index 2de3252..83f4698 100644 (file)
@@ -49,11 +49,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
 #define _O_TEXT        0x4000
 #define _O_BINARY      0x8000
 
 #define _O_TEXT        0x4000
 #define _O_BINARY      0x8000
 
-static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPWSTR source_root)
+static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
 {
     WCHAR volume_name[MAX_PATH + 1];
 {
     WCHAR volume_name[MAX_PATH + 1];
+    WCHAR root[MAX_PATH + 1];
 
 
-    if (!GetVolumeInformationW(source_root, volume_name, MAX_PATH + 1,
+    strcpyW(root, source_root);
+    PathStripToRootW(root);
+    PathAddBackslashW(root);
+
+    if (!GetVolumeInformationW(root, volume_name, MAX_PATH + 1,
                                NULL, NULL, NULL, NULL, 0))
     {
         ERR("Failed to get volume information\n");
                                NULL, NULL, NULL, NULL, 0))
     {
         ERR("Failed to get volume information\n");
@@ -80,7 +85,6 @@ static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
     error = generate_error_string(package, 1302, 1, mi->disk_prompt);
     error_dialog = msi_dup_property(package, error_prop);
     source_dir = msi_dup_property(package, cszSourceDir);
     error = generate_error_string(package, 1302, 1, mi->disk_prompt);
     error_dialog = msi_dup_property(package, error_prop);
     source_dir = msi_dup_property(package, cszSourceDir);
-    PathStripToRootW(source_dir);
 
     while (r == ERROR_SUCCESS &&
            !source_matches_volume(mi, source_dir))
 
     while (r == ERROR_SUCCESS &&
            !source_matches_volume(mi, source_dir))
@@ -333,11 +337,56 @@ static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
                          NULL, CREATE_ALWAYS, attrs, NULL);
     if (handle == INVALID_HANDLE_VALUE)
     {
                          NULL, CREATE_ALWAYS, attrs, NULL);
     if (handle == INVALID_HANDLE_VALUE)
     {
-        if (GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
-            ERR("failed to create %s (error %d)\n",
-                debugstr_w(path), GetLastError());
+        DWORD err = GetLastError();
+        DWORD attrs2 = GetFileAttributesW(path);
 
 
-        goto done;
+        if (attrs2 == INVALID_FILE_ATTRIBUTES)
+        {
+            ERR("failed to create %s (error %d)\n", debugstr_w(path), err);
+            goto done;
+        }
+        else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
+        {
+            TRACE("removing read-only attribute on %s\n", debugstr_w(path));
+            SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY );
+            handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL);
+
+            if (handle != INVALID_HANDLE_VALUE) goto done;
+            err = GetLastError();
+        }
+        if (err == ERROR_SHARING_VIOLATION)
+        {
+            static const WCHAR msiW[] = {'m','s','i',0};
+            static const WCHAR slashW[] = {'\\',0};
+            WCHAR tmpfileW[MAX_PATH], *tmppathW, *p;
+            DWORD len;
+
+            TRACE("file in use, scheduling rename operation\n");
+
+            GetTempFileNameW(slashW, msiW, 0, tmpfileW);
+            len = strlenW(path) + strlenW(tmpfileW) + 1;
+            if (!(tmppathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
+                return ERROR_OUTOFMEMORY;
+
+            strcpyW(tmppathW, path);
+            if ((p = strrchrW(tmppathW, '\\'))) *p = 0;
+            strcatW(tmppathW, tmpfileW);
+
+            handle = CreateFileW(tmppathW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
+
+            if (handle != INVALID_HANDLE_VALUE &&
+                MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) &&
+                MoveFileExW(tmppathW, path, MOVEFILE_DELAY_UNTIL_REBOOT))
+            {
+                data->package->need_reboot = 1;
+            }
+            else
+                WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError());
+
+            HeapFree(GetProcessHeap(), 0, tmppathW);
+        }
+        else
+            WARN("failed to create %s (error %d)\n", debugstr_w(path), err);
     }
 
 done:
     }
 
 done:
@@ -455,6 +504,17 @@ void msi_free_media_info(MSIMEDIAINFO *mi)
     msi_free(mi);
 }
 
     msi_free(mi);
 }
 
+static UINT get_drive_type(const WCHAR *path)
+{
+    WCHAR root[MAX_PATH + 1];
+
+    strcpyW(root, path);
+    PathStripToRootW(root);
+    PathAddBackslashW(root);
+
+    return GetDriveTypeW(root);
+}
+
 static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
 {
     MSIRECORD *row;
 static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO *mi)
 {
     MSIRECORD *row;
@@ -494,9 +554,7 @@ static UINT msi_load_media_info(MSIPACKAGE *package, MSIFILE *file, MSIMEDIAINFO
 
     source_dir = msi_dup_property(package, cszSourceDir);
     lstrcpyW(mi->source, source_dir);
 
     source_dir = msi_dup_property(package, cszSourceDir);
     lstrcpyW(mi->source, source_dir);
-
-    PathStripToRootW(source_dir);
-    mi->type = GetDriveTypeW(source_dir);
+    mi->type = get_drive_type(source_dir);
 
     if (file->IsCompressed && mi->cabinet)
     {
 
     if (file->IsCompressed && mi->cabinet)
     {
@@ -576,7 +634,6 @@ static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
         {
             /* FIXME: what about SourceDir */
             lstrcpyW(mi->source, source);
         {
             /* FIXME: what about SourceDir */
             lstrcpyW(mi->source, source);
-            lstrcatW(mi->source, mi->cabinet);
             return ERROR_SUCCESS;
         }
     }
             return ERROR_SUCCESS;
         }
     }
index be1ad93..2a66d60 100644 (file)
@@ -489,13 +489,86 @@ UINT WINAPI MsiDetermineApplicablePatchesA(LPCSTR szProductPackagePath,
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
     return ERROR_CALL_NOT_IMPLEMENTED;
 }
 
+static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
+{
+    MSISUMMARYINFO *si;
+    MSIDATABASE *patch_db;
+    UINT r = ERROR_SUCCESS;
+
+    r = MSI_OpenDatabaseW( patch, MSIDBOPEN_READONLY, &patch_db );
+    if (r != ERROR_SUCCESS)
+    {
+        WARN("failed to open patch file %s\n", debugstr_w(patch));
+        return r;
+    }
+
+    si = MSI_GetSummaryInformationW( patch_db->storage, 0 );
+    if (!si)
+    {
+        r = ERROR_FUNCTION_FAILED;
+        goto done;
+    }
+
+    r = msi_check_patch_applicable( package, si );
+    if (r != ERROR_SUCCESS)
+        TRACE("patch not applicable\n");
+
+done:
+    msiobj_release( &patch_db->hdr );
+    msiobj_release( &si->hdr );
+    return r;
+}
+
 UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
         DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
 {
 UINT WINAPI MsiDetermineApplicablePatchesW(LPCWSTR szProductPackagePath,
         DWORD cPatchInfo, PMSIPATCHSEQUENCEINFOW pPatchInfo)
 {
-    FIXME("(%s, %d, %p): stub!\n", debugstr_w(szProductPackagePath),
-          cPatchInfo, pPatchInfo);
+    UINT i, r, ret = ERROR_FUNCTION_FAILED;
+    MSIPACKAGE *package;
 
 
-    return ERROR_CALL_NOT_IMPLEMENTED;
+    TRACE("(%s, %d, %p)\n", debugstr_w(szProductPackagePath), cPatchInfo, pPatchInfo);
+
+    r = MSI_OpenPackageW( szProductPackagePath, &package );
+    if (r != ERROR_SUCCESS)
+    {
+        ERR("failed to open package %u\n", r);
+        return r;
+    }
+
+    for (i = 0; i < cPatchInfo; i++)
+    {
+        switch (pPatchInfo[i].ePatchDataType)
+        {
+        case MSIPATCH_DATATYPE_PATCHFILE:
+        {
+            FIXME("patch ordering not supported\n");
+            r = MSI_ApplicablePatchW( package, pPatchInfo[i].szPatchData );
+            if (r != ERROR_SUCCESS)
+            {
+                pPatchInfo[i].dwOrder = ~0u;
+                pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+            }
+            else
+            {
+                pPatchInfo[i].dwOrder = i;
+                pPatchInfo[i].uStatus = ret = ERROR_SUCCESS;
+            }
+            break;
+        }
+        default:
+        {
+            FIXME("patch data type %u not supported\n", pPatchInfo[i].ePatchDataType);
+            pPatchInfo[i].dwOrder = ~0u;
+            pPatchInfo[i].uStatus = ERROR_PATCH_TARGET_NOT_FOUND;
+            break;
+        }
+        }
+
+        TRACE("   szPatchData: %s\n", debugstr_w(pPatchInfo[i].szPatchData));
+        TRACE("ePatchDataType: %u\n", pPatchInfo[i].ePatchDataType);
+        TRACE("       dwOrder: %u\n", pPatchInfo[i].dwOrder);
+        TRACE("       uStatus: %u\n", pPatchInfo[i].uStatus);
+    }
+    return ret;
 }
 
 UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
 }
 
 UINT WINAPI MsiDeterminePatchSequenceA(LPCSTR szProductCode, LPCSTR szUserSid,
@@ -620,9 +693,6 @@ UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
     if (szCommandLine)
         lstrcpyW(commandline,szCommandLine);
 
     if (szCommandLine)
         lstrcpyW(commandline,szCommandLine);
 
-    if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
-        lstrcatW(commandline,szInstalled);
-
     if (eInstallState == INSTALLSTATE_ABSENT)
         lstrcatW(commandline, szRemoveAll);
 
     if (eInstallState == INSTALLSTATE_ABSENT)
         lstrcatW(commandline, szRemoveAll);
 
index b61d7b6..71c3b69 100644 (file)
@@ -340,6 +340,7 @@ typedef struct tagMSIPACKAGE
     unsigned char scheduled_action_running : 1;
     unsigned char commit_action_running : 1;
     unsigned char rollback_action_running : 1;
     unsigned char scheduled_action_running : 1;
     unsigned char commit_action_running : 1;
     unsigned char rollback_action_running : 1;
+    unsigned char need_reboot : 1;
 } MSIPACKAGE;
 
 typedef struct tagMSIPREVIEW
 } MSIPACKAGE;
 
 typedef struct tagMSIPREVIEW
@@ -683,6 +684,8 @@ extern UINT MSI_DatabaseApplyTransformW( MSIDATABASE *db,
                  LPCWSTR szTransformFile, int iErrorCond );
 extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg );
 
                  LPCWSTR szTransformFile, int iErrorCond );
 extern void append_storage_to_db( MSIDATABASE *db, IStorage *stg );
 
+extern UINT msi_check_patch_applicable( MSIPACKAGE *package, MSISUMMARYINFO *si );
+
 /* action internals */
 extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
 extern void ACTION_free_package_structures( MSIPACKAGE* );
 /* action internals */
 extern UINT MSI_InstallPackage( MSIPACKAGE *, LPCWSTR, LPCWSTR );
 extern void ACTION_free_package_structures( MSIPACKAGE* );
index 546b758..ac442db 100644 (file)
@@ -424,4 +424,4 @@ library WindowsInstaller
         properties:
         methods:
     }
         properties:
         methods:
     }
-}
\ No newline at end of file
+}
index 82de944..f74bf05 100644 (file)
@@ -453,13 +453,14 @@ static VOID set_installer_properties(MSIPACKAGE *package)
     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 szSystemLangID[] = {'S','y','s','t','e','m','L','a','n','g','u','a','g','e','I','D',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 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};
 
     /*
      * Other things that probably should be set:
      *
      * ComputerName LogonUser VirtualMemory
      * ShellAdvSupport DefaultUIFont PackagecodeChanging
 
     /*
      * Other things that probably should be set:
      *
      * ComputerName LogonUser VirtualMemory
      * ShellAdvSupport DefaultUIFont PackagecodeChanging
-     * ProductState CaptionHeight BorderTop BorderSide TextHeight
+     * CaptionHeight BorderTop BorderSide TextHeight
      * RedirectedDllSupport
      */
 
      * RedirectedDllSupport
      */
 
@@ -658,6 +659,9 @@ static VOID set_installer_properties(MSIPACKAGE *package)
     sprintfW(bufstr, szIntFormat, langid);
 
     MSI_SetPropertyW( package, szSystemLangID, bufstr );
     sprintfW(bufstr, szIntFormat, langid);
 
     MSI_SetPropertyW( package, szSystemLangID, bufstr );
+
+    sprintfW(bufstr, szIntFormat, MsiQueryProductStateW(package->ProductCode));
+    MSI_SetPropertyW( package, szProductState, bufstr );
 }
 
 static UINT msi_load_summary_properties( MSIPACKAGE *package )
 }
 
 static UINT msi_load_summary_properties( MSIPACKAGE *package )
@@ -804,12 +808,14 @@ MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
 
         create_temp_property_table( package );
         msi_clone_properties( package );
 
         create_temp_property_table( package );
         msi_clone_properties( package );
-        set_installer_properties(package);
-        sprintfW(uilevel,szpi,gUILevel);
-        MSI_SetPropertyW(package, szLevel, uilevel);
 
         package->ProductCode = msi_dup_property( package, szProductCode );
         set_installed_prop( package );
 
         package->ProductCode = msi_dup_property( package, szProductCode );
         set_installed_prop( package );
+        set_installer_properties( package );
+
+        sprintfW(uilevel,szpi,gUILevel);
+        MSI_SetPropertyW(package, szLevel, uilevel);
+
         r = msi_load_summary_properties( package );
         if (r != ERROR_SUCCESS)
         {
         r = msi_load_summary_properties( package );
         if (r != ERROR_SUCCESS)
         {
index a02f949..ef16665 100644 (file)
@@ -475,7 +475,9 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
 
     if( szDatabase )
     {
 
     if( szDatabase )
     {
-        ret = MSI_OpenDatabaseW( szDatabase, NULL, &db );
+        LPCWSTR persist = uiUpdateCount ? MSIDBOPEN_TRANSACT : MSIDBOPEN_READONLY;
+
+        ret = MSI_OpenDatabaseW( szDatabase, persist, &db );
         if( ret != ERROR_SUCCESS )
             return ret;
     }
         if( ret != ERROR_SUCCESS )
             return ret;
     }
index b963a20..86cd4be 100644 (file)
@@ -2777,7 +2777,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
 
                 r = TABLE_insert_row( &tv->view, rec, -1, FALSE );
                 if (r != ERROR_SUCCESS)
 
                 r = TABLE_insert_row( &tv->view, rec, -1, FALSE );
                 if (r != ERROR_SUCCESS)
-                    ERR("insert row failed\n");
+                    WARN("insert row failed\n");
 
                 if ( number != MSI_NULL_INTEGER && !lstrcmpW(name, szColumns) )
                     msi_update_table_columns( db, table );
 
                 if ( number != MSI_NULL_INTEGER && !lstrcmpW(name, szColumns) )
                     msi_update_table_columns( db, table );
@@ -2788,7 +2788,7 @@ static UINT msi_table_load_transform( MSIDATABASE *db, IStorage *stg,
 
                 r = msi_table_find_row( tv, rec, &row );
                 if (r != ERROR_SUCCESS)
 
                 r = msi_table_find_row( tv, rec, &row );
                 if (r != ERROR_SUCCESS)
-                    ERR("no matching row to transform\n");
+                    WARN("no matching row to transform\n");
                 else if ( mask )
                 {
                     TRACE("modifying row [%d]:\n", row);
                 else if ( mask )
                 {
                     TRACE("modifying row [%d]:\n", row);
index 5e68fdc..2c0a37f 100644 (file)
@@ -237,6 +237,8 @@ typedef struct tagMSIPATCHSEQUENCEINFOW
 
 #define MAX_FEATURE_CHARS 38
 
 
 #define MAX_FEATURE_CHARS 38
 
+#define ERROR_PATCH_TARGET_NOT_FOUND        1642
+
 /* Strings defined in msi.h */
 /* Advertised Information */
 
 /* Strings defined in msi.h */
 /* Advertised Information */