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
0decadd6
Commit
0decadd6
authored
Mar 25, 2019
by
Jacek Caban
Committed by
Alexandre Julliard
Mar 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntoskrnl.exe: Support creating event objects from server handle.
Signed-off-by:
Jacek Caban
<
jacek@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
a5c2f043
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
91 additions
and
6 deletions
+91
-6
ntoskrnl_private.h
dlls/ntoskrnl.exe/ntoskrnl_private.h
+2
-0
sync.c
dlls/ntoskrnl.exe/sync.c
+41
-2
driver.c
dlls/ntoskrnl.exe/tests/driver.c
+38
-3
event.c
server/event.c
+10
-1
No files found.
dlls/ntoskrnl.exe/ntoskrnl_private.h
View file @
0decadd6
...
...
@@ -27,6 +27,8 @@ struct _OBJECT_TYPE {
void
(
*
release
)(
void
*
);
/* called when the last reference is released */
};
void
*
alloc_kernel_object
(
POBJECT_TYPE
type
,
HANDLE
handle
,
SIZE_T
size
,
LONG
ref
)
DECLSPEC_HIDDEN
;
extern
POBJECT_TYPE
ExEventObjectType
;
extern
POBJECT_TYPE
ExSemaphoreObjectType
;
extern
POBJECT_TYPE
IoDeviceObjectType
;
...
...
dlls/ntoskrnl.exe/sync.c
View file @
0decadd6
...
...
@@ -76,6 +76,13 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
EnterCriticalSection
(
&
sync_cs
);
for
(
i
=
0
;
i
<
count
;
i
++
)
{
if
(
objs
[
i
]
->
WaitListHead
.
Blink
==
INVALID_HANDLE_VALUE
)
{
FIXME
(
"unsupported on kernel objects
\n
"
);
handles
[
i
]
=
INVALID_HANDLE_VALUE
;
continue
;
}
++*
((
ULONG_PTR
*
)
&
objs
[
i
]
->
WaitListHead
.
Flink
);
if
(
!
objs
[
i
]
->
WaitListHead
.
Blink
)
{
...
...
@@ -127,6 +134,8 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
}
}
if
(
objs
[
i
]
->
WaitListHead
.
Blink
==
INVALID_HANDLE_VALUE
)
continue
;
if
(
!--*
((
ULONG_PTR
*
)
&
objs
[
i
]
->
WaitListHead
.
Flink
))
{
switch
(
objs
[
i
]
->
Type
)
...
...
@@ -186,10 +195,24 @@ void WINAPI KeInitializeEvent( PRKEVENT event, EVENT_TYPE type, BOOLEAN state )
event
->
Header
.
WaitListHead
.
Flink
=
NULL
;
}
static
void
*
create_event_object
(
HANDLE
handle
)
{
EVENT_BASIC_INFORMATION
info
;
KEVENT
*
event
;
if
(
!
(
event
=
alloc_kernel_object
(
ExEventObjectType
,
handle
,
sizeof
(
*
event
),
0
)))
return
NULL
;
if
(
!
NtQueryEvent
(
handle
,
EventBasicInformation
,
&
info
,
sizeof
(
info
),
NULL
))
KeInitializeEvent
(
event
,
info
.
EventType
,
info
.
EventState
);
event
->
Header
.
WaitListHead
.
Blink
=
INVALID_HANDLE_VALUE
;
/* mark as kernel object */
return
event
;
}
static
const
WCHAR
event_type_name
[]
=
{
'E'
,
'v'
,
'e'
,
'n'
,
't'
,
0
};
static
struct
_OBJECT_TYPE
event_type
=
{
event_type_name
,
create_event_object
};
POBJECT_TYPE
ExEventObjectType
=
&
event_type
;
...
...
@@ -200,15 +223,23 @@ POBJECT_TYPE ExEventObjectType = &event_type;
LONG
WINAPI
KeSetEvent
(
PRKEVENT
event
,
KPRIORITY
increment
,
BOOLEAN
wait
)
{
HANDLE
handle
;
LONG
ret
;
ULONG
ret
=
0
;
TRACE
(
"event %p, increment %d, wait %u.
\n
"
,
event
,
increment
,
wait
);
if
(
event
->
Header
.
WaitListHead
.
Blink
!=
INVALID_HANDLE_VALUE
)
{
EnterCriticalSection
(
&
sync_cs
);
ret
=
InterlockedExchange
(
&
event
->
Header
.
SignalState
,
TRUE
);
if
((
handle
=
event
->
Header
.
WaitListHead
.
Blink
))
SetEvent
(
handle
);
LeaveCriticalSection
(
&
sync_cs
);
}
else
{
FIXME
(
"unsupported on kernel objects
\n
"
);
event
->
Header
.
SignalState
=
TRUE
;
}
return
ret
;
}
...
...
@@ -219,15 +250,23 @@ LONG WINAPI KeSetEvent( PRKEVENT event, KPRIORITY increment, BOOLEAN wait )
LONG
WINAPI
KeResetEvent
(
PRKEVENT
event
)
{
HANDLE
handle
;
LONG
ret
;
ULONG
ret
=
0
;
TRACE
(
"event %p.
\n
"
,
event
);
if
(
event
->
Header
.
WaitListHead
.
Blink
!=
INVALID_HANDLE_VALUE
)
{
EnterCriticalSection
(
&
sync_cs
);
ret
=
InterlockedExchange
(
&
event
->
Header
.
SignalState
,
FALSE
);
if
((
handle
=
event
->
Header
.
WaitListHead
.
Blink
))
ResetEvent
(
handle
);
LeaveCriticalSection
(
&
sync_cs
);
}
else
{
FIXME
(
"unsupported on kernel objects
\n
"
);
event
->
Header
.
SignalState
=
FALSE
;
}
return
ret
;
}
...
...
dlls/ntoskrnl.exe/tests/driver.c
View file @
0decadd6
...
...
@@ -308,6 +308,14 @@ static NTSTATUS wait_multiple(ULONG count, void *objs[], WAIT_TYPE wait_type, UL
return
KeWaitForMultipleObjects
(
count
,
objs
,
wait_type
,
Executive
,
KernelMode
,
FALSE
,
&
integer
,
NULL
);
}
static
NTSTATUS
wait_single_handle
(
HANDLE
handle
,
ULONGLONG
timeout
)
{
LARGE_INTEGER
integer
;
integer
.
QuadPart
=
timeout
;
return
ZwWaitForSingleObject
(
handle
,
FALSE
,
&
integer
);
}
static
void
run_thread
(
PKSTART_ROUTINE
proc
,
void
*
arg
)
{
OBJECT_ATTRIBUTES
attr
=
{
0
};
...
...
@@ -341,11 +349,13 @@ static void WINAPI mutex_thread(void *arg)
static
void
test_sync
(
void
)
{
KSEMAPHORE
semaphore
,
semaphore2
;
KEVENT
manual_event
,
auto_event
;
KEVENT
manual_event
,
auto_event
,
*
event
;
KTIMER
timer
;
LARGE_INTEGER
timeout
;
OBJECT_ATTRIBUTES
attr
;
void
*
objs
[
2
];
NTSTATUS
ret
;
HANDLE
handle
;
int
i
;
KeInitializeEvent
(
&
manual_event
,
NotificationEvent
,
FALSE
);
...
...
@@ -440,6 +450,33 @@ static void test_sync(void)
ret
=
wait_multiple
(
2
,
objs
,
WaitAny
,
0
);
ok
(
ret
==
1
,
"got %#x
\n
"
,
ret
);
InitializeObjectAttributes
(
&
attr
,
NULL
,
OBJ_KERNEL_HANDLE
,
NULL
,
NULL
);
ret
=
ZwCreateEvent
(
&
handle
,
SYNCHRONIZE
,
&
attr
,
NotificationEvent
,
TRUE
);
ok
(
!
ret
,
"ZwCreateEvent failed: %#x
\n
"
,
ret
);
ret
=
ObReferenceObjectByHandle
(
handle
,
SYNCHRONIZE
,
*
pExEventObjectType
,
KernelMode
,
(
void
**
)
&
event
,
NULL
);
ok
(
!
ret
,
"ObReferenceObjectByHandle failed: %#x
\n
"
,
ret
);
ret
=
wait_single
(
event
,
0
);
todo_wine
ok
(
ret
==
0
,
"got %#x
\n
"
,
ret
);
KeResetEvent
(
event
);
ret
=
wait_single
(
event
,
0
);
ok
(
ret
==
STATUS_TIMEOUT
,
"got %#x
\n
"
,
ret
);
ret
=
wait_single_handle
(
handle
,
0
);
todo_wine
ok
(
ret
==
STATUS_TIMEOUT
,
"got %#x
\n
"
,
ret
);
KeSetEvent
(
event
,
0
,
FALSE
);
ret
=
wait_single
(
event
,
0
);
todo_wine
ok
(
ret
==
0
,
"got %#x
\n
"
,
ret
);
ret
=
wait_single_handle
(
handle
,
0
);
ok
(
!
ret
,
"got %#x
\n
"
,
ret
);
ZwClose
(
handle
);
ObDereferenceObject
(
event
);
/* test semaphores */
KeInitializeSemaphore
(
&
semaphore
,
0
,
5
);
...
...
@@ -731,14 +768,12 @@ static void test_ob_reference(const WCHAR *test_path)
status
=
ObReferenceObjectByHandle
(
event_handle
,
SYNCHRONIZE
,
*
pExEventObjectType
,
KernelMode
,
&
obj2
,
NULL
);
ok
(
!
status
,
"ObReferenceObjectByHandle failed: %#x
\n
"
,
status
);
todo_wine
ok
(
obj1
==
obj2
,
"obj1 != obj2
\n
"
);
ObDereferenceObject
(
obj2
);
status
=
ObReferenceObjectByHandle
(
event_handle
,
SYNCHRONIZE
,
NULL
,
KernelMode
,
&
obj2
,
NULL
);
ok
(
!
status
,
"ObReferenceObjectByHandle failed: %#x
\n
"
,
status
);
todo_wine
ok
(
obj1
==
obj2
,
"obj1 != obj2
\n
"
);
ObDereferenceObject
(
obj2
);
...
...
server/event.c
View file @
0decadd6
...
...
@@ -39,6 +39,7 @@
struct
event
{
struct
object
obj
;
/* object header */
struct
list
kernel_object
;
/* list of kernel object pointers */
int
manual_reset
;
/* is it a manual reset event? */
int
signaled
;
/* event has been signaled */
};
...
...
@@ -49,6 +50,7 @@ static int event_signaled( struct object *obj, struct wait_queue_entry *entry );
static
void
event_satisfied
(
struct
object
*
obj
,
struct
wait_queue_entry
*
entry
);
static
unsigned
int
event_map_access
(
struct
object
*
obj
,
unsigned
int
access
);
static
int
event_signal
(
struct
object
*
obj
,
unsigned
int
access
);
static
struct
list
*
event_get_kernel_obj_list
(
struct
object
*
obj
);
static
const
struct
object_ops
event_ops
=
{
...
...
@@ -68,7 +70,7 @@ static const struct object_ops event_ops =
directory_link_name
,
/* link_name */
default_unlink_name
,
/* unlink_name */
no_open_file
,
/* open_file */
no_kernel_obj_list
,
/* get_kernel_obj_list */
event_get_kernel_obj_list
,
/* get_kernel_obj_list */
no_close_handle
,
/* close_handle */
no_destroy
/* destroy */
};
...
...
@@ -119,6 +121,7 @@ struct event *create_event( struct object *root, const struct unicode_str *name,
if
(
get_error
()
!=
STATUS_OBJECT_NAME_EXISTS
)
{
/* initialize it if it didn't already exist */
list_init
(
&
event
->
kernel_object
);
event
->
manual_reset
=
manual_reset
;
event
->
signaled
=
initial_state
;
}
...
...
@@ -204,6 +207,12 @@ static int event_signal( struct object *obj, unsigned int access )
return
1
;
}
static
struct
list
*
event_get_kernel_obj_list
(
struct
object
*
obj
)
{
struct
event
*
event
=
(
struct
event
*
)
obj
;
return
&
event
->
kernel_object
;
}
struct
keyed_event
*
create_keyed_event
(
struct
object
*
root
,
const
struct
unicode_str
*
name
,
unsigned
int
attr
,
const
struct
security_descriptor
*
sd
)
{
...
...
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