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
e561ce4b
Commit
e561ce4b
authored
Jun 06, 2020
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Move NtRaiseException() implementation to the Unix library.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3cc3b445
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
309 additions
and
277 deletions
+309
-277
exception.c
dlls/ntdll/exception.c
+9
-0
ntdll.spec
dlls/ntdll/ntdll.spec
+1
-1
signal_arm.c
dlls/ntdll/signal_arm.c
+47
-12
signal_arm64.c
dlls/ntdll/signal_arm64.c
+45
-83
signal_i386.c
dlls/ntdll/signal_i386.c
+38
-85
signal_powerpc.c
dlls/ntdll/signal_powerpc.c
+41
-10
signal_x86_64.c
dlls/ntdll/signal_x86_64.c
+41
-85
loader.c
dlls/ntdll/unix/loader.c
+1
-0
thread.c
dlls/ntdll/unix/thread.c
+83
-0
unix_private.h
dlls/ntdll/unix/unix_private.h
+1
-0
unixlib.h
dlls/ntdll/unixlib.h
+2
-1
No files found.
dlls/ntdll/exception.c
View file @
e561ce4b
...
...
@@ -239,6 +239,15 @@ void raise_status( NTSTATUS status, EXCEPTION_RECORD *rec )
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
return
unix_funcs
->
NtRaiseException
(
rec
,
context
,
first_chance
);
}
/***********************************************************************
* RtlRaiseStatus (NTDLL.@)
*
...
...
dlls/ntdll/ntdll.spec
View file @
e561ce4b
...
...
@@ -69,7 +69,7 @@
@ stub KiRaiseUserExceptionDispatcher
@ stub KiUserApcDispatcher
@ stub KiUserCallbackDispatcher
@ st
ub KiUserExceptionDispatcher
@ st
dcall -norelay KiUserExceptionDispatcher(ptr ptr)
# @ stub LdrAccessOutOfProcessResource
@ stdcall LdrAccessResource(long ptr ptr ptr)
@ stdcall LdrAddDllDirectory(ptr ptr)
...
...
dlls/ntdll/signal_arm.c
View file @
e561ce4b
...
...
@@ -492,6 +492,52 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
}
/*******************************************************************
* KiUserExceptionDispatcher (NTDLL.@)
*/
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p pc=%08x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Pc
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
TRACE
(
" r0=%08x r1=%08x r2=%08x r3=%08x r4=%08x r5=%08x
\n
"
,
context
->
R0
,
context
->
R1
,
context
->
R2
,
context
->
R3
,
context
->
R4
,
context
->
R5
);
TRACE
(
" r6=%08x r7=%08x r8=%08x r9=%08x r10=%08x r11=%08x
\n
"
,
context
->
R6
,
context
->
R7
,
context
->
R8
,
context
->
R9
,
context
->
R10
,
context
->
R11
);
TRACE
(
" r12=%08x sp=%08x lr=%08x pc=%08x cpsr=%08x
\n
"
,
context
->
R12
,
context
->
Sp
,
context
->
Lr
,
context
->
Pc
,
context
->
Cpsr
);
}
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
RtlRaiseStatus
(
status
);
return
NtRaiseException
(
rec
,
context
,
FALSE
);
}
/**********************************************************************
* segv_handler
*
...
...
@@ -833,15 +879,6 @@ void WINAPI RtlUnwind( void *endframe, void *target_ip, EXCEPTION_RECORD *rec, v
}
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
...
...
@@ -849,12 +886,10 @@ NTSTATUS WINAPI NtRaiseException( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL
void
WINAPI
RtlRaiseException
(
EXCEPTION_RECORD
*
rec
)
{
CONTEXT
context
;
NTSTATUS
status
;
RtlCaptureContext
(
&
context
);
rec
->
ExceptionAddress
=
(
LPVOID
)
context
.
Pc
;
status
=
raise_exception
(
rec
,
&
context
,
TRUE
);
if
(
status
)
raise_status
(
status
,
rec
);
RtlRaiseStatus
(
NtRaiseException
(
rec
,
&
context
,
TRUE
));
}
/*************************************************************************
...
...
dlls/ntdll/signal_arm64.c
View file @
e561ce4b
...
...
@@ -736,77 +736,60 @@ static NTSTATUS call_function_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_con
return
STATUS_UNHANDLED_EXCEPTION
;
}
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
* KiUserExceptionDispatcher (NTDLL.@)
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
DWORD
c
;
if
(
first_chance
)
TRACE
(
"code=%x flags=%x addr=%p pc=%lx tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Pc
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%016lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p pc=%lx tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Pc
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%016lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
{
TRACE
(
" x0=%016lx x1=%016lx x2=%016lx x3=%016lx
\n
"
,
context
->
u
.
s
.
X0
,
context
->
u
.
s
.
X1
,
context
->
u
.
s
.
X2
,
context
->
u
.
s
.
X3
);
TRACE
(
" x4=%016lx x5=%016lx x6=%016lx x7=%016lx
\n
"
,
context
->
u
.
s
.
X4
,
context
->
u
.
s
.
X5
,
context
->
u
.
s
.
X6
,
context
->
u
.
s
.
X7
);
TRACE
(
" x8=%016lx x9=%016lx x10=%016lx x11=%016lx
\n
"
,
context
->
u
.
s
.
X8
,
context
->
u
.
s
.
X9
,
context
->
u
.
s
.
X10
,
context
->
u
.
s
.
X11
);
TRACE
(
" x12=%016lx x13=%016lx x14=%016lx x15=%016lx
\n
"
,
context
->
u
.
s
.
X12
,
context
->
u
.
s
.
X13
,
context
->
u
.
s
.
X14
,
context
->
u
.
s
.
X15
);
TRACE
(
" x16=%016lx x17=%016lx x18=%016lx x19=%016lx
\n
"
,
context
->
u
.
s
.
X16
,
context
->
u
.
s
.
X17
,
context
->
u
.
s
.
X18
,
context
->
u
.
s
.
X19
);
TRACE
(
" x20=%016lx x21=%016lx x22=%016lx x23=%016lx
\n
"
,
context
->
u
.
s
.
X20
,
context
->
u
.
s
.
X21
,
context
->
u
.
s
.
X22
,
context
->
u
.
s
.
X23
);
TRACE
(
" x24=%016lx x25=%016lx x26=%016lx x27=%016lx
\n
"
,
context
->
u
.
s
.
X24
,
context
->
u
.
s
.
X25
,
context
->
u
.
s
.
X26
,
context
->
u
.
s
.
X27
);
TRACE
(
" x28=%016lx fp=%016lx lr=%016lx sp=%016lx
\n
"
,
context
->
u
.
s
.
X28
,
context
->
u
.
s
.
Fp
,
context
->
u
.
s
.
Lr
,
context
->
Sp
);
}
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
goto
done
;
if
((
status
=
call_function_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
goto
done
;
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
else
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
rec
->
ExceptionCode
);
TRACE
(
" x0=%016lx x1=%016lx x2=%016lx x3=%016lx
\n
"
,
context
->
u
.
s
.
X0
,
context
->
u
.
s
.
X1
,
context
->
u
.
s
.
X2
,
context
->
u
.
s
.
X3
);
TRACE
(
" x4=%016lx x5=%016lx x6=%016lx x7=%016lx
\n
"
,
context
->
u
.
s
.
X4
,
context
->
u
.
s
.
X5
,
context
->
u
.
s
.
X6
,
context
->
u
.
s
.
X7
);
TRACE
(
" x8=%016lx x9=%016lx x10=%016lx x11=%016lx
\n
"
,
context
->
u
.
s
.
X8
,
context
->
u
.
s
.
X9
,
context
->
u
.
s
.
X10
,
context
->
u
.
s
.
X11
);
TRACE
(
" x12=%016lx x13=%016lx x14=%016lx x15=%016lx
\n
"
,
context
->
u
.
s
.
X12
,
context
->
u
.
s
.
X13
,
context
->
u
.
s
.
X14
,
context
->
u
.
s
.
X15
);
TRACE
(
" x16=%016lx x17=%016lx x18=%016lx x19=%016lx
\n
"
,
context
->
u
.
s
.
X16
,
context
->
u
.
s
.
X17
,
context
->
u
.
s
.
X18
,
context
->
u
.
s
.
X19
);
TRACE
(
" x20=%016lx x21=%016lx x22=%016lx x23=%016lx
\n
"
,
context
->
u
.
s
.
X20
,
context
->
u
.
s
.
X21
,
context
->
u
.
s
.
X22
,
context
->
u
.
s
.
X23
);
TRACE
(
" x24=%016lx x25=%016lx x26=%016lx x27=%016lx
\n
"
,
context
->
u
.
s
.
X24
,
context
->
u
.
s
.
X25
,
context
->
u
.
s
.
X26
,
context
->
u
.
s
.
X27
);
TRACE
(
" x28=%016lx fp=%016lx lr=%016lx sp=%016lx
\n
"
,
context
->
u
.
s
.
X28
,
context
->
u
.
s
.
Fp
,
context
->
u
.
s
.
Lr
,
context
->
Sp
);
}
done:
return
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
((
status
=
call_function_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
RtlRaiseStatus
(
status
);
return
NtRaiseException
(
rec
,
context
,
FALSE
);
}
/***********************************************************************
...
...
@@ -833,14 +816,6 @@ static struct stack_layout *setup_exception( ucontext_t *sigcontext )
return
stack
;
}
/**********************************************************************
* raise_generic_exception
*/
static
void
WINAPI
raise_generic_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
TRUE
);
raise_status
(
status
,
rec
);
}
extern
void
raise_func_trampoline
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
raise_func
func
,
void
*
sp
);
__ASM_GLOBAL_FUNC
(
raise_func_trampoline
,
...
...
@@ -880,7 +855,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
PC_sig
(
sigcontext
)
=
(
ULONG_PTR
)
raise_func_trampoline
;
/* raise_generic_exception; */
REGn_sig
(
0
,
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
rec
;
/* first arg for raise_generic_exception */
REGn_sig
(
1
,
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
context
;
/* second arg for raise_generic_exception */
REGn_sig
(
2
,
sigcontext
)
=
(
ULONG_PTR
)
raise_generic_exception
;
/* third arg for raise_func_trampoline */
REGn_sig
(
2
,
sigcontext
)
=
(
ULONG_PTR
)
KiUserExceptionDispatcher
;
/* third arg for raise_func_trampoline */
REGn_sig
(
18
,
sigcontext
)
=
(
ULONG_PTR
)
NtCurrentTeb
();
}
...
...
@@ -1829,19 +1804,6 @@ void WINAPI RtlUnwind( void *frame, void *target_ip, EXCEPTION_RECORD *rec, void
RtlUnwindEx
(
frame
,
target_ip
,
rec
,
retval
,
&
context
,
NULL
);
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
if
(
first_chance
)
{
NTSTATUS
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
return
raise_exception
(
rec
,
context
,
first_chance
);
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
...
...
dlls/ntdll/signal_i386.c
View file @
e561ce4b
...
...
@@ -719,69 +719,51 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *context )
/*******************************************************************
* raise_exception
*
* Implementation of NtRaiseException.
* KiUserExceptionDispatcher (NTDLL.@)
*/
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%08x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Eip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
first_chance
)
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%08x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Eip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
{
TRACE
(
" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
TRACE
(
" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x
\n
"
,
context
->
Ebp
,
context
->
Esp
,
context
->
SegCs
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
,
context
->
EFlags
);
}
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
TRACE
(
" eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x
\n
"
,
context
->
Eax
,
context
->
Ebx
,
context
->
Ecx
,
context
->
Edx
,
context
->
Esi
,
context
->
Edi
);
TRACE
(
" ebp=%08x esp=%08x cs=%04x ds=%04x es=%04x fs=%04x gs=%04x flags=%08x
\n
"
,
context
->
Ebp
,
context
->
Esp
,
context
->
SegCs
,
context
->
SegDs
,
context
->
SegEs
,
context
->
SegFs
,
context
->
SegGs
,
context
->
EFlags
);
}
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
goto
done
;
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Eip
--
;
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
goto
done
;
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
/* last chance exception */
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
{
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
WINE_ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
WINE_ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
WINE_ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
rec
->
ExceptionCode
);
}
done:
return
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
RtlRaiseStatus
(
status
);
return
NtRaiseException
(
rec
,
context
,
FALSE
);
}
...
...
@@ -1513,20 +1495,6 @@ static struct stack_layout *setup_exception( ucontext_t *sigcontext )
}
/**********************************************************************
* raise_generic_exception
*
* Generic raise function for exceptions that don't need special treatment.
*/
static
void
WINAPI
raise_generic_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
status
=
raise_exception
(
rec
,
context
,
TRUE
);
raise_status
(
status
,
rec
);
}
/***********************************************************************
* setup_raise_exception
*
...
...
@@ -1542,7 +1510,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
return
;
}
ESP_sig
(
sigcontext
)
=
(
DWORD
)
stack
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
raise_generic_exception
;
EIP_sig
(
sigcontext
)
=
(
DWORD
)
KiUserExceptionDispatcher
;
/* clear single-step, direction, and align check flag */
EFL_sig
(
sigcontext
)
&=
~
(
0x100
|
0x400
|
0x40000
);
CS_sig
(
sigcontext
)
=
get_cs
();
...
...
@@ -1551,8 +1519,8 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
FS_sig
(
sigcontext
)
=
get_fs
();
GS_sig
(
sigcontext
)
=
get_gs
();
SS_sig
(
sigcontext
)
=
get_ds
();
stack
->
ret_addr
=
(
void
*
)
0xdeadbabe
;
/*
raise_generic_exception
must not return */
stack
->
rec_ptr
=
&
stack
->
rec
;
/* arguments for
raise_generic_exception
*/
stack
->
ret_addr
=
(
void
*
)
0xdeadbabe
;
/*
KiUserExceptionDispatcher
must not return */
stack
->
rec_ptr
=
&
stack
->
rec
;
/* arguments for
KiUserExceptionDispatcher
*/
stack
->
context_ptr
=
&
stack
->
context
;
}
...
...
@@ -2039,21 +2007,6 @@ __ASM_STDCALL_FUNC( RtlUnwind, 16,
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
if
(
first_chance
)
{
NTSTATUS
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
return
raise_exception
(
rec
,
context
,
first_chance
);
}
/*******************************************************************
* raise_exception_full_context
*
* Raise an exception with the full CPU context.
...
...
dlls/ntdll/signal_powerpc.c
View file @
e561ce4b
...
...
@@ -341,6 +341,47 @@ static NTSTATUS raise_exception( EXCEPTION_RECORD *rec, CONTEXT *context, BOOL f
}
/*******************************************************************
* KiUserExceptionDispatcher (NTDLL.@)
*/
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%x tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Iar
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
rec
->
NumberParameters
;
c
++
)
TRACE
(
" info[%d]=%08lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
/* FIXME: dump context */
}
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
RtlRaiseStatus
(
status
);
return
NtRaiseException
(
rec
,
context
,
FALSE
);
}
/**********************************************************************
* segv_handler
*
...
...
@@ -686,16 +727,6 @@ void WINAPI RtlUnwind( PVOID pEndFrame, PVOID targetIp, PEXCEPTION_RECORD pRecor
FIXME
(
"Not implemented on PowerPC
\n
"
);
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
first_chance
);
if
(
status
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
return
status
;
}
/***********************************************************************
* RtlRaiseException (NTDLL.@)
*/
...
...
dlls/ntdll/signal_x86_64.c
View file @
e561ce4b
...
...
@@ -2223,102 +2223,58 @@ static NTSTATUS call_stack_handlers( EXCEPTION_RECORD *rec, CONTEXT *orig_contex
}
static
NTSTATUS
raise_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
/*******************************************************************
* KiUserExceptionDispatcher (NTDLL.@)
*/
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
;
DWORD
c
;
if
(
first_chance
)
{
DWORD
c
;
TRACE
(
"code=%x flags=%x addr=%p ip=%lx tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Rip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
min
(
EXCEPTION_MAXIMUM_PARAMETERS
,
rec
->
NumberParameters
);
c
++
)
TRACE
(
" info[%d]=%016lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
ExceptionInformation
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
else
{
TRACE
(
" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx
\n
"
,
context
->
Rax
,
context
->
Rbx
,
context
->
Rcx
,
context
->
Rdx
);
TRACE
(
" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx
\n
"
,
context
->
Rsi
,
context
->
Rdi
,
context
->
Rbp
,
context
->
Rsp
);
TRACE
(
" r8=%016lx r9=%016lx r10=%016lx r11=%016lx
\n
"
,
context
->
R8
,
context
->
R9
,
context
->
R10
,
context
->
R11
);
TRACE
(
" r12=%016lx r13=%016lx r14=%016lx r15=%016lx
\n
"
,
context
->
R12
,
context
->
R13
,
context
->
R14
,
context
->
R15
);
}
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Rip
--
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
goto
done
;
TRACE
(
"code=%x flags=%x addr=%p ip=%lx tid=%04x
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
,
context
->
Rip
,
GetCurrentThreadId
()
);
for
(
c
=
0
;
c
<
min
(
EXCEPTION_MAXIMUM_PARAMETERS
,
rec
->
NumberParameters
);
c
++
)
TRACE
(
" info[%d]=%016lx
\n
"
,
c
,
rec
->
ExceptionInformation
[
c
]
);
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
goto
done
;
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
return
status
;
}
/* last chance exception */
status
=
send_debug_event
(
rec
,
FALSE
,
context
);
if
(
status
!=
DBG_CONTINUE
)
if
(
rec
->
ExceptionCode
==
EXCEPTION_WINE_STUB
)
{
if
(
rec
->
Exception
Flags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
if
(
rec
->
Exception
Information
[
1
]
>>
16
)
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%s, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
(
char
*
)
rec
->
ExceptionInformation
[
1
]
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
rec
->
ExceptionCode
);
MESSAGE
(
"wine: Call from %p to unimplemented function %s.%ld, aborting
\n
"
,
rec
->
ExceptionAddress
,
(
char
*
)
rec
->
ExceptionInformation
[
0
],
rec
->
ExceptionInformation
[
1
]
);
}
done:
return
NtSetContextThread
(
GetCurrentThread
(),
context
);
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
;
if
(
first_chance
)
else
{
status
=
send_debug_event
(
rec
,
TRUE
,
context
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
return
NtSetContextThread
(
GetCurrentThread
(),
context
);
TRACE
(
" rax=%016lx rbx=%016lx rcx=%016lx rdx=%016lx
\n
"
,
context
->
Rax
,
context
->
Rbx
,
context
->
Rcx
,
context
->
Rdx
);
TRACE
(
" rsi=%016lx rdi=%016lx rbp=%016lx rsp=%016lx
\n
"
,
context
->
Rsi
,
context
->
Rdi
,
context
->
Rbp
,
context
->
Rsp
);
TRACE
(
" r8=%016lx r9=%016lx r10=%016lx r11=%016lx
\n
"
,
context
->
R8
,
context
->
R9
,
context
->
R10
,
context
->
R11
);
TRACE
(
" r12=%016lx r13=%016lx r14=%016lx r15=%016lx
\n
"
,
context
->
R12
,
context
->
R13
,
context
->
R14
,
context
->
R15
);
}
return
raise_exception
(
rec
,
context
,
first_chance
);
}
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if
(
rec
->
ExceptionCode
==
EXCEPTION_BREAKPOINT
)
context
->
Rip
--
;
if
(
call_vectored_handlers
(
rec
,
context
)
==
EXCEPTION_CONTINUE_EXECUTION
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
/**********************************************************************
* raise_generic_exception
*
* Generic raise function for exceptions that don't need special treatment.
*/
static
void
raise_generic_exception
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
)
{
NTSTATUS
status
=
raise_exception
(
rec
,
context
,
TRUE
);
raise_status
(
status
,
rec
);
if
((
status
=
call_stack_handlers
(
rec
,
context
))
==
STATUS_SUCCESS
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
status
!=
STATUS_UNHANDLED_EXCEPTION
)
RtlRaiseStatus
(
status
);
return
NtRaiseException
(
rec
,
context
,
FALSE
);
}
extern
void
raise_func_trampoline
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
raise_func
func
);
extern
void
CDECL
raise_func_trampoline
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
raise_func
func
);
__ASM_GLOBAL_FUNC
(
raise_func_trampoline
,
__ASM_CFI
(
".cfi_signal_frame
\n\t
"
)
__ASM_CFI
(
".cfi_def_cfa %rbp,160
\n\t
"
)
/* red zone + rip + rbp + rdi + rsi */
...
...
@@ -2326,7 +2282,7 @@ __ASM_GLOBAL_FUNC( raise_func_trampoline,
__ASM_CFI
(
".cfi_rel_offset %rbp,16
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rdi,8
\n\t
"
)
__ASM_CFI
(
".cfi_rel_offset %rsi,0
\n\t
"
)
"call *%r
dx
\n\t
"
"call *%r
8
\n\t
"
"int $3"
)
/***********************************************************************
...
...
@@ -2446,9 +2402,9 @@ static void setup_raise_exception( ucontext_t *sigcontext, struct stack_layout *
/* now modify the sigcontext to return to the raise function */
RIP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
raise_func_trampoline
;
R
DI
_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
rec
;
R
SI
_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
context
;
R
DX_sig
(
sigcontext
)
=
(
ULONG_PTR
)
raise_generic_exception
;
R
CX
_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
rec
;
R
DX
_sig
(
sigcontext
)
=
(
ULONG_PTR
)
&
stack
->
context
;
R
8_sig
(
sigcontext
)
=
(
ULONG_PTR
)
KiUserExceptionDispatcher
;
RBP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
rsp_ptr
;
RSP_sig
(
sigcontext
)
=
(
ULONG_PTR
)
stack
;
/* clear single-step, direction, and align check flag */
...
...
dlls/ntdll/unix/loader.c
View file @
e561ce4b
...
...
@@ -1018,6 +1018,7 @@ static struct unix_funcs unix_funcs =
NtQuerySemaphore
,
NtQueryTimer
,
NtQueryVirtualMemory
,
NtRaiseException
,
NtReadVirtualMemory
,
NtReleaseKeyedEvent
,
NtReleaseMutant
,
...
...
dlls/ntdll/unix/thread.c
View file @
e561ce4b
...
...
@@ -52,6 +52,8 @@
#include "wine/exception.h"
#include "unix_private.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
seh
);
#ifndef PTHREAD_STACK_MIN
#define PTHREAD_STACK_MIN 16384
#endif
...
...
@@ -387,6 +389,87 @@ void wait_suspend( CONTEXT *context )
}
/**********************************************************************
* send_debug_event
*
* Send an EXCEPTION_DEBUG_EVENT event to the debugger.
*/
static
NTSTATUS
send_debug_event
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
ret
;
DWORD
i
;
obj_handle_t
handle
=
0
;
client_ptr_t
params
[
EXCEPTION_MAXIMUM_PARAMETERS
];
CONTEXT
exception_context
=
*
context
;
select_op_t
select_op
;
sigset_t
old_set
;
if
(
!
NtCurrentTeb
()
->
Peb
->
BeingDebugged
)
return
0
;
/* no debugger present */
pthread_sigmask
(
SIG_BLOCK
,
&
server_block_set
,
&
old_set
);
for
(
i
=
0
;
i
<
min
(
rec
->
NumberParameters
,
EXCEPTION_MAXIMUM_PARAMETERS
);
i
++
)
params
[
i
]
=
rec
->
ExceptionInformation
[
i
];
SERVER_START_REQ
(
queue_exception_event
)
{
req
->
first
=
first_chance
;
req
->
code
=
rec
->
ExceptionCode
;
req
->
flags
=
rec
->
ExceptionFlags
;
req
->
record
=
wine_server_client_ptr
(
rec
->
ExceptionRecord
);
req
->
address
=
wine_server_client_ptr
(
rec
->
ExceptionAddress
);
req
->
len
=
i
*
sizeof
(
params
[
0
]);
wine_server_add_data
(
req
,
params
,
req
->
len
);
if
(
!
(
ret
=
wine_server_call
(
req
)))
handle
=
reply
->
handle
;
}
SERVER_END_REQ
;
if
(
handle
)
{
select_op
.
wait
.
op
=
SELECT_WAIT
;
select_op
.
wait
.
handles
[
0
]
=
handle
;
server_select
(
&
select_op
,
offsetof
(
select_op_t
,
wait
.
handles
[
1
]
),
SELECT_INTERRUPTIBLE
,
TIMEOUT_INFINITE
,
&
exception_context
,
NULL
,
NULL
);
SERVER_START_REQ
(
get_exception_status
)
{
req
->
handle
=
handle
;
ret
=
wine_server_call
(
req
);
}
SERVER_END_REQ
;
if
(
ret
>=
0
)
*
context
=
exception_context
;
}
pthread_sigmask
(
SIG_SETMASK
,
&
old_set
,
NULL
);
return
ret
;
}
/*******************************************************************
* NtRaiseException (NTDLL.@)
*/
NTSTATUS
WINAPI
NtRaiseException
(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
)
{
NTSTATUS
status
=
send_debug_event
(
rec
,
context
,
first_chance
);
if
(
status
==
DBG_CONTINUE
||
status
==
DBG_EXCEPTION_HANDLED
)
NtSetContextThread
(
GetCurrentThread
(),
context
);
if
(
first_chance
)
KiUserExceptionDispatcher
(
rec
,
context
);
if
(
rec
->
ExceptionFlags
&
EH_STACK_INVALID
)
ERR
(
"Exception frame is not in stack limits => unable to dispatch exception.
\n
"
);
else
if
(
rec
->
ExceptionCode
==
STATUS_NONCONTINUABLE_EXCEPTION
)
ERR
(
"Process attempted to continue execution after noncontinuable exception.
\n
"
);
else
ERR
(
"Unhandled exception code %x flags %x addr %p
\n
"
,
rec
->
ExceptionCode
,
rec
->
ExceptionFlags
,
rec
->
ExceptionAddress
);
NtTerminateProcess
(
NtCurrentProcess
(),
rec
->
ExceptionCode
);
return
STATUS_SUCCESS
;
}
/***********************************************************************
* set_thread_context
*/
...
...
dlls/ntdll/unix/unix_private.h
View file @
e561ce4b
...
...
@@ -50,6 +50,7 @@ static inline struct ntdll_thread_data *ntdll_get_thread_data(void)
return
(
struct
ntdll_thread_data
*
)
&
NtCurrentTeb
()
->
GdiTebBatch
;
}
NTSTATUS
WINAPI
KiUserExceptionDispatcher
(
EXCEPTION_RECORD
*
,
CONTEXT
*
);
void
WINAPI
LdrInitializeThunk
(
CONTEXT
*
,
void
**
,
ULONG_PTR
,
ULONG_PTR
);
void
CDECL
mmap_add_reserved_area
(
void
*
addr
,
SIZE_T
size
)
DECLSPEC_HIDDEN
;
...
...
dlls/ntdll/unixlib.h
View file @
e561ce4b
...
...
@@ -28,7 +28,7 @@ struct ldt_copy;
struct
msghdr
;
/* increment this when you change the function table */
#define NTDLL_UNIXLIB_VERSION 3
0
#define NTDLL_UNIXLIB_VERSION 3
1
struct
unix_funcs
{
...
...
@@ -101,6 +101,7 @@ struct unix_funcs
NTSTATUS
(
WINAPI
*
NtQueryVirtualMemory
)(
HANDLE
process
,
LPCVOID
addr
,
MEMORY_INFORMATION_CLASS
info_class
,
PVOID
buffer
,
SIZE_T
len
,
SIZE_T
*
res_len
);
NTSTATUS
(
WINAPI
*
NtRaiseException
)(
EXCEPTION_RECORD
*
rec
,
CONTEXT
*
context
,
BOOL
first_chance
);
NTSTATUS
(
WINAPI
*
NtReadVirtualMemory
)(
HANDLE
process
,
const
void
*
addr
,
void
*
buffer
,
SIZE_T
size
,
SIZE_T
*
bytes_read
);
NTSTATUS
(
WINAPI
*
NtReleaseKeyedEvent
)(
HANDLE
handle
,
const
void
*
key
,
...
...
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