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@codeweavers.com>
Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Vincent Povirk 2019-11-04 15:05:42 -06:00 committed by Alexandre Julliard
parent 3dadd980bf
commit cce9a5f124
3 changed files with 33 additions and 21 deletions

View File

@ -144,7 +144,8 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
HRESULT r; HRESULT r;
MSIDATABASE *db = NULL; MSIDATABASE *db = NULL;
UINT ret = ERROR_FUNCTION_FAILED; UINT ret = ERROR_FUNCTION_FAILED;
LPCWSTR szMode, save_path; LPCWSTR save_path;
UINT mode;
STATSTG stat; STATSTG stat;
BOOL created = FALSE, patch = FALSE; BOOL created = FALSE, patch = FALSE;
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
@ -154,31 +155,34 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
if( !pdb ) if( !pdb )
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
if (szPersist - MSIDBOPEN_PATCHFILE <= MSIDBOPEN_CREATEDIRECT)
{
TRACE("Database is a patch\n");
szPersist -= MSIDBOPEN_PATCHFILE;
patch = TRUE;
}
save_path = szDBPath; save_path = szDBPath;
szMode = szPersist; if ( IS_INTMSIDBOPEN(szPersist) )
if( !IS_INTMSIDBOPEN(szPersist) ) {
mode = LOWORD(szPersist);
}
else
{ {
if (!CopyFileW( szDBPath, szPersist, FALSE )) if (!CopyFileW( szDBPath, szPersist, FALSE ))
return ERROR_OPEN_FAILED; return ERROR_OPEN_FAILED;
szDBPath = szPersist; szDBPath = szPersist;
szPersist = MSIDBOPEN_TRANSACT; mode = MSI_OPEN_TRANSACT;
created = TRUE; 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, r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 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, r = StgCreateDocfile( szDBPath,
STGM_CREATE|STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg ); 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 ); r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
created = TRUE; created = TRUE;
} }
else if( szPersist == MSIDBOPEN_CREATEDIRECT ) else if( mode == MSI_OPEN_CREATEDIRECT )
{ {
r = StgCreateDocfile( szDBPath, r = StgCreateDocfile( szDBPath,
STGM_CREATE|STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg ); 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 ); r = db_initialize( stg, patch ? &CLSID_MsiPatch : &CLSID_MsiDatabase );
created = TRUE; created = TRUE;
} }
else if( szPersist == MSIDBOPEN_TRANSACT ) else if( mode == MSI_OPEN_TRANSACT )
{ {
r = StgOpenStorage( szDBPath, NULL, r = StgOpenStorage( szDBPath, NULL,
STGM_TRANSACTED|STGM_READWRITE|STGM_SHARE_DENY_WRITE, NULL, 0, &stg); 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, r = StgOpenStorage( szDBPath, NULL,
STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg); STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
} }
else else
{ {
ERR("unknown flag %p\n",szPersist); ERR("unknown flag %x\n",mode);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
@ -267,7 +271,7 @@ UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
enum_stream_names( stg ); enum_stream_names( stg );
db->storage = stg; db->storage = stg;
db->mode = szMode; db->mode = mode;
if (created) if (created)
db->deletefile = strdupW( szDBPath ); db->deletefile = strdupW( szDBPath );
list_init( &db->tables ); list_init( &db->tables );
@ -1977,7 +1981,7 @@ MSIDBSTATE WINAPI MsiGetDatabaseState( MSIHANDLE handle )
if (!(db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE ))) if (!(db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE )))
return MSIDBSTATE_ERROR; return MSIDBSTATE_ERROR;
if (db->mode != MSIDBOPEN_READONLY ) if (db->mode != MSI_OPEN_READONLY )
ret = MSIDBSTATE_WRITE; ret = MSIDBSTATE_WRITE;
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );

View File

@ -95,6 +95,14 @@ typedef struct tagMSITRANSFORM
IStorage *stg; IStorage *stg;
} MSITRANSFORM; } 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 typedef struct tagMSIDATABASE
{ {
MSIOBJECTHDR hdr; MSIOBJECTHDR hdr;
@ -104,7 +112,7 @@ typedef struct tagMSIDATABASE
LPWSTR path; LPWSTR path;
LPWSTR deletefile; LPWSTR deletefile;
LPWSTR tempfolder; LPWSTR tempfolder;
LPCWSTR mode; UINT mode;
UINT media_transform_offset; UINT media_transform_offset;
UINT media_transform_disk_id; UINT media_transform_disk_id;
struct list tables; struct list tables;

View File

@ -981,7 +981,7 @@ UINT WINAPI MsiDatabaseCommit( MSIHANDLE hdb )
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
if (db->mode == MSIDBOPEN_READONLY) if (db->mode == MSI_OPEN_READONLY)
{ {
msiobj_release( &db->hdr ); msiobj_release( &db->hdr );
return ERROR_SUCCESS; return ERROR_SUCCESS;