diff --git a/dlls/kernel32/instr.c b/dlls/kernel32/instr.c index 8a37a47b864..f9b99c8a9c1 100644 --- a/dlls/kernel32/instr.c +++ b/dlls/kernel32/instr.c @@ -428,12 +428,12 @@ static void INSTR_outport( WORD port, int size, DWORD val, CONTEXT86 *context ) /*********************************************************************** - * INSTR_EmulateInstruction + * __wine_emulate_instruction * * Emulate a privileged instruction. * Returns exception continuation status. */ -DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ) +DWORD __wine_emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ) { int prefix, segprefix, prefixlen, len, repX, long_op, long_addr; BYTE *instr; @@ -886,7 +886,7 @@ LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs ) (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION)) { - if (INSTR_EmulateInstruction( record, context ) == ExceptionContinueExecution) + if (__wine_emulate_instruction( record, context ) == ExceptionContinueExecution) return EXCEPTION_CONTINUE_EXECUTION; } return EXCEPTION_CONTINUE_SEARCH; diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index d6bb2bf71e5..32bf8e3f030 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1234,6 +1234,7 @@ @ cdecl __wine_dll_register_16(ptr str) @ cdecl __wine_dll_unregister_16(ptr) @ varargs -private __wine_call_from_16_regs() +@ cdecl __wine_emulate_instruction(ptr ptr) # Unix files @ cdecl wine_get_unix_file_name(wstr) diff --git a/dlls/kernel32/kernel_private.h b/dlls/kernel32/kernel_private.h index 4796e62ce07..dd7c91608fc 100644 --- a/dlls/kernel32/kernel_private.h +++ b/dlls/kernel32/kernel_private.h @@ -79,7 +79,7 @@ extern void FILE_SetDosError(void); extern WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc ); extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ); -extern DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ); +extern DWORD __wine_emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ); extern LONG CALLBACK INSTR_vectored_handler( EXCEPTION_POINTERS *ptrs ); extern void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum ); diff --git a/dlls/kernel32/wowthunk.c b/dlls/kernel32/wowthunk.c index 9e27f85646e..4f714ab6317 100644 --- a/dlls/kernel32/wowthunk.c +++ b/dlls/kernel32/wowthunk.c @@ -256,7 +256,7 @@ static DWORD call16_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RE else { SEGPTR gpHandler; - DWORD ret = INSTR_EmulateInstruction( record, context ); + DWORD ret = __wine_emulate_instruction( record, context ); /* * Insert check for pending DPMI events. Note that this @@ -310,7 +310,7 @@ static DWORD vm86_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECO if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) { - return INSTR_EmulateInstruction( record, context ); + return __wine_emulate_instruction( record, context ); } return ExceptionContinueSearch; diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c index 33804343942..b0007fc8eee 100644 --- a/dlls/ntoskrnl.exe/ntoskrnl.c +++ b/dlls/ntoskrnl.exe/ntoskrnl.c @@ -30,6 +30,7 @@ #define WIN32_NO_STATUS #include "windef.h" #include "winternl.h" +#include "excpt.h" #include "ddk/wdm.h" #include "wine/unicode.h" #include "wine/server.h" @@ -103,6 +104,23 @@ static HANDLE get_device_manager(void) return ret; } +/* exception handler for emulation of privileged instructions */ +static LONG CALLBACK vectored_handler( EXCEPTION_POINTERS *ptrs ) +{ + extern DWORD __wine_emulate_instruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ); + + EXCEPTION_RECORD *record = ptrs->ExceptionRecord; + CONTEXT86 *context = ptrs->ContextRecord; + + if (record->ExceptionCode == EXCEPTION_ACCESS_VIOLATION || + record->ExceptionCode == EXCEPTION_PRIV_INSTRUCTION) + { + if (__wine_emulate_instruction( record, context ) == ExceptionContinueExecution) + return EXCEPTION_CONTINUE_EXECUTION; + } + return EXCEPTION_CONTINUE_SEARCH; +} + /* process an ioctl request for a given device */ static NTSTATUS process_ioctl( DEVICE_OBJECT *device, ULONG code, void *in_buff, ULONG in_size, void *out_buff, ULONG *out_size ) @@ -479,6 +497,7 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved ) { case DLL_PROCESS_ATTACH: DisableThreadLibraryCalls( inst ); + RtlAddVectoredExceptionHandler( TRUE, vectored_handler ); break; } return TRUE;