Vincent Povirk : msi: Use integers internally for MSIDBOPEN constants.

Alexandre Julliard julliard at winehq.org
Tue Nov 5 16:11:44 CST 2019


Module: wine
Branch: master
Commit: cce9a5f124ae6d3fffcc7772cab6523f09a1e3d1
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=cce9a5f124ae6d3fffcc7772cab6523f09a1e3d1

Author: Vincent Povirk <vincent at codeweavers.com>
Date:   Mon Nov  4 15:05:42 2019 -0600

msi: Use integers internally for MSIDBOPEN constants.

This fixes a bug where some verions of mingw and probably gcc
assume that the result of pointer subtraction will be non-NULL,
causing MSI_OpenDatabaseW to break when given the mode
MSIDBOPEN_READONLY + MSIDBOPEN_PATCHFILE.

Signed-off-by: Vincent Povirk <vincent at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msi/database.c | 40 ++++++++++++++++++++++------------------
 dlls/msi/msipriv.h  | 10 +++++++++-
 dlls/msi/msiquery.c |  2 +-
 3 files changed, 32 insertions(+), 20 deletions(-)

diff --git a/dlls/msi/database.c b/dlls/msi/database.c
index 776fe53e16..f7c70aeead 100644
--- a/dlls/msi/database.c
+++ b/dlls/msi/database.c
@@ -144,7 +144,8 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
     HRESULT r;
     MSIDATABASE *db = NULL;
     UINT ret = ERROR_FUNCTION_FAILED;
-    LPCWSTR szMode, save_path;
+    LPCWSTR save_path;
+    UINT mode;
     STATSTG stat;
     BOOL created = FALSE, patch = FALSE;
     WCHAR path[MAX_PATH];
@@ -154,31 +155,34 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
     if( !pdb )
         return ERROR_INVALID_PARAMETER;
 
-    if (szPersist - MSIDBOPEN_PATCHFILE <= MSIDBOPEN_CREATEDIRECT)
+    save_path = szDBPath;
+    if ( IS_INTMSIDBOPEN(szPersist) )
     {
-        TRACE("Database is a patch\n");
-        szPersist -= MSIDBOPEN_PATCHFILE;
-        patch = TRUE;
+        mode = LOWORD(szPersist);
     }
-
-    save_path = szDBPath;
-    szMode = szPersist;
-    if( !IS_INTMSIDBOPEN(szPersist) )
+    else
     {
         if (!CopyFileW( szDBPath, szPersist, FALSE ))
             return ERROR_OPEN_FAILED;
 
         szDBPath = szPersist;
-        szPersist = MSIDBOPEN_TRANSACT;
+        mode = MSI_OPEN_TRANSACT;
         created = TRUE;
     }
 
-    if( szPersist == MSIDBOPEN_READONLY )
+    if ((mode & MSI_OPEN_PATCHFILE) == MSI_OPEN_PATCHFILE)
+    {
+        TRACE("Database is a patch\n");
+        mode &= ~MSI_OPEN_PATCHFILE;
+        patch = TRUE;
+    }
+
+    if( mode == MSI_OPEN_READONLY )
     {
         r = StgOpenStorage( szDBPath, NULL,
               STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
     }
-    else if( szPersist == MSIDBOPEN_CREATE )
+    else if( mode == MSI_OPEN_CREATE )
     {
         r = StgCreateDocfile( szDBPath,
               STGM_CREATE|STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg );
@@ -187,7 +191,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
             r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
         created = TRUE;
     }
-    else if( szPersist == MSIDBOPEN_CREATEDIRECT )
+    else if( mode == MSI_OPEN_CREATEDIRECT )
     {
         r = StgCreateDocfile( szDBPath,
               STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg );
@@ -196,19 +200,19 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
             r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
         created = TRUE;
     }
-    else if( szPersist == MSIDBOPEN_TRANSACT )
+    else if( mode == MSI_OPEN_TRANSACT )
     {
         r = StgOpenStorage( szDBPath, NULL,
               STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
     }
-    else if( szPersist == MSIDBOPEN_DIRECT )
+    else if( mode == MSI_OPEN_DIRECT )
     {
         r = StgOpenStorage( szDBPath, NULL,
               STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
     }
     else
     {
-        ERR("unknown flag %p\n",szPersist);
+        ERR("unknown flag %x\n",mode);
         return ERROR_INVALID_PARAMETER;
     }
 
@@ -267,7 +271,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
         enum_stream_names( stg );
 
     db->storage = stg;
-    db->mode = szMode;
+    db->mode = mode;
     if (created)
         db->deletefile = strdupW( szDBPath );
     list_init( &db->tables );
@@ -1977,7 +1981,7 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
     if (!(db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE )))
         return MSIDBSTATE_ERROR;
 
-    if (db->mode != MSIDBOPEN_READONLY )
+    if (db->mode != MSI_OPEN_READONLY )
         ret = MSIDBSTATE_WRITE;
     msiobj_release( &db->hdr );
 
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 0732973341..fca2f9e7b4 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -95,6 +95,14 @@ typedef struct tagMSITRANSFORM
     IStorage *stg;
 } MSITRANSFORM;
 
+/* integer versions of the MSIDBOPEN_* constants */
+#define MSI_OPEN_READONLY 0
+#define MSI_OPEN_TRANSACT 1
+#define MSI_OPEN_DIRECT 2
+#define MSI_OPEN_CREATE 3
+#define MSI_OPEN_CREATEDIRECT 4
+#define MSI_OPEN_PATCHFILE 32
+
 typedef struct tagMSIDATABASE
 {
     MSIOBJECTHDR hdr;
@@ -104,7 +112,7 @@ typedef struct tagMSIDATABASE
     LPWSTR path;
     LPWSTR deletefile;
     LPWSTR tempfolder;
-    LPCWSTR mode;
+    UINT mode;
     UINT media_transform_offset;
     UINT media_transform_disk_id;
     struct list tables;
diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c
index cf8b2b2b4d..526589c320 100644
--- a/dlls/msi/msiquery.c
+++ b/dlls/msi/msiquery.c
@@ -981,7 +981,7 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
         return ERROR_SUCCESS;
     }
 
-    if (db->mode == MSIDBOPEN_READONLY)
+    if (db->mode == MSI_OPEN_READONLY)
     {
         msiobj_release( &db->hdr );
         return ERROR_SUCCESS;




More information about the wine-cvs mailing list