Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
db3fdbe1
Commit
db3fdbe1
authored
Mar 16, 2015
by
Hans Leidekker
Committed by
Alexandre Julliard
Mar 17, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
msi: Fix the case where the summary information stream is already open in…
msi: Fix the case where the summary information stream is already open in MsiGetSummaryInformationW.
parent
7a4d8f57
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
112 additions
and
58 deletions
+112
-58
msi.c
dlls/msi/msi.c
+3
-3
msipriv.h
dlls/msi/msipriv.h
+1
-1
package.c
dlls/msi/package.c
+8
-6
patch.c
dlls/msi/patch.c
+12
-10
suminfo.c
dlls/msi/suminfo.c
+88
-38
No files found.
dlls/msi/msi.c
View file @
db3fdbe1
...
...
@@ -557,7 +557,7 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
{
MSISUMMARYINFO
*
si
;
MSIDATABASE
*
patch_db
;
UINT
r
=
ERROR_SUCCESS
;
UINT
r
;
r
=
MSI_OpenDatabaseW
(
patch
,
MSIDBOPEN_READONLY
,
&
patch_db
);
if
(
r
!=
ERROR_SUCCESS
)
...
...
@@ -566,8 +566,8 @@ static UINT MSI_ApplicablePatchW( MSIPACKAGE *package, LPCWSTR patch )
return
r
;
}
si
=
MSI_GetSummaryInformationW
(
patch_db
->
storage
,
0
);
if
(
!
si
)
r
=
msi_get_suminfo
(
patch_db
->
storage
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
patch_db
->
hdr
);
return
ERROR_FUNCTION_FAILED
;
...
...
dlls/msi/msipriv.h
View file @
db3fdbe1
...
...
@@ -951,7 +951,7 @@ extern void msi_dialog_unregister_class( void ) DECLSPEC_HIDDEN;
extern
UINT
msi_spawn_error_dialog
(
MSIPACKAGE
*
,
LPWSTR
,
LPWSTR
)
DECLSPEC_HIDDEN
;
/* summary information */
extern
MSISUMMARYINFO
*
MSI_GetSummaryInformationW
(
IStorage
*
stg
,
UINT
uiUpdateCount
)
DECLSPEC_HIDDEN
;
extern
UINT
msi_get_suminfo
(
IStorage
*
stg
,
UINT
uiUpdateCount
,
MSISUMMARYINFO
**
si
)
DECLSPEC_HIDDEN
;
extern
LPWSTR
msi_suminfo_dup_string
(
MSISUMMARYINFO
*
si
,
UINT
uiProperty
)
DECLSPEC_HIDDEN
;
extern
INT
msi_suminfo_get_int32
(
MSISUMMARYINFO
*
si
,
UINT
uiProperty
)
DECLSPEC_HIDDEN
;
extern
LPWSTR
msi_get_suminfo_product
(
IStorage
*
stg
)
DECLSPEC_HIDDEN
;
...
...
dlls/msi/package.c
View file @
db3fdbe1
...
...
@@ -1280,7 +1280,7 @@ enum platform parse_platform( const WCHAR *str )
return
PLATFORM_UNKNOWN
;
}
static
UINT
msi_parse_summary
(
MSISUMMARYINFO
*
si
,
MSIPACKAGE
*
package
)
static
UINT
parse_suminfo
(
MSISUMMARYINFO
*
si
,
MSIPACKAGE
*
package
)
{
WCHAR
*
template
,
*
p
,
*
q
,
*
platform
;
DWORD
i
,
count
;
...
...
@@ -1483,10 +1483,12 @@ static WCHAR *get_package_code( MSIDATABASE *db )
{
WCHAR
*
ret
;
MSISUMMARYINFO
*
si
;
UINT
r
;
if
(
!
(
si
=
MSI_GetSummaryInformationW
(
db
->
storage
,
0
)))
r
=
msi_get_suminfo
(
db
->
storage
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
WARN
(
"failed to load summary info
\n
"
);
WARN
(
"failed to load summary info
%u
\n
"
,
r
);
return
NULL
;
}
ret
=
msi_suminfo_dup_string
(
si
,
PID_REVNUMBER
);
...
...
@@ -1633,14 +1635,14 @@ UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
package
->
localfile
=
strdupW
(
localfile
);
package
->
delete_on_close
=
delete_on_close
;
si
=
MSI_GetSummaryInformationW
(
db
->
storage
,
0
);
if
(
!
si
)
r
=
msi_get_suminfo
(
db
->
storage
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
WARN
(
"failed to load summary info
\n
"
);
msiobj_release
(
&
package
->
hdr
);
return
ERROR_INSTALL_PACKAGE_INVALID
;
}
r
=
msi_parse_summary
(
si
,
package
);
r
=
parse_suminfo
(
si
,
package
);
msiobj_release
(
&
si
->
hdr
);
if
(
r
!=
ERROR_SUCCESS
)
{
...
...
dlls/msi/patch.c
View file @
db3fdbe1
...
...
@@ -124,15 +124,16 @@ static UINT check_transform_applicable( MSIPACKAGE *package, IStorage *transform
MSITRANSFORM_VALIDATE_PRODUCT
|
MSITRANSFORM_VALIDATE_LANGUAGE
|
MSITRANSFORM_VALIDATE_PLATFORM
|
MSITRANSFORM_VALIDATE_MAJORVERSION
|
MSITRANSFORM_VALIDATE_MINORVERSION
|
MSITRANSFORM_VALIDATE_UPGRADECODE
;
MSISUMMARYINFO
*
si
=
MSI_GetSummaryInformationW
(
transform
,
0
)
;
UINT
valid_flags
=
0
,
wanted_flags
=
0
;
MSISUMMARYINFO
*
si
;
UINT
r
,
valid_flags
=
0
,
wanted_flags
=
0
;
WCHAR
*
template
,
*
product
,
*
p
;
struct
transform_desc
*
desc
;
if
(
!
si
)
r
=
msi_get_suminfo
(
transform
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
WARN
(
"no summary information!
\n
"
);
return
ERROR_FUNCTION_FAILED
;
return
r
;
}
wanted_flags
=
msi_suminfo_get_int32
(
si
,
PID_CHARCOUNT
);
wanted_flags
&=
0xffff
;
/* mask off error condition flags */
...
...
@@ -886,7 +887,7 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file )
WCHAR
localfile
[
MAX_PATH
];
MSISUMMARYINFO
*
si
;
MSIPATCHINFO
*
patch
=
NULL
;
UINT
r
=
ERROR_SUCCESS
;
UINT
r
;
TRACE
(
"%p, %s
\n
"
,
package
,
debugstr_w
(
file
));
...
...
@@ -896,10 +897,11 @@ static UINT msi_apply_patch_package( MSIPACKAGE *package, const WCHAR *file )
ERR
(
"failed to open patch collection %s
\n
"
,
debugstr_w
(
file
)
);
return
r
;
}
if
(
!
(
si
=
MSI_GetSummaryInformationW
(
patch_db
->
storage
,
0
)))
r
=
msi_get_suminfo
(
patch_db
->
storage
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
patch_db
->
hdr
);
return
ERROR_FUNCTION_FAILED
;
return
r
;
}
r
=
msi_check_patch_applicable
(
package
,
si
);
if
(
r
!=
ERROR_SUCCESS
)
...
...
@@ -1019,11 +1021,11 @@ UINT msi_apply_registered_patch( MSIPACKAGE *package, LPCWSTR patch_code )
ERR
(
"failed to open patch database %s
\n
"
,
debugstr_w
(
patch_file
));
return
r
;
}
si
=
MSI_GetSummaryInformationW
(
patch_db
->
storage
,
0
);
if
(
!
si
)
r
=
msi_get_suminfo
(
patch_db
->
storage
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
patch_db
->
hdr
);
return
ERROR_FUNCTION_FAILED
;
return
r
;
}
r
=
msi_parse_patch_summary
(
si
,
&
patch_info
);
msiobj_release
(
&
si
->
hdr
);
...
...
dlls/msi/suminfo.c
View file @
db3fdbe1
...
...
@@ -235,7 +235,6 @@ static void read_properties_from_data( PROPVARIANT *prop, LPBYTE data, DWORD sz
static
UINT
load_summary_info
(
MSISUMMARYINFO
*
si
,
IStream
*
stm
)
{
UINT
ret
=
ERROR_FUNCTION_FAILED
;
PROPERTYSETHEADER
set_hdr
;
FORMATIDOFFSET
format_hdr
;
PROPERTYSECTIONHEADER
section_hdr
;
...
...
@@ -250,44 +249,44 @@ static UINT load_summary_info( MSISUMMARYINFO *si, IStream *stm )
sz
=
sizeof
set_hdr
;
r
=
IStream_Read
(
stm
,
&
set_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
if
(
set_hdr
.
wByteOrder
!=
0xfffe
)
{
ERR
(
"property set not big-endian %04X
\n
"
,
set_hdr
.
wByteOrder
);
return
ret
;
return
ERROR_FUNCTION_FAILED
;
}
sz
=
sizeof
format_hdr
;
r
=
IStream_Read
(
stm
,
&
format_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
/* check the format id is correct */
if
(
!
IsEqualGUID
(
&
FMTID_SummaryInformation
,
&
format_hdr
.
fmtid
)
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
/* seek to the location of the section */
ofs
.
QuadPart
=
format_hdr
.
dwOffset
;
r
=
IStream_Seek
(
stm
,
ofs
,
STREAM_SEEK_SET
,
NULL
);
if
(
FAILED
(
r
)
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
/* read the section itself */
sz
=
SECT_HDR_SIZE
;
r
=
IStream_Read
(
stm
,
&
section_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
if
(
section_hdr
.
cProperties
>
MSI_MAX_PROPS
)
{
ERR
(
"too many properties %d
\n
"
,
section_hdr
.
cProperties
);
return
ret
;
return
ERROR_FUNCTION_FAILED
;
}
data
=
msi_alloc
(
section_hdr
.
cbSection
);
if
(
!
data
)
return
ret
;
return
ERROR_FUNCTION_FAILED
;
memcpy
(
data
,
&
section_hdr
,
SECT_HDR_SIZE
);
...
...
@@ -300,7 +299,7 @@ static UINT load_summary_info( MSISUMMARYINFO *si, IStream *stm )
ERR
(
"failed to read properties %d %d
\n
"
,
count
,
sz
);
msi_free
(
data
);
return
ret
;
return
ERROR_SUCCESS
;
}
static
DWORD
write_dword
(
LPBYTE
data
,
DWORD
ofs
,
DWORD
val
)
...
...
@@ -426,34 +425,75 @@ static UINT save_summary_info( const MSISUMMARYINFO * si, IStream *stm )
return
ERROR_SUCCESS
;
}
MSISUMMARYINFO
*
MSI_GetSummaryInformationW
(
IStorage
*
stg
,
UINT
uiUpdateC
ount
)
static
MSISUMMARYINFO
*
create_suminfo
(
IStorage
*
stg
,
UINT
update_c
ount
)
{
IStream
*
stm
=
NULL
;
MSISUMMARYINFO
*
si
;
DWORD
grfMode
;
HRESULT
r
;
TRACE
(
"%p %d
\n
"
,
stg
,
uiUpdateCount
);
si
=
alloc_msiobject
(
MSIHANDLETYPE_SUMMARYINFO
,
sizeof
(
MSISUMMARYINFO
),
MSI_CloseSummaryInfo
);
if
(
!
si
)
return
si
;
if
(
!
(
si
=
alloc_msiobject
(
MSIHANDLETYPE_SUMMARYINFO
,
sizeof
(
MSISUMMARYINFO
),
MSI_CloseSummaryInfo
)))
return
NULL
;
si
->
update_count
=
u
iUpdateC
ount
;
si
->
update_count
=
u
pdate_c
ount
;
IStorage_AddRef
(
stg
);
si
->
storage
=
stg
;
/* read the stream... if we fail, we'll start with an empty property set */
grfMode
=
STGM_READ
|
STGM_SHARE_EXCLUSIVE
;
r
=
IStorage_OpenStream
(
si
->
storage
,
szSumInfo
,
0
,
grfMode
,
0
,
&
stm
);
if
(
SUCCEEDED
(
r
)
)
return
si
;
}
UINT
msi_get_suminfo
(
IStorage
*
stg
,
UINT
uiUpdateCount
,
MSISUMMARYINFO
**
ret
)
{
IStream
*
stm
;
MSISUMMARYINFO
*
si
;
HRESULT
hr
;
UINT
r
;
TRACE
(
"%p, %u
\n
"
,
stg
,
uiUpdateCount
);
if
(
!
(
si
=
create_suminfo
(
stg
,
uiUpdateCount
)))
return
ERROR_OUTOFMEMORY
;
hr
=
IStorage_OpenStream
(
si
->
storage
,
szSumInfo
,
0
,
STGM_READ
|
STGM_SHARE_EXCLUSIVE
,
0
,
&
stm
);
if
(
FAILED
(
hr
))
{
load_summary_info
(
si
,
stm
);
IStream_Release
(
stm
)
;
msiobj_release
(
&
si
->
hdr
);
return
ERROR_FUNCTION_FAILED
;
}
return
si
;
r
=
load_summary_info
(
si
,
stm
);
IStream_Release
(
stm
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
si
->
hdr
);
return
r
;
}
*
ret
=
si
;
return
ERROR_SUCCESS
;
}
static
UINT
get_db_suminfo
(
MSIDATABASE
*
db
,
UINT
uiUpdateCount
,
MSISUMMARYINFO
**
ret
)
{
IStream
*
stm
;
MSISUMMARYINFO
*
si
;
UINT
r
;
if
(
!
(
si
=
create_suminfo
(
db
->
storage
,
uiUpdateCount
)))
return
ERROR_OUTOFMEMORY
;
r
=
msi_get_stream
(
db
,
szSumInfo
,
&
stm
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
si
->
hdr
);
return
r
;
}
r
=
load_summary_info
(
si
,
stm
);
IStream_Release
(
stm
);
if
(
r
!=
ERROR_SUCCESS
)
{
msiobj_release
(
&
si
->
hdr
);
return
r
;
}
*
ret
=
si
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiGetSummaryInformationW
(
MSIHANDLE
hDatabase
,
...
...
@@ -461,7 +501,7 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
{
MSISUMMARYINFO
*
si
;
MSIDATABASE
*
db
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
UINT
ret
;
TRACE
(
"%d %s %d %p
\n
"
,
hDatabase
,
debugstr_w
(
szDatabase
),
uiUpdateCount
,
pHandle
);
...
...
@@ -505,8 +545,16 @@ UINT WINAPI MsiGetSummaryInformationW( MSIHANDLE hDatabase,
}
}
si
=
MSI_GetSummaryInformationW
(
db
->
storage
,
uiUpdateCount
);
if
(
si
)
ret
=
msi_get_suminfo
(
db
->
storage
,
uiUpdateCount
,
&
si
);
if
(
ret
!=
ERROR_SUCCESS
)
ret
=
get_db_suminfo
(
db
,
uiUpdateCount
,
&
si
);
if
(
ret
!=
ERROR_SUCCESS
)
{
if
((
si
=
create_suminfo
(
db
->
storage
,
uiUpdateCount
)))
ret
=
ERROR_SUCCESS
;
}
if
(
ret
==
ERROR_SUCCESS
)
{
*
pHandle
=
alloc_msihandle
(
&
si
->
hdr
);
if
(
*
pHandle
)
...
...
@@ -658,9 +706,10 @@ LPWSTR msi_get_suminfo_product( IStorage *stg )
{
MSISUMMARYINFO
*
si
;
LPWSTR
prod
;
UINT
r
;
si
=
MSI_GetSummaryInformationW
(
stg
,
0
);
if
(
!
si
)
r
=
msi_get_suminfo
(
stg
,
0
,
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"no summary information!
\n
"
);
return
NULL
;
...
...
@@ -921,15 +970,16 @@ static UINT parse_prop( LPCWSTR prop, LPCWSTR value, UINT *pid, INT *int_value,
UINT
msi_add_suminfo
(
MSIDATABASE
*
db
,
LPWSTR
**
records
,
int
num_records
,
int
num_columns
)
{
UINT
r
=
ERROR_FUNCTION_FAILED
;
UINT
r
;
int
i
,
j
;
MSISUMMARYINFO
*
si
;
si
=
MSI_GetSummaryInformationW
(
db
->
storage
,
num_records
*
(
num_columns
/
2
)
);
if
(
!
si
)
r
=
msi_get_suminfo
(
db
->
storage
,
num_records
*
(
num_columns
/
2
),
&
si
);
if
(
r
!=
ERROR_SUCCESS
)
{
ERR
(
"no summary information!
\n
"
);
return
ERROR_FUNCTION_FAILED
;
if
(
!
(
si
=
create_suminfo
(
db
->
storage
,
num_records
*
(
num_columns
/
2
)
)))
return
ERROR_OUTOFMEMORY
;
r
=
ERROR_SUCCESS
;
}
for
(
i
=
0
;
i
<
num_records
;
i
++
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment