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
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
Show 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