From d8504e0550243ff969ae9c392debb3e67e43c9fb Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Mon, 19 Apr 2010 12:38:51 +0200 Subject: [PATCH] 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 fb614db28ce..3e577926340 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 92eee6ceab5..e889cf45c6b 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 ); }