Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
758a6951
Commit
758a6951
authored
Mar 18, 2005
by
Mike McCormack
Committed by
Alexandre Julliard
Mar 18, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement summary information loading and saving.
parent
6064680f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
587 additions
and
163 deletions
+587
-163
msipriv.h
dlls/msi/msipriv.h
+0
-6
suminfo.c
dlls/msi/suminfo.c
+572
-143
msi.h
include/msi.h
+0
-14
msiquery.h
include/msiquery.h
+15
-0
No files found.
dlls/msi/msipriv.h
View file @
758a6951
...
...
@@ -171,12 +171,6 @@ typedef struct tagMSIVIEWOPS
}
MSIVIEWOPS
;
typedef
struct
tagMSISUMMARYINFO
{
MSIOBJECTHDR
hdr
;
IPropertyStorage
*
propstg
;
}
MSISUMMARYINFO
;
struct
tagMSIVIEW
{
MSIOBJECTHDR
hdr
;
...
...
dlls/msi/suminfo.c
View file @
758a6951
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2002 Mike McCormack for CodeWeavers
* Copyright 2002
, 2005
Mike McCormack for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -31,61 +31,395 @@
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msidefs.h"
#include "msipriv.h"
#include "objidl.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
msi
);
#define MSI_MAX_PROPS 19
#include "pshpack1.h"
typedef
struct
{
WORD
wByteOrder
;
WORD
wFormat
;
DWORD
dwOSVer
;
CLSID
clsID
;
DWORD
reserved
;
}
PROPERTYSETHEADER
;
typedef
struct
{
FMTID
fmtid
;
DWORD
dwOffset
;
}
FORMATIDOFFSET
;
typedef
struct
{
DWORD
cbSection
;
DWORD
cProperties
;
}
PROPERTYSECTIONHEADER
;
typedef
struct
{
DWORD
propid
;
DWORD
dwOffset
;
}
PROPERTYIDOFFSET
;
typedef
struct
{
DWORD
type
;
union
{
INT
i4
;
SHORT
i2
;
FILETIME
ft
;
struct
{
DWORD
len
;
BYTE
str
[
1
];
}
str
;
}
u
;
}
PROPERTY_DATA
;
#include "poppack.h"
typedef
struct
{
BOOL
unicode
;
union
{
LPSTR
a
;
LPWSTR
w
;
}
str
;
}
awstring
;
typedef
struct
tagMSISUMMARYINFO
{
MSIOBJECTHDR
hdr
;
MSIDATABASE
*
db
;
DWORD
update_count
;
PROPVARIANT
property
[
MSI_MAX_PROPS
];
}
MSISUMMARYINFO
;
static
const
WCHAR
szSumInfo
[]
=
{
5
,
'S'
,
'u'
,
'm'
,
'm'
,
'a'
,
'r'
,
'y'
,
'I'
,
'n'
,
'f'
,
'o'
,
'r'
,
'm'
,
'a'
,
't'
,
'i'
,
'o'
,
'n'
,
0
};
static
void
MSI_CloseSummaryInfo
(
MSIOBJECTHDR
*
arg
)
{
MSISUMMARYINFO
*
s
uminfo
=
(
MSISUMMARYINFO
*
)
arg
;
IPropertyStorage_Release
(
suminfo
->
propstg
);
MSISUMMARYINFO
*
s
i
=
(
MSISUMMARYINFO
*
)
arg
;
msiobj_release
(
&
si
->
db
->
hdr
);
}
UINT
WINAPI
MsiGetSummaryInformationA
(
MSIHANDLE
hDatabase
,
LPCSTR
szDatabase
,
UINT
uiUpdateCount
,
MSIHANDLE
*
phSummaryInfo
)
static
UINT
get_type
(
UINT
uiProperty
)
{
LPWSTR
szwDatabase
=
NULL
;
UINT
ret
;
switch
(
uiProperty
)
{
case
PID_CODEPAGE
:
return
VT_I2
;
case
PID_SUBJECT
:
case
PID_AUTHOR
:
case
PID_KEYWORDS
:
case
PID_COMMENTS
:
case
PID_TEMPLATE
:
case
PID_LASTAUTHOR
:
case
PID_REVNUMBER
:
case
PID_APPNAME
:
case
PID_TITLE
:
return
VT_LPSTR
;
case
PID_LASTPRINTED
:
case
PID_CREATE_DTM
:
case
PID_LASTSAVE_DTM
:
return
VT_FILETIME
;
case
PID_WORDCOUNT
:
case
PID_CHARCOUNT
:
case
PID_SECURITY
:
case
PID_PAGECOUNT
:
return
VT_I4
;
}
return
VT_EMPTY
;
}
TRACE
(
"%ld %s %d %p
\n
"
,
hDatabase
,
debugstr_a
(
szDatabase
),
uiUpdateCount
,
phSummaryInfo
);
static
UINT
get_property_count
(
PROPVARIANT
*
property
)
{
UINT
i
,
n
=
0
;
if
(
!
property
)
return
n
;
for
(
i
=
0
;
i
<
MSI_MAX_PROPS
;
i
++
)
if
(
property
[
i
].
vt
!=
VT_EMPTY
)
n
++
;
return
n
;
}
if
(
szDatabase
)
/* FIXME: doesn't deal with endian conversion */
static
void
read_properties_from_data
(
PROPVARIANT
*
prop
,
PROPERTYIDOFFSET
*
idofs
,
DWORD
count
,
LPBYTE
data
,
DWORD
sz
)
{
UINT
type
;
DWORD
i
;
int
size
;
PROPERTY_DATA
*
propdata
;
PROPVARIANT
*
property
;
/* now set all the properties */
for
(
i
=
0
;
i
<
count
;
i
++
)
{
UINT
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
szDatabase
,
-
1
,
NULL
,
0
);
szwDatabase
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
)
);
if
(
!
szwDatabase
)
return
ERROR_FUNCTION_FAILED
;
MultiByteToWideChar
(
CP_ACP
,
0
,
szDatabase
,
-
1
,
szwDatabase
,
len
);
type
=
get_type
(
idofs
[
i
].
propid
);
if
(
type
==
VT_EMPTY
)
{
ERR
(
"propid %ld has unknown type
\n
"
,
idofs
[
i
].
propid
);
break
;
}
propdata
=
(
PROPERTY_DATA
*
)
&
data
[
idofs
[
i
].
dwOffset
];
/* check the type is the same as we expect */
if
(
type
!=
propdata
->
type
)
{
ERR
(
"wrong type
\n
"
);
break
;
}
/* check we don't run off the end of the data */
size
=
sz
-
idofs
[
i
].
dwOffset
-
sizeof
(
DWORD
);
if
(
sizeof
(
DWORD
)
>
size
||
(
type
==
VT_FILETIME
&&
sizeof
(
FILETIME
)
>
size
)
||
(
type
==
VT_LPSTR
&&
(
propdata
->
u
.
str
.
len
+
sizeof
(
DWORD
))
>
size
)
)
{
ERR
(
"not enough data
\n
"
);
break
;
}
property
=
&
prop
[
idofs
[
i
].
propid
];
property
->
vt
=
type
;
if
(
type
==
VT_LPSTR
)
{
LPSTR
str
=
HeapAlloc
(
GetProcessHeap
(),
0
,
propdata
->
u
.
str
.
len
);
memcpy
(
str
,
propdata
->
u
.
str
.
str
,
propdata
->
u
.
str
.
len
);
str
[
propdata
->
u
.
str
.
len
-
1
]
=
0
;
property
->
u
.
pszVal
=
str
;
}
else
if
(
type
==
VT_FILETIME
)
property
->
u
.
filetime
=
propdata
->
u
.
ft
;
else
if
(
type
==
VT_I2
)
property
->
u
.
iVal
=
propdata
->
u
.
i2
;
else
if
(
type
==
VT_I4
)
property
->
u
.
lVal
=
propdata
->
u
.
i4
;
}
}
ret
=
MsiGetSummaryInformationW
(
hDatabase
,
szwDatabase
,
uiUpdateCount
,
phSummaryInfo
);
static
UINT
load_summary_info
(
MSISUMMARYINFO
*
si
,
IStream
*
stm
)
{
UINT
ret
=
ERROR_FUNCTION_FAILED
;
PROPERTYSETHEADER
set_hdr
;
FORMATIDOFFSET
format_hdr
;
PROPERTYSECTIONHEADER
section_hdr
;
PROPERTYIDOFFSET
idofs
[
MSI_MAX_PROPS
];
LPBYTE
data
=
NULL
;
LARGE_INTEGER
ofs
;
ULONG
count
,
sz
;
HRESULT
r
;
HeapFree
(
GetProcessHeap
(),
0
,
szwDatabase
);
TRACE
(
"%p %p
\n
"
,
si
,
stm
);
/* read the header */
sz
=
sizeof
set_hdr
;
r
=
IStream_Read
(
stm
,
&
set_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
if
(
set_hdr
.
wByteOrder
!=
0xfffe
)
{
ERR
(
"property set not big-endian %04X
\n
"
,
set_hdr
.
wByteOrder
);
return
ret
;
}
sz
=
sizeof
format_hdr
;
r
=
IStream_Read
(
stm
,
&
format_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
/* check the format id is correct */
if
(
!
IsEqualGUID
(
&
FMTID_SummaryInformation
,
&
format_hdr
.
fmtid
)
)
return
ret
;
/* 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
;
/* read the section itself */
sz
=
sizeof
section_hdr
;
r
=
IStream_Read
(
stm
,
&
section_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
if
(
section_hdr
.
cProperties
>
MSI_MAX_PROPS
)
{
ERR
(
"too many properties %ld
\n
"
,
section_hdr
.
cProperties
);
return
ret
;
}
/* read the offsets */
sz
=
sizeof
idofs
[
0
]
*
section_hdr
.
cProperties
;
r
=
IStream_Read
(
stm
,
idofs
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
/* read all the data in one go */
sz
=
section_hdr
.
cbSection
;
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
if
(
!
data
)
return
ret
;
r
=
IStream_Read
(
stm
,
data
,
sz
,
&
count
);
if
(
SUCCEEDED
(
r
)
&&
count
==
sz
)
{
read_properties_from_data
(
si
->
property
,
idofs
,
section_hdr
.
cProperties
,
data
,
sz
);
}
HeapFree
(
GetProcessHeap
(),
0
,
data
);
return
ret
;
}
UINT
WINAPI
MsiGetSummaryInformationW
(
MSIHANDLE
hDatabase
,
LPCWSTR
szDatabase
,
UINT
uiUpdateCount
,
MSIHANDLE
*
phSummaryInfo
)
static
DWORD
write_dword
(
LPBYTE
data
,
DWORD
ofs
,
DWORD
val
)
{
if
(
data
)
{
data
[
ofs
++
]
=
val
&
0xff
;
data
[
ofs
++
]
=
(
val
>>
8
)
&
0xff
;
data
[
ofs
++
]
=
(
val
>>
16
)
&
0xff
;
data
[
ofs
++
]
=
(
val
>>
24
)
&
0xff
;
}
return
4
;
}
static
DWORD
write_filetime
(
LPBYTE
data
,
DWORD
ofs
,
LPFILETIME
ft
)
{
write_dword
(
data
,
ofs
,
ft
->
dwLowDateTime
);
write_dword
(
data
,
ofs
+
4
,
ft
->
dwHighDateTime
);
return
8
;
}
static
DWORD
write_string
(
LPBYTE
data
,
DWORD
ofs
,
LPCSTR
str
)
{
DWORD
len
=
lstrlenA
(
str
)
+
1
;
write_dword
(
data
,
ofs
,
len
);
if
(
data
)
lstrcpyA
(
&
data
[
ofs
+
4
],
str
);
return
(
7
+
len
)
&
~
3
;
}
static
UINT
write_property_to_data
(
PROPVARIANT
*
prop
,
LPBYTE
data
)
{
DWORD
sz
=
0
;
if
(
prop
->
vt
==
VT_EMPTY
)
return
sz
;
/* add the type */
sz
+=
write_dword
(
data
,
sz
,
prop
->
vt
);
switch
(
prop
->
vt
)
{
case
VT_I2
:
sz
+=
write_dword
(
data
,
sz
,
prop
->
u
.
iVal
);
break
;
case
VT_I4
:
sz
+=
write_dword
(
data
,
sz
,
prop
->
u
.
lVal
);
break
;
case
VT_FILETIME
:
sz
+=
write_filetime
(
data
,
sz
,
&
prop
->
u
.
filetime
);
break
;
case
VT_LPSTR
:
sz
+=
write_string
(
data
,
sz
,
prop
->
u
.
pszVal
);
break
;
}
return
sz
;
}
static
UINT
save_summary_info
(
MSISUMMARYINFO
*
si
,
IStream
*
stm
)
{
UINT
ret
=
ERROR_FUNCTION_FAILED
;
PROPERTYSETHEADER
set_hdr
;
FORMATIDOFFSET
format_hdr
;
PROPERTYSECTIONHEADER
section_hdr
;
PROPERTYIDOFFSET
idofs
[
MSI_MAX_PROPS
];
LPBYTE
data
=
NULL
;
ULONG
count
,
sz
;
HRESULT
r
;
int
i
,
n
;
/* write the header */
sz
=
sizeof
set_hdr
;
memset
(
&
set_hdr
,
0
,
sz
);
set_hdr
.
wByteOrder
=
0xfffe
;
set_hdr
.
wFormat
=
0
;
set_hdr
.
dwOSVer
=
0x00020005
;
/* build 5, platform id 2 */
/* set_hdr.clsID is {00000000-0000-0000-0000-000000000000} */
set_hdr
.
reserved
=
1
;
r
=
IStream_Write
(
stm
,
&
set_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
/* write the format header */
sz
=
sizeof
format_hdr
;
memcpy
(
&
format_hdr
.
fmtid
,
&
FMTID_SummaryInformation
,
sizeof
(
FMTID
)
);
format_hdr
.
dwOffset
=
sizeof
format_hdr
+
sizeof
set_hdr
;
r
=
IStream_Write
(
stm
,
&
format_hdr
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
/* add up how much space the data will take and calculate the offsets */
section_hdr
.
cbSection
=
sizeof
section_hdr
;
section_hdr
.
cbSection
+=
(
get_property_count
(
si
->
property
)
*
sizeof
idofs
[
0
]);
section_hdr
.
cProperties
=
0
;
n
=
0
;
for
(
i
=
0
;
i
<
MSI_MAX_PROPS
;
i
++
)
{
sz
=
write_property_to_data
(
&
si
->
property
[
i
],
NULL
);
if
(
!
sz
)
continue
;
idofs
[
section_hdr
.
cProperties
].
propid
=
i
;
idofs
[
section_hdr
.
cProperties
].
dwOffset
=
section_hdr
.
cbSection
;
section_hdr
.
cProperties
++
;
section_hdr
.
cbSection
+=
sz
;
}
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
section_hdr
.
cbSection
);
sz
=
0
;
memcpy
(
&
data
[
sz
],
&
section_hdr
,
sizeof
section_hdr
);
sz
+=
sizeof
section_hdr
;
memcpy
(
&
data
[
sz
],
idofs
,
section_hdr
.
cProperties
*
sizeof
idofs
[
0
]
);
sz
+=
section_hdr
.
cProperties
*
sizeof
idofs
[
0
];
/* write out the data */
for
(
i
=
0
;
i
<
MSI_MAX_PROPS
;
i
++
)
sz
+=
write_property_to_data
(
&
si
->
property
[
i
],
&
data
[
sz
]
);
r
=
IStream_Write
(
stm
,
data
,
sz
,
&
count
);
HeapFree
(
GetProcessHeap
(),
0
,
data
);
if
(
FAILED
(
r
)
||
count
!=
sz
)
return
ret
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiGetSummaryInformationW
(
MSIHANDLE
hDatabase
,
LPCWSTR
szDatabase
,
UINT
uiUpdateCount
,
MSIHANDLE
*
pHandle
)
{
UINT
ret
=
ERROR_SUCCESS
;
IStream
*
stm
=
NULL
;
MSISUMMARYINFO
*
si
;
MSIHANDLE
handle
;
MSISUMMARYINFO
*
suminfo
;
MSIDATABASE
*
db
;
UINT
ret
=
ERROR_SUCCESS
;
IPropertySetStorage
*
psstg
=
NULL
;
IPropertyStorage
*
ps
=
NULL
;
DWORD
grfMode
;
HRESULT
r
;
TRACE
(
"%ld %s %d %p
\n
"
,
hDatabase
,
debugstr_w
(
szDatabase
),
uiUpdateCount
,
p
hSummaryInfo
);
uiUpdateCount
,
p
Handle
);
if
(
!
p
hSummaryInfo
)
if
(
!
p
Handle
)
return
ERROR_INVALID_PARAMETER
;
if
(
szDatabase
)
...
...
@@ -103,113 +437,136 @@ UINT WINAPI MsiGetSummaryInformationW(MSIHANDLE hDatabase,
return
ERROR_INVALID_PARAMETER
;
}
r
=
IStorage_QueryInterface
(
db
->
storage
,
&
IID_IPropertySetStorage
,
(
LPVOID
)
&
psstg
);
if
(
FAILED
(
r
)
)
si
=
alloc_msiobject
(
MSIHANDLETYPE_SUMMARYINFO
,
sizeof
(
MSISUMMARYINFO
),
MSI_CloseSummaryInfo
);
if
(
!
si
)
{
ERR
(
"IStorage -> IPropertySetStorage failed
\n
"
);
ret
=
ERROR_FUNCTION_FAILED
;
goto
end
;
}
grfMode
=
STGM_READ
|
STGM_SHARE_EXCLUSIVE
;
r
=
IPropertySetStorage_Open
(
psstg
,
&
FMTID_SummaryInformation
,
grfMode
,
&
ps
);
if
(
FAILED
(
r
)
)
{
ERR
(
"failed to get IPropertyStorage r=%08lx
\n
"
,
r
);
ret
=
ERROR_FUNCTION_FAILED
;
goto
end
;
}
msiobj_addref
(
&
db
->
hdr
);
si
->
db
=
db
;
memset
(
&
si
->
property
,
0
,
sizeof
si
->
property
);
si
->
update_count
=
uiUpdateCount
;
suminfo
=
alloc_msiobject
(
MSIHANDLETYPE_SUMMARYINFO
,
sizeof
(
MSISUMMARYINFO
),
MSI_CloseSummaryInfo
);
if
(
!
suminfo
)
/* read the stream... if we fail, we'll start with an empty property set */
grfMode
=
STGM_READ
|
STGM_SHARE_EXCLUSIVE
;
r
=
IStorage_OpenStream
(
si
->
db
->
storage
,
szSumInfo
,
0
,
grfMode
,
0
,
&
stm
);
if
(
SUCCEEDED
(
r
)
)
{
ret
=
ERROR_FUNCTION_FAILED
;
goto
end
;
load_summary_info
(
si
,
stm
)
;
IStream_Release
(
stm
)
;
}
IPropertyStorage_AddRef
(
ps
);
suminfo
->
propstg
=
ps
;
handle
=
alloc_msihandle
(
&
suminfo
->
hdr
);
handle
=
alloc_msihandle
(
&
si
->
hdr
);
if
(
handle
)
*
p
hSummaryInfo
=
handle
;
*
p
Handle
=
handle
;
else
ret
=
ERROR_FUNCTION_FAILED
;
msiobj_release
(
&
s
uminfo
->
hdr
);
msiobj_release
(
&
s
i
->
hdr
);
end:
if
(
ps
)
IPropertyStorage_Release
(
ps
);
if
(
psstg
)
IPropertySetStorage_Release
(
psstg
);
if
(
db
)
msiobj_release
(
&
db
->
hdr
);
return
ret
;
}
UINT
WINAPI
MsiSummaryInfoGetPropertyCount
(
MSIHANDLE
hSummaryInfo
,
UINT
*
pCount
)
UINT
WINAPI
MsiGetSummaryInformationA
(
MSIHANDLE
hDatabase
,
LPCSTR
szDatabase
,
UINT
uiUpdateCount
,
MSIHANDLE
*
pHandle
)
{
MSISUMMARYINFO
*
suminfo
;
LPWSTR
szwDatabase
=
NULL
;
UINT
ret
;
FIXME
(
"%ld %p
\n
"
,
hSummaryInfo
,
pCount
);
TRACE
(
"%ld %s %d %p
\n
"
,
hDatabase
,
debugstr_a
(
szDatabase
),
uiUpdateCount
,
pHandle
);
suminfo
=
msihandle2msiinfo
(
hSummaryInfo
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
suminfo
)
return
ERROR_INVALID_HANDLE
;
if
(
szDatabase
)
{
szwDatabase
=
strdupAtoW
(
szDatabase
);
if
(
!
szwDatabase
)
return
ERROR_FUNCTION_FAILED
;
}
ret
=
MsiGetSummaryInformationW
(
hDatabase
,
szwDatabase
,
uiUpdateCount
,
pHandle
);
msiobj_release
(
&
suminfo
->
hdr
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
HeapFree
(
GetProcessHeap
(),
0
,
szwDatabase
);
return
ret
;
}
UINT
WINAPI
MsiSummaryInfoGetPropertyA
(
MSIHANDLE
hSummaryInfo
,
UINT
uiProperty
,
UINT
*
puiDataType
,
INT
*
piValue
,
FILETIME
*
pftValue
,
LPSTR
szValueBuf
,
DWORD
*
pcchValueBuf
)
UINT
WINAPI
MsiSummaryInfoGetPropertyCount
(
MSIHANDLE
hSummaryInfo
,
UINT
*
pCount
)
{
MSISUMMARYINFO
*
suminfo
;
HRESULT
r
;
PROPSPEC
spec
;
PROPVARIANT
var
;
UINT
rc
=
ERROR_SUCCESS
;
MSISUMMARYINFO
*
si
;
TRACE
(
"%ld %d %p %p %p %p %p
\n
"
,
hSummaryInfo
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
szValueBuf
,
pcchValueBuf
);
TRACE
(
"%ld %p
\n
"
,
hSummaryInfo
,
pCount
);
s
uminfo
=
msihandle2msiinfo
(
hSummaryInfo
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
s
uminfo
)
s
i
=
msihandle2msiinfo
(
hSummaryInfo
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
s
i
)
return
ERROR_INVALID_HANDLE
;
spec
.
ulKind
=
PRSPEC_PROPID
;
spec
.
u
.
propid
=
uiProperty
;
if
(
pCount
)
*
pCount
=
get_property_count
(
si
->
property
);
msiobj_release
(
&
si
->
hdr
);
r
=
IPropertyStorage_ReadMultiple
(
suminfo
->
propstg
,
1
,
&
spec
,
&
var
);
if
(
FAILED
(
r
)
)
{
rc
=
ERROR_FUNCTION_FAILED
;
goto
end
;
}
return
ERROR_SUCCESS
;
}
static
UINT
get_prop
(
MSIHANDLE
handle
,
UINT
uiProperty
,
UINT
*
puiDataType
,
INT
*
piValue
,
FILETIME
*
pftValue
,
awstring
*
str
,
DWORD
*
pcchValueBuf
)
{
MSISUMMARYINFO
*
si
;
PROPVARIANT
*
prop
;
UINT
type
;
TRACE
(
"%ld %d %p %p %p %p %p
\n
"
,
handle
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
str
,
pcchValueBuf
);
type
=
get_type
(
uiProperty
);
if
(
puiDataType
)
*
puiDataType
=
var
.
vt
;
*
puiDataType
=
type
;
switch
(
var
.
vt
)
si
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
si
)
return
ERROR_INVALID_HANDLE
;
prop
=
&
si
->
property
[
uiProperty
];
if
(
prop
->
vt
!=
type
)
goto
end
;
switch
(
type
)
{
case
VT_I2
:
if
(
piValue
)
*
piValue
=
prop
->
u
.
iVal
;
break
;
case
VT_I4
:
if
(
piValue
)
*
piValue
=
var
.
u
.
lVal
;
*
piValue
=
prop
->
u
.
lVal
;
break
;
case
VT_LPSTR
:
if
(
pcchValueBuf
&&
szValueBuf
)
if
(
pcchValueBuf
)
{
lstrcpynA
(
szValueBuf
,
var
.
u
.
pszVal
,
*
pcchValueBuf
);
*
pcchValueBuf
=
lstrlenA
(
var
.
u
.
pszVal
);
DWORD
len
=
0
;
if
(
str
->
unicode
)
{
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
prop
->
u
.
pszVal
,
-
1
,
str
->
str
.
w
,
*
pcchValueBuf
);
}
else
{
len
=
lstrlenA
(
prop
->
u
.
pszVal
);
if
(
str
->
str
.
a
)
lstrcpynA
(
str
->
str
.
a
,
prop
->
u
.
pszVal
,
*
pcchValueBuf
);
}
*
pcchValueBuf
=
len
;
}
break
;
case
VT_FILETIME
:
if
(
pftValue
)
memcpy
(
pftValue
,
&
var
.
u
.
filetime
,
sizeof
(
FILETIME
)
);
memcpy
(
pftValue
,
&
prop
->
u
.
filetime
,
sizeof
(
FILETIME
)
);
break
;
case
VT_EMPTY
:
break
;
...
...
@@ -217,93 +574,165 @@ UINT WINAPI MsiSummaryInfoGetPropertyA(
FIXME
(
"Unknown property variant type
\n
"
);
break
;
}
end:
msiobj_release
(
&
suminfo
->
hdr
);
return
rc
;
msiobj_release
(
&
si
->
hdr
);
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiSummaryInfoGetPropertyA
(
MSIHANDLE
handle
,
UINT
uiProperty
,
UINT
*
puiDataType
,
INT
*
piValue
,
FILETIME
*
pftValue
,
LPSTR
szValueBuf
,
DWORD
*
pcchValueBuf
)
{
awstring
str
;
TRACE
(
"%ld %d %p %p %p %p %p
\n
"
,
handle
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
szValueBuf
,
pcchValueBuf
);
str
.
unicode
=
FALSE
;
str
.
str
.
a
=
szValueBuf
;
return
get_prop
(
handle
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
&
str
,
pcchValueBuf
);
}
UINT
WINAPI
MsiSummaryInfoGetPropertyW
(
MSIHANDLE
h
SummaryInfo
,
UINT
uiProperty
,
UINT
*
puiDataType
,
INT
*
piValue
,
MSIHANDLE
h
andle
,
UINT
uiProperty
,
UINT
*
puiDataType
,
INT
*
piValue
,
FILETIME
*
pftValue
,
LPWSTR
szValueBuf
,
DWORD
*
pcchValueBuf
)
{
MSISUMMARYINFO
*
suminfo
;
HRESULT
r
;
PROPSPEC
spec
;
PROPVARIANT
var
;
UINT
rc
=
ERROR_SUCCESS
;
awstring
str
;
TRACE
(
"%ld %d %p %p %p %p %p
\n
"
,
handle
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
szValueBuf
,
pcchValueBuf
);
TRACE
(
"%ld %d %p %p %p %p %p
\n
"
,
hSummaryInfo
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
szValueBuf
,
pcchValueBuf
);
str
.
unicode
=
TRUE
;
str
.
str
.
w
=
szValueBuf
;
suminfo
=
msihandle2msiinfo
(
hSummaryInfo
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
suminfo
)
return
get_prop
(
handle
,
uiProperty
,
puiDataType
,
piValue
,
pftValue
,
&
str
,
pcchValueBuf
);
}
static
UINT
set_prop
(
MSIHANDLE
handle
,
UINT
uiProperty
,
UINT
uiDataType
,
INT
iValue
,
FILETIME
*
pftValue
,
awstring
*
str
)
{
MSISUMMARYINFO
*
si
;
PROPVARIANT
*
prop
;
UINT
type
,
len
,
ret
=
ERROR_SUCCESS
;
TRACE
(
"%ld %u %u %i %p %p
\n
"
,
handle
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
str
);
type
=
get_type
(
uiProperty
);
if
(
type
==
VT_EMPTY
||
type
!=
uiDataType
)
return
ERROR_DATATYPE_MISMATCH
;
if
(
uiDataType
==
VT_LPSTR
&&
!
str
->
str
.
w
)
return
ERROR_INVALID_PARAMETER
;
if
(
uiDataType
==
VT_FILETIME
&&
!
pftValue
)
return
ERROR_INVALID_PARAMETER
;
si
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
si
)
return
ERROR_INVALID_HANDLE
;
spec
.
ulKind
=
PRSPEC_PROPID
;
spec
.
u
.
propid
=
uiProperty
;
prop
=
&
si
->
property
[
uiProperty
];
r
=
IPropertyStorage_ReadMultiple
(
suminfo
->
propstg
,
1
,
&
spec
,
&
var
);
if
(
FAILED
(
r
)
)
if
(
prop
->
vt
==
VT_EMPTY
)
{
rc
=
ERROR_FUNCTION_FAILED
;
goto
end
;
if
(
!
si
->
update_count
)
{
ret
=
ERROR_FUNCTION_FAILED
;
goto
end
;
}
si
->
update_count
--
;
prop
->
vt
=
type
;
}
else
if
(
prop
->
vt
!=
type
)
goto
end
;
if
(
puiDataType
)
*
puiDataType
=
var
.
vt
;
switch
(
var
.
vt
)
switch
(
type
)
{
case
VT_I4
:
if
(
piValue
)
*
piValue
=
var
.
u
.
lVal
;
prop
->
u
.
lVal
=
iValue
;
break
;
case
VT_LPSTR
:
if
(
pcchValueBuf
&&
szValueBuf
)
{
MultiByteToWideChar
(
CP_ACP
,
0
,
var
.
u
.
pszVal
,
-
1
,
szValueBuf
,
*
pcchValueBuf
);
*
pcchValueBuf
=
lstrlenA
(
var
.
u
.
pszVal
);
}
case
VT_I2
:
prop
->
u
.
iVal
=
iValue
;
break
;
case
VT_FILETIME
:
if
(
pftValue
)
memcpy
(
pftValue
,
&
var
.
u
.
filetime
,
sizeof
(
FILETIME
)
);
break
;
case
VT_EMPTY
:
memcpy
(
&
prop
->
u
.
filetime
,
pftValue
,
sizeof
prop
->
u
.
filetime
);
break
;
default:
FIXME
(
"Unknown property variant type
\n
"
);
case
VT_LPSTR
:
HeapFree
(
GetProcessHeap
(),
0
,
prop
->
u
.
pszVal
);
if
(
str
->
unicode
)
{
len
=
WideCharToMultiByte
(
CP_ACP
,
0
,
str
->
str
.
w
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
prop
->
u
.
pszVal
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
WideCharToMultiByte
(
CP_ACP
,
0
,
str
->
str
.
w
,
-
1
,
prop
->
u
.
pszVal
,
len
,
NULL
,
NULL
);
}
else
{
len
=
lstrlenA
(
str
->
str
.
a
)
+
1
;
prop
->
u
.
pszVal
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
);
lstrcpyA
(
prop
->
u
.
pszVal
,
str
->
str
.
a
);
}
break
;
}
end:
msiobj_release
(
&
s
uminfo
->
hdr
);
return
r
c
;
msiobj_release
(
&
s
i
->
hdr
);
return
r
et
;
}
UINT
WINAPI
MsiSummaryInfoSetPropertyA
(
MSIHANDLE
hSummaryInfo
,
UINT
uiProperty
,
UINT
uiDataType
,
INT
iValue
,
FILETIME
*
pftValue
,
LPSTR
szValue
)
UINT
WINAPI
MsiSummaryInfoSetPropertyW
(
MSIHANDLE
handle
,
UINT
uiProperty
,
UINT
uiDataType
,
INT
iValue
,
FILETIME
*
pftValue
,
LPWSTR
szValue
)
{
FIXME
(
"%ld %u %u %i %p %s
\n
"
,
hSummaryInfo
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
debugstr_a
(
szValue
)
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
awstring
str
;
TRACE
(
"%ld %u %u %i %p %s
\n
"
,
handle
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
debugstr_w
(
szValue
)
);
str
.
unicode
=
TRUE
;
str
.
str
.
w
=
szValue
;
return
set_prop
(
handle
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
&
str
);
}
UINT
WINAPI
MsiSummaryInfoSetPropertyW
(
MSIHANDLE
hSummaryInfo
,
UINT
uiProperty
,
UINT
uiDataType
,
INT
iValue
,
FILETIME
*
pftValue
,
LPWSTR
szValue
)
UINT
WINAPI
MsiSummaryInfoSetPropertyA
(
MSIHANDLE
handle
,
UINT
uiProperty
,
UINT
uiDataType
,
INT
iValue
,
FILETIME
*
pftValue
,
LPSTR
szValue
)
{
FIXME
(
"%ld %u %u %i %p %s
\n
"
,
hSummaryInfo
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
debugstr_w
(
szValue
)
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
awstring
str
;
TRACE
(
"%ld %u %u %i %p %s
\n
"
,
handle
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
debugstr_a
(
szValue
)
);
str
.
unicode
=
FALSE
;
str
.
str
.
a
=
szValue
;
return
set_prop
(
handle
,
uiProperty
,
uiDataType
,
iValue
,
pftValue
,
&
str
);
}
UINT
WINAPI
MsiSummaryInfoPersist
(
MSIHANDLE
h
SummaryInfo
)
UINT
WINAPI
MsiSummaryInfoPersist
(
MSIHANDLE
h
andle
)
{
FIXME
(
"%ld
\n
"
,
hSummaryInfo
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
IStream
*
stm
=
NULL
;
MSISUMMARYINFO
*
si
;
DWORD
grfMode
;
HRESULT
r
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
TRACE
(
"%ld
\n
"
,
handle
);
si
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_SUMMARYINFO
);
if
(
!
si
)
return
ERROR_INVALID_HANDLE
;
grfMode
=
STGM_CREATE
|
STGM_READWRITE
|
STGM_SHARE_EXCLUSIVE
;
r
=
IStorage_CreateStream
(
si
->
db
->
storage
,
szSumInfo
,
grfMode
,
0
,
0
,
&
stm
);
if
(
SUCCEEDED
(
r
)
)
{
ret
=
save_summary_info
(
si
,
stm
);
IStream_Release
(
stm
);
}
msiobj_release
(
&
si
->
hdr
);
return
ret
;
}
include/msi.h
View file @
758a6951
...
...
@@ -201,20 +201,6 @@ UINT WINAPI MsiOpenProductA(LPCSTR, MSIHANDLE*);
UINT
WINAPI
MsiOpenProductW
(
LPCWSTR
,
MSIHANDLE
*
);
#define MsiOpenProduct WINELIB_NAME_AW(MsiOpenProduct)
UINT
WINAPI
MsiGetSummaryInformationA
(
MSIHANDLE
,
LPCSTR
,
UINT
,
MSIHANDLE
*
);
UINT
WINAPI
MsiGetSummaryInformationW
(
MSIHANDLE
,
LPCWSTR
,
UINT
,
MSIHANDLE
*
);
#define MsiGetSummaryInformation WINELIB_NAME_AW(MsiGetSummaryInformation)
UINT
WINAPI
MsiSummaryInfoGetPropertyA
(
MSIHANDLE
,
UINT
,
UINT
*
,
INT
*
,
FILETIME
*
,
LPSTR
,
DWORD
*
);
UINT
WINAPI
MsiSummaryInfoGetPropertyW
(
MSIHANDLE
,
UINT
,
UINT
*
,
INT
*
,
FILETIME
*
,
LPWSTR
,
DWORD
*
);
#define MsiSummaryInfoGetProperty WINELIB_NAME_AW(MsiSummaryInfoGetProperty)
UINT
WINAPI
MsiSummaryInfoPersist
(
MSIHANDLE
);
UINT
WINAPI
MsiSummaryInfoSetPropertyA
(
MSIHANDLE
,
UINT
,
UINT
,
INT
,
FILETIME
*
,
LPSTR
);
UINT
WINAPI
MsiSummaryInfoSetPropertyW
(
MSIHANDLE
,
UINT
,
UINT
,
INT
,
FILETIME
*
,
LPWSTR
);
#define MsiSummaryInfoSetProperty WINELIB_NAME_AW(MsiSummaryInfoSetProperty)
UINT
WINAPI
MsiProvideComponentFromDescriptorA
(
LPCSTR
,
LPSTR
,
DWORD
*
,
DWORD
*
);
UINT
WINAPI
MsiProvideComponentFromDescriptorW
(
LPCWSTR
,
LPWSTR
,
DWORD
*
,
DWORD
*
);
#define MsiProvideComponentFromDescriptor WINELIB_NAME_AW(MsiProvideComponentFromDescriptor)
...
...
include/msiquery.h
View file @
758a6951
...
...
@@ -181,6 +181,21 @@ UINT WINAPI MsiPreviewBillboardA(MSIHANDLE, LPCSTR, LPCSTR);
UINT
WINAPI
MsiPreviewBillboardW
(
MSIHANDLE
,
LPCWSTR
,
LPCWSTR
);
#define MsiPreviewBillboard WINELIB_NAME_AW(MsiPreviewBillboard)
UINT
WINAPI
MsiGetSummaryInformationA
(
MSIHANDLE
,
LPCSTR
,
UINT
,
MSIHANDLE
*
);
UINT
WINAPI
MsiGetSummaryInformationW
(
MSIHANDLE
,
LPCWSTR
,
UINT
,
MSIHANDLE
*
);
#define MsiGetSummaryInformation WINELIB_NAME_AW(MsiGetSummaryInformation)
UINT
WINAPI
MsiSummaryInfoGetPropertyA
(
MSIHANDLE
,
UINT
,
UINT
*
,
INT
*
,
FILETIME
*
,
LPSTR
,
DWORD
*
);
UINT
WINAPI
MsiSummaryInfoGetPropertyW
(
MSIHANDLE
,
UINT
,
UINT
*
,
INT
*
,
FILETIME
*
,
LPWSTR
,
DWORD
*
);
#define MsiSummaryInfoGetProperty WINELIB_NAME_AW(MsiSummaryInfoGetProperty)
UINT
WINAPI
MsiSummaryInfoSetPropertyA
(
MSIHANDLE
,
UINT
,
UINT
,
INT
,
FILETIME
*
,
LPSTR
);
UINT
WINAPI
MsiSummaryInfoSetPropertyW
(
MSIHANDLE
,
UINT
,
UINT
,
INT
,
FILETIME
*
,
LPWSTR
);
#define MsiSummaryInfoSetProperty WINELIB_NAME_AW(MsiSummaryInfoSetProperty)
UINT
WINAPI
MsiSummaryInfoPersist
(
MSIHANDLE
);
UINT
WINAPI
MsiSummaryInfoGetPropertyCount
(
MSIHANDLE
,
UINT
*
);
UINT
WINAPI
MsiEnableUIPreview
(
MSIHANDLE
,
MSIHANDLE
*
);
BOOL
WINAPI
MsiGetMode
(
MSIHANDLE
,
MSIRUNMODE
);
...
...
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