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
696f73a7
Commit
696f73a7
authored
May 05, 2006
by
Huw Davies
Committed by
Alexandre Julliard
May 07, 2006
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Rewrite VARIANT user marshaling.
parent
b2c4b2cf
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
934 additions
and
192 deletions
+934
-192
usrmarshal.c
dlls/oleaut32/tests/usrmarshal.c
+668
-1
usrmarshal.c
dlls/oleaut32/usrmarshal.c
+266
-191
No files found.
dlls/oleaut32/tests/usrmarshal.c
View file @
696f73a7
...
...
@@ -31,6 +31,7 @@
* MIDL_STUB_MESSAGE structure to be filled out */
#define LPSAFEARRAY_UNMARSHAL_WORKS 0
#define BSTR_UNMARSHAL_WORKS 0
#define VARIANT_UNMARSHAL_WORKS 0
static
inline
SF_TYPE
get_union_type
(
SAFEARRAY
*
psa
)
{
...
...
@@ -126,7 +127,7 @@ static void check_safearray(void *buffer, LPSAFEARRAY lpsa)
wiresa
+=
sizeof
(
DWORD
);
ok
(
*
(
DWORD
*
)
wiresa
==
cell_count
,
"wiresa + 0x1c should be %lu instead of %lu
\n
"
,
cell_count
,
*
(
DWORD
*
)
wiresa
);
wiresa
+=
sizeof
(
DWORD
);
ok
(
*
(
DWORD_PTR
*
)
wiresa
==
(
DWORD_PTR
)
lpsa
->
pvData
,
"wires
tgm
+ 0x20 should be lpsa->pvData instead of 0x%08lx
\n
"
,
*
(
DWORD_PTR
*
)
wiresa
);
ok
(
*
(
DWORD_PTR
*
)
wiresa
==
(
DWORD_PTR
)
lpsa
->
pvData
,
"wires
a
+ 0x20 should be lpsa->pvData instead of 0x%08lx
\n
"
,
*
(
DWORD_PTR
*
)
wiresa
);
wiresa
+=
sizeof
(
DWORD_PTR
);
if
(
sftype
==
SF_HAVEIID
)
{
...
...
@@ -175,8 +176,14 @@ static void test_marshal_LPSAFEARRAY(void)
if
(
LPSAFEARRAY_UNMARSHAL_WORKS
)
{
VARTYPE
vt
,
vt2
;
LPSAFEARRAY_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
lpsa2
);
ok
(
lpsa2
!=
NULL
,
"LPSAFEARRAY didn't unmarshal
\n
"
);
SafeArrayGetVartype
(
lpsa
,
&
vt
);
SafeArrayGetVartype
(
lpsa2
,
&
vt2
);
todo_wine
{
ok
(
vt
==
vt2
,
"vts differ %x %x
\n
"
,
vt
,
vt2
);
}
LPSAFEARRAY_UserFree
(
&
umcb
.
Flags
,
&
lpsa2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
...
...
@@ -293,12 +300,672 @@ static void test_marshal_BSTR(void)
}
static
void
check_variant_header
(
DWORD
*
wirev
,
VARIANT
*
v
,
unsigned
long
size
)
{
WORD
*
wp
;
DWORD
switch_is
;
ok
(
*
wirev
==
(
size
+
7
)
>>
3
,
"wv[0] %08lx, expected %08lx
\n
"
,
*
wirev
,
(
size
+
7
)
>>
3
);
wirev
++
;
ok
(
*
wirev
==
0
,
"wv[1] %08lx
\n
"
,
*
wirev
);
wirev
++
;
wp
=
(
WORD
*
)
wirev
;
ok
(
*
wp
==
V_VT
(
v
),
"vt %04x expected %04x
\n
"
,
*
wp
,
V_VT
(
v
));
wp
++
;
ok
(
*
wp
==
v
->
n1
.
n2
.
wReserved1
,
"res1 %04x expected %04x
\n
"
,
*
wp
,
v
->
n1
.
n2
.
wReserved1
);
wp
++
;
ok
(
*
wp
==
v
->
n1
.
n2
.
wReserved2
,
"res2 %04x expected %04x
\n
"
,
*
wp
,
v
->
n1
.
n2
.
wReserved2
);
wp
++
;
ok
(
*
wp
==
v
->
n1
.
n2
.
wReserved3
,
"res3 %04x expected %04x
\n
"
,
*
wp
,
v
->
n1
.
n2
.
wReserved3
);
wp
++
;
wirev
=
(
DWORD
*
)
wp
;
switch_is
=
V_VT
(
v
);
if
(
switch_is
&
VT_ARRAY
)
switch_is
&=
~
VT_TYPEMASK
;
ok
(
*
wirev
==
switch_is
,
"switch_is %08lx expected %08lx
\n
"
,
*
wirev
,
switch_is
);
}
static
void
test_marshal_VARIANT
(
void
)
{
unsigned
long
size
;
VARIANT
v
,
v2
;
MIDL_STUB_MESSAGE
stubMsg
=
{
0
};
USER_MARSHAL_CB
umcb
=
{
0
};
unsigned
char
*
buffer
,
*
next
;
unsigned
long
ul
;
short
s
;
double
d
;
DWORD
*
wirev
;
BSTR
b
;
WCHAR
str
[]
=
{
'm'
,
'a'
,
'r'
,
's'
,
'h'
,
'a'
,
'l'
,
' '
,
't'
,
'e'
,
's'
,
't'
,
0
};
SAFEARRAYBOUND
sab
;
LPSAFEARRAY
lpsa
;
DECIMAL
dec
,
dec2
;
umcb
.
Flags
=
MAKELONG
(
MSHCTX_DIFFERENTMACHINE
,
NDR_LOCAL_DATA_REPRESENTATION
);
umcb
.
pReserve
=
NULL
;
umcb
.
pStubMsg
=
&
stubMsg
;
/*** I1 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_I1
;
V_I1
(
&
v
)
=
0x12
;
/* Variants have an alignment of 8 */
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
1
,
&
v
);
ok
(
size
==
29
,
"size %ld
\n
"
,
size
);
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
21
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
(
char
*
)
wirev
==
V_I1
(
&
v
),
"wv[5] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_I1
(
&
v
)
==
V_I1
(
&
v2
),
"got i1 %x expect %x
\n
"
,
V_I1
(
&
v
),
V_I1
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** I2 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_I2
;
V_I2
(
&
v
)
=
0x1234
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
22
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
(
short
*
)
wirev
==
V_I2
(
&
v
),
"wv[5] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_I2
(
&
v
)
==
V_I2
(
&
v2
),
"got i2 %x expect %x
\n
"
,
V_I2
(
&
v
),
V_I2
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** I2 BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_I2
|
VT_BYREF
;
s
=
0x1234
;
V_I2REF
(
&
v
)
=
&
s
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
26
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0x4
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
(
short
*
)
wirev
==
s
,
"wv[6] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
*
V_I2REF
(
&
v
)
==
*
V_I2REF
(
&
v2
),
"got i2 ref %x expect ui4 ref %x
\n
"
,
*
V_I2REF
(
&
v
),
*
V_I2REF
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** I4 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_I4
;
V_I4
(
&
v
)
=
0x1234
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
24
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
V_I4
(
&
v
),
"wv[5] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_I4
(
&
v
)
==
V_I4
(
&
v2
),
"got i4 %lx expect %lx
\n
"
,
V_I4
(
&
v
),
V_I4
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** UI4 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_UI4
;
V_UI4
(
&
v
)
=
0x1234
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
24
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0x1234
,
"wv[5] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_UI4
(
&
v
)
==
V_UI4
(
&
v2
),
"got ui4 %lx expect %lx
\n
"
,
V_UI4
(
&
v
),
V_UI4
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** UI4 BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_UI4
|
VT_BYREF
;
ul
=
0x1234
;
V_UI4REF
(
&
v
)
=
&
ul
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
28
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0x4
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
wirev
==
ul
,
"wv[6] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
*
V_UI4REF
(
&
v
)
==
*
V_UI4REF
(
&
v2
),
"got ui4 ref %lx expect ui4 ref %lx
\n
"
,
*
V_UI4REF
(
&
v
),
*
V_UI4REF
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** R4 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_R4
;
V_R8
(
&
v
)
=
3
.
1415
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
24
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
(
float
*
)
wirev
==
V_R4
(
&
v
),
"wv[5] %08lx
\n
"
,
*
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_R4
(
&
v
)
==
V_R4
(
&
v2
),
"got r4 %f expect %f
\n
"
,
V_R4
(
&
v
),
V_R4
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** R8 ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_R8
;
V_R8
(
&
v
)
=
3
.
1415
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
32
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
memset
(
buffer
,
0xcc
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0xcccccccc
,
"wv[5] %08lx
\n
"
,
*
wirev
);
/* pad */
wirev
++
;
ok
(
*
(
double
*
)
wirev
==
V_R8
(
&
v
),
"wv[6] %08lx, wv[7] %08lx
\n
"
,
*
wirev
,
*
(
wirev
+
1
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_R8
(
&
v
)
==
V_R8
(
&
v2
),
"got r8 %f expect %f
\n
"
,
V_R8
(
&
v
),
V_R8
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** R8 BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_R8
|
VT_BYREF
;
d
=
3
.
1415
;
V_R8REF
(
&
v
)
=
&
d
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
32
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
8
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
(
double
*
)
wirev
==
d
,
"wv[6] %08lx wv[7] %08lx
\n
"
,
*
wirev
,
*
(
wirev
+
1
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
*
V_R8REF
(
&
v
)
==
*
V_R8REF
(
&
v2
),
"got r8 ref %f expect %f
\n
"
,
*
V_R8REF
(
&
v
),
*
V_R8REF
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** VARIANT_BOOL ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_BOOL
;
V_BOOL
(
&
v
)
=
0x1234
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
22
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
(
short
*
)
wirev
==
V_BOOL
(
&
v
),
"wv[5] %04x
\n
"
,
*
(
WORD
*
)
wirev
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
V_BOOL
(
&
v
)
==
V_BOOL
(
&
v2
),
"got bool %x expect %x
\n
"
,
V_BOOL
(
&
v
),
V_BOOL
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** DECIMAL ***/
VarDecFromI4
(
0x12345678
,
&
dec
);
VariantInit
(
&
v
);
V_DECIMAL
(
&
v
)
=
dec
;
V_VT
(
&
v
)
=
VT_DECIMAL
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
40
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
memset
(
buffer
,
0xcc
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0xcccccccc
,
"wirev[5] %08lx
\n
"
,
*
wirev
);
/* pad */
wirev
++
;
dec2
=
dec
;
dec2
.
wReserved
=
VT_DECIMAL
;
ok
(
!
memcmp
(
wirev
,
&
dec2
,
sizeof
(
dec2
)),
"wirev[6] %08lx wirev[7] %08lx wirev[8] %08lx wirev[9] %08lx
\n
"
,
*
wirev
,
*
(
wirev
+
1
),
*
(
wirev
+
2
),
*
(
wirev
+
3
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
!
memcmp
(
&
V_DECIMAL
(
&
v
),
&
V_DECIMAL
(
&
v2
),
sizeof
(
DECIMAL
)),
"decimals differ
\n
"
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** DECIMAL BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_DECIMAL
|
VT_BYREF
;
V_DECIMALREF
(
&
v
)
=
&
dec
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
40
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
16
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
!
memcmp
(
wirev
,
&
dec
,
sizeof
(
dec
)),
"wirev[6] %08lx wirev[7] %08lx wirev[8] %08lx wirev[9] %08lx
\n
"
,
*
wirev
,
*
(
wirev
+
1
),
*
(
wirev
+
2
),
*
(
wirev
+
3
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
!
memcmp
(
V_DECIMALREF
(
&
v
),
V_DECIMALREF
(
&
v2
),
sizeof
(
DECIMAL
)),
"decimals differ
\n
"
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** EMPTY ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_EMPTY
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
20
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** NULL ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_NULL
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
20
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** BSTR ***/
b
=
SysAllocString
(
str
);
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_BSTR
;
V_BSTR
(
&
v
)
=
b
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
60
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
,
"wv[5] %08lx
\n
"
,
*
wirev
);
/* win2k: this is b. winxp: this is (char*)b + 1 */
wirev
++
;
check_bstr
(
wirev
,
V_BSTR
(
&
v
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
SysStringByteLen
(
V_BSTR
(
&
v
))
==
SysStringByteLen
(
V_BSTR
(
&
v2
)),
"bstr string lens differ
\n
"
);
ok
(
!
memcmp
(
V_BSTR
(
&
v
),
V_BSTR
(
&
v2
),
SysStringByteLen
(
V_BSTR
(
&
v
))),
"bstrs differ
\n
"
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** BSTR BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_BSTR
|
VT_BYREF
;
V_BSTRREF
(
&
v
)
=
&
b
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
64
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
0x4
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
wirev
,
"wv[6] %08lx
\n
"
,
*
wirev
);
/* win2k: this is b. winxp: this is (char*)b + 1 */
wirev
++
;
check_bstr
(
wirev
,
b
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
SysStringByteLen
(
*
V_BSTRREF
(
&
v
))
==
SysStringByteLen
(
*
V_BSTRREF
(
&
v2
)),
"bstr string lens differ
\n
"
);
ok
(
!
memcmp
(
*
V_BSTRREF
(
&
v
),
*
V_BSTRREF
(
&
v2
),
SysStringByteLen
(
*
V_BSTRREF
(
&
v
))),
"bstrs differ
\n
"
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
SysFreeString
(
b
);
/*** ARRAY ***/
sab
.
lLbound
=
5
;
sab
.
cElements
=
10
;
lpsa
=
SafeArrayCreate
(
VT_R8
,
1
,
&
sab
);
*
(
DWORD
*
)
lpsa
->
pvData
=
0xcafebabe
;
*
((
DWORD
*
)
lpsa
->
pvData
+
1
)
=
0xdeadbeef
;
lpsa
->
cLocks
=
7
;
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_UI4
|
VT_ARRAY
;
V_ARRAY
(
&
v
)
=
lpsa
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
152
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
,
"wv[5] %08lx
\n
"
,
*
wirev
);
/* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
wirev
++
;
check_safearray
(
wirev
,
lpsa
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
long
bound
,
bound2
;
VARTYPE
vt
,
vt2
;
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
SafeArrayGetDim
(
V_ARRAY
(
&
v
))
==
SafeArrayGetDim
(
V_ARRAY
(
&
v
)),
"array dims differ
\n
"
);
SafeArrayGetLBound
(
V_ARRAY
(
&
v
),
1
,
&
bound
);
SafeArrayGetLBound
(
V_ARRAY
(
&
v2
),
1
,
&
bound2
);
ok
(
bound
==
bound2
,
"array lbounds differ
\n
"
);
SafeArrayGetUBound
(
V_ARRAY
(
&
v
),
1
,
&
bound
);
SafeArrayGetUBound
(
V_ARRAY
(
&
v2
),
1
,
&
bound2
);
ok
(
bound
==
bound2
,
"array ubounds differ
\n
"
);
SafeArrayGetVartype
(
V_ARRAY
(
&
v
),
&
vt
);
SafeArrayGetVartype
(
V_ARRAY
(
&
v2
),
&
vt2
);
todo_wine
{
ok
(
vt
==
vt2
,
"array vts differ %x %x
\n
"
,
vt
,
vt2
);
}
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
/*** ARRAY BYREF ***/
VariantInit
(
&
v
);
V_VT
(
&
v
)
=
VT_UI4
|
VT_ARRAY
|
VT_BYREF
;
V_ARRAYREF
(
&
v
)
=
&
lpsa
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
152
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
4
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
wirev
,
"wv[6] %08lx
\n
"
,
*
wirev
);
/* win2k: this is lpsa. winxp: this is (char*)lpsa + 1 */
wirev
++
;
check_safearray
(
wirev
,
lpsa
);
if
(
VARIANT_UNMARSHAL_WORKS
)
{
long
bound
,
bound2
;
VARTYPE
vt
,
vt2
;
VariantInit
(
&
v2
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v2
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v2
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v2
));
ok
(
SafeArrayGetDim
(
*
V_ARRAYREF
(
&
v
))
==
SafeArrayGetDim
(
*
V_ARRAYREF
(
&
v
)),
"array dims differ
\n
"
);
SafeArrayGetLBound
(
*
V_ARRAYREF
(
&
v
),
1
,
&
bound
);
SafeArrayGetLBound
(
*
V_ARRAYREF
(
&
v2
),
1
,
&
bound2
);
ok
(
bound
==
bound2
,
"array lbounds differ
\n
"
);
SafeArrayGetUBound
(
*
V_ARRAYREF
(
&
v
),
1
,
&
bound
);
SafeArrayGetUBound
(
*
V_ARRAYREF
(
&
v2
),
1
,
&
bound2
);
ok
(
bound
==
bound2
,
"array ubounds differ
\n
"
);
SafeArrayGetVartype
(
*
V_ARRAYREF
(
&
v
),
&
vt
);
SafeArrayGetVartype
(
*
V_ARRAYREF
(
&
v2
),
&
vt2
);
ok
(
vt
==
vt2
,
"array vts differ %x %x
\n
"
,
vt
,
vt2
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v2
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
SafeArrayDestroy
(
lpsa
);
/*** VARIANT BYREF ***/
VariantInit
(
&
v
);
VariantInit
(
&
v2
);
V_VT
(
&
v2
)
=
VT_R8
;
V_R8
(
&
v2
)
=
3
.
1415
;
V_VT
(
&
v
)
=
VT_VARIANT
|
VT_BYREF
;
V_VARIANTREF
(
&
v
)
=
&
v2
;
size
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
size
==
64
,
"size %ld
\n
"
,
size
);
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
memset
(
buffer
,
0xcc
,
size
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
wirev
=
(
DWORD
*
)
buffer
;
check_variant_header
(
wirev
,
&
v
,
size
);
wirev
+=
5
;
ok
(
*
wirev
==
16
,
"wv[5] %08lx
\n
"
,
*
wirev
);
wirev
++
;
ok
(
*
wirev
==
(
'U'
|
's'
<<
8
|
'e'
<<
16
|
'r'
<<
24
),
"wv[6] %08lx
\n
"
,
*
wirev
);
/* 'User' */
wirev
++
;
ok
(
*
wirev
==
0xcccccccc
,
"wv[7] %08lx
\n
"
,
*
wirev
);
/* pad */
wirev
++
;
check_variant_header
(
wirev
,
&
v2
,
size
-
32
);
wirev
+=
5
;
ok
(
*
wirev
==
0xcccccccc
,
"wv[13] %08lx
\n
"
,
*
wirev
);
/* pad for VT_R8 */
wirev
++
;
ok
(
*
(
double
*
)
wirev
==
V_R8
(
&
v2
),
"wv[6] %08lx wv[7] %08lx
\n
"
,
*
wirev
,
*
(
wirev
+
1
));
if
(
VARIANT_UNMARSHAL_WORKS
)
{
VARIANT
v3
;
VariantInit
(
&
v3
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v3
);
ok
(
next
==
buffer
+
size
,
"got %p expect %p
\n
"
,
next
,
buffer
+
size
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v3
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v3
));
ok
(
V_VT
(
V_VARIANTREF
(
&
v
))
==
V_VT
(
V_VARIANTREF
(
&
v3
)),
"vts differ %x %x
\n
"
,
V_VT
(
V_VARIANTREF
(
&
v
)),
V_VT
(
V_VARIANTREF
(
&
v3
)));
ok
(
V_R8
(
V_VARIANTREF
(
&
v
))
==
V_R8
(
V_VARIANTREF
(
&
v3
)),
"r8s differ
\n
"
);
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v3
);
}
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
}
START_TEST
(
usrmarshal
)
{
CoInitialize
(
NULL
);
test_marshal_LPSAFEARRAY
();
test_marshal_BSTR
();
test_marshal_VARIANT
();
CoUninitialize
();
}
dlls/oleaut32/usrmarshal.c
View file @
696f73a7
...
...
@@ -210,55 +210,73 @@ void WINAPI BSTR_UserFree(unsigned long *pFlags, BSTR *pstr)
}
/* VARIANT */
/* I'm not too sure how to do this yet */
#define VARIANT_wiresize sizeof(struct _wireVARIANT)
typedef
struct
{
DWORD
clSize
;
DWORD
rpcReserverd
;
USHORT
vt
;
USHORT
wReserved1
;
USHORT
wReserved2
;
USHORT
wReserved3
;
DWORD
switch_is
;
}
variant_wire_t
;
static
unsigned
wire_size
(
VARTYPE
vt
)
static
unsigned
int
get_type_size
(
unsigned
long
*
pFlags
,
VARIANT
*
pvar
)
{
if
(
vt
&
VT_ARRAY
)
return
0
;
if
(
V_VT
(
pvar
)
&
VT_ARRAY
)
return
4
;
switch
(
vt
&
~
VT_BYREF
)
{
case
VT_EMPTY
:
case
VT_NULL
:
return
0
;
case
VT_I1
:
case
VT_UI1
:
return
sizeof
(
CHAR
);
case
VT_I2
:
case
VT_UI2
:
return
sizeof
(
SHORT
);
case
VT_I4
:
case
VT_UI4
:
return
sizeof
(
LONG
);
case
VT_INT
:
case
VT_UINT
:
return
sizeof
(
INT
);
case
VT_R4
:
return
sizeof
(
FLOAT
);
case
VT_R8
:
return
sizeof
(
DOUBLE
);
case
VT_BOOL
:
return
sizeof
(
VARIANT_BOOL
);
case
VT_ERROR
:
return
sizeof
(
SCODE
);
case
VT_DATE
:
return
sizeof
(
DATE
);
case
VT_CY
:
return
sizeof
(
CY
);
case
VT_DECIMAL
:
return
sizeof
(
DECIMAL
);
case
VT_BSTR
:
case
VT_VARIANT
:
case
VT_UNKNOWN
:
case
VT_DISPATCH
:
case
VT_SAFEARRAY
:
case
VT_RECORD
:
return
0
;
default:
FIXME
(
"unhandled VT %d
\n
"
,
vt
);
return
0
;
}
switch
(
V_VT
(
pvar
)
&
~
VT_BYREF
)
{
case
VT_EMPTY
:
case
VT_NULL
:
return
0
;
case
VT_I1
:
case
VT_UI1
:
return
sizeof
(
CHAR
);
case
VT_I2
:
case
VT_UI2
:
return
sizeof
(
SHORT
);
case
VT_I4
:
case
VT_UI4
:
return
sizeof
(
LONG
);
case
VT_INT
:
case
VT_UINT
:
return
sizeof
(
INT
);
case
VT_R4
:
return
sizeof
(
FLOAT
);
case
VT_R8
:
return
sizeof
(
DOUBLE
);
case
VT_BOOL
:
return
sizeof
(
VARIANT_BOOL
);
case
VT_ERROR
:
return
sizeof
(
SCODE
);
case
VT_DATE
:
return
sizeof
(
DATE
);
case
VT_CY
:
return
sizeof
(
CY
);
case
VT_DECIMAL
:
return
sizeof
(
DECIMAL
);
case
VT_BSTR
:
return
sizeof
(
BSTR
);
case
VT_VARIANT
:
return
sizeof
(
VARIANT
);
case
VT_UNKNOWN
:
case
VT_DISPATCH
:
case
VT_RECORD
:
return
0
;
default:
FIXME
(
"unhandled VT %d
\n
"
,
V_VT
(
pvar
));
return
0
;
}
}
static
unsigned
int
get_type_alignment
(
unsigned
long
*
pFlags
,
VARIANT
*
pvar
)
{
unsigned
int
size
=
get_type_size
(
pFlags
,
pvar
);
if
(
V_VT
(
pvar
)
&
VT_BYREF
)
return
3
;
if
(
size
==
0
)
return
0
;
if
(
size
<=
4
)
return
size
-
1
;
return
7
;
}
static
unsigned
interface_variant_size
(
unsigned
long
*
pFlags
,
REFIID
riid
,
VARIANT
*
pvar
)
...
...
@@ -279,32 +297,36 @@ static unsigned interface_variant_size(unsigned long *pFlags, REFIID riid, VARIA
return
size
;
}
static
unsigned
wire_extra
(
unsigned
long
*
pFlags
,
VARIANT
*
pvar
)
static
unsigned
long
wire_extra_user_size
(
unsigned
long
*
pFlags
,
unsigned
long
Start
,
VARIANT
*
pvar
)
{
if
(
V_ISARRAY
(
pvar
))
{
FIXME
(
"wire-size safearray
\n
"
);
return
0
;
if
(
V_ISARRAY
(
pvar
))
{
if
(
V_ISBYREF
(
pvar
))
return
LPSAFEARRAY_UserSize
(
pFlags
,
Start
,
V_ARRAYREF
(
pvar
));
else
return
LPSAFEARRAY_UserSize
(
pFlags
,
Start
,
&
V_ARRAY
(
pvar
));
}
switch
(
V_VT
(
pvar
))
{
case
VT_BSTR
:
return
BSTR_UserSize
(
pFlags
,
0
,
&
V_BSTR
(
pvar
));
return
BSTR_UserSize
(
pFlags
,
Start
,
&
V_BSTR
(
pvar
));
case
VT_BSTR
|
VT_BYREF
:
return
BSTR_UserSize
(
pFlags
,
0
,
V_BSTRREF
(
pvar
));
case
VT_SAFEARRAY
:
case
VT_SAFEARRAY
|
VT_BYREF
:
FIXME
(
"wire-size safearray
\n
"
);
return
0
;
return
BSTR_UserSize
(
pFlags
,
Start
,
V_BSTRREF
(
pvar
));
case
VT_VARIANT
|
VT_BYREF
:
return
VARIANT_UserSize
(
pFlags
,
0
,
V_VARIANTREF
(
pvar
));
return
VARIANT_UserSize
(
pFlags
,
Start
,
V_VARIANTREF
(
pvar
));
case
VT_UNKNOWN
:
return
interface_variant_size
(
pFlags
,
&
IID_IUnknown
,
pvar
);
return
Start
+
interface_variant_size
(
pFlags
,
&
IID_IUnknown
,
pvar
);
case
VT_DISPATCH
:
return
interface_variant_size
(
pFlags
,
&
IID_IDispatch
,
pvar
);
return
Start
+
interface_variant_size
(
pFlags
,
&
IID_IDispatch
,
pvar
);
case
VT_RECORD
:
FIXME
(
"wire-size record
\n
"
);
return
0
;
return
Start
;
case
VT_SAFEARRAY
:
case
VT_SAFEARRAY
|
VT_BYREF
:
FIXME
(
"wire-size safearray: shouldn't be marshaling this
\n
"
);
return
Start
;
default:
return
0
;
return
Start
;
}
}
...
...
@@ -328,7 +350,7 @@ static unsigned char* interface_variant_marshal(unsigned long *pFlags, unsigned
* but that would be overkill here, hence this implementation. We save the size because the unmarshal
* code has no way to know how long the marshalled buffer is. */
size
=
wire_extra
(
pFlags
,
pvar
);
size
=
wire_extra
_user_size
(
pFlags
,
0
,
pvar
);
working_mem
=
GlobalAlloc
(
0
,
size
);
if
(
!
working_mem
)
return
oldpos
;
...
...
@@ -347,7 +369,7 @@ static unsigned char* interface_variant_marshal(unsigned long *pFlags, unsigned
working_memlocked
=
GlobalLock
(
working_mem
);
memcpy
(
Buffer
,
&
size
,
sizeof
(
ULONG
));
/* copy the buffersize */
memcpy
(
Buffer
+
sizeof
(
ULONG
),
working_memlocked
,
size
);
memcpy
(
Buffer
+
sizeof
(
ULONG
),
working_memlocked
,
size
-
sizeof
(
ULONG
)
);
GlobalUnlock
(
working_mem
);
IStream_Release
(
working
);
...
...
@@ -406,156 +428,209 @@ static unsigned char *interface_variant_unmarshal(unsigned long *pFlags, unsigne
unsigned
long
WINAPI
VARIANT_UserSize
(
unsigned
long
*
pFlags
,
unsigned
long
Start
,
VARIANT
*
pvar
)
{
TRACE
(
"(%lx,%ld,%p)
\n
"
,
*
pFlags
,
Start
,
pvar
);
TRACE
(
"vt=%04x
\n
"
,
V_VT
(
pvar
));
Start
+=
VARIANT_wiresize
+
wire_extra
(
pFlags
,
pvar
);
TRACE
(
"returning %ld
\n
"
,
Start
);
return
Start
;
int
align
;
TRACE
(
"(%lx,%ld,%p)
\n
"
,
*
pFlags
,
Start
,
pvar
);
TRACE
(
"vt=%04x
\n
"
,
V_VT
(
pvar
));
ALIGN_LENGTH
(
Start
,
7
);
Start
+=
sizeof
(
variant_wire_t
);
if
(
V_VT
(
pvar
)
&
VT_BYREF
)
Start
+=
4
;
align
=
get_type_alignment
(
pFlags
,
pvar
);
ALIGN_LENGTH
(
Start
,
align
);
if
(
V_VT
(
pvar
)
==
(
VT_VARIANT
|
VT_BYREF
))
Start
+=
4
;
else
Start
+=
get_type_size
(
pFlags
,
pvar
);
Start
=
wire_extra_user_size
(
pFlags
,
Start
,
pvar
);
TRACE
(
"returning %ld
\n
"
,
Start
);
return
Start
;
}
unsigned
char
*
WINAPI
VARIANT_UserMarshal
(
unsigned
long
*
pFlags
,
unsigned
char
*
Buffer
,
VARIANT
*
pvar
)
{
wireVARIANT
var
=
(
wireVARIANT
)
Buffer
;
unsigned
size
,
extra
;
unsigned
char
*
Pos
=
Buffer
+
VARIANT_wiresize
;
variant_wire_t
*
header
;
unsigned
long
type_size
;
int
align
;
unsigned
char
*
Pos
;
TRACE
(
"(%lx,%p,%p)
\n
"
,
*
pFlags
,
Buffer
,
pvar
);
TRACE
(
"vt=%04x
\n
"
,
V_VT
(
pvar
));
TRACE
(
"(%lx,%p,%p)
\n
"
,
*
pFlags
,
Buffer
,
pvar
);
TRACE
(
"vt=%04x
\n
"
,
V_VT
(
pvar
));
memset
(
var
,
0
,
sizeof
(
*
var
));
var
->
clSize
=
sizeof
(
*
var
);
var
->
vt
=
pvar
->
n1
.
n2
.
vt
;
ALIGN_POINTER
(
Buffer
,
7
);
var
->
rpcReserved
=
var
->
vt
;
if
((
var
->
vt
&
VT_ARRAY
)
||
((
var
->
vt
&
VT_TYPEMASK
)
==
VT_SAFEARRAY
))
var
->
vt
=
VT_ARRAY
|
(
var
->
vt
&
VT_BYREF
);
header
=
(
variant_wire_t
*
)
Buffer
;
if
(
var
->
vt
==
VT_DECIMAL
)
{
/* special case because decVal is on a different level */
var
->
u
.
decVal
=
pvar
->
n1
.
decVal
;
return
Pos
;
}
header
->
clSize
=
0
;
/* fixed up at the end */
header
->
rpcReserverd
=
0
;
header
->
vt
=
pvar
->
n1
.
n2
.
vt
;
header
->
wReserved1
=
pvar
->
n1
.
n2
.
wReserved1
;
header
->
wReserved2
=
pvar
->
n1
.
n2
.
wReserved2
;
header
->
wReserved3
=
pvar
->
n1
.
n2
.
wReserved3
;
header
->
switch_is
=
pvar
->
n1
.
n2
.
vt
;
if
(
header
->
switch_is
&
VT_ARRAY
)
header
->
switch_is
&=
~
VT_TYPEMASK
;
size
=
wire_size
(
V_VT
(
pvar
));
extra
=
wire_extra
(
pFlags
,
pvar
);
var
->
wReserved1
=
pvar
->
n1
.
n2
.
wReserved1
;
var
->
wReserved2
=
pvar
->
n1
.
n2
.
wReserved2
;
var
->
wReserved3
=
pvar
->
n1
.
n2
.
wReserved3
;
if
(
size
)
{
if
(
var
->
vt
&
VT_BYREF
)
memcpy
(
&
var
->
u
.
cVal
,
pvar
->
n1
.
n2
.
n3
.
byref
,
size
);
Pos
=
(
unsigned
char
*
)(
header
+
1
);
type_size
=
get_type_size
(
pFlags
,
pvar
);
align
=
get_type_alignment
(
pFlags
,
pvar
);
ALIGN_POINTER
(
Pos
,
align
);
if
(
header
->
vt
&
VT_BYREF
)
{
*
(
DWORD
*
)
Pos
=
max
(
type_size
,
4
);
Pos
+=
4
;
if
((
header
->
vt
&
VT_TYPEMASK
)
!=
VT_VARIANT
)
{
memcpy
(
Pos
,
pvar
->
n1
.
n2
.
n3
.
byref
,
type_size
);
Pos
+=
type_size
;
}
else
{
*
(
DWORD
*
)
Pos
=
'U'
|
's'
<<
8
|
'e'
<<
16
|
'r'
<<
24
;
Pos
+=
4
;
}
}
else
memcpy
(
&
var
->
u
.
cVal
,
&
pvar
->
n1
.
n2
.
n3
,
size
);
}
if
(
!
extra
)
return
Pos
;
{
if
((
header
->
vt
&
VT_TYPEMASK
)
==
VT_DECIMAL
)
memcpy
(
Pos
,
pvar
,
type_size
);
else
memcpy
(
Pos
,
&
pvar
->
n1
.
n2
.
n3
,
type_size
);
Pos
+=
type_size
;
}
switch
(
var
->
vt
)
{
case
VT_BSTR
:
Pos
=
BSTR_UserMarshal
(
pFlags
,
Pos
,
&
V_BSTR
(
pvar
));
break
;
case
VT_BSTR
|
VT_BYREF
:
Pos
=
BSTR_UserMarshal
(
pFlags
,
Pos
,
V_BSTRREF
(
pvar
));
break
;
case
VT_VARIANT
|
VT_BYREF
:
Pos
=
VARIANT_UserMarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_DISPATCH
|
VT_BYREF
:
FIXME
(
"handle DISPATCH by ref
\n
"
);
break
;
case
VT_UNKNOWN
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
pvar
);
break
;
case
VT_DISPATCH
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
pvar
);
break
;
case
VT_RECORD
:
FIXME
(
"handle BRECORD by val
\n
"
);
break
;
case
VT_RECORD
|
VT_BYREF
:
FIXME
(
"handle BRECORD by ref
\n
"
);
break
;
default:
FIXME
(
"handle unknown complex type
\n
"
);
break
;
}
var
->
clSize
=
Pos
-
Buffer
;
TRACE
(
"marshalled size=%ld
\n
"
,
var
->
clSize
);
return
Pos
;
if
(
header
->
vt
&
VT_ARRAY
)
{
if
(
header
->
vt
&
VT_BYREF
)
Pos
=
LPSAFEARRAY_UserMarshal
(
pFlags
,
Pos
,
V_ARRAYREF
(
pvar
));
else
Pos
=
LPSAFEARRAY_UserMarshal
(
pFlags
,
Pos
,
&
V_ARRAY
(
pvar
));
}
else
{
switch
(
header
->
vt
)
{
case
VT_BSTR
:
Pos
=
BSTR_UserMarshal
(
pFlags
,
Pos
,
&
V_BSTR
(
pvar
));
break
;
case
VT_BSTR
|
VT_BYREF
:
Pos
=
BSTR_UserMarshal
(
pFlags
,
Pos
,
V_BSTRREF
(
pvar
));
break
;
case
VT_VARIANT
|
VT_BYREF
:
Pos
=
VARIANT_UserMarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_DISPATCH
|
VT_BYREF
:
FIXME
(
"handle DISPATCH by ref
\n
"
);
break
;
case
VT_UNKNOWN
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
pvar
);
break
;
case
VT_DISPATCH
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
pvar
);
break
;
case
VT_RECORD
:
FIXME
(
"handle BRECORD by val
\n
"
);
break
;
case
VT_RECORD
|
VT_BYREF
:
FIXME
(
"handle BRECORD by ref
\n
"
);
break
;
}
}
header
->
clSize
=
((
Pos
-
Buffer
)
+
7
)
>>
3
;
TRACE
(
"marshalled size=%ld
\n
"
,
header
->
clSize
);
return
Pos
;
}
unsigned
char
*
WINAPI
VARIANT_UserUnmarshal
(
unsigned
long
*
pFlags
,
unsigned
char
*
Buffer
,
VARIANT
*
pvar
)
{
wireVARIANT
var
=
(
wireVARIANT
)
Buffer
;
unsigned
size
;
unsigned
char
*
Pos
=
Buffer
+
VARIANT_wiresize
;
variant_wire_t
*
header
;
unsigned
long
type_size
;
int
align
;
unsigned
char
*
Pos
;
TRACE
(
"(%lx,%p,%p)
\n
"
,
*
pFlags
,
Buffer
,
pvar
);
VariantInit
(
pvar
);
pvar
->
n1
.
n2
.
vt
=
var
->
rpcReserved
;
TRACE
(
"marshalled: clSize=%ld, vt=%04x
\n
"
,
var
->
clSize
,
var
->
vt
);
TRACE
(
"vt=%04x
\n
"
,
V_VT
(
pvar
));
TRACE
(
"reserved: %d, %d, %d
\n
"
,
var
->
wReserved1
,
var
->
wReserved2
,
var
->
wReserved3
);
TRACE
(
"val: %ld
\n
"
,
var
->
u
.
lVal
);
TRACE
(
"(%lx,%p,%p)
\n
"
,
*
pFlags
,
Buffer
,
pvar
);
if
(
var
->
vt
==
VT_DECIMAL
)
{
/* special case because decVal is on a different level */
pvar
->
n1
.
decVal
=
var
->
u
.
decVal
;
return
Pos
;
}
ALIGN_POINTER
(
Buffer
,
7
);
VariantInit
(
pvar
);
header
=
(
variant_wire_t
*
)
Buffer
;
pvar
->
n1
.
n2
.
vt
=
header
->
vt
;
pvar
->
n1
.
n2
.
wReserved1
=
header
->
wReserved1
;
pvar
->
n1
.
n2
.
wReserved2
=
header
->
wReserved2
;
pvar
->
n1
.
n2
.
wReserved3
=
header
->
wReserved3
;
size
=
wire_size
(
V_VT
(
pvar
));
pvar
->
n1
.
n2
.
wReserved1
=
var
->
wReserved1
;
pvar
->
n1
.
n2
.
wReserved2
=
var
->
wReserved2
;
pvar
->
n1
.
n2
.
wReserved3
=
var
->
wReserved3
;
if
(
size
)
{
if
(
var
->
vt
&
VT_BYREF
)
{
pvar
->
n1
.
n2
.
n3
.
byref
=
CoTaskMemAlloc
(
size
);
memcpy
(
pvar
->
n1
.
n2
.
n3
.
byref
,
&
var
->
u
.
cVal
,
size
);
Pos
=
(
unsigned
char
*
)(
header
+
1
);
type_size
=
get_type_size
(
pFlags
,
pvar
);
align
=
get_type_alignment
(
pFlags
,
pvar
);
ALIGN_POINTER
(
Pos
,
align
);
if
(
header
->
vt
&
VT_BYREF
)
{
Pos
+=
4
;
pvar
->
n1
.
n2
.
n3
.
byref
=
CoTaskMemAlloc
(
type_size
);
memcpy
(
pvar
->
n1
.
n2
.
n3
.
byref
,
Pos
,
type_size
);
if
((
header
->
vt
&
VT_TYPEMASK
)
!=
VT_VARIANT
)
Pos
+=
type_size
;
else
Pos
+=
4
;
}
else
memcpy
(
&
pvar
->
n1
.
n2
.
n3
,
&
var
->
u
.
cVal
,
size
);
}
if
(
var
->
clSize
<=
VARIANT_wiresize
)
return
Pos
;
{
if
((
header
->
vt
&
VT_TYPEMASK
)
==
VT_DECIMAL
)
memcpy
(
pvar
,
Pos
,
type_size
);
else
memcpy
(
&
pvar
->
n1
.
n2
.
n3
,
Pos
,
type_size
);
Pos
+=
type_size
;
}
switch
(
var
->
vt
)
{
case
VT_BSTR
:
V_BSTR
(
pvar
)
=
NULL
;
Pos
=
BSTR_UserUnmarshal
(
pFlags
,
Pos
,
&
V_BSTR
(
pvar
));
break
;
case
VT_BSTR
|
VT_BYREF
:
pvar
->
n1
.
n2
.
n3
.
byref
=
CoTaskMemAlloc
(
sizeof
(
BSTR
));
*
(
BSTR
*
)
V_BYREF
(
pvar
)
=
NULL
;
Pos
=
BSTR_UserUnmarshal
(
pFlags
,
Pos
,
V_BSTRREF
(
pvar
));
break
;
case
VT_VARIANT
|
VT_BYREF
:
pvar
->
n1
.
n2
.
n3
.
byref
=
CoTaskMemAlloc
(
sizeof
(
VARIANT
));
Pos
=
VARIANT_UserUnmarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_RECORD
:
FIXME
(
"handle BRECORD by val
\n
"
);
break
;
case
VT_RECORD
|
VT_BYREF
:
FIXME
(
"handle BRECORD by ref
\n
"
);
break
;
case
VT_UNKNOWN
:
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
pvar
);
break
;
case
VT_DISPATCH
:
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
pvar
);
break
;
case
VT_DISPATCH
|
VT_BYREF
:
FIXME
(
"handle DISPATCH by ref
\n
"
);
default:
FIXME
(
"handle unknown complex type
\n
"
);
break
;
}
if
(
Pos
!=
Buffer
+
var
->
clSize
)
{
ERR
(
"size difference during unmarshal
\n
"
);
}
return
Buffer
+
var
->
clSize
;
if
(
header
->
vt
&
VT_ARRAY
)
{
if
(
header
->
vt
&
VT_BYREF
)
Pos
=
LPSAFEARRAY_UserUnmarshal
(
pFlags
,
Pos
,
V_ARRAYREF
(
pvar
));
else
Pos
=
LPSAFEARRAY_UserUnmarshal
(
pFlags
,
Pos
,
&
V_ARRAY
(
pvar
));
}
else
{
switch
(
header
->
vt
)
{
case
VT_BSTR
:
V_BSTR
(
pvar
)
=
NULL
;
Pos
=
BSTR_UserUnmarshal
(
pFlags
,
Pos
,
&
V_BSTR
(
pvar
));
break
;
case
VT_BSTR
|
VT_BYREF
:
*
V_BSTRREF
(
pvar
)
=
NULL
;
Pos
=
BSTR_UserUnmarshal
(
pFlags
,
Pos
,
V_BSTRREF
(
pvar
));
break
;
case
VT_VARIANT
|
VT_BYREF
:
Pos
=
VARIANT_UserUnmarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_DISPATCH
|
VT_BYREF
:
FIXME
(
"handle DISPATCH by ref
\n
"
);
break
;
case
VT_UNKNOWN
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
pvar
);
break
;
case
VT_DISPATCH
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
pvar
);
break
;
case
VT_RECORD
:
FIXME
(
"handle BRECORD by val
\n
"
);
break
;
case
VT_RECORD
|
VT_BYREF
:
FIXME
(
"handle BRECORD by ref
\n
"
);
break
;
}
}
return
Pos
;
}
void
WINAPI
VARIANT_UserFree
(
unsigned
long
*
pFlags
,
VARIANT
*
pvar
)
...
...
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