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
0eecfdef
Commit
0eecfdef
authored
Jun 29, 2004
by
Mike McCormack
Committed by
Alexandre Julliard
Jun 29, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow reading records containing streams.
parent
8079d2ae
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
222 additions
and
78 deletions
+222
-78
msipriv.h
dlls/msi/msipriv.h
+6
-0
msiquery.c
dlls/msi/msiquery.c
+33
-3
record.c
dlls/msi/record.c
+69
-2
table.c
dlls/msi/table.c
+114
-73
No files found.
dlls/msi/msipriv.h
View file @
0eecfdef
...
...
@@ -206,4 +206,10 @@ UINT read_raw_stream_data( MSIHANDLE hdb, LPCWSTR stname,
UINT
ACTION_DoTopLevelINSTALL
(
MSIHANDLE
hPackage
,
LPCWSTR
szPackagePath
,
LPCWSTR
szCommandLine
);
extern
UINT
WINAPI
MSI_RecordSetIStream
(
MSIHANDLE
handle
,
unsigned
int
iField
,
IStream
*
stm
);
extern
UINT
get_raw_stream
(
MSIHANDLE
hdb
,
LPCWSTR
stname
,
IStream
**
stm
);
extern
UINT
db_get_raw_stream
(
MSIDATABASE
*
db
,
LPCWSTR
stname
,
IStream
**
stm
);
#endif
/* __WINE_MSI_PRIVATE__ */
dlls/msi/msiquery.c
View file @
0eecfdef
...
...
@@ -24,6 +24,7 @@
#include "winbase.h"
#include "winerror.h"
#include "wine/debug.h"
#include "wine/unicode.h"
#include "msi.h"
#include "msiquery.h"
#include "objbase.h"
...
...
@@ -208,9 +209,38 @@ UINT WINAPI MsiViewFetch(MSIHANDLE hView, MSIHANDLE *record)
if
(
type
&
MSITYPE_STRING
)
{
LPWSTR
sval
=
MSI_makestring
(
query
->
db
,
ival
);
MsiRecordSetStringW
(
handle
,
i
,
sval
);
HeapFree
(
GetProcessHeap
(),
0
,
sval
);
LPWSTR
sval
;
if
(
type
&
MSI_DATASIZEMASK
)
{
sval
=
MSI_makestring
(
query
->
db
,
ival
);
MsiRecordSetStringW
(
handle
,
i
,
sval
);
HeapFree
(
GetProcessHeap
(),
0
,
sval
);
}
else
{
UINT
refcol
=
0
;
IStream
*
stm
=
NULL
;
WCHAR
full_name
[
0x40
];
static
const
WCHAR
szBinary
[]
=
{
'B'
,
'i'
,
'n'
,
'a'
,
'r'
,
'y'
,
'.'
,
0
};
const
int
maxlen
=
(
sizeof
full_name
-
sizeof
szBinary
)
/
sizeof
(
WCHAR
);
ret
=
view
->
ops
->
fetch_int
(
view
,
query
->
row
,
ival
,
&
refcol
);
sval
=
MSI_makestring
(
query
->
db
,
refcol
);
if
(
sval
&&
(
strlenW
(
sval
)
<
maxlen
)
)
{
strcpyW
(
full_name
,
szBinary
);
strcatW
(
full_name
,
sval
);
db_get_raw_stream
(
query
->
db
,
full_name
,
&
stm
);
if
(
stm
)
MSI_RecordSetIStream
(
handle
,
i
,
stm
);
else
ERR
(
"failed to get stream
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
sval
);
}
}
}
else
{
...
...
dlls/msi/record.c
View file @
0eecfdef
...
...
@@ -434,6 +434,73 @@ UINT WINAPI MsiRecordSetStreamW(MSIHANDLE hRecord, unsigned int iField, LPCWSTR
UINT
WINAPI
MsiRecordReadStream
(
MSIHANDLE
handle
,
unsigned
int
iField
,
char
*
buf
,
DWORD
*
sz
)
{
FIXME
(
"%ld %d %p %p
\n
"
,
handle
,
iField
,
buf
,
sz
);
return
ERROR_CALL_NOT_IMPLEMENTED
;
MSIRECORD
*
rec
;
ULONG
count
;
HRESULT
r
;
IStream
*
stm
;
TRACE
(
"%ld %d %p %p
\n
"
,
handle
,
iField
,
buf
,
sz
);
rec
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_RECORD
);
if
(
!
rec
)
return
ERROR_INVALID_HANDLE
;
if
(
iField
>
rec
->
count
)
return
ERROR_INVALID_FIELD
;
if
(
rec
->
fields
[
iField
].
type
!=
MSIFIELD_STREAM
)
return
ERROR_INVALID_FIELD
;
stm
=
rec
->
fields
[
iField
].
u
.
stream
;
if
(
!
stm
)
return
ERROR_INVALID_FIELD
;
/* if there's no buffer pointer, calculate the length to the end */
if
(
!
buf
)
{
LARGE_INTEGER
ofs
;
ULARGE_INTEGER
end
,
cur
;
ofs
.
QuadPart
=
cur
.
QuadPart
=
0
;
end
.
QuadPart
=
0
;
r
=
IStream_Seek
(
stm
,
ofs
,
STREAM_SEEK_SET
,
&
cur
);
IStream_Seek
(
stm
,
ofs
,
STREAM_SEEK_END
,
&
end
);
ofs
.
QuadPart
=
cur
.
QuadPart
;
IStream_Seek
(
stm
,
ofs
,
STREAM_SEEK_SET
,
&
cur
);
*
sz
=
end
.
QuadPart
-
cur
.
QuadPart
;
return
ERROR_SUCCESS
;
}
/* read the data */
count
=
0
;
r
=
IStream_Read
(
stm
,
buf
,
*
sz
,
&
count
);
if
(
FAILED
(
r
)
)
return
ERROR_FUNCTION_FAILED
;
*
sz
=
count
;
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MSI_RecordSetIStream
(
MSIHANDLE
handle
,
unsigned
int
iField
,
IStream
*
stm
)
{
MSIRECORD
*
rec
;
TRACE
(
"%ld %d %p
\n
"
,
handle
,
iField
,
stm
);
rec
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_RECORD
);
if
(
!
rec
)
return
ERROR_INVALID_HANDLE
;
if
(
iField
>
rec
->
count
)
return
ERROR_INVALID_FIELD
;
MSI_FreeField
(
&
rec
->
fields
[
iField
]
);
rec
->
fields
[
iField
].
type
=
MSIFIELD_STREAM
;
rec
->
fields
[
iField
].
u
.
stream
=
stm
;
IStream_AddRef
(
stm
);
return
ERROR_SUCCESS
;
}
dlls/msi/table.c
View file @
0eecfdef
...
...
@@ -165,6 +165,35 @@ static BOOL decode_streamname(LPWSTR in, LPWSTR out)
*out = 0;
return count;
}
void enum_stream_names( IStorage *stg )
{
IEnumSTATSTG *stgenum = NULL;
HRESULT r;
STATSTG stat;
ULONG n, count;
WCHAR name[0x40];
r = IStorage_EnumElements( stg, 0, NULL, 0, &stgenum );
if( FAILED( r ) )
return;
n = 0;
while( 1 )
{
count = 0;
r = IEnumSTATSTG_Next( stgenum, 1, &stat, &count );
if( FAILED( r ) || !count )
break;
decode_streamname( stat.pwcsName, name );
ERR("stream %2ld -> %s %s\n", n,
debugstr_w(stat.pwcsName), debugstr_w(name) );
n++;
}
IEnumSTATSTG_Release( stgenum );
}
#endif
static
UINT
read_stream_data
(
IStorage
*
stg
,
LPCWSTR
stname
,
...
...
@@ -230,6 +259,91 @@ end:
return
ret
;
}
UINT
db_get_raw_stream
(
MSIDATABASE
*
db
,
LPCWSTR
stname
,
IStream
**
stm
)
{
WCHAR
encname
[
0x20
];
HRESULT
r
;
encode_streamname
(
FALSE
,
stname
,
encname
);
TRACE
(
"%s -> %s
\n
"
,
debugstr_w
(
stname
),
debugstr_w
(
encname
));
r
=
IStorage_OpenStream
(
db
->
storage
,
encname
,
NULL
,
STGM_READ
|
STGM_SHARE_EXCLUSIVE
,
0
,
stm
);
if
(
FAILED
(
r
)
)
{
WARN
(
"open stream failed r = %08lx - empty table?
\n
"
,
r
);
return
ERROR_FUNCTION_FAILED
;
}
return
ERROR_SUCCESS
;
}
/* FIXME: we should be passing around pointers to db structures internally */
UINT
get_raw_stream
(
MSIHANDLE
hdb
,
LPCWSTR
stname
,
IStream
**
stm
)
{
MSIDATABASE
*
db
=
msihandle2msiinfo
(
hdb
,
MSIHANDLETYPE_DATABASE
);
if
(
!
db
)
return
ERROR_INVALID_HANDLE
;
return
db_get_raw_stream
(
db
,
stname
,
stm
);
}
UINT
read_raw_stream_data
(
MSIHANDLE
hdb
,
LPCWSTR
stname
,
USHORT
**
pdata
,
UINT
*
psz
)
{
HRESULT
r
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
VOID
*
data
;
ULONG
sz
,
count
;
IStream
*
stm
=
NULL
;
STATSTG
stat
;
r
=
get_raw_stream
(
hdb
,
stname
,
&
stm
);
if
(
r
!=
ERROR_SUCCESS
)
goto
end
;
ret
=
ERROR_FUNCTION_FAILED
;
r
=
IStream_Stat
(
stm
,
&
stat
,
STATFLAG_NONAME
);
if
(
FAILED
(
r
)
)
{
ERR
(
"open stream failed r = %08lx!
\n
"
,
r
);
goto
end
;
}
if
(
stat
.
cbSize
.
QuadPart
>>
32
)
{
ERR
(
"Too big!
\n
"
);
goto
end
;
}
sz
=
stat
.
cbSize
.
QuadPart
;
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
if
(
!
data
)
{
ERR
(
"couldn't allocate memory r=%08lx!
\n
"
,
r
);
ret
=
ERROR_NOT_ENOUGH_MEMORY
;
goto
end
;
}
r
=
IStream_Read
(
stm
,
data
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
(
count
!=
sz
)
)
{
HeapFree
(
GetProcessHeap
(),
0
,
data
);
ERR
(
"read stream failed r = %08lx!
\n
"
,
r
);
goto
end
;
}
*
pdata
=
data
;
*
psz
=
sz
;
ret
=
ERROR_SUCCESS
;
end:
IStream_Release
(
stm
);
return
ret
;
}
static
UINT
write_stream_data
(
IStorage
*
stg
,
LPCWSTR
stname
,
LPVOID
data
,
UINT
sz
)
{
...
...
@@ -1254,76 +1368,3 @@ UINT MSI_CommitTables( MSIDATABASE *db )
return
ERROR_SUCCESS
;
}
UINT
read_raw_stream_data
(
MSIHANDLE
hdb
,
LPCWSTR
stname
,
USHORT
**
pdata
,
UINT
*
psz
)
{
HRESULT
r
;
UINT
ret
=
ERROR_FUNCTION_FAILED
;
VOID
*
data
;
ULONG
sz
,
count
;
IStream
*
stm
=
NULL
;
IStorage
*
stg
=
NULL
;
STATSTG
stat
;
WCHAR
encname
[
0x20
];
MSIDATABASE
*
db
;
db
=
msihandle2msiinfo
(
hdb
,
MSIHANDLETYPE_DATABASE
);
if
(
!
db
)
return
ERROR_INVALID_HANDLE
;
stg
=
db
->
storage
;
encode_streamname
(
FALSE
,
stname
,
encname
);
TRACE
(
"%s -> %s
\n
"
,
debugstr_w
(
stname
),
debugstr_w
(
encname
));
r
=
IStorage_OpenStream
(
stg
,
encname
,
NULL
,
STGM_READ
|
STGM_SHARE_EXCLUSIVE
,
0
,
&
stm
);
if
(
FAILED
(
r
)
)
{
WARN
(
"open stream failed r = %08lx - empty table?
\n
"
,
r
);
return
ret
;
}
r
=
IStream_Stat
(
stm
,
&
stat
,
STATFLAG_NONAME
);
if
(
FAILED
(
r
)
)
{
ERR
(
"open stream failed r = %08lx!
\n
"
,
r
);
goto
end
;
}
if
(
stat
.
cbSize
.
QuadPart
>>
32
)
{
ERR
(
"Too big!
\n
"
);
goto
end
;
}
sz
=
stat
.
cbSize
.
QuadPart
;
data
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sz
);
if
(
!
data
)
{
ERR
(
"couldn't allocate memory r=%08lx!
\n
"
,
r
);
ret
=
ERROR_NOT_ENOUGH_MEMORY
;
goto
end
;
}
r
=
IStream_Read
(
stm
,
data
,
sz
,
&
count
);
if
(
FAILED
(
r
)
||
(
count
!=
sz
)
)
{
HeapFree
(
GetProcessHeap
(),
0
,
data
);
ERR
(
"read stream failed r = %08lx!
\n
"
,
r
);
goto
end
;
}
*
pdata
=
data
;
*
psz
=
sz
;
ret
=
ERROR_SUCCESS
;
end:
IStream_Release
(
stm
);
return
ret
;
}
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