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
6d3bfe8e
Commit
6d3bfe8e
authored
Sep 24, 2012
by
Jacek Caban
Committed by
Alexandre Julliard
Sep 24, 2012
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
mshtml: Added support for overriding builtin functions.
parent
313157a0
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
28 deletions
+107
-28
dispex.c
dlls/mshtml/dispex.c
+107
-28
No files found.
dlls/mshtml/dispex.c
View file @
6d3bfe8e
...
...
@@ -74,15 +74,21 @@ typedef struct {
typedef
struct
{
DispatchEx
dispex
;
IUnknown
IUnknown_iface
;
LONG
ref
;
DispatchEx
*
obj
;
func_info_t
*
info
;
}
func_disp_t
;
typedef
struct
{
func_disp_t
*
func_obj
;
IDispatch
*
val
;
}
func_obj_entry_t
;
struct
dispex_dynamic_data_t
{
DWORD
buf_size
;
DWORD
prop_cnt
;
dynamic_prop_t
*
props
;
func_
disp_t
*
*
func_disps
;
func_
obj_entry_t
*
func_disps
;
};
#define DISPID_DYNPROP_0 0x50000000
...
...
@@ -575,19 +581,27 @@ static HRESULT WINAPI Function_QueryInterface(IUnknown *iface, REFIID riid, void
static
ULONG
WINAPI
Function_AddRef
(
IUnknown
*
iface
)
{
func_disp_t
*
This
=
impl_from_IUnknown
(
iface
);
LONG
ref
=
InterlockedIncrement
(
&
This
->
ref
);
TRACE
(
"(%p)
\n
"
,
This
);
TRACE
(
"(%p)
ref=%d
\n
"
,
This
,
ref
);
return
IDispatchEx_AddRef
(
&
This
->
obj
->
IDispatchEx_iface
)
;
return
ref
;
}
static
ULONG
WINAPI
Function_Release
(
IUnknown
*
iface
)
{
func_disp_t
*
This
=
impl_from_IUnknown
(
iface
);
LONG
ref
=
InterlockedDecrement
(
&
This
->
ref
);
TRACE
(
"(%p)
\n
"
,
This
);
TRACE
(
"(%p)
ref=%d
\n
"
,
This
,
ref
);
return
IDispatchEx_Release
(
&
This
->
obj
->
IDispatchEx_iface
);
if
(
!
ref
)
{
assert
(
!
This
->
obj
);
release_dispex
(
&
This
->
dispex
);
heap_free
(
This
);
}
return
ref
;
}
static
const
IUnknownVtbl
FunctionUnkVtbl
=
{
...
...
@@ -613,6 +627,8 @@ static HRESULT function_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPAR
return
E_INVALIDARG
;
/* fall through */
case
DISPATCH_METHOD
:
if
(
!
This
->
obj
)
return
E_UNEXPECTED
;
hres
=
typeinfo_invoke
(
This
->
obj
,
This
->
info
,
flags
,
params
,
res
,
ei
);
break
;
default:
...
...
@@ -649,6 +665,7 @@ static func_disp_t *create_func_disp(DispatchEx *obj, func_info_t *info)
ret
->
IUnknown_iface
.
lpVtbl
=
&
FunctionUnkVtbl
;
init_dispex
(
&
ret
->
dispex
,
&
ret
->
IUnknown_iface
,
&
function_dispex
);
ret
->
ref
=
1
;
ret
->
obj
=
obj
;
ret
->
info
=
info
;
...
...
@@ -696,6 +713,37 @@ static HRESULT invoke_disp_value(DispatchEx *This, IDispatch *func_disp, LCID lc
return
hres
;
}
static
HRESULT
get_func_obj_entry
(
DispatchEx
*
This
,
func_info_t
*
func
,
func_obj_entry_t
**
ret
)
{
dispex_dynamic_data_t
*
dynamic_data
;
dynamic_data
=
get_dynamic_data
(
This
);
if
(
!
dynamic_data
)
return
E_OUTOFMEMORY
;
if
(
!
dynamic_data
->
func_disps
)
{
dynamic_data
->
func_disps
=
heap_alloc_zero
(
This
->
data
->
data
->
func_disp_cnt
*
sizeof
(
*
dynamic_data
->
func_disps
));
if
(
!
dynamic_data
->
func_disps
)
return
E_OUTOFMEMORY
;
}
if
(
!
dynamic_data
->
func_disps
[
func
->
func_disp_idx
].
func_obj
)
{
func_disp_t
*
func_obj
;
func_obj
=
create_func_disp
(
This
,
func
);
if
(
!
func_obj
)
return
E_OUTOFMEMORY
;
dynamic_data
->
func_disps
[
func
->
func_disp_idx
].
func_obj
=
func_obj
;
IDispatchEx_AddRef
(
&
func_obj
->
dispex
.
IDispatchEx_iface
);
dynamic_data
->
func_disps
[
func
->
func_disp_idx
].
val
=
(
IDispatch
*
)
&
func_obj
->
dispex
.
IDispatchEx_iface
;
}
*
ret
=
dynamic_data
->
func_disps
+
func
->
func_disp_idx
;
return
S_OK
;
}
static
HRESULT
function_invoke
(
DispatchEx
*
This
,
func_info_t
*
func
,
WORD
flags
,
DISPPARAMS
*
dp
,
VARIANT
*
res
,
EXCEPINFO
*
ei
)
{
...
...
@@ -707,10 +755,25 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
return
E_INVALIDARG
;
/* fall through */
case
DISPATCH_METHOD
:
if
(
This
->
dynamic_data
&&
This
->
dynamic_data
&&
This
->
dynamic_data
->
func_disps
&&
This
->
dynamic_data
->
func_disps
[
func
->
func_disp_idx
].
func_obj
)
{
func_obj_entry_t
*
entry
=
This
->
dynamic_data
->
func_disps
+
func
->
func_disp_idx
;
if
((
IDispatch
*
)
&
entry
->
func_obj
->
dispex
.
IDispatchEx_iface
!=
entry
->
val
)
{
if
(
!
entry
->
val
)
{
FIXME
(
"Calling null
\n
"
);
return
E_FAIL
;
}
hres
=
invoke_disp_value
(
This
,
entry
->
val
,
0
,
flags
,
dp
,
res
,
ei
,
NULL
);
break
;
}
}
hres
=
typeinfo_invoke
(
This
,
func
,
flags
,
dp
,
res
,
ei
);
break
;
case
DISPATCH_PROPERTYGET
:
{
dispex_dynamic_data_t
*
dynamic_data
;
func_obj_entry_t
*
entry
;
if
(
func
->
id
==
DISPID_VALUE
)
{
BSTR
ret
;
...
...
@@ -724,32 +787,46 @@ static HRESULT function_invoke(DispatchEx *This, func_info_t *func, WORD flags,
return
S_OK
;
}
dynamic_data
=
get_dynamic_data
(
This
);
if
(
!
dynamic_data
)
return
E_OUTOFMEMORY
;
hres
=
get_func_obj_entry
(
This
,
func
,
&
entry
);
if
(
FAILED
(
hres
)
)
return
hres
;
if
(
!
dynamic_data
->
func_disps
)
{
dynamic_data
->
func_disps
=
heap_alloc_zero
(
This
->
data
->
data
->
func_disp_cnt
*
sizeof
(
func_disp_t
*
));
if
(
!
dynamic_data
->
func_disps
)
return
E_OUTOFMEMORY
;
}
V_VT
(
res
)
=
VT_DISPATCH
;
V_DISPATCH
(
res
)
=
entry
->
val
;
if
(
V_DISPATCH
(
res
))
IDispatch_AddRef
(
V_DISPATCH
(
res
));
hres
=
S_OK
;
break
;
}
case
DISPATCH_PROPERTYPUT
:
{
func_obj_entry_t
*
entry
;
VARIANT
*
v
;
if
(
!
dynamic_data
->
func_disps
[
func
->
func_disp_idx
])
{
dynamic_data
->
func_disps
[
func
->
func_disp_idx
]
=
create_func_disp
(
This
,
func
);
if
(
!
dynamic_data
->
func_disps
[
func
->
func_disp_idx
])
return
E_OUTOFMEMORY
;
if
(
dp
->
cArgs
!=
1
||
(
dp
->
cNamedArgs
==
1
&&
*
dp
->
rgdispidNamedArgs
!=
DISPID_PROPERTYPUT
)
||
dp
->
cNamedArgs
>
1
)
{
FIXME
(
"invalid args
\n
"
);
return
E_INVALIDARG
;
}
V_VT
(
res
)
=
VT_DISPATCH
;
V_DISPATCH
(
res
)
=
(
IDispatch
*
)
&
dynamic_data
->
func_disps
[
func
->
func_disp_idx
]
->
dispex
.
IDispatchEx_iface
;
IDispatch_AddRef
(
V_DISPATCH
(
res
));
v
=
dp
->
rgvarg
;
/* FIXME: not exactly right */
if
(
V_VT
(
v
)
!=
VT_DISPATCH
)
return
E_NOTIMPL
;
hres
=
get_func_obj_entry
(
This
,
func
,
&
entry
);
if
(
FAILED
(
hres
))
return
hres
;
if
(
entry
->
val
)
IDispatch_Release
(
entry
->
val
);
entry
->
val
=
V_DISPATCH
(
v
);
if
(
entry
->
val
)
IDispatch_AddRef
(
entry
->
val
);
hres
=
S_OK
;
break
;
}
default:
FIXME
(
"Unimplemented flags %x
\n
"
,
flags
);
/* fall through */
case
DISPATCH_PROPERTYPUT
:
hres
=
E_NOTIMPL
;
}
...
...
@@ -1445,13 +1522,15 @@ void release_dispex(DispatchEx *This)
heap_free
(
This
->
dynamic_data
->
props
);
if
(
This
->
dynamic_data
->
func_disps
)
{
unsigned
i
;
func_obj_entry_t
*
iter
;
for
(
i
=
0
;
i
<
This
->
data
->
data
->
func_disp_cnt
;
i
++
)
{
if
(
This
->
dynamic_data
->
func_disps
[
i
]
)
{
release_dispex
(
&
This
->
dynamic_data
->
func_disps
[
i
]
->
dispex
)
;
heap_free
(
This
->
dynamic_data
->
func_disps
[
i
]
);
for
(
i
ter
=
This
->
dynamic_data
->
func_disps
;
iter
<
This
->
dynamic_data
->
func_disps
+
This
->
data
->
data
->
func_disp_cnt
;
iter
++
)
{
if
(
iter
->
func_obj
)
{
iter
->
func_obj
->
obj
=
NULL
;
IDispatchEx_Release
(
&
iter
->
func_obj
->
dispex
.
IDispatchEx_iface
);
}
if
(
iter
->
val
)
IDispatch_Release
(
iter
->
val
);
}
heap_free
(
This
->
dynamic_data
->
func_disps
);
...
...
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