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
44360823
Commit
44360823
authored
Mar 08, 2015
by
Nikolay Sivov
Committed by
Alexandre Julliard
Mar 09, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
oleaut32: Use WdtpInterfacePointer_* functions in VARIANT marshalling.
parent
52d30cc3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
62 additions
and
114 deletions
+62
-114
usrmarshal.c
dlls/ole32/tests/usrmarshal.c
+24
-5
usrmarshal.c
dlls/oleaut32/tests/usrmarshal.c
+10
-10
usrmarshal.c
dlls/oleaut32/usrmarshal.c
+28
-99
No files found.
dlls/ole32/tests/usrmarshal.c
View file @
44360823
...
...
@@ -472,6 +472,17 @@ static void test_marshal_HMETAFILEPICT(void)
HMETAFILEPICT_UserFree
(
&
umcb
.
Flags
,
&
hmfp2
);
}
typedef
struct
{
IUnknown
IUnknown_iface
;
LONG
refs
;
}
TestUnknown
;
static
inline
TestUnknown
*
impl_from_IUnknown
(
IUnknown
*
iface
)
{
return
CONTAINING_RECORD
(
iface
,
TestUnknown
,
IUnknown_iface
);
}
static
HRESULT
WINAPI
Test_IUnknown_QueryInterface
(
LPUNKNOWN
iface
,
REFIID
riid
,
...
...
@@ -492,12 +503,14 @@ static HRESULT WINAPI Test_IUnknown_QueryInterface(
static
ULONG
WINAPI
Test_IUnknown_AddRef
(
LPUNKNOWN
iface
)
{
return
2
;
/* non-heap-based object */
TestUnknown
*
This
=
impl_from_IUnknown
(
iface
);
return
InterlockedIncrement
(
&
This
->
refs
);
}
static
ULONG
WINAPI
Test_IUnknown_Release
(
LPUNKNOWN
iface
)
{
return
1
;
/* non-heap-based object */
TestUnknown
*
This
=
impl_from_IUnknown
(
iface
);
return
InterlockedDecrement
(
&
This
->
refs
);
}
static
const
IUnknownVtbl
TestUnknown_Vtbl
=
...
...
@@ -542,7 +555,7 @@ static const IStreamVtbl TestStream_Vtbl =
/* the rest can be NULLs */
};
static
IUnknown
Test_Unknown
=
{
&
TestUnknown_Vtbl
};
static
TestUnknown
Test_Unknown
=
{
{
&
TestUnknown_Vtbl
},
1
};
static
IStream
Test_Stream
=
{
&
TestStream_Vtbl
};
ULONG
__RPC_USER
WdtpInterfacePointer_UserSize
(
ULONG
*
,
ULONG
,
ULONG
,
IUnknown
*
,
REFIID
);
...
...
@@ -582,7 +595,8 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
/* Now for a non-NULL pointer. The marshalled data are two size DWORDS and then
the result of CoMarshalInterface called with the LOWORD of the ctx */
unk
=
&
Test_Unknown
;
unk
=
&
Test_Unknown
.
IUnknown_iface
;
Test_Unknown
.
refs
=
1
;
CreateStreamOnHGlobal
(
h
,
TRUE
,
&
stm
);
CoMarshalInterface
(
stm
,
&
IID_IUnknown
,
unk
,
LOWORD
(
ctx
),
NULL
,
MSHLFLAGS_NORMAL
);
...
...
@@ -591,6 +605,8 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
marshal_size
=
pos
.
u
.
LowPart
;
marshal_data
=
GlobalLock
(
h
);
trace
(
"marshal_size %x
\n
"
,
marshal_size
);
todo_wine
ok
(
Test_Unknown
.
refs
==
2
,
"got %d
\n
"
,
Test_Unknown
.
refs
);
init_user_marshal_cb
(
&
umcb
,
&
stub_msg
,
&
rpc_msg
,
NULL
,
0
,
umcb_ctx
);
size
=
WdtpInterfacePointer_UserSize
(
&
umcb
.
Flags
,
ctx
,
0
,
unk
,
&
IID_IUnknown
);
...
...
@@ -599,6 +615,8 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
buffer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
size
);
init_user_marshal_cb
(
&
umcb
,
&
stub_msg
,
&
rpc_msg
,
buffer
,
size
,
umcb_ctx
);
buffer_end
=
WdtpInterfacePointer_UserMarshal
(
&
umcb
.
Flags
,
ctx
,
buffer
,
unk
,
&
IID_IUnknown
);
todo_wine
ok
(
Test_Unknown
.
refs
==
2
,
"got %d
\n
"
,
Test_Unknown
.
refs
);
wireip
=
buffer
;
ok
(
buffer_end
==
buffer
+
marshal_size
+
2
*
sizeof
(
DWORD
),
"buffer_end %p buffer %p
\n
"
,
buffer_end
,
buffer
);
...
...
@@ -619,6 +637,7 @@ static void marshal_WdtpInterfacePointer(DWORD umcb_ctx, DWORD ctx)
init_user_marshal_cb
(
&
umcb
,
&
stub_msg
,
&
rpc_msg
,
buffer
,
size
,
umcb_ctx
);
WdtpInterfacePointer_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
unk2
,
&
IID_IUnknown
);
ok
(
unk2
!=
NULL
,
"IUnknown object didn't unmarshal properly
\n
"
);
ok
(
Test_Unknown
.
refs
==
2
,
"got %d
\n
"
,
Test_Unknown
.
refs
);
HeapFree
(
GetProcessHeap
(),
0
,
buffer
);
init_user_marshal_cb
(
&
umcb
,
&
stub_msg
,
&
rpc_msg
,
NULL
,
0
,
MSHCTX_INPROC
);
IUnknown_Release
(
unk2
);
...
...
@@ -651,7 +670,7 @@ static void test_marshal_STGMEDIUM(void)
unsigned
char
*
buffer
,
*
buffer_end
,
*
expect_buffer
,
*
expect_buffer_end
;
ULONG
size
,
expect_size
;
STGMEDIUM
med
,
med2
;
IUnknown
*
unk
=
&
Test_Unknown
;
IUnknown
*
unk
=
&
Test_Unknown
.
IUnknown_iface
;
IStream
*
stm
=
&
Test_Stream
;
/* TYMED_NULL with pUnkForRelease */
...
...
dlls/oleaut32/tests/usrmarshal.c
View file @
44360823
...
...
@@ -1386,31 +1386,31 @@ static void test_marshal_VARIANT(void)
V_UNKNOWN
(
&
v
)
=
&
heap_unknown
->
IUnknown_iface
;
rpcMsg
.
BufferLength
=
stubMsg
.
BufferLength
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
stubMsg
.
BufferLength
>
32
,
"size %d
\n
"
,
stubMsg
.
BufferLength
);
ok
(
stubMsg
.
BufferLength
>
40
,
"size %d
\n
"
,
stubMsg
.
BufferLength
);
buffer
=
rpcMsg
.
Buffer
=
stubMsg
.
Buffer
=
stubMsg
.
BufferStart
=
alloc_aligned
(
stubMsg
.
BufferLength
,
&
oldbuffer
);
stubMsg
.
BufferEnd
=
stubMsg
.
Buffer
+
stubMsg
.
BufferLength
;
memset
(
buffer
,
0xcc
,
stubMsg
.
BufferLength
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
todo_wine
ok
(
heap_unknown
->
refs
==
2
,
"got refcount %d
\n
"
,
heap_unknown
->
refs
);
wirev
=
(
DWORD
*
)
buffer
;
wirev
=
check_variant_header
(
wirev
,
&
v
,
next
-
buffer
);
todo_wine
ok
(
*
wirev
==
(
DWORD_PTR
)
V_UNKNOWN
(
&
v
)
/* Win9x */
||
*
wirev
==
(
DWORD_PTR
)
V_UNKNOWN
(
&
v
)
+
1
/* NT */
,
"wv[5] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
next
-
buffer
-
0x20
,
"wv[6] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
next
-
buffer
-
0x20
,
"wv[7] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
0x574f454d
,
"wv[8] %08x
\n
"
,
*
wirev
);
VariantInit
(
&
v3
);
V_VT
(
&
v3
)
=
VT_UNKNOWN
;
V_UNKNOWN
(
&
v3
)
=
&
heap_unknown
->
IUnknown_iface
;
IUnknown_AddRef
(
V_UNKNOWN
(
&
v3
));
stubMsg
.
Buffer
=
buffer
;
todo_wine
ok
(
heap_unknown
->
refs
==
3
,
"got refcount %d
\n
"
,
heap_unknown
->
refs
);
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v3
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v3
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v3
));
ok
(
V_UNKNOWN
(
&
v
)
==
V_UNKNOWN
(
&
v3
),
"got %p expect %p
\n
"
,
V_UNKNOWN
(
&
v
),
V_UNKNOWN
(
&
v3
));
...
...
@@ -1452,27 +1452,26 @@ static void test_marshal_VARIANT(void)
V_UNKNOWNREF
(
&
v
)
=
(
IUnknown
**
)
&
heap_unknown
;
rpcMsg
.
BufferLength
=
stubMsg
.
BufferLength
=
VARIANT_UserSize
(
&
umcb
.
Flags
,
0
,
&
v
);
ok
(
stubMsg
.
BufferLength
>
36
,
"size %d
\n
"
,
stubMsg
.
BufferLength
);
ok
(
stubMsg
.
BufferLength
>
=
44
,
"size %d
\n
"
,
stubMsg
.
BufferLength
);
buffer
=
rpcMsg
.
Buffer
=
stubMsg
.
Buffer
=
stubMsg
.
BufferStart
=
alloc_aligned
(
stubMsg
.
BufferLength
,
&
oldbuffer
);
stubMsg
.
BufferEnd
=
stubMsg
.
Buffer
+
stubMsg
.
BufferLength
;
memset
(
buffer
,
0xcc
,
stubMsg
.
BufferLength
);
ok
(
heap_unknown
->
refs
==
1
,
"got refcount %d
\n
"
,
heap_unknown
->
refs
);
next
=
VARIANT_UserMarshal
(
&
umcb
.
Flags
,
buffer
,
&
v
);
todo_wine
ok
(
heap_unknown
->
refs
==
2
,
"got refcount %d
\n
"
,
heap_unknown
->
refs
);
wirev
=
(
DWORD
*
)
buffer
;
wirev
=
check_variant_header
(
wirev
,
&
v
,
next
-
buffer
);
ok
(
*
wirev
==
4
,
"wv[5] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
(
DWORD_PTR
)
heap_unknown
/* Win9x, Win2000 */
||
*
wirev
==
(
DWORD_PTR
)
heap_unknown
+
1
/* XP */
,
"wv[6] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
next
-
buffer
-
0x24
,
"wv[7] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
next
-
buffer
-
0x24
,
"wv[8] %08x
\n
"
,
*
wirev
);
wirev
++
;
todo_wine
ok
(
*
wirev
==
0x574f454d
,
"wv[9] %08x
\n
"
,
*
wirev
);
VariantInit
(
&
v3
);
...
...
@@ -1481,6 +1480,7 @@ static void test_marshal_VARIANT(void)
IUnknown_AddRef
(
V_UNKNOWN
(
&
v3
));
stubMsg
.
Buffer
=
buffer
;
next
=
VARIANT_UserUnmarshal
(
&
umcb
.
Flags
,
buffer
,
&
v3
);
ok
(
heap_unknown
->
refs
==
2
,
"got refcount %d
\n
"
,
heap_unknown
->
refs
);
ok
(
V_VT
(
&
v
)
==
V_VT
(
&
v3
),
"got vt %d expect %d
\n
"
,
V_VT
(
&
v
),
V_VT
(
&
v3
));
ok
(
*
V_UNKNOWNREF
(
&
v
)
==
*
V_UNKNOWNREF
(
&
v3
),
"got %p expect %p
\n
"
,
*
V_UNKNOWNREF
(
&
v
),
*
V_UNKNOWNREF
(
&
v3
));
VARIANT_UserFree
(
&
umcb
.
Flags
,
&
v3
);
...
...
dlls/oleaut32/usrmarshal.c
View file @
44360823
...
...
@@ -45,6 +45,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
#define ALIGN_LENGTH(_Len, _Align) _Len = ALIGNED_LENGTH(_Len, _Align)
#define ALIGN_POINTER(_Ptr, _Align) _Ptr = ALIGNED_POINTER(_Ptr, _Align)
/* ole32 exports those, not defined in public headers */
ULONG
__RPC_USER
WdtpInterfacePointer_UserSize
(
ULONG
*
,
ULONG
,
ULONG
,
IUnknown
*
,
REFIID
);
unsigned
char
*
__RPC_USER
WdtpInterfacePointer_UserMarshal
(
ULONG
*
,
ULONG
,
unsigned
char
*
,
IUnknown
*
,
REFIID
);
unsigned
char
*
__RPC_USER
WdtpInterfacePointer_UserUnmarshal
(
ULONG
*
,
unsigned
char
*
,
IUnknown
**
,
REFIID
);
static
void
dump_user_flags
(
const
ULONG
*
pFlags
)
{
if
(
HIWORD
(
*
pFlags
)
==
NDR_LOCAL_DATA_REPRESENTATION
)
...
...
@@ -256,21 +261,21 @@ static unsigned int get_type_alignment(ULONG *pFlags, VARTYPE vt)
return
7
;
}
static
unsigned
interface_variant_size
(
const
ULONG
*
pFlags
,
REFIID
riid
,
IUnknown
*
punk
)
/* WdtpInterfacePointer_UserSize takes care of 2 additional DWORDs to store marshalling buffer size */
static
unsigned
interface_variant_size
(
ULONG
*
pFlags
,
REFIID
riid
,
IUnknown
*
punk
)
{
ULONG
size
=
0
;
HRESULT
hr
;
if
(
punk
)
{
hr
=
CoGetMarshalSizeMax
(
&
size
,
riid
,
punk
,
LOWORD
(
*
pFlags
),
NULL
,
MSHLFLAGS_NORMAL
);
if
(
FAILED
(
hr
)
)
size
=
WdtpInterfacePointer_UserSize
(
pFlags
,
LOWORD
(
*
pFlags
),
0
,
punk
,
riid
);
if
(
!
size
)
{
ERR
(
"interface variant buffer size calculation failed
, HRESULT=0x%x
\n
"
,
hr
);
ERR
(
"interface variant buffer size calculation failed
\n
"
);
return
0
;
}
}
size
+=
sizeof
(
ULONG
);
/* we have to store the buffersize in the stream */
size
+=
sizeof
(
ULONG
);
TRACE
(
"wire-size extra of interface variant is %d
\n
"
,
size
);
return
size
;
}
...
...
@@ -312,116 +317,48 @@ static ULONG wire_extra_user_size(ULONG *pFlags, ULONG Start, VARIANT *pvar)
}
}
/* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer
. returns Buffer on failure, new position otherwise
*/
static
unsigned
char
*
interface_variant_marshal
(
const
ULONG
*
pFlags
,
unsigned
char
*
Buffer
,
/* helper: called for VT_DISPATCH variants to marshal the IDispatch* into the buffer */
static
unsigned
char
*
interface_variant_marshal
(
ULONG
*
pFlags
,
unsigned
char
*
Buffer
,
REFIID
riid
,
IUnknown
*
punk
)
{
IStream
*
working
;
HGLOBAL
working_mem
;
void
*
working_memlocked
;
unsigned
char
*
oldpos
;
ULONG
size
;
HRESULT
hr
;
TRACE
(
"pFlags=%d, Buffer=%p, pUnk=%p
\n
"
,
*
pFlags
,
Buffer
,
punk
);
/* first DWORD is used to store pointer itself, truncated on win64 */
if
(
!
punk
)
{
memset
(
Buffer
,
0
,
sizeof
(
ULONG
));
return
Buffer
+
sizeof
(
ULONG
);
}
oldpos
=
Buffer
;
/* CoMarshalInterface needs a stream, whereas at this level we are operating in terms of buffers.
* We create a stream on an HGLOBAL, so we can simply do a memcpy to move it to the buffer.
* in rpcrt4/ndr_ole.c, a simple IStream implementation is wrapped around the buffer object,
* 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
=
interface_variant_size
(
pFlags
,
riid
,
punk
);
working_mem
=
GlobalAlloc
(
0
,
size
);
if
(
!
working_mem
)
return
oldpos
;
hr
=
CreateStreamOnHGlobal
(
working_mem
,
TRUE
,
&
working
);
if
(
hr
!=
S_OK
)
{
GlobalFree
(
working_mem
);
return
oldpos
;
}
hr
=
CoMarshalInterface
(
working
,
riid
,
punk
,
LOWORD
(
*
pFlags
),
NULL
,
MSHLFLAGS_NORMAL
);
if
(
hr
!=
S_OK
)
{
IStream_Release
(
working
);
/* this also releases the hglobal */
return
oldpos
;
else
{
*
(
DWORD
*
)
Buffer
=
(
DWORD_PTR
)
punk
;
Buffer
+=
sizeof
(
DWORD
);
}
working_memlocked
=
GlobalLock
(
working_mem
);
memcpy
(
Buffer
,
&
size
,
sizeof
(
ULONG
));
/* copy the buffersize */
memcpy
(
Buffer
+
sizeof
(
ULONG
),
working_memlocked
,
size
-
sizeof
(
ULONG
));
GlobalUnlock
(
working_mem
);
IStream_Release
(
working
);
/* size includes the ULONG for the size written above */
TRACE
(
"done, size=%d
\n
"
,
size
);
return
Buffer
+
size
;
return
WdtpInterfacePointer_UserMarshal
(
pFlags
,
LOWORD
(
*
pFlags
),
Buffer
,
punk
,
riid
);
}
/* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer
. returns Buffer on failure, new position otherwise
*/
static
unsigned
char
*
interface_variant_unmarshal
(
const
ULONG
*
pFlags
,
unsigned
char
*
Buffer
,
/* helper: called for VT_DISPATCH / VT_UNKNOWN variants to unmarshal the buffer */
static
unsigned
char
*
interface_variant_unmarshal
(
ULONG
*
pFlags
,
unsigned
char
*
Buffer
,
REFIID
riid
,
IUnknown
**
ppunk
)
{
IStream
*
working
;
HGLOBAL
working_mem
;
void
*
working_memlocked
;
unsigned
char
*
oldpos
;
ULONG
size
;
HRESULT
hr
;
DWORD
ptr
;
TRACE
(
"pFlags=%d, Buffer=%p, ppUnk=%p
\n
"
,
*
pFlags
,
Buffer
,
ppunk
);
oldpos
=
Buffer
;
/* skip pointer part itself */
ptr
=
*
(
DWORD
*
)
Buffer
;
Buffer
+=
sizeof
(
DWORD
);
/* get the buffersize */
memcpy
(
&
size
,
Buffer
,
sizeof
(
ULONG
));
TRACE
(
"buffersize=%d
\n
"
,
size
);
if
(
!
size
)
if
(
!
ptr
)
{
*
ppunk
=
NULL
;
return
Buffer
+
sizeof
(
ULONG
);
}
working_mem
=
GlobalAlloc
(
0
,
size
);
if
(
!
working_mem
)
return
oldpos
;
hr
=
CreateStreamOnHGlobal
(
working_mem
,
TRUE
,
&
working
);
if
(
hr
!=
S_OK
)
{
GlobalFree
(
working_mem
);
return
oldpos
;
return
Buffer
;
}
working_memlocked
=
GlobalLock
(
working_mem
);
/* now we copy the contents of the marshalling buffer to working_memlocked, unlock it, and demarshal the stream */
memcpy
(
working_memlocked
,
Buffer
+
sizeof
(
ULONG
),
size
);
GlobalUnlock
(
working_mem
);
hr
=
CoUnmarshalInterface
(
working
,
riid
,
(
void
**
)
ppunk
);
if
(
hr
!=
S_OK
)
{
IStream_Release
(
working
);
return
oldpos
;
}
IStream_Release
(
working
);
/* this also frees the underlying hglobal */
/* size includes the ULONG for the size written above */
TRACE
(
"done, processed=%d bytes
\n
"
,
size
);
return
Buffer
+
size
;
return
WdtpInterfacePointer_UserUnmarshal
(
pFlags
,
Buffer
,
ppunk
,
riid
);
}
ULONG
WINAPI
VARIANT_UserSize
(
ULONG
*
pFlags
,
ULONG
Start
,
VARIANT
*
pvar
)
{
int
align
;
...
...
@@ -519,19 +456,15 @@ unsigned char * WINAPI VARIANT_UserMarshal(ULONG *pFlags, unsigned char *Buffer,
Pos
=
VARIANT_UserMarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_UNKNOWN
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
V_UNKNOWN
(
pvar
));
break
;
case
VT_UNKNOWN
|
VT_BYREF
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
*
V_UNKNOWNREF
(
pvar
));
break
;
case
VT_DISPATCH
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
(
IUnknown
*
)
V_DISPATCH
(
pvar
));
break
;
case
VT_DISPATCH
|
VT_BYREF
:
/* this should probably call WdtpInterfacePointer_UserMarshal in ole32.dll */
Pos
=
interface_variant_marshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
(
IUnknown
*
)
*
V_DISPATCHREF
(
pvar
));
break
;
case
VT_RECORD
:
...
...
@@ -634,19 +567,15 @@ unsigned char * WINAPI VARIANT_UserUnmarshal(ULONG *pFlags, unsigned char *Buffe
Pos
=
VARIANT_UserUnmarshal
(
pFlags
,
Pos
,
V_VARIANTREF
(
pvar
));
break
;
case
VT_UNKNOWN
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
&
V_UNKNOWN
(
pvar
));
break
;
case
VT_UNKNOWN
|
VT_BYREF
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IUnknown
,
V_UNKNOWNREF
(
pvar
));
break
;
case
VT_DISPATCH
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
(
IUnknown
**
)
&
V_DISPATCH
(
pvar
));
break
;
case
VT_DISPATCH
|
VT_BYREF
:
/* this should probably call WdtpInterfacePointer_UserUnmarshal in ole32.dll */
Pos
=
interface_variant_unmarshal
(
pFlags
,
Pos
,
&
IID_IDispatch
,
(
IUnknown
**
)
V_DISPATCHREF
(
pvar
));
break
;
case
VT_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