Hans Leidekker : msi: Open database cabinet streams through the streams implementation.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jun 22 07:44:59 CDT 2015


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

Author: Hans Leidekker <hans at codeweavers.com>
Date:   Mon Jun 22 12:12:48 2015 +0200

msi: Open database cabinet streams through the streams implementation.

---

 dlls/msi/action.c      |  7 ++++---
 dlls/msi/media.c       | 35 +++++++++++++++++++++++------------
 dlls/msi/tests/patch.c | 30 +++++++++++++++++++++++++++++-
 3 files changed, 56 insertions(+), 16 deletions(-)

diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index e87dd7f..88bb1bb 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1313,9 +1313,10 @@ static UINT load_media( MSIRECORD *row, LPVOID param )
     const WCHAR *cabinet = MSI_RecordGetString( row, 4 );
 
     /* FIXME: load external cabinets and directory sources too */
-    if (!cabinet || cabinet[0] != '#') return ERROR_SUCCESS;
-    msi_add_cabinet_stream( package, disk_id, package->db->storage, cabinet );
-    return ERROR_SUCCESS;
+    if (!cabinet || cabinet[0] != '#' || disk_id >= MSI_INITIAL_MEDIA_TRANSFORM_DISKID)
+        return ERROR_SUCCESS;
+
+    return msi_add_cabinet_stream( package, disk_id, package->db->storage, cabinet );
 }
 
 static UINT load_all_media( MSIPACKAGE *package )
diff --git a/dlls/msi/media.c b/dlls/msi/media.c
index 7c8c94f..d75f59f 100644
--- a/dlls/msi/media.c
+++ b/dlls/msi/media.c
@@ -220,28 +220,39 @@ static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode )
 {
     MSICABINETSTREAM *cab;
     IStream *stream;
-    WCHAR *encoded;
-    HRESULT hr;
 
-    cab = msi_get_cabinet_stream( package_disk.package, package_disk.id );
-    if (!cab)
+    if (!(cab = msi_get_cabinet_stream( package_disk.package, package_disk.id )))
     {
         WARN("failed to get cabinet stream\n");
         return -1;
     }
-    if (!cab->stream[0] || !(encoded = encode_streamname( FALSE, cab->stream + 1 )))
+    if (cab->storage == package_disk.package->db->storage)
     {
-        WARN("failed to encode stream name\n");
-        return -1;
+        UINT r = msi_get_stream( package_disk.package->db, cab->stream + 1, &stream );
+        if (r != ERROR_SUCCESS)
+        {
+            WARN("failed to get stream %u\n", r);
+            return -1;
+        }
     }
-    hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
-    if (FAILED(hr))
+    else /* patch storage */
     {
-        WARN("failed to open stream 0x%08x\n", hr);
+        HRESULT hr;
+        WCHAR *encoded;
+
+        if (!(encoded = encode_streamname( FALSE, cab->stream + 1 )))
+        {
+            WARN("failed to encode stream name\n");
+            return -1;
+        }
+        hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
         msi_free( encoded );
-        return -1;
+        if (FAILED(hr))
+        {
+            WARN("failed to open stream 0x%08x\n", hr);
+            return -1;
+        }
     }
-    msi_free( encoded );
     return (INT_PTR)stream;
 }
 
diff --git a/dlls/msi/tests/patch.c b/dlls/msi/tests/patch.c
index 62a4b86..3c23656 100644
--- a/dlls/msi/tests/patch.c
+++ b/dlls/msi/tests/patch.c
@@ -969,6 +969,29 @@ static UINT find_entry( MSIHANDLE hdb, const char *table, const char *entry )
     return r;
 }
 
+static UINT find_entryW( MSIHANDLE hdb, const WCHAR *table, const WCHAR *entry )
+{
+    static const WCHAR fmt[] =
+        {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','`','%','s','`',' ',
+         'W','H','E','R','E',' ','`','N','a','m','e','`',' ','=',' ','\'','%','s','\'',0};
+    WCHAR query[0x100];
+    MSIHANDLE hview, hrec;
+    UINT r;
+
+    wsprintfW( query, fmt, table, entry );
+    r = MsiDatabaseOpenViewW( hdb, query, &hview );
+    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
+
+    r = MsiViewExecute( hview, 0 );
+    ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );
+
+    r = MsiViewFetch( hview, &hrec );
+    MsiViewClose( hview );
+    MsiCloseHandle( hview );
+    MsiCloseHandle( hrec );
+    return r;
+}
+
 static INT get_integer( MSIHANDLE hdb, UINT field, const char *query)
 {
     UINT r;
@@ -1032,11 +1055,13 @@ static char *get_string( MSIHANDLE hdb, UINT field, const char *query)
 
 static void test_system_tables( void )
 {
+    static const char patchsource[] = "MSPSRC0F96CDC04CDF4304B2837B9264889EF7";
+    static const WCHAR streamsW[] = {'_','S','t','r','e','a','m','s',0};
+    static const WCHAR CAB_msitest_encodedW[] = {0x3a8c,0x47cb,0x45b0,0x45ec,0x45a8,0x4837,0};
     UINT r;
     char *cr;
     const char *query;
     MSIHANDLE hproduct, hdb, hview, hrec;
-    static const char patchsource[] = "MSPSRC0F96CDC04CDF4304B2837B9264889EF7";
 
     if (!pMsiApplyPatchA)
     {
@@ -1138,6 +1163,9 @@ static void test_system_tables( void )
     r = find_entry( hdb, "_Streams", "\5SummaryInformation" );
     ok( r == ERROR_SUCCESS, "failed to find entry %u\n", r );
 
+    r = find_entryW( hdb, streamsW, CAB_msitest_encodedW );
+    ok( r == ERROR_NO_MORE_ITEMS, "failed to find entry %u\n", r );
+
     query = "SELECT * FROM `_Storages`";
     r = MsiDatabaseOpenViewA( hdb, query, &hview );
     ok( r == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", r );




More information about the wine-cvs mailing list