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
fb42af12
Commit
fb42af12
authored
Jun 29, 2005
by
Robert Shearman
Committed by
Alexandre Julliard
Jun 29, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add a generic TYPEDESC VT to VARIANT VT mapper so we can use the
standard Variant* routines. Use this new function to properly copy & de-reference the return value.
parent
9f96664d
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
133 additions
and
66 deletions
+133
-66
typelib.c
dlls/oleaut32/typelib.c
+133
-66
No files found.
dlls/oleaut32/typelib.c
View file @
fb42af12
...
...
@@ -84,6 +84,8 @@ WINE_DECLARE_DEBUG_CHANNEL(typelib);
/* The OLE Automation ProxyStub Interface Class (aka Typelib Marshaler) */
const
GUID
CLSID_PSOAInterface
=
{
0x00020424
,
0
,
0
,
{
0xC0
,
0
,
0
,
0
,
0
,
0
,
0
,
0x46
}
};
static
HRESULT
typedescvt_to_variantvt
(
ITypeInfo
*
tinfo
,
TYPEDESC
*
tdesc
,
VARTYPE
*
vt
);
/****************************************************************************
* FromLExxx
*
...
...
@@ -4700,6 +4702,117 @@ _copy_arg( ITypeInfo2 *tinfo, TYPEDESC *tdesc,
return
E_FAIL
;
}
static
HRESULT
userdefined_to_variantvt
(
ITypeInfo
*
tinfo
,
TYPEDESC
*
tdesc
,
VARTYPE
*
vt
)
{
HRESULT
hr
=
S_OK
;
ITypeInfo
*
tinfo2
=
NULL
;
TYPEATTR
*
tattr
=
NULL
;
hr
=
ITypeInfo_GetRefTypeInfo
(
tinfo
,
tdesc
->
u
.
hreftype
,
&
tinfo2
);
if
(
hr
)
{
ERR
(
"Could not get typeinfo of hreftype %lx for VT_USERDEFINED, "
"hr = 0x%08lx
\n
"
,
tdesc
->
u
.
hreftype
,
hr
);
return
hr
;
}
hr
=
ITypeInfo_GetTypeAttr
(
tinfo2
,
&
tattr
);
if
(
hr
)
{
ERR
(
"ITypeInfo_GetTypeAttr failed, hr = 0x%08lx
\n
"
,
hr
);
ITypeInfo_Release
(
tinfo2
);
return
hr
;
}
switch
(
tattr
->
typekind
)
{
case
TKIND_ENUM
:
*
vt
|=
VT_INT
;
break
;
case
TKIND_ALIAS
:
tdesc
=
&
tattr
->
tdescAlias
;
hr
=
typedescvt_to_variantvt
(
tinfo2
,
&
tattr
->
tdescAlias
,
vt
);
break
;
case
TKIND_INTERFACE
:
if
(
IsEqualIID
(
&
IID_IDispatch
,
&
tattr
->
guid
))
*
vt
|=
VT_DISPATCH
;
else
*
vt
|=
VT_UNKNOWN
;
break
;
case
TKIND_DISPATCH
:
*
vt
|=
VT_DISPATCH
;
break
;
case
TKIND_RECORD
:
FIXME
(
"TKIND_RECORD unhandled.
\n
"
);
hr
=
E_NOTIMPL
;
break
;
case
TKIND_UNION
:
FIXME
(
"TKIND_RECORD unhandled.
\n
"
);
hr
=
E_NOTIMPL
;
break
;
default:
FIXME
(
"TKIND %d unhandled.
\n
"
,
tattr
->
typekind
);
hr
=
E_NOTIMPL
;
break
;
}
ITypeInfo_ReleaseTypeAttr
(
tinfo2
,
tattr
);
ITypeInfo_Release
(
tinfo2
);
return
hr
;
}
static
HRESULT
typedescvt_to_variantvt
(
ITypeInfo
*
tinfo
,
TYPEDESC
*
tdesc
,
VARTYPE
*
vt
)
{
HRESULT
hr
=
S_OK
;
/* enforce only one level of pointer indirection */
if
(
!
(
*
vt
&
VT_BYREF
)
&&
(
tdesc
->
vt
==
VT_PTR
))
{
tdesc
=
tdesc
->
u
.
lptdesc
;
/* munch VT_PTR -> VT_USERDEFINED(interface) into VT_UNKNOWN or
* VT_DISPATCH and VT_PTR -> VT_PTR -> VT_USERDEFINED(interface) into
* VT_BYREF|VT_DISPATCH or VT_BYREF|VT_UNKNOWN */
if
((
tdesc
->
vt
==
VT_USERDEFINED
)
||
((
tdesc
->
vt
==
VT_PTR
)
&&
(
tdesc
->
u
.
lptdesc
->
vt
==
VT_USERDEFINED
)))
{
VARTYPE
vt_userdefined
=
0
;
TYPEDESC
*
tdesc_userdefined
=
tdesc
;
if
(
tdesc
->
vt
==
VT_PTR
)
{
vt_userdefined
=
VT_BYREF
;
tdesc_userdefined
=
tdesc
->
u
.
lptdesc
;
}
hr
=
userdefined_to_variantvt
(
tinfo
,
tdesc_userdefined
,
&
vt_userdefined
);
if
(
!
hr
&&
((
vt_userdefined
==
VT_UNKNOWN
)
||
(
vt_userdefined
==
VT_DISPATCH
)))
{
*
vt
|=
vt_userdefined
;
return
S_OK
;
}
}
*
vt
=
VT_BYREF
;
}
switch
(
tdesc
->
vt
)
{
case
VT_HRESULT
:
*
vt
|=
VT_ERROR
;
break
;
case
VT_USERDEFINED
:
hr
=
userdefined_to_variantvt
(
tinfo
,
tdesc
,
vt
);
break
;
default:
*
vt
|=
tdesc
->
vt
;
break
;
}
return
hr
;
}
/***********************************************************************
* DispCallFunc (OLEAUT32.@)
*/
...
...
@@ -4775,6 +4888,11 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
hres
=
ITypeInfo2_GetFuncDesc
(
iface
,
func_index
,
&
func_desc
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
TRACE_ON
(
ole
))
{
TRACE
(
"invoking:
\n
"
);
dump_FUNCDESC
(
func_desc
);
}
switch
(
func_desc
->
funckind
)
{
case
FUNC_PUREVIRTUAL
:
...
...
@@ -4876,74 +4994,23 @@ static HRESULT WINAPI ITypeInfo_fnInvoke(
args
);
if
(
pVarResult
&&
(
dwFlags
&
(
DISPATCH_PROPERTYGET
)))
{
args2pos
=
0
;
for
(
i
=
0
;
i
<
func_desc
->
cParams
-
pDispParams
->
cArgs
;
i
++
)
{
ELEMDESC
*
elemdesc
=
&
(
func_desc
->
lprgelemdescParam
[
i
+
pDispParams
->
cArgs
]);
TYPEDESC
*
tdesc
=
&
(
elemdesc
->
tdesc
);
int
arglen
=
_argsize
(
tdesc
->
vt
);
TYPEDESC
i4_tdesc
;
i4_tdesc
.
vt
=
VT_I4
;
/* If we are a pointer to a variant, we are done already */
if
((
tdesc
->
vt
==
VT_PTR
)
&&
(
tdesc
->
u
.
lptdesc
->
vt
==
VT_VARIANT
))
continue
;
if
(
tdesc
->
vt
==
VT_PTR
)
{
tdesc
=
tdesc
->
u
.
lptdesc
;
arglen
=
_argsize
(
tdesc
->
vt
);
}
VariantInit
(
pVarResult
);
memcpy
(
&
V_INT
(
pVarResult
),
&
args2
[
args2pos
],
arglen
*
sizeof
(
DWORD
));
if
(
tdesc
->
vt
==
VT_USERDEFINED
)
{
ITypeInfo
*
tinfo2
;
TYPEATTR
*
tattr
;
hres
=
ITypeInfo_GetRefTypeInfo
(
iface
,
tdesc
->
u
.
hreftype
,
&
tinfo2
);
if
(
FAILED
(
hres
))
{
FIXME
(
"Could not get typeinfo of hreftype %lx for VT_USERDEFINED, while coercing. Copying 4 byte.
\n
"
,
tdesc
->
u
.
hreftype
);
goto
func_fail
;
}
ITypeInfo_GetTypeAttr
(
tinfo2
,
&
tattr
);
switch
(
tattr
->
typekind
)
{
case
TKIND_ENUM
:
/* force the return type to be VT_I4 */
tdesc
=
&
i4_tdesc
;
if
(
pVarResult
)
{
for
(
i
=
0
;
i
<
func_desc
->
cParams
;
i
++
)
{
USHORT
wParamFlags
=
func_desc
->
lprgelemdescParam
[
i
].
u
.
paramdesc
.
wParamFlags
;
if
(
wParamFlags
&
PARAMFLAG_FRETVAL
)
{
ELEMDESC
*
elemdesc
=
&
func_desc
->
lprgelemdescParam
[
i
];
TYPEDESC
*
tdesc
=
&
elemdesc
->
tdesc
;
VARIANTARG
varresult
;
V_VT
(
&
varresult
)
=
0
;
hres
=
typedescvt_to_variantvt
((
ITypeInfo
*
)
iface
,
tdesc
,
&
V_VT
(
&
varresult
));
if
(
hres
)
break
;
case
TKIND_ALIAS
:
TRACE
(
"TKIND_ALIAS to vt 0x%x
\n
"
,
tattr
->
tdescAlias
.
vt
);
tdesc
=
&
(
tattr
->
tdescAlias
);
break
;
case
TKIND_INTERFACE
:
FIXME
(
"TKIND_INTERFACE unhandled.
\n
"
);
break
;
case
TKIND_DISPATCH
:
FIXME
(
"TKIND_DISPATCH unhandled.
\n
"
);
break
;
case
TKIND_RECORD
:
FIXME
(
"TKIND_RECORD unhandled.
\n
"
);
break
;
default:
FIXME
(
"TKIND %d unhandled.
\n
"
,
tattr
->
typekind
);
break
;
}
ITypeInfo_Release
(
tinfo2
);
/* FIXME: this is really messy - we should keep the
* args in VARIANTARGs rather than a DWORD array */
memcpy
(
&
V_UI4
(
&
varresult
),
&
args
[
i
+
1
],
sizeof
(
DWORD
));
hres
=
VariantCopyInd
(
pVarResult
,
&
varresult
);
break
;
}
V_VT
(
pVarResult
)
=
tdesc
->
vt
;
/* HACK: VB5 likes this.
* I do not know why. There is 1 example in MSDN which uses
* this which appears broken (mixes int vals and
* IDispatch*.).
*/
if
((
tdesc
->
vt
==
VT_PTR
)
&&
(
dwFlags
&
DISPATCH_METHOD
))
V_VT
(
pVarResult
)
=
VT_DISPATCH
;
TRACE
(
"storing into variant:
\n
"
);
dump_Variant
(
pVarResult
);
args2pos
+=
arglen
;
}
}
func_fail:
...
...
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