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
2da4d47b
Commit
2da4d47b
authored
Apr 21, 2023
by
Connor McAdams
Committed by
Alexandre Julliard
Jun 19, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
uiautomationcore: Prevent creation of duplicate serverside events.
Signed-off-by:
Connor McAdams
<
cmcadams@codeweavers.com
>
parent
549a276c
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
100 additions
and
24 deletions
+100
-24
uia_classes.idl
dlls/uiautomationcore/uia_classes.idl
+1
-1
uia_client.c
dlls/uiautomationcore/uia_client.c
+15
-7
uia_event.c
dlls/uiautomationcore/uia_event.c
+78
-14
uia_private.h
dlls/uiautomationcore/uia_private.h
+6
-1
uia_provider.c
dlls/uiautomationcore/uia_provider.c
+0
-1
No files found.
dlls/uiautomationcore/uia_classes.idl
View file @
2da4d47b
...
...
@@ -103,6 +103,6 @@ library UIA_wine_private
HRESULT
get_prop_val
(
[
in
]
const
GUID
*
prop_guid
,
[
out
,
retval
]
VARIANT
*
ret_val
)
;
HRESULT
disconnect
()
;
HRESULT
get_hwnd
(
[
out
,
retval
]
ULONG
*
out_hwnd
)
;
HRESULT
attach_event
(
[
out
,
retval
]
IWineUiaEvent
**
ret_event
)
;
HRESULT
attach_event
(
[
in
]
long
proc_id
,
[
in
]
long
event_cookie
,
[
out
,
retval
]
IWineUiaEvent
**
ret_event
)
;
}
}
dlls/uiautomationcore/uia_client.c
View file @
2da4d47b
...
...
@@ -539,23 +539,29 @@ static HRESULT WINAPI uia_node_get_hwnd(IWineUiaNode *iface, ULONG *out_hwnd)
return
S_OK
;
}
static
HRESULT
WINAPI
uia_node_attach_event
(
IWineUiaNode
*
iface
,
IWineUiaEvent
**
ret_event
)
static
HRESULT
WINAPI
uia_node_attach_event
(
IWineUiaNode
*
iface
,
long
proc_id
,
long
event_cookie
,
IWineUiaEvent
**
ret_event
)
{
struct
uia_node
*
node
=
impl_from_IWineUiaNode
(
iface
);
struct
uia_event
*
event
=
NULL
;
HRESULT
hr
;
TRACE
(
"%p, %
p
\n
"
,
nod
e
,
ret_event
);
TRACE
(
"%p, %
ld, %ld, %p
\n
"
,
node
,
proc_id
,
event_cooki
e
,
ret_event
);
*
ret_event
=
NULL
;
hr
=
create_serverside_uia_event
(
&
event
);
hr
=
create_serverside_uia_event
(
&
event
,
proc_id
,
event_cookie
);
if
(
FAILED
(
hr
))
return
hr
;
/* Newly created serverside event. */
if
(
hr
==
S_OK
)
*
ret_event
=
&
event
->
IWineUiaEvent_iface
;
hr
=
attach_event_to_node_provider
(
iface
,
0
,
(
HUIAEVENT
)
event
);
if
(
FAILED
(
hr
))
{
IWineUiaEvent_Release
(
&
event
->
IWineUiaEvent_iface
);
*
ret_event
=
NULL
;
return
hr
;
}
...
...
@@ -563,9 +569,11 @@ static HRESULT WINAPI uia_node_attach_event(IWineUiaNode *iface, IWineUiaEvent *
* Attach this nested node to the serverside event to keep the provider
* thread alive.
*/
IWineUiaNode_AddRef
(
iface
);
event
->
u
.
serverside
.
node
=
iface
;
*
ret_event
=
&
event
->
IWineUiaEvent_iface
;
if
(
*
ret_event
)
{
IWineUiaNode_AddRef
(
iface
);
event
->
u
.
serverside
.
node
=
iface
;
}
return
hr
;
}
...
...
@@ -2282,7 +2290,7 @@ static HRESULT WINAPI uia_nested_node_provider_attach_event(IWineUiaProvider *if
TRACE
(
"%p, %#Ix
\n
"
,
iface
,
huiaevent
);
hr
=
IWineUiaNode_attach_event
(
prov
->
nested_node
,
&
remote_event
);
hr
=
IWineUiaNode_attach_event
(
prov
->
nested_node
,
GetCurrentProcessId
(),
event
->
event_cookie
,
&
remote_event
);
if
(
FAILED
(
hr
)
||
!
remote_event
)
return
hr
;
...
...
dlls/uiautomationcore/uia_event.c
View file @
2da4d47b
...
...
@@ -57,6 +57,10 @@ static struct uia_event_map
{
struct
rb_tree
event_map
;
LONG
event_count
;
/* rb_tree for serverside events, sorted by PID/event cookie. */
struct
rb_tree
serverside_event_map
;
LONG
serverside_event_count
;
}
uia_event_map
;
struct
uia_event_map_entry
...
...
@@ -77,6 +81,22 @@ struct uia_event_map_entry
struct
list
events_list
;
};
struct
uia_event_identifier
{
LONG
event_cookie
;
LONG
proc_id
;
};
static
int
uia_serverside_event_id_compare
(
const
void
*
key
,
const
struct
rb_entry
*
entry
)
{
struct
uia_event
*
event
=
RB_ENTRY_VALUE
(
entry
,
struct
uia_event
,
u
.
serverside
.
serverside_event_entry
);
struct
uia_event_identifier
*
event_id
=
(
struct
uia_event_identifier
*
)
key
;
if
(
event_id
->
proc_id
!=
event
->
u
.
serverside
.
proc_id
)
return
(
event_id
->
proc_id
>
event
->
u
.
serverside
.
proc_id
)
-
(
event_id
->
proc_id
<
event
->
u
.
serverside
.
proc_id
);
else
return
(
event_id
->
event_cookie
>
event
->
event_cookie
)
-
(
event_id
->
event_cookie
<
event
->
event_cookie
);
}
static
CRITICAL_SECTION
event_map_cs
;
static
CRITICAL_SECTION_DEBUG
event_map_cs_debug
=
{
...
...
@@ -231,8 +251,15 @@ static ULONG WINAPI uia_event_Release(IWineUiaEvent *iface)
if
(
event
->
u
.
clientside
.
mta_cookie
)
CoDecrementMTAUsage
(
event
->
u
.
clientside
.
mta_cookie
);
}
else
if
(
event
->
u
.
serverside
.
node
)
IWineUiaNode_Release
(
event
->
u
.
serverside
.
node
);
else
{
EnterCriticalSection
(
&
event_map_cs
);
rb_remove
(
&
uia_event_map
.
serverside_event_map
,
&
event
->
u
.
serverside
.
serverside_event_entry
);
uia_event_map
.
serverside_event_count
--
;
LeaveCriticalSection
(
&
event_map_cs
);
if
(
event
->
u
.
serverside
.
node
)
IWineUiaNode_Release
(
event
->
u
.
serverside
.
node
);
}
for
(
i
=
0
;
i
<
event
->
event_advisers_count
;
i
++
)
IWineUiaEventAdviser_Release
(
event
->
event_advisers
[
i
]);
...
...
@@ -292,8 +319,7 @@ static struct uia_event *unsafe_impl_from_IWineUiaEvent(IWineUiaEvent *iface)
return
CONTAINING_RECORD
(
iface
,
struct
uia_event
,
IWineUiaEvent_iface
);
}
static
HRESULT
create_uia_event
(
struct
uia_event
**
out_event
,
int
event_id
,
int
scope
,
UiaEventCallback
*
cback
,
SAFEARRAY
*
runtime_id
)
static
HRESULT
create_uia_event
(
struct
uia_event
**
out_event
,
LONG
event_cookie
,
int
event_type
)
{
struct
uia_event
*
event
=
heap_alloc_zero
(
sizeof
(
*
event
));
...
...
@@ -303,30 +329,68 @@ static HRESULT create_uia_event(struct uia_event **out_event, int event_id, int
event
->
IWineUiaEvent_iface
.
lpVtbl
=
&
uia_event_vtbl
;
event
->
ref
=
1
;
event
->
event_cookie
=
event_cookie
;
event
->
event_type
=
event_type
;
*
out_event
=
event
;
return
S_OK
;
}
static
HRESULT
create_clientside_uia_event
(
struct
uia_event
**
out_event
,
int
event_id
,
int
scope
,
UiaEventCallback
*
cback
,
SAFEARRAY
*
runtime_id
)
{
struct
uia_event
*
event
=
NULL
;
static
LONG
next_event_cookie
;
HRESULT
hr
;
*
out_event
=
NULL
;
hr
=
create_uia_event
(
&
event
,
InterlockedIncrement
(
&
next_event_cookie
),
EVENT_TYPE_CLIENTSIDE
);
if
(
FAILED
(
hr
))
return
hr
;
event
->
runtime_id
=
runtime_id
;
event
->
event_id
=
event_id
;
event
->
scope
=
scope
;
event
->
u
.
clientside
.
cback
=
cback
;
event
->
event_type
=
EVENT_TYPE_CLIENTSIDE
;
*
out_event
=
event
;
return
S_OK
;
}
HRESULT
create_serverside_uia_event
(
struct
uia_event
**
out_event
)
HRESULT
create_serverside_uia_event
(
struct
uia_event
**
out_event
,
LONG
process_id
,
LONG
event_cookie
)
{
struct
uia_event
*
event
=
heap_alloc_zero
(
sizeof
(
*
event
));
struct
uia_event_identifier
event_identifier
=
{
event_cookie
,
process_id
};
struct
rb_entry
*
rb_entry
;
struct
uia_event
*
event
;
HRESULT
hr
=
S_OK
;
/*
* Attempt to lookup an existing event for this PID/event_cookie. If there
* is one, return S_FALSE.
*/
*
out_event
=
NULL
;
if
(
!
event
)
return
E_OUTOFMEMORY
;
EnterCriticalSection
(
&
event_map_cs
);
if
(
uia_event_map
.
serverside_event_count
&&
(
rb_entry
=
rb_get
(
&
uia_event_map
.
serverside_event_map
,
&
event_identifier
)))
{
*
out_event
=
RB_ENTRY_VALUE
(
rb_entry
,
struct
uia_event
,
u
.
serverside
.
serverside_event_entry
);
hr
=
S_FALSE
;
goto
exit
;
}
event
->
IWineUiaEvent_iface
.
lpVtbl
=
&
uia_event_vtbl
;
event
->
ref
=
1
;
event
->
event_type
=
EVENT_TYPE_SERVERSIDE
;
hr
=
create_uia_event
(
&
event
,
event_cookie
,
EVENT_TYPE_SERVERSIDE
)
;
if
(
FAILED
(
hr
))
goto
exit
;
event
->
u
.
serverside
.
proc_id
=
process_id
;
uia_event_map
.
serverside_event_count
++
;
if
(
uia_event_map
.
serverside_event_count
==
1
)
rb_init
(
&
uia_event_map
.
serverside_event_map
,
uia_serverside_event_id_compare
);
rb_put
(
&
uia_event_map
.
serverside_event_map
,
&
event_identifier
,
&
event
->
u
.
serverside
.
serverside_event_entry
);
*
out_event
=
event
;
return
S_OK
;
exit:
LeaveCriticalSection
(
&
event_map_cs
);
return
hr
;
}
static
HRESULT
uia_event_add_event_adviser
(
IWineUiaEventAdviser
*
adviser
,
struct
uia_event
*
event
)
...
...
@@ -614,7 +678,7 @@ HRESULT WINAPI UiaAddEvent(HUIANODE huianode, EVENTID event_id, UiaEventCallback
if
(
FAILED
(
hr
))
return
hr
;
hr
=
create_uia_event
(
&
event
,
event_id
,
scope
,
callback
,
sa
);
hr
=
create_
clientside_
uia_event
(
&
event
,
event_id
,
scope
,
callback
,
sa
);
if
(
FAILED
(
hr
))
{
SafeArrayDestroy
(
sa
);
...
...
dlls/uiautomationcore/uia_private.h
View file @
2da4d47b
...
...
@@ -21,6 +21,7 @@
#include "uiautomation.h"
#include "uia_classes.h"
#include "wine/list.h"
#include "wine/rbtree.h"
#include "wine/heap.h"
extern
HMODULE
huia_module
DECLSPEC_HIDDEN
;
...
...
@@ -116,6 +117,7 @@ struct uia_event
struct
uia_event_map_entry
*
event_map_entry
;
LONG
event_defunct
;
LONG
event_cookie
;
int
event_type
;
union
{
...
...
@@ -137,6 +139,9 @@ struct uia_event
* event thread.
*/
IWineUiaNode
*
node
;
struct
rb_entry
serverside_event_entry
;
LONG
proc_id
;
}
serverside
;
}
u
;
};
...
...
@@ -196,7 +201,7 @@ BOOL uia_condition_matched(HRESULT hr) DECLSPEC_HIDDEN;
HRESULT
create_uia_iface
(
IUnknown
**
iface
,
BOOL
is_cui8
)
DECLSPEC_HIDDEN
;
/* uia_event.c */
HRESULT
create_serverside_uia_event
(
struct
uia_event
**
out_event
)
DECLSPEC_HIDDEN
;
HRESULT
create_serverside_uia_event
(
struct
uia_event
**
out_event
,
LONG
process_id
,
LONG
event_cookie
)
DECLSPEC_HIDDEN
;
HRESULT
uia_event_add_provider_event_adviser
(
IRawElementProviderAdviseEvents
*
advise_events
,
struct
uia_event
*
event
)
DECLSPEC_HIDDEN
;
HRESULT
uia_event_add_serverside_event_adviser
(
IWineUiaEvent
*
serverside_event
,
struct
uia_event
*
event
)
DECLSPEC_HIDDEN
;
...
...
dlls/uiautomationcore/uia_provider.c
View file @
2da4d47b
...
...
@@ -20,7 +20,6 @@
#include "ocidl.h"
#include "wine/debug.h"
#include "wine/rbtree.h"
#include "initguid.h"
#include "wine/iaccessible2.h"
...
...
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