Hans Leidekker : msi: Handle MSIDBOPEN_PATCHFILE properly in MsiOpenDatabase.

Alexandre Julliard julliard at winehq.org
Mon Apr 19 11:51:16 CDT 2010


Module: wine
Branch: master
Commit: d8504e0550243ff969ae9c392debb3e67e43c9fb
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d8504e0550243ff969ae9c392debb3e67e43c9fb

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Apr 19 12:38:51 2010 +0200

msi: Handle MSIDBOPEN_PATCHFILE properly in MsiOpenDatabase.

---

 dlls/msi/database.c    |   13 +++++++++++--
 dlls/msi/tests/patch.c |   43 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index fb614db..3e57792 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -262,7 +262,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
     UINT ret = ERROR_FUNCTION_FAILED;
     LPCWSTR szMode, save_path;
     STATSTG stat;
-    BOOL created = FALSE;
+    BOOL created = FALSE, patch = FALSE;
     WCHAR path[MAX_PATH];
 
     static const WCHAR szTables[]  = { '_','T','a','b','l','e','s',0 };
@@ -277,6 +277,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
     {
         TRACE("Database is a patch\n");
         szPersist -= MSIDBOPEN_PATCHFILE;
+        patch = TRUE;
     }
 
     save_path = szDBPath;
@@ -304,7 +305,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
               STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
         if( r == ERROR_SUCCESS )
         {
-            IStorage_SetClass( stg, &CLSID_MsiDatabase );
+            IStorage_SetClass( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
             /* create the _Tables stream */
             r = write_stream_data(stg, szTables, NULL, 0, TRUE);
             if (SUCCEEDED(r))
@@ -352,6 +353,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
         goto end;
     }
 
+    if ( patch && !IsEqualGUID( &stat.clsid, &CLSID_MsiPatch ) )
+    {
+        ERR("storage GUID is not the MSI patch GUID %s\n",
+             debugstr_guid(&stat.clsid) );
+        ret = ERROR_OPEN_FAILED;
+        goto end;
+    }
+
     db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
                               MSI_CloseDatabase );
     if( !db )
diff --git a/dlls/msi/tests/patch.c b/dlls/msi/tests/patch.c
index 92eee6c..e889cf4 100644
--- a/dlls/msi/tests/patch.c
+++ b/dlls/msi/tests/patch.c
@@ -723,6 +723,48 @@ static void test_simple_patch( void )
     RemoveDirectoryA( "msitest" );
 }
 
+static void test_MsiOpenDatabase( void )
+{
+    UINT r;
+    MSIHANDLE hdb;
+
+    r = MsiOpenDatabase( mspfile, MSIDBOPEN_CREATE, &hdb );
+    ok(r == ERROR_SUCCESS, "failed to open database %u\n", r);
+
+    r = MsiDatabaseCommit( hdb );
+    ok(r == ERROR_SUCCESS, "failed to commit database %u\n", r);
+    MsiCloseHandle( hdb );
+
+    r = MsiOpenDatabase( mspfile, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &hdb );
+    ok(r == ERROR_OPEN_FAILED, "expected ERROR_OPEN_FAILED, got %u\n", r);
+    DeleteFileA( mspfile );
+
+    r = MsiOpenDatabase( mspfile, MSIDBOPEN_CREATE + MSIDBOPEN_PATCHFILE, &hdb );
+    ok(r == ERROR_SUCCESS , "failed to open database %u\n", r);
+
+    r = MsiDatabaseCommit( hdb );
+    ok(r == ERROR_SUCCESS, "failed to commit database %u\n", r);
+    MsiCloseHandle( hdb );
+
+    r = MsiOpenDatabase( mspfile, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &hdb );
+    ok(r == ERROR_SUCCESS, "failed to open database %u\n", r);
+    MsiCloseHandle( hdb );
+    DeleteFileA( mspfile );
+
+    create_database( msifile, tables, sizeof(tables) / sizeof(struct msi_table) );
+    create_patch( mspfile );
+
+    r = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &hdb );
+    ok(r == ERROR_OPEN_FAILED, "failed to open database %u\n", r );
+
+    r = MsiOpenDatabase( mspfile, MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE, &hdb );
+    ok(r == ERROR_SUCCESS, "failed to open database %u\n", r );
+    MsiCloseHandle( hdb );
+
+    DeleteFileA( msifile );
+    DeleteFileA( mspfile );
+}
+
 START_TEST(patch)
 {
     DWORD len;
@@ -743,6 +785,7 @@ START_TEST(patch)
     get_program_files_dir( PROG_FILES_DIR, COMMON_FILES_DIR );
 
     test_simple_patch();
+    test_MsiOpenDatabase();
 
     SetCurrentDirectoryA( prev_path );
 }




More information about the wine-cvs mailing list