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
921be0a8
Commit
921be0a8
authored
Jan 09, 2005
by
Mike McCormack
Committed by
Alexandre Julliard
Jan 09, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement MsiRecordSetStreamA/W and add tests for records containing
streams.
parent
dd8fccfe
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
218 additions
and
14 deletions
+218
-14
record.c
dlls/msi/record.c
+130
-12
record.c
dlls/msi/tests/record.c
+88
-2
No files found.
dlls/msi/record.c
View file @
921be0a8
...
...
@@ -32,6 +32,7 @@
#include "msipriv.h"
#include "objidl.h"
#include "winnls.h"
#include "ole2.h"
#include "query.h"
...
...
@@ -531,16 +532,133 @@ UINT WINAPI MsiFormatRecordW(MSIHANDLE hInstall, MSIHANDLE hRecord, LPWSTR szRes
return
ERROR_CALL_NOT_IMPLEMENTED
;
}
/* read the data in a file into an IStream */
UINT
RECORD_StreamFromFile
(
LPCWSTR
szFile
,
IStream
**
pstm
)
{
DWORD
sz
,
szHighWord
=
0
,
read
;
HANDLE
handle
;
HGLOBAL
hGlob
=
0
;
HRESULT
hr
;
ULARGE_INTEGER
ulSize
;
TRACE
(
"reading %s
\n
"
,
debugstr_w
(
szFile
));
/* read the file into memory */
handle
=
CreateFileW
(
szFile
,
GENERIC_READ
,
FILE_SHARE_READ
,
NULL
,
OPEN_EXISTING
,
0
,
NULL
);
if
(
handle
==
INVALID_HANDLE_VALUE
)
return
GetLastError
();
sz
=
GetFileSize
(
handle
,
&
szHighWord
);
if
(
sz
!=
INVALID_FILE_SIZE
&&
szHighWord
==
0
)
{
hGlob
=
GlobalAlloc
(
GMEM_FIXED
,
sz
);
if
(
hGlob
)
{
BOOL
r
=
ReadFile
(
handle
,
hGlob
,
sz
,
&
read
,
NULL
);
if
(
!
r
)
{
GlobalFree
(
hGlob
);
hGlob
=
0
;
}
}
}
CloseHandle
(
handle
);
if
(
!
hGlob
)
return
ERROR_FUNCTION_FAILED
;
/* make a stream out of it, and set the correct file size */
hr
=
CreateStreamOnHGlobal
(
hGlob
,
TRUE
,
pstm
);
if
(
FAILED
(
hr
)
)
{
GlobalFree
(
hGlob
);
return
ERROR_FUNCTION_FAILED
;
}
/* set the correct size - CreateStreamOnHGlobal screws it up */
ulSize
.
QuadPart
=
sz
;
IStream_SetSize
(
*
pstm
,
ulSize
);
TRACE
(
"read %s, %ld bytes into IStream %p
\n
"
,
debugstr_w
(
szFile
),
sz
,
*
pstm
);
return
ERROR_SUCCESS
;
}
UINT
MSI_RecordSetStreamW
(
MSIRECORD
*
rec
,
unsigned
int
iField
,
LPCWSTR
szFilename
)
{
IStream
*
stm
=
NULL
;
HRESULT
r
;
if
(
(
iField
==
0
)
||
(
iField
>
rec
->
count
)
)
return
ERROR_INVALID_PARAMETER
;
/* no filename means we should seek back to the start of the stream */
if
(
!
szFilename
)
{
LARGE_INTEGER
ofs
;
ULARGE_INTEGER
cur
;
if
(
rec
->
fields
[
iField
].
type
!=
MSIFIELD_STREAM
)
return
ERROR_INVALID_FIELD
;
stm
=
rec
->
fields
[
iField
].
u
.
stream
;
if
(
!
stm
)
return
ERROR_INVALID_FIELD
;
ofs
.
QuadPart
=
0
;
r
=
IStream_Seek
(
stm
,
ofs
,
STREAM_SEEK_SET
,
&
cur
);
if
(
FAILED
(
r
)
)
return
ERROR_FUNCTION_FAILED
;
}
else
{
/* read the file into a stream and save the stream in the record */
r
=
RECORD_StreamFromFile
(
szFilename
,
&
stm
);
if
(
r
!=
ERROR_SUCCESS
)
return
r
;
/* if all's good, store it in the record */
MSI_FreeField
(
&
rec
->
fields
[
iField
]
);
rec
->
fields
[
iField
].
type
=
MSIFIELD_STREAM
;
rec
->
fields
[
iField
].
u
.
stream
=
stm
;
}
return
ERROR_SUCCESS
;
}
UINT
WINAPI
MsiRecordSetStreamA
(
MSIHANDLE
hRecord
,
unsigned
int
iField
,
LPCSTR
szFilename
)
{
FIXME
(
"%ld %d %s
\n
"
,
hRecord
,
iField
,
debugstr_a
(
szFilename
));
return
ERROR_CALL_NOT_IMPLEMENTED
;
LPWSTR
wstr
=
NULL
;
UINT
ret
,
len
;
TRACE
(
"%ld %d %s
\n
"
,
hRecord
,
iField
,
debugstr_a
(
szFilename
));
if
(
szFilename
)
{
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
szFilename
,
-
1
,
NULL
,
0
);
wstr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
len
*
sizeof
(
WCHAR
));
MultiByteToWideChar
(
CP_ACP
,
0
,
szFilename
,
-
1
,
wstr
,
len
);
}
ret
=
MsiRecordSetStreamW
(
hRecord
,
iField
,
wstr
);
HeapFree
(
GetProcessHeap
(),
0
,
wstr
);
return
ret
;
}
UINT
WINAPI
MsiRecordSetStreamW
(
MSIHANDLE
h
Record
,
unsigned
int
iField
,
LPCWSTR
szFilename
)
UINT
WINAPI
MsiRecordSetStreamW
(
MSIHANDLE
h
andle
,
unsigned
int
iField
,
LPCWSTR
szFilename
)
{
FIXME
(
"%ld %d %s
\n
"
,
hRecord
,
iField
,
debugstr_w
(
szFilename
));
return
ERROR_CALL_NOT_IMPLEMENTED
;
MSIRECORD
*
rec
;
UINT
ret
;
TRACE
(
"%ld %d %s
\n
"
,
handle
,
iField
,
debugstr_w
(
szFilename
));
rec
=
msihandle2msiinfo
(
handle
,
MSIHANDLETYPE_RECORD
);
if
(
!
rec
)
return
ERROR_INVALID_HANDLE
;
msiobj_lock
(
&
rec
->
hdr
);
ret
=
MSI_RecordSetStreamW
(
rec
,
iField
,
szFilename
);
msiobj_unlock
(
&
rec
->
hdr
);
msiobj_release
(
&
rec
->
hdr
);
return
ret
;
}
UINT
MSI_RecordReadStream
(
MSIRECORD
*
rec
,
unsigned
int
iField
,
char
*
buf
,
DWORD
*
sz
)
...
...
@@ -551,18 +669,18 @@ UINT MSI_RecordReadStream(MSIRECORD *rec, unsigned int iField, char *buf, DWORD
TRACE
(
"%p %d %p %p
\n
"
,
rec
,
iField
,
buf
,
sz
);
if
(
iField
>
rec
->
count
)
return
ERROR_INVALID_FIELD
;
if
(
!
sz
)
return
ERROR_INVALID_PARAMETER
;
if
(
iField
>
rec
->
count
)
return
ERROR_INVALID_PARAMETER
;
if
(
rec
->
fields
[
iField
].
type
!=
MSIFIELD_STREAM
)
{
*
sz
=
0
;
return
ERROR_INVALID_FIELD
;
}
return
ERROR_INVALID_DATATYPE
;
stm
=
rec
->
fields
[
iField
].
u
.
stream
;
if
(
!
stm
)
return
ERROR_INVALID_
FIELD
;
return
ERROR_INVALID_
PARAMETER
;
/* if there's no buffer pointer, calculate the length to the end */
if
(
!
buf
)
...
...
dlls/msi/tests/record.c
View file @
921be0a8
...
...
@@ -24,6 +24,27 @@
#include "wine/test.h"
static
BOOL
create_temp_file
(
char
*
name
)
{
UINT
r
;
unsigned
char
buffer
[
26
],
i
;
DWORD
sz
;
HANDLE
handle
;
r
=
GetTempFileName
(
"."
,
"msitest"
,
0
,
name
);
if
(
!
r
)
return
r
;
handle
=
CreateFile
(
name
,
GENERIC_READ
|
GENERIC_WRITE
,
0
,
NULL
,
CREATE_ALWAYS
,
FILE_ATTRIBUTE_NORMAL
,
NULL
);
if
(
handle
==
INVALID_HANDLE_VALUE
)
return
0
;
for
(
i
=
0
;
i
<
26
;
i
++
)
buffer
[
i
]
=
i
+
'a'
;
r
=
WriteFile
(
handle
,
buffer
,
sizeof
buffer
,
&
sz
,
NULL
);
CloseHandle
(
handle
);
return
r
;
}
void
test_msirecord
(
void
)
{
DWORD
r
,
sz
;
...
...
@@ -31,6 +52,7 @@ void test_msirecord(void)
MSIHANDLE
h
;
char
buf
[
10
];
const
char
str
[]
=
"hello"
;
char
filename
[
MAX_PATH
];
/* check behaviour with an invalid record */
r
=
MsiRecordGetFieldCount
(
0
);
...
...
@@ -88,10 +110,8 @@ void test_msirecord(void)
r
=
MsiRecordSetInteger
(
h
,
0
,
1
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to set integer at 0 to 1
\n
"
);
r
=
MsiRecordSetInteger
(
h
,
1
,
1
);
/*printf("r = %d\n",r); */
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"set integer at 1
\n
"
);
r
=
MsiRecordSetInteger
(
h
,
-
1
,
0
);
/*printf("r = %d\n",r); */
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"set integer at -1
\n
"
);
r
=
MsiRecordIsNull
(
h
,
0
);
ok
(
r
==
0
,
"new record is null after setting an integer
\n
"
);
...
...
@@ -185,9 +205,75 @@ void test_msirecord(void)
ok
(
r
==
ERROR_SUCCESS
,
"failed to get string from integer
\n
"
);
ok
(
0
==
strcmp
(
buf
,
"-32"
),
"failed to get string from integer
\n
"
);
/* same record, now try streams */
r
=
MsiRecordSetStream
(
h
,
0
,
NULL
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"set NULL stream
\n
"
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
0
,
buf
,
&
sz
);
ok
(
r
==
ERROR_INVALID_DATATYPE
,
"read non-stream type
\n
"
);
ok
(
sz
==
sizeof
buf
,
"set sz
\n
"
);
/* same record, now close it */
r
=
MsiCloseHandle
(
h
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to close handle
\n
"
);
/* now try streams in a new record - need to create a file to play with */
r
=
create_temp_file
(
filename
);
if
(
!
r
)
return
;
/* streams can't be inserted in field 0 for some reason */
h
=
MsiCreateRecord
(
2
);
ok
(
h
,
"couldn't create a two field record
\n
"
);
r
=
MsiRecordSetStream
(
h
,
0
,
filename
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"added stream to field 0
\n
"
);
r
=
MsiRecordSetStream
(
h
,
1
,
filename
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to add stream to record
\n
"
);
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
NULL
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"should return error
\n
"
);
ok
(
DeleteFile
(
filename
),
"failed to delete stream temp file
\n
"
);
r
=
MsiRecordReadStream
(
h
,
1
,
NULL
,
NULL
);
ok
(
r
==
ERROR_INVALID_PARAMETER
,
"should return error
\n
"
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
1
,
NULL
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
26
,
"couldn't get size of stream"
);
sz
=
0
;
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
0
,
"short read"
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
sizeof
buf
,
"short read"
);
ok
(
!
strncmp
(
buf
,
"abcdefghij"
,
10
),
"read the wrong thing
\n
"
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
sizeof
buf
,
"short read"
);
ok
(
!
strncmp
(
buf
,
"klmnopqrst"
,
10
),
"read the wrong thing
\n
"
);
memset
(
buf
,
0
,
sizeof
buf
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
6
,
"short read"
);
ok
(
!
strcmp
(
buf
,
"uvwxyz"
),
"read the wrong thing
\n
"
);
memset
(
buf
,
0
,
sizeof
buf
);
sz
=
sizeof
buf
;
r
=
MsiRecordReadStream
(
h
,
1
,
buf
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to read stream
\n
"
);
ok
(
sz
==
0
,
"size non-zero at end of stream
\n
"
);
ok
(
buf
[
0
]
==
0
,
"read something at end of the stream
\n
"
);
r
=
MsiRecordSetStream
(
h
,
1
,
NULL
);
ok
(
r
==
ERROR_SUCCESS
,
"failed to reset stream
\n
"
);
sz
=
0
;
r
=
MsiRecordReadStream
(
h
,
1
,
NULL
,
&
sz
);
ok
(
r
==
ERROR_SUCCESS
,
"bytes left wrong after reset
\n
"
);
ok
(
sz
==
26
,
"couldn't get size of stream
\n
"
);
/* now close the stream record */
r
=
MsiCloseHandle
(
h
);
ok
(
r
==
ERROR_SUCCESS
,
"Failed to close handle
\n
"
);
}
START_TEST
(
record
)
...
...
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