Mike McCormack : msi: Delete databases we create but never commit.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Sep 13 06:06:58 CDT 2006


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

Author: Mike McCormack <mike at codeweavers.com>
Date:   Wed Sep 13 00:47:10 2006 +0900

msi: Delete databases we create but never commit.

---

 dlls/msi/database.c |   26 ++++++++++++++++++++------
 dlls/msi/msipriv.h  |    1 +
 dlls/msi/msiquery.c |    6 ++++++
 dlls/msi/tests/db.c |   41 ++++++++++++++++++++++++++++++++++-------
 4 files changed, 61 insertions(+), 13 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index b92d3bf..1c0a586 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -64,6 +64,11 @@ static VOID MSI_CloseDatabase( MSIOBJECT
     r = IStorage_Release( db->storage );
     if( r )
         ERR("database reference count was not zero (%ld)\n", r);
+    if (db->deletefile)
+    {
+        DeleteFileW( db->deletefile );
+        msi_free( db->deletefile );
+    }
 }
 
 UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
@@ -74,6 +79,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath,
     UINT ret = ERROR_FUNCTION_FAILED;
     LPCWSTR szMode;
     STATSTG stat;
+    BOOL created = FALSE;
 
     TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
 
@@ -83,12 +89,15 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath,
     szMode = szPersist;
     if( HIWORD( szPersist ) )
     {
-        /* UINT len = lstrlenW( szPerist ) + 1; */
-        FIXME("don't support persist files yet\b");
-        return ERROR_INVALID_PARAMETER;
-        /* szMode = msi_alloc( len * sizeof (DWORD) ); */
+        if (!CopyFileW( szDBPath, szPersist, FALSE ))
+            return ERROR_OPEN_FAILED;
+
+        szDBPath = szPersist;
+        szPersist = MSIDBOPEN_TRANSACT;
+        created = TRUE;
     }
-    else if( szPersist == MSIDBOPEN_READONLY )
+
+    if( szPersist == MSIDBOPEN_READONLY )
     {
         r = StgOpenStorage( szDBPath, NULL,
               STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
@@ -97,13 +106,14 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath,
     {
         /* FIXME: MSIDBOPEN_CREATE should case STGM_TRANSACTED flag to be
          * used here: */
-        r = StgCreateDocfile( szDBPath, 
+        r = StgCreateDocfile( szDBPath,
               STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
         if( r == ERROR_SUCCESS )
         {
             IStorage_SetClass( stg, &CLSID_MsiDatabase );
             r = init_string_table( stg );
         }
+        created = TRUE;
     }
     else if( szPersist == MSIDBOPEN_TRANSACT )
     {
@@ -157,6 +167,10 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath,
 
     db->storage = stg;
     db->mode = szMode;
+    if (created)
+        db->deletefile = strdupW( szDBPath );
+    else
+        db->deletefile = NULL;
     list_init( &db->tables );
     list_init( &db->transforms );
 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 9a9b8b4..9177b1d 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -71,6 +71,7 @@ typedef struct tagMSIDATABASE
     MSIOBJECTHDR hdr;
     IStorage *storage;
     string_table *strings;
+    LPWSTR deletefile;
     LPCWSTR mode;
     struct list tables;
     struct list transforms;
diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c
index 78614fe..157ae18 100644
--- a/dlls/msi/msiquery.c
+++ b/dlls/msi/msiquery.c
@@ -753,6 +753,12 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE
 
     msiobj_release( &db->hdr );
 
+    if (r == ERROR_SUCCESS)
+    {
+        msi_free( db->deletefile );
+        db->deletefile = NULL;
+    }
+
     return r;
 }
 
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index f46190a..86d2389 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -40,6 +40,15 @@ static void test_msidatabase(void)
 
     DeleteFile(msifile);
 
+    res = MsiOpenDatabase( msifile, msifile2, &hdb );
+    ok( res == ERROR_OPEN_FAILED, "expected failure\n");
+
+    res = MsiOpenDatabase( msifile, (LPSTR) 0xff, &hdb );
+    ok( res == ERROR_INVALID_PARAMETER, "expected failure\n");
+
+    res = MsiCloseHandle( hdb );
+    ok( res == ERROR_SUCCESS , "Failed to close database\n" );
+
     /* create an empty database */
     res = MsiOpenDatabase(msifile, MSIDBOPEN_CREATE, &hdb );
     ok( res == ERROR_SUCCESS , "Failed to create database\n" );
@@ -51,18 +60,36 @@ static void test_msidatabase(void)
 
     res = MsiCloseHandle( hdb );
     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
-    todo_wine {
     res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
-    ok( res == ERROR_SUCCESS , "Failed to close database\n" );
+    ok( res == ERROR_SUCCESS , "Failed to open database\n" );
 
     ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile2 ), "database should exist\n");
 
     res = MsiDatabaseCommit( hdb2 );
     ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
-    }
+
     res = MsiCloseHandle( hdb2 );
     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
 
+    res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
+    ok( res == ERROR_SUCCESS , "Failed to open database\n" );
+
+    res = MsiCloseHandle( hdb2 );
+    ok( res == ERROR_SUCCESS , "Failed to close database\n" );
+
+    ok( INVALID_FILE_ATTRIBUTES == GetFileAttributes( msifile2 ), "uncommitted database should not exist\n");
+
+    res = MsiOpenDatabase( msifile, msifile2, &hdb2 );
+    ok( res == ERROR_SUCCESS , "Failed to close database\n" );
+
+    res = MsiDatabaseCommit( hdb2 );
+    ok( res == ERROR_SUCCESS , "Failed to commit database\n" );
+
+    res = MsiCloseHandle( hdb2 );
+    ok( res == ERROR_SUCCESS , "Failed to close database\n" );
+
+    ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile2 ), "committed database should exist\n");
+
     res = MsiOpenDatabase( msifile, MSIDBOPEN_READONLY, &hdb );
     ok( res == ERROR_SUCCESS , "Failed to open database\n" );
 
@@ -80,9 +107,9 @@ static void test_msidatabase(void)
 
     res = MsiCloseHandle( hdb );
     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
-    todo_wine {
-    ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile2 ), "database should exist\n");
+    ok( INVALID_FILE_ATTRIBUTES != GetFileAttributes( msifile ), "database should exist\n");
 
+    todo_wine {
     /* MSIDBOPEN_CREATE deletes the database if MsiCommitDatabase isn't called */
     res = MsiOpenDatabase( msifile, MSIDBOPEN_CREATE, &hdb );
     ok( res == ERROR_SUCCESS , "Failed to open database\n" );
@@ -98,10 +125,10 @@ static void test_msidatabase(void)
 
     res = MsiCloseHandle( hdb );
     ok( res == ERROR_SUCCESS , "Failed to close database\n" );
-
+    }
     res = DeleteFile( msifile2 );
     ok( res == TRUE, "Failed to delete database\n" );
-    }
+
     res = DeleteFile( msifile );
     ok( res == TRUE, "Failed to delete database\n" );
 }




More information about the wine-cvs mailing list