From 74a6a1e71b06f0fbf6e6c61e00233ebb2ab29d82 Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Wed, 13 Sep 2006 00:47:10 +0900 Subject: [PATCH] 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 b92d3bf27a6..1c0a586f461 100644 --- a/dlls/msi/database.c +++ b/dlls/msi/database.c @@ -64,6 +64,11 @@ static VOID MSI_CloseDatabase( MSIOBJECTHDR *arg ) 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, LPCWSTR szPersist, MSIDATABASE **pdb) 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, LPCWSTR szPersist, MSIDATABASE **pdb) 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, LPCWSTR szPersist, MSIDATABASE **pdb) { /* 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, LPCWSTR szPersist, MSIDATABASE **pdb) 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 9a9b8b4bac3..9177b1d7237 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 78614fe5b2b..157ae183bbe 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -753,6 +753,12 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb ) 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 f46190ad3e1..86d23898324 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" ); }