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