Major refactoring of the exception handling code + misc fixes:
authorAlex Ionescu <aionescu@gmail.com>
Sun, 11 Sep 2005 22:32:20 +0000 (22:32 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Sun, 11 Sep 2005 22:32:20 +0000 (22:32 +0000)
- Fix/add prototypes for RtlCaptureContext, RtlDispatchException and RtlUnwind
- Fix EXCEPTION_REGISTRATION_RECORD structure and PEXCEPTION_ROUTINE
- Add w32api excpt.h (based on mingw) with PSDK compatibility fixes
- Fix seriously broken User-Mode Ldr thunk and APC Callback prototypes
- Fix KiUserExceptionDispatcher
- Remove useless NTDLL entrypoint
- Implement NTDLL Ki* callbacks in ASM
- Implement RtlCaptureContext
- Fix RtlRaiseException to handle cases when a user-mode debugger is present
- Fix RtlRaiseStatus as above, plus set the exception address and capture context
- Little cleanup of RTL headers
- Implement RtlpGetStackLimits, RtlpGetExceptionList, RtlpSetExceptionList, RtlpGetExceptionAddress in ASM
- Fix RtlDispatchException, add cases for exceptions in the DPC stack and validate the validity of the
exception frames. Add support for exception logging by the global flag. Use TRAP_FRAME/EXCPETION_FRAME instead of
Context.
- Fix RtlUnwind logic, support cases where it's called with custom arguments instead of NULL.
- Reimplement RtlpCaptureContext to work properly, convert exception handler calling functions to INTEL syntax
and fix some bugs (like checking for the right unwind flag, clearing volatile register values, etc. Also use some
optimizations to increase speed.
- Modify some kernel functions (like KeContextToTrapFrame, KiDispatchException, KiInitializeUserApc, etc.) to
support a PKEXCEPTION_FRAME for future PPC compatibility.
- Reimplement RtlCaptureUnicodeString/FreeUnicodeString as inlined probe macros and optimize them.
- Export ExRaiseStatus/Exception as Rtl*
- Reimplement NtContinue to have more platform-independent code, and to protect and validate user-mode context
and parameters with SEH.
- Implement KiRaiseException, add SEH to all user-mode parameters and when copying data to the user-mode stack.
- Fix KiInitializeUserApc to use KeTrapFrameToContext, to save the debug registers, not to deliver APCs during
v86 mode, and to protect user-mode stack operations in SEH and probing. Also make it generate the proper stack for the
user-mode callback.
- Implement KiUnexpectedInterrupt and KiCoprocessorError
- Reimplement NtRaiseException in ASM to take advantage of optimizations due to the trap frame being in the
stack when called through System call interface.
- Fix Ntcontinue to respect AlertThread paramter
- Fix some functiosn to return with KiServiceExit2 instead of KiServiceExit when required/needed
- Fix KiDispatchException's logic, fix hacks when calling KeUserExceptionDispatcher, use correct context
flags,...
- Make NTDLL Ki* callbacks have SEH to protect them and return to kernel-mode with notification of any
exceptions (the kernel-mode code to handle this isn't written yet though)

svn path=/trunk/; revision=17811

48 files changed:
reactos/include/ndk/asm.h
reactos/include/ndk/ntndk.h
reactos/include/ndk/rtlfuncs.h
reactos/include/ndk/rtltypes.h
reactos/include/wine/exception.h
reactos/lib/crt/except/unwind.c
reactos/lib/crt/wine/scanf.c
reactos/lib/dbghelp/stack.c
reactos/lib/dbghelp/stackframe.h
reactos/lib/dbghelp/thread.h
reactos/lib/ntdll/def/ntdll.def
reactos/lib/ntdll/ldr/entry.S [deleted file]
reactos/lib/ntdll/ldr/startup.c
reactos/lib/ntdll/main/dispatch.c
reactos/lib/ntdll/main/dllmain.c [deleted file]
reactos/lib/ntdll/main/i386/dispatch.S [new file with mode: 0644]
reactos/lib/ntdll/ntdll.xml
reactos/lib/ntdll/rtl/libsupp.c
reactos/lib/rtl/exception.c
reactos/lib/rtl/i386/except.s
reactos/lib/rtl/i386/exception.c
reactos/lib/rtl/rtl.h
reactos/lib/rtl/rtlp.h [new file with mode: 0644]
reactos/ntoskrnl/ex/error.c
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/include/ntoskrnl.h
reactos/ntoskrnl/io/driver.c
reactos/ntoskrnl/kd/wrappers/gdbstub.c
reactos/ntoskrnl/ke/apc.c
reactos/ntoskrnl/ke/exception.c [new file with mode: 0644]
reactos/ntoskrnl/ke/i386/exp.c
reactos/ntoskrnl/ke/i386/fpu.c
reactos/ntoskrnl/ke/i386/irqhand.s
reactos/ntoskrnl/ke/i386/syscall.S
reactos/ntoskrnl/ke/i386/thread.c
reactos/ntoskrnl/ke/i386/trap.s
reactos/ntoskrnl/mm/pagefile.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.xml
reactos/ntoskrnl/ob/symlink.c
reactos/ntoskrnl/ps/debug.c
reactos/ntoskrnl/rtl/capture.c [deleted file]
reactos/ntoskrnl/rtl/i386/exception.c
reactos/ntoskrnl/rtl/libsupp.c
reactos/w32api/include/ddk/ntddk.h
reactos/w32api/include/excpt.h [new file with mode: 0644]

index 756b5ed..11363c4 100644 (file)
 #define CONTEXT_FLAGS                   0x0
 #define CONTEXT_DR6                     0x14
 #define CONTEXT_FLOAT_SAVE              0x1C
+#define CONTEXT_SEGGS                   0x8C
+#define CONTEXT_SEGFS                   0x90
+#define CONTEXT_SEGES                   0x94
+#define CONTEXT_SEGDS                   0x98
 #define CONTEXT_EDI                     0x9C
 #define CONTEXT_ESI                     0xA0
 #define CONTEXT_EBX                     0xA4
 #define CONTEXT_EAX                     0xB0
 #define CONTEXT_EBP                     0xB4
 #define CONTEXT_EIP                     0xB8
+#define CONTEXT_SEGCS                   0xBC
+#define CONTEXT_EFLAGS                  0xC0
 #define CONTEXT_ESP                     0xC4
+#define CONTEXT_SEGSS                   0xC8
 #define CONTEXT_FLOAT_SAVE_CONTROL_WORD CONTEXT_FLOAT_SAVE + FN_CONTROL_WORD
 #define CONTEXT_FLOAT_SAVE_STATUS_WORD  CONTEXT_FLOAT_SAVE + FN_STATUS_WORD
 #define CONTEXT_FLOAT_SAVE_TAG_WORD     CONTEXT_FLOAT_SAVE + FN_TAG_WORD
 
+/* EXCEPTION_RECORD Constants */
+#define EXCEPTION_RECORD_EXCEPTION_CODE     0x0
+#define EXCEPTION_RECORD_EXCEPTION_FLAGS    0x4
+#define EXCEPTION_RECORD_EXCEPTION_RECORD   0x8
+#define EXCEPTION_RECORD_EXCEPTION_ADDRESS  0xC
+#define EXCEPTION_RECORD_NUMBER_PARAMETERS  0x10
+#define SIZEOF_EXCEPTION_RECORD             0x14
+
 /* TEB CONSTANTS */
 #define TEB_EXCEPTION_LIST              0x0
 #define TEB_STACK_BASE                  0x4
 #define TEB_STACK_LIMIT                 0x8
 #define TEB_FIBER_DATA                  0x10
+#define TEB_PEB                         0x30
+#define TEB_EXCEPTION_CODE              0x1A4
 #define TEB_ACTIVATION_CONTEXT_STACK_POINTER 0x1A8
 #define TEB_DEALLOCATION_STACK          0xE0C
 #define TEB_GUARANTEED_STACK_BYTES      0xF78
 #define TEB_FLS_DATA                    0xFB4
 
+/* PEB CONSTANTS */
+#define PEB_KERNEL_CALLBACK_TABLE       0x2C
+
 /* FIBER CONSTANTS */
 #define FIBER_PARAMETER                 0x0
 #define FIBER_EXCEPTION_LIST            0x4
index 245aa37..e65400d 100644 (file)
@@ -11,7 +11,6 @@
 
 /* C Standard Headers */
 #include <stdarg.h>
-#include <excpt.h>
 
 /* Helper Header */
 #include <helper.h>
index c0a326b..48e6a94 100644 (file)
@@ -37,6 +37,11 @@ RtlAssert(
     PCHAR Message
 );
 
+NTSYSAPI
+VOID
+NTAPI
+RtlCaptureContext(OUT PCONTEXT ContextRecord);
+
 NTSYSAPI
 PVOID
 NTAPI
@@ -47,6 +52,14 @@ PVOID
 NTAPI
 RtlDecodePointer(IN PVOID Pointer);
 
+NTSYSAPI
+BOOLEAN
+NTAPI
+RtlDispatchException(
+    IN PEXCEPTION_RECORD ExceptionRecord,
+    IN PCONTEXT Context
+);
+
 NTSYSAPI
 ULONG
 NTAPI
@@ -71,10 +84,10 @@ NTSYSAPI
 VOID
 NTAPI
 RtlUnwind(
-    PEXCEPTION_REGISTRATION RegistrationFrame,
-    PVOID ReturnAddress,
-    PEXCEPTION_RECORD ExceptionRecord,
-    ULONG EaxValue
+    IN PVOID TargetFrame OPTIONAL,
+    IN PVOID TargetIp OPTIONAL,
+    IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
+    IN PVOID ReturnValue
 );
 
 /*
index b7e9ba0..e8e9269 100644 (file)
@@ -10,7 +10,6 @@
 #define _RTLTYPES_H
 
 /* DEPENDENCIES **************************************************************/
-#include "excpt.h"
 
 /* CONSTANTS *****************************************************************/
 #define MAXIMUM_LEADBYTES 12
@@ -27,6 +26,7 @@
 
 #define PEB_BASE                   (0x7FFDF000)
 
+#define EXCEPTION_CHAIN_END           ((PEXCEPTION_REGISTRATION_RECORD)-1)
 #define EXCEPTION_CONTINUE_SEARCH     0
 #define EXCEPTION_EXECUTE_HANDLER     1
 
@@ -292,11 +292,11 @@ typedef NTSTATUS
 );
 
 typedef EXCEPTION_DISPOSITION
-(*PEXCEPTION_HANDLER)(
-    struct _EXCEPTION_RECORD*,
-    PVOID,
-    struct _CONTEXT*,
-    PVOID
+(NTAPI *PEXCEPTION_ROUTINE)(
+    IN struct _EXCEPTION_RECORD *ExceptionRecord,
+    IN PVOID EstablisherFrame,
+    IN OUT struct _CONTEXT *ContextRecord,
+    IN OUT PVOID DispatcherContext
 );
 
 typedef LONG (NTAPI *PVECTORED_EXCEPTION_HANDLER)(
@@ -634,16 +634,11 @@ typedef struct _MODULE_INFORMATION
 } MODULE_INFORMATION, *PMODULE_INFORMATION;
 /* END REVIEW AREA */
 
-#ifdef _INC_EXCPT
-typedef struct _EXCEPTION_REGISTRATION
+typedef struct _EXCEPTION_REGISTRATION_RECORD
 {
-    struct _EXCEPTION_REGISTRATION *prev;
-    PEXCEPTION_HANDLER handler;
-} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;
-#endif
-
-typedef EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION_RECORD;
-typedef PEXCEPTION_REGISTRATION PEXCEPTION_REGISTRATION_RECORD;
+    struct _EXCEPTION_REGISTRATION_RECORD *Next;
+    PEXCEPTION_HANDLER Handler;
+} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
 
 typedef struct _CURDIR
 {
index 7bfc1c9..8308114 100644 (file)
  * -- AJ
  */
 
+typedef struct _EXCEPTION_REGISTRATION_RECORD
+{
+    struct _EXCEPTION_REGISTRATION_RECORD *prev;
+    PEXCEPTION_HANDLER handler;
+} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;
+
 /* Define this if you want to use your compiler built-in __try/__except support.
  * This is only useful when compiling to a native Windows binary, as the built-in
  * compiler exceptions will most certainly not work under Winelib.
index e481d4f..c329164 100644 (file)
@@ -1,11 +1,15 @@
 #include "precomp.h"
-#include <winternl.h>
+#include <windows.h>
+#define NTOS_MODE_USER
+#include <ndk/umtypes.h>
+#include <ndk/extypes.h>
+#include <ndk/rtlfuncs.h>
 
 /*
  * @implemented
  */
 void __cdecl
-_global_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame)
+_global_unwind2(PEXCEPTION_REGISTRATION_RECORD RegistrationFrame)
 {
 #ifdef __GNUC__
    RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0);
@@ -17,14 +21,6 @@ __ret_label:
 }
 
 
-// This is dragged over from WINE:
-
-typedef struct __EXCEPTION_FRAME
-{
-  struct __EXCEPTION_FRAME *Prev;
-  PEXCEPTION_HANDLER       Handler;
-} EXCEPTION_FRAME, *PEXCEPTION_FRAME;
-
 /* VC++ extensions to Win32 SEH */
 typedef struct _SCOPETABLE
 {
@@ -35,8 +31,8 @@ typedef struct _SCOPETABLE
 
 typedef struct _MSVCRT_EXCEPTION_FRAME
 {
-  EXCEPTION_FRAME *prev;
-  void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_FRAME,
+  PEXCEPTION_REGISTRATION_RECORD *prev;
+  void (*handler)(PEXCEPTION_RECORD, PEXCEPTION_REGISTRATION_RECORD,
                   PCONTEXT, PEXCEPTION_RECORD);
   PSCOPETABLE scopetable;
   int trylevel;
index 36d76db..9b9d03e 100644 (file)
 #include <ctype.h>
 #include <internal/file.h>
 
+#include <windows.h>
 #define NTOS_MODE_USER
-#include <ndk/ntndk.h>
+#include <ndk/umtypes.h>
+#include <ndk/extypes.h>
+#include <ndk/rtlfuncs.h>
 
 #define NDEBUG
 #include <internal/debug.h>
index 5d7e2ec..fc9c602 100644 (file)
@@ -31,7 +31,6 @@
 #include "winreg.h"
 #include "ntstatus.h"
 #include "thread.h" /* FIXME: must be included before winternl.h */
-#include "winternl.h"
 #include "wine/debug.h"
 #include "stackframe.h"
 
@@ -127,10 +126,11 @@ BOOL WINAPI StackWalk(DWORD MachineType, HANDLE hProcess, HANDLE hThread,
         /* cur_switch holds address of curr_stack's field in TEB in debuggee
          * address space
          */
+        /*
         if (NtQueryInformationThread(hThread, ThreadBasicInformation, &info,    
                                      sizeof(info), NULL) != STATUS_SUCCESS)
             goto done_err;
-        curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, cur_stack);
+        curr_switch = (unsigned long)info.TebBaseAddress + FIELD_OFFSET(TEB, cur_stack); */
         if (!f_read_mem(hProcess, (void*)curr_switch, &next_switch, 
                         sizeof(next_switch), NULL))
         {
index bedf4d7..b709d0b 100644 (file)
 
 #include <string.h>
 #include <winnt.h>
-#include <excpt.h>
+#define NTOS_MODE_USER
+#include <ndk/umtypes.h>
+#include <ndk/extypes.h>
+#include <ndk/rtlfuncs.h>
 
 #define SELECTOROF(ptr)     (HIWORD(ptr))
 #define OFFSETOF(ptr)       (LOWORD(ptr))
@@ -77,23 +80,5 @@ return -1;
 #define CURRENT_STACK16      ((STACK16FRAME*)MapSL(NtCurrentTeb()->cur_stack))
 #define CURRENT_DS           (CURRENT_STACK16->ds)
 
-/* Push bytes on the 16-bit stack of a thread;
- * return a segptr to the first pushed byte
- */
-static inline SEGPTR stack16_push( int size )
-{
-    STACK16FRAME *frame = CURRENT_STACK16;
-    memmove( (char*)frame - size, frame, sizeof(*frame) );
-    NtCurrentTeb()->cur_stack -= size;
-    return (SEGPTR)(NtCurrentTeb()->cur_stack + sizeof(*frame));
-}
-
-/* Pop bytes from the 16-bit stack of a thread */
-static inline void stack16_pop( int size )
-{
-    STACK16FRAME *frame = CURRENT_STACK16;
-    memmove( (char*)frame + size, frame, sizeof(*frame) );
-    NtCurrentTeb()->cur_stack += size;
-}
 
 #endif /* __WINE_STACKFRAME_H */
index 210a96c..7d617f8 100644 (file)
@@ -26,7 +26,6 @@
 #include <winbase.h>
 #include <winreg.h>
 #define WINE_NO_TEB
-#include <winternl.h>
 #include <wine/windef16.h>
 
 struct _SECURITY_ATTRIBUTES;
@@ -42,114 +41,4 @@ struct debug_info
     char  output[1024];  /* current output line */
 };
 
-/* Thread exception block
-
-  flags in the comment:
-  1-- win95 field
-  d-- win95 debug version
-  -2- nt field
-  --3 wine special
-  --n wine unused
-  !-- or -!- likely or observed  collision
-  more problems (collected from mailing list):
-  psapi.dll 0x10/0x30 (expects nt fields)
-  ie4       0x40
-  PESHiELD  0x23/0x30 (win95)
-*/
-#ifndef WINE_TEB_DEFINED
-#define WINE_TEB_DEFINED
-typedef struct _TEB
-{
-    NT_TIB       Tib;            /* 12-  00 Thread information block */
-    PVOID        EnvironmentPointer; /* 12-  1c EnvironmentPointer (win95: tib flags + win16 mutex count) */
-    CLIENT_ID    ClientId;       /* -2-  20 Process and thread id (win95: debug context) */
-    HQUEUE16     queue;          /* 1!-  28 Message queue (NT: DWORD ActiveRpcHandle)*/
-    WORD         pad1;           /* --n  2a */
-    PVOID        ThreadLocalStoragePointer; /* 1--  2c Pointer to TLS array */
-    PEB         *Peb;            /* 12-  30 owning process PEB */
-    DWORD        LastErrorValue; /* -2-  34 Last error code */
-    DWORD        exit_code;      /* 1--  38 Termination status */
-    WORD         teb_sel;        /* 1--  3c Selector to TEB */
-    WORD         emu_sel;        /* 1-n  3e 80387 emulator selector */
-    DWORD        unknown1;       /* --n  40 */
-    DWORD        unknown2;       /* --n  44 */
-    DWORD        unknown3;       /* --n  48 */
-    int          thread_errno;   /* --3  4c Per-thread errno (was: ring0_thread) */
-    int          thread_h_errno; /* --3  50 Per-thread h_errno (was: ptr to tdbx structure) */
-    void        *stack_base;     /* 1-n  54 Stack base (unused) */
-    void        *exit_stack;     /* 1-n  58 Exit stack */
-    void        *emu_data;       /* --n  5c Related to 80387 emulation */
-    DWORD        last_error;     /* 1--  60 Last error code */
-    HANDLE       debug_cb;       /* 1-n  64 Debugger context block */
-    DWORD        debug_thread;   /* 1-n  68 Thread debugging this one (?) */
-    void        *pcontext;       /* 1-n  6c Thread register context */
-    DWORD        cur_stack;      /* --3  70 Current stack (was: unknown) */
-    DWORD        ThunkConnect;   /* 1-n  74 */
-    DWORD        NegStackBase;   /* 1-n  78 */
-    WORD         current_ss;     /* 1-n  7c Another 16-bit stack selector */
-    WORD         pad2;           /* --n  7e */
-    void        *ss_table;       /* --n  80 Pointer to info about 16-bit stack */
-    WORD         stack_sel;      /* --3  84 16-bit stack selector */
-    HTASK16      htask16;        /* --3  86 Win16 task handle */
-    DWORD        pad4[15];       /* --n  88 */
-    ULONG        CurrentLocale;  /* -2-  C4 */
-    DWORD        pad5[48];       /* --n  C8 */
-    DWORD        delta_priority; /* 1-n 188 Priority delta */
-    DWORD        unknown4[7];    /* d-n 18c Unknown */
-    void        *create_data;    /* d-n 1a8 Pointer to creation structure */
-    DWORD        suspend_count;  /* d-n 1ac SuspendThread() counter */
-    DWORD        unknown5[6];    /* --n 1b0 Unknown */
-    DWORD        sys_count[4];   /* --3 1c8 Syslevel mutex entry counters */
-    struct tagSYSLEVEL *sys_mutex[4];   /* --3 1d8 Syslevel mutex pointers */
-    DWORD        unknown6[5];    /* --n 1e8 Unknown */
-
-    /* The following are Wine-specific fields (NT: GDI stuff) */
-    UINT         code_page;      /* --3 1fc Thread code page */
-    DWORD        unused[2];      /* --3 200 Was server buffer */
-    DWORD        gs_sel;         /* --3 208 %gs selector for this thread */
-    int          request_fd;     /* --3 20c fd for sending server requests */
-    int          reply_fd;       /* --3 210 fd for receiving server replies */
-    int          wait_fd[2];     /* --3 214 fd for sleeping server requests */
-    struct debug_info *debug_info;        /* --3 21c Info for debugstr functions */
-    void        *pthread_data;   /* --3 220 Data for pthread emulation */
-    struct async_private *pending_list;   /* --3 224 list of pending async operations */
-    void        *driver_data;    /* --3 228 Graphics driver private data */
-    DWORD        dpmi_vif;       /* --3 22c Protected mode virtual interrupt flag */
-    DWORD        vm86_pending;   /* --3 230 Data for vm86 mode */
-    void        *vm86_ptr;       /* --3 234 Data for vm86 mode */
-    /* here is plenty space for wine specific fields (don't forget to change pad6!!) */
-
-    /* the following are nt specific fields */
-    DWORD        pad6[624];                  /* --n 238 */
-    UNICODE_STRING StaticUnicodeString;      /* -2- bf8 used by advapi32 */
-    WCHAR        StaticUnicodeBuffer[261];   /* -2- c00 used by advapi32 */
-    PVOID        DeallocationStack;          /* -2- e0c Base of the stack */
-    LPVOID       TlsSlots[64];               /* -2- e10 Thread local storage */
-    LIST_ENTRY   TlsLinks;                   /* -2- f10 */
-    DWORD        pad8[1];                    /* --n f18 */
-    PVOID        ReservedForNtRpc;           /* -2- f1c used by rpcrt4 */
-    DWORD        pad9[24];                   /* --n f20 */
-    PVOID        ReservedForOle;             /* -2- f80 used by ole32 (IErrorInfo*) */
-    PVOID        pad10[4];                   /* --n f84 */
-    PVOID        TlsExpansionSlots;          /* -2- f94 */
-} TEB;
-#endif /* WINE_TEB_DEFINED */
-
-
-/* The thread information for 16-bit threads */
-/* NtCurrentTeb()->SubSystemTib points to this */
-typedef struct
-{
-    void           *unknown;    /* 00 unknown */
-    UNICODE_STRING *exe_name;   /* 04 exe module name */
-
-    /* the following fields do not exist under Windows */
-    UNICODE_STRING  exe_str;    /* exe name string pointed to by exe_name */
-    CURDIR          curdir;     /* current directory */
-    WCHAR           curdir_buffer[MAX_PATH];
-} WIN16_SUBSYSTEM_TIB;
-
-/* scheduler/thread.c */
-extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
-
 #endif  /* __WINE_THREAD_H */
index 1fd10bd..6de5ba6 100644 (file)
@@ -33,7 +33,7 @@ DbgUiRemoteBreakin@0
 DbgUiWaitStateChange@8
 DbgUserBreakPoint@0
 KiRaiseUserExceptionDispatcher@0
-KiUserApcDispatcher@20
+KiUserApcDispatcher@16
 KiUserCallbackDispatcher@12
 KiUserExceptionDispatcher@8
 LdrAccessResource@16
diff --git a/reactos/lib/ntdll/ldr/entry.S b/reactos/lib/ntdll/ldr/entry.S
deleted file mode 100755 (executable)
index 78d6190..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-#include <roscfg.h>
-
-.extern ___true_LdrInitializeThunk@16
-
-.globl _LdrInitializeThunk@16
-_LdrInitializeThunk@16:
-#if defined(_M_IX86)
- nop /* breakin overwrites this with "int 3" */
- jmp ___true_LdrInitializeThunk@16
-#elif defined(_M_ALPHA)
- nop /* breakin overwrites this with "call_pal bpt" */
- br ___true_LdrInitializeThunk@16
-#elif defined(_M_MIPS)
- nop /* breakin overwrites this with "break" */
- j ___true_LdrInitializeThunk@16
-#else
-#error Unsupported architecture.
-#endif
index 5ad16c8..8e8c7c2 100644 (file)
@@ -239,11 +239,11 @@ finish:
 
 /* FUNCTIONS *****************************************************************/
 
-VOID STDCALL
-__true_LdrInitializeThunk (ULONG Unknown1,
-                    ULONG Unknown2,
-                    ULONG Unknown3,
-                    ULONG Unknown4)
+VOID
+STDCALL
+LdrpInit(PCONTEXT Context,
+         PVOID SystemArgument1,
+         PVOID SystemArgument2)
 {
    PIMAGE_NT_HEADERS NTHeaders;
    PEPFUNC EntryPoint;
@@ -256,7 +256,7 @@ __true_LdrInitializeThunk (ULONG Unknown1,
    SYSTEM_BASIC_INFORMATION SystemInformation;
    NTSTATUS Status;
 
-   DPRINT("LdrInitializeThunk()\n");
+   DPRINT("LdrpInit()\n");
    if (NtCurrentPeb()->Ldr == NULL || NtCurrentPeb()->Ldr->Initialized == FALSE)
      {
        Peb = (PPEB)(PEB_BASE);
index 6b2774d..1be0021 100644 (file)
@@ -1,8 +1,9 @@
 /* COPYRIGHT:       See COPYING in the top level directory\r
- * PROJECT:         ReactOS system libraries\r
- * PURPOSE:         User-mode APC support\r
+ * PROJECT:         ReactOS NT Library\r
  * FILE:            lib/ntdll/main/dispatch.c\r
- * PROGRAMER:       David Welch <welch@cwcom.net>\r
+ * PURPOSE:         User-Mode NT Dispatchers\r
+ * PROGRAMERS:      Alex Ionescu (alex@relsoft.net)\r
+ *                  David Welch <welch@cwcom.net>\r
  */\r
 \r
 /* INCLUDES *****************************************************************/\r
 #define NDEBUG\r
 #include <debug.h>\r
 \r
-typedef NTSTATUS (STDCALL *KERNEL_CALLBACK_FUNCTION)(PVOID Argument,\r
-                                                    ULONG ArgumentLength);\r
+typedef NTSTATUS (STDCALL *USER_CALL)(PVOID Argument, ULONG ArgumentLength);\r
 \r
-EXCEPTION_DISPOSITION\r
-RtlpExecuteVectoredExceptionHandlers(IN PEXCEPTION_RECORD ExceptionRecord,\r
-                                     IN PCONTEXT Context);\r
-\r
-ULONG\r
-RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,\r
-                      IN PCONTEXT  Context);\r
 /* FUNCTIONS ****************************************************************/\r
 \r
-/*\r
- * @implemented\r
- */\r
-VOID\r
-STDCALL\r
-KiUserApcDispatcher(PIO_APC_ROUTINE ApcRoutine,\r
-                   PVOID ApcContext,\r
-                   PIO_STATUS_BLOCK Iosb,\r
-                   ULONG Reserved,\r
-                   PCONTEXT Context)\r
-{\r
-   /*\r
-    * Call the APC\r
-    */\r
-   //DPRINT1("ITS ME\n");\r
-   ApcRoutine(ApcContext,\r
-             Iosb,\r
-             Reserved);\r
-   /*\r
-    * Switch back to the interrupted context\r
-    */\r
-    //DPRINT1("switch back\n");\r
-   NtContinue(Context, 1);\r
-}\r
-\r
 /*\r
  * @implemented\r
  */\r
 VOID\r
 STDCALL\r
 KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord,\r
-                         PCONTEXT Context)\r
+                          PCONTEXT Context)\r
 {\r
-  EXCEPTION_RECORD NestedExceptionRecord;\r
-  NTSTATUS Status;\r
+    EXCEPTION_RECORD NestedExceptionRecord;\r
+    NTSTATUS Status;\r
 \r
-  if(RtlpExecuteVectoredExceptionHandlers(ExceptionRecord,\r
-                                          Context) != ExceptionContinueExecution)\r
+    /* Dispatch the exception and check the result */\r
+    if(RtlDispatchException(ExceptionRecord, Context))\r
     {\r
-      Status = NtContinue(Context, FALSE);\r
+        /* Continue executing */\r
+        Status = NtContinue(Context, FALSE);\r
     }\r
-  else\r
+    else\r
     {\r
-      if(RtlpDispatchException(ExceptionRecord, Context) != ExceptionContinueExecution)\r
-        {\r
-          Status = NtContinue(Context, FALSE);\r
-        }\r
-      else\r
-        {\r
-          Status = NtRaiseException(ExceptionRecord, Context, FALSE);\r
-        }\r
+        /* Raise an exception */\r
+        Status = NtRaiseException(ExceptionRecord, Context, FALSE);\r
     }\r
 \r
-  NestedExceptionRecord.ExceptionCode = Status;\r
-  NestedExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;\r
-  NestedExceptionRecord.ExceptionRecord = ExceptionRecord;\r
-  NestedExceptionRecord.NumberParameters = Status;\r
+    /* Setup the Exception record */\r
+    NestedExceptionRecord.ExceptionCode = Status;\r
+    NestedExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;\r
+    NestedExceptionRecord.ExceptionRecord = ExceptionRecord;\r
+    NestedExceptionRecord.NumberParameters = Status;\r
 \r
-  RtlRaiseException(&NestedExceptionRecord);\r
+    /* Raise the exception */\r
+    RtlRaiseException(&NestedExceptionRecord);\r
 }\r
 \r
 /*\r
@@ -91,14 +56,16 @@ VOID
 STDCALL\r
 KiRaiseUserExceptionDispatcher(VOID)\r
 {\r
-  EXCEPTION_RECORD ExceptionRecord;\r
+    EXCEPTION_RECORD ExceptionRecord;\r
 \r
-  ExceptionRecord.ExceptionCode = ((PTEB)NtCurrentTeb())->ExceptionCode;\r
-  ExceptionRecord.ExceptionFlags = 0;\r
-  ExceptionRecord.ExceptionRecord = NULL;\r
-  ExceptionRecord.NumberParameters = 0;\r
+    /* Setup the exception record */\r
+    ExceptionRecord.ExceptionCode = ((PTEB)NtCurrentTeb())->ExceptionCode;\r
+    ExceptionRecord.ExceptionFlags = 0;\r
+    ExceptionRecord.ExceptionRecord = NULL;\r
+    ExceptionRecord.NumberParameters = 0;\r
 \r
-  RtlRaiseException(&ExceptionRecord);\r
+    /* Raise the exception */\r
+    RtlRaiseException(&ExceptionRecord);\r
 }\r
 \r
 /*\r
@@ -106,16 +73,13 @@ KiRaiseUserExceptionDispatcher(VOID)
  */\r
 VOID\r
 STDCALL\r
-KiUserCallbackDispatcher(ULONG RoutineIndex,\r
-                        PVOID Argument,\r
-                        ULONG ArgumentLength)\r
+KiUserCallbackDispatcher(ULONG Index,\r
+                         PVOID Argument,\r
+                         ULONG ArgumentLength)\r
 {\r
-   PPEB Peb;\r
-   NTSTATUS Status;\r
-   KERNEL_CALLBACK_FUNCTION Callback;\r
-\r
-   Peb = NtCurrentPeb();\r
-   Callback = (KERNEL_CALLBACK_FUNCTION)Peb->KernelCallbackTable[RoutineIndex];\r
-   Status = Callback(Argument, ArgumentLength);\r
-   ZwCallbackReturn(NULL, 0, Status);\r
+    /* Return with the result of the callback function */\r
+    ZwCallbackReturn(NULL,\r
+                     0,\r
+                     ((USER_CALL)(NtCurrentPeb()->KernelCallbackTable[Index]))\r
+                     (Argument, ArgumentLength));\r
 }\r
diff --git a/reactos/lib/ntdll/main/dllmain.c b/reactos/lib/ntdll/main/dllmain.c
deleted file mode 100644 (file)
index 1ff23a6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * FILE:            lib/ntdll/main/dllmain.c
- * PURPOSE:
- * PROGRAMMER:
- */
-
-#include <ntdll.h>
-#define NDEBUG
-#include <debug.h>
-
-BOOL WINAPI DllMainCRTStartup(HINSTANCE hinstDll,
-                             DWORD fdwReason,
-                             LPVOID fImpLoad)
-{
-  return TRUE;
-}
-
-/* EOF */
diff --git a/reactos/lib/ntdll/main/i386/dispatch.S b/reactos/lib/ntdll/main/i386/dispatch.S
new file mode 100644 (file)
index 0000000..42bbff5
--- /dev/null
@@ -0,0 +1,186 @@
+/*\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS NT Library\r
+ * FILE:            lib/ntdll/main/i386/dispatch.S\r
+ * PURPOSE:         User-Mode NT Dispatchers\r
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+#include <ndk/asm.h>\r
+#include <ndk/i386/segment.h>\r
+.intel_syntax noprefix\r
+\r
+#define EXCEPTION_NONCONTINUABLE    1\r
+#define EXCEPTION_UNWINDING         2\r
+#define EXCEPTION_EXIT_UNWIND       4\r
+#define EXCEPTION_UNWIND            (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)\r
+\r
+#define STATUS_CALLBACK_POP_STACK   0xC0000423\r
+\r
+#define ExceptionContinueSearch     1\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+.globl _LdrInitializeThunk@16\r
+_LdrInitializeThunk@16:\r
+\r
+    /* Get the APC Context */\r
+    lea eax, [esp+16]\r
+\r
+    /* Send it as the first parameter */\r
+    mov [esp+4], eax\r
+\r
+    /* Terminate the frame list */\r
+    xor ebp, ebp\r
+\r
+    /* Jump into the C initialization routine */\r
+    jmp _LdrpInit@12\r
+\r
+.globl _KiUserExceptionApcHandler@16\r
+_KiUserApcExceptionHandler@16:\r
+\r
+    /* Put the exception record in ECX and check the Flags */\r
+    mov ecx, [esp+4]\r
+    test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND\r
+    jz .return\r
+\r
+    /* Test alert the thread */\r
+    call _NtTestAlert@0\r
+\r
+.return:\r
+    /* We'll continue */\r
+    mov eax, ExceptionContinueSearch\r
+    ret 16\r
+    \r
+.globl _KiUserApcDispatcher@16\r
+_KiUserApcDispatcher@16:\r
+\r
+    /* Put the Context in EDI */\r
+    lea edi, [esp+16]\r
+\r
+    /* Get the ApcRoutine and call it */\r
+    pop eax\r
+    call eax\r
+\r
+    /* Switch back to the context */\r
+    push 1\r
+    push edi\r
+    call _ZwContinue@8\r
+\r
+.globl _KiUserCallbackExceptionHandler@16\r
+_KiUserCallbackExceptionHandler@16:\r
+\r
+    /* Put the exception record in ECX and check the Flags */\r
+    mov ecx, [esp+4]\r
+    test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND\r
+    jz return\r
+\r
+    /* Tell the kernel to invalidate the stack */\r
+    push STATUS_CALLBACK_POP_STACK\r
+    push 0\r
+    push 0\r
+    call _ZwCallbackReturn@12\r
+\r
+return:\r
+    /* We'll continue */\r
+    mov eax, ExceptionContinueSearch\r
+    ret 16\r
+\r
+.globl _KiUserCallbackDispatcher@12\r
+_KiUserCallbackDispatcher@12:\r
+    \r
+    /* Get the callback Index */\r
+    add esp, 4\r
+    pop edx\r
+\r
+    /* Get the callback table */\r
+    mov eax, [fs:TEB_PEB]\r
+    mov eax, [eax+PEB_KERNEL_CALLBACK_TABLE]\r
+\r
+    /* Call the routine */\r
+    call [eax+edx*4]\r
+\r
+    /* Return from callback */\r
+    push eax\r
+    push 0\r
+    push 0\r
+    call _ZwCallbackReturn@12\r
+\r
+.globl _KiRaiseUserExceptionDispatcher@0\r
+_KiRaiseUserExceptionDispatcher@0:\r
+\r
+    /* Setup stack for EXCEPTION_RECORD */\r
+    push ebp\r
+    mov ebp, esp\r
+    sub esp, SIZEOF_EXCEPTION_RECORD\r
+\r
+    /* Fill out the record */\r
+    mov eax, [fs:TEB_SELECTOR]\r
+    mov eax, [eax+TEB_EXCEPTION_CODE]\r
+    mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax\r
+    mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], 0\r
+    mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], 0\r
+    mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0\r
+\r
+    /* Raise the exception */\r
+    push esp\r
+    call _RtlRaiseException@4\r
+\r
+    /* Return exception code */\r
+    mov eax, [esp+EXCEPTION_RECORD_EXCEPTION_CODE]\r
+    mov esp, ebp\r
+    pop ebp\r
+    ret\r
+\r
+.globl _KiUserExceptionDispatcher@8\r
+_KiUserExceptionDispatcher@8:\r
+\r
+    /* Save the Context and Exception Records */\r
+    mov ecx, [esp+4]\r
+    mov ebx, [esp]\r
+\r
+    /* Dispatch the exception */\r
+    push ecx\r
+    push ebx\r
+    call _RtlDispatchException@8\r
+\r
+    /* Check for success */\r
+    or al, al\r
+    jz RaiseException\r
+\r
+    /* We're fine, continue execution */\r
+    push 0\r
+    push ecx\r
+    call _ZwContinue@8\r
+\r
+    /* Exit */\r
+    jmp Exit\r
+\r
+RaiseException:\r
+    /* Pop off the records */\r
+    pop ebx\r
+    pop ecx\r
+\r
+    /* Raise the exception */\r
+    push 0\r
+    push ecx\r
+    push ebx\r
+    call _ZwRaiseException@12\r
+\r
+Exit:\r
+    /* Allocate space for the nested exception record */\r
+    add esp, -SIZEOF_EXCEPTION_RECORD\r
+\r
+    /* Set it up */\r
+    mov [esp+EXCEPTION_RECORD_EXCEPTION_CODE], eax\r
+    mov dword ptr [esp+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_NONCONTINUABLE\r
+    mov [esp+EXCEPTION_RECORD_EXCEPTION_RECORD], ebx\r
+    mov dword ptr [esp+EXCEPTION_RECORD_NUMBER_PARAMETERS], 0\r
+\r
+    /* Raise the exception */\r
+    push esp\r
+    call _RtlRaiseException@4\r
+    ret 8\r
+\r
index c87d722..7f7339f 100644 (file)
                <file>print.c</file>
        </directory>
        <directory name="ldr">
-               <file>entry.S</file>
                <file>res.c</file>
                <file>startup.c</file>
                <file>utils.c</file>
        </directory>
        <directory name="main">
-               <file>dispatch.c</file>
-               <file>dllmain.c</file>
+               <if property="ARCH" value="i386">
+                       <directory name="i386">
+                               <file>dispatch.S</file>
+                       </directory>
+               </if>
+               <ifnot property="ARCH" value="i386">
+                       <file>dispatch.c</file>
+               </ifnot>
        </directory>
        <directory name="rtl">
                <file>libsupp.c</file>
index b92354d..30b7121 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
+ * PROJECT:         ReactOS NT User-Mode DLL
  * FILE:            lib/ntdll/rtl/libsup.c
- * PURPOSE:         Rtl library support routines
- * PROGRAMMER:      Gunnar Dalsnes
+ * PURPOSE:         RTL Support Routines
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Gunnar Dalsnes
  */
 
 /* INCLUDES *****************************************************************/
 
 /* FUNCTIONS ***************************************************************/
 
+BOOLEAN
+NTAPI
+RtlpCheckForActiveDebugger(VOID)
+{
+    return (NtCurrentPeb()->BeingDebugged);
+}
+
 KPROCESSOR_MODE
 STDCALL
 RtlpGetMode()
@@ -28,7 +36,6 @@ RtlpCurrentPeb(VOID)
     return NtCurrentPeb();
 }
 
-
 /*
  * @implemented
  */
@@ -39,7 +46,6 @@ RtlAcquirePebLock(VOID)
    Peb->FastPebLockRoutine (Peb->FastPebLock);
 }
 
-
 /*
  * @implemented
  */
@@ -57,8 +63,8 @@ ULONG
 STDCALL
 RtlGetNtGlobalFlags(VOID)
 {
-       PPEB pPeb = NtCurrentPeb();
-       return pPeb->NtGlobalFlag;
+    PPEB pPeb = NtCurrentPeb();
+    return pPeb->NtGlobalFlag;
 }
 
 NTSTATUS
@@ -82,7 +88,7 @@ STDCALL
 RtlInitializeHeapLock(
     PRTL_CRITICAL_SECTION CriticalSection)
 {
-     return RtlInitializeCriticalSection(CriticalSection );
+     return RtlInitializeCriticalSection(CriticalSection);
 }
 
 NTSTATUS
@@ -127,6 +133,27 @@ CHECK_PAGED_CODE_RTL(char *file, int line)
 }
 #endif
 
+BOOLEAN
+NTAPI
+RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
+                            IN ULONG_PTR RegistrationFrameEnd,
+                            IN OUT PULONG_PTR StackLow,
+                            IN OUT PULONG_PTR StackHigh)
+{
+    /* There's no such thing as a DPC stack in user-mode */
+    return FALSE;
+}
+
+VOID
+NTAPI
+RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
+                      IN PCONTEXT ContextRecord,
+                      IN PVOID ContextData,
+                      IN ULONG Size)
+{
+    /* Exception logging is not done in user-mode */
+}
+
 /* RTL Atom Tables ************************************************************/
 
 typedef struct _RTL_ATOM_HANDLE
index 49a1ccf..60401ef 100644 (file)
@@ -1,8 +1,9 @@
 /* COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * PURPOSE:         User-mode exception support
+ * PROJECT:         ReactOS Runtime Library
+ * PURPOSE:         User-Mode Exception Support
  * FILE:            lib/rtl/exception.c
- * PROGRAMERS:      David Welch <welch@cwcom.net>
+ * PROGRAMERS:      Alex Ionescu (alex@relsoft.net)
+ *                  David Welch <welch@cwcom.net>
  *                  Skywing <skywing@valhallalegends.com>
  *                  KJK::Hyperion <noog@libero.it>
  */
 
 /* FUNCTIONS ***************************************************************/
 
-/* implemented in except.s */
-VOID
-RtlpCaptureContext(PCONTEXT Context);
-
-/*
-* @unimplemented
-*/
-NTSTATUS
-STDCALL
-RtlDispatchException(
-       PEXCEPTION_RECORD pExcptRec,
-       CONTEXT * pContext
-       )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
-}
-
 /*
-* @unimplemented
-*/
+ * @implemented
+ */
 VOID
 STDCALL
-RtlGetCallersAddress(
-       OUT PVOID *CallersAddress,
-       OUT PVOID *CallersCaller
-       )
+RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
 {
-       UNIMPLEMENTED;
+    CONTEXT Context;
+    NTSTATUS Status;
+    DPRINT1("RtlRaiseException(Status %p)\n", ExceptionRecord);
+
+    /* Capture the context */
+    RtlCaptureContext(&Context);
+
+    /* Save the exception address */
+    ExceptionRecord->ExceptionAddress = RtlpGetExceptionAddress();
+    DPRINT1("ExceptionAddress %p\n", ExceptionRecord->ExceptionAddress);
+
+    /* Write the context flag */
+    Context.ContextFlags = CONTEXT_FULL;
+
+    /* Check if we're being debugged (user-mode only) */
+    if (!RtlpCheckForActiveDebugger())
+    {
+        /* Raise an exception immediately */
+        ZwRaiseException(ExceptionRecord, &Context, TRUE);
+    }
+    else
+    {
+        /* Dispatch the exception and check if we should continue */
+        if (RtlDispatchException(ExceptionRecord, &Context))
+        {
+            /* Raise the exception */
+            Status = ZwRaiseException(ExceptionRecord, &Context, FALSE);
+        }
+        else
+        {
+            /* Continue, go back to previous context */
+            ZwContinue(&Context, FALSE);
+        }
+    }
+
+    /* If we returned, raise a status  */
+    RtlRaiseStatus(Status);
 }
 
 /*
  * @implemented
  */
-VOID STDCALL
-RtlRaiseException(PEXCEPTION_RECORD ExceptionRecord)
+VOID
+STDCALL
+RtlRaiseStatus(NTSTATUS Status)
 {
-  CONTEXT Context;
-  NTSTATUS Status;
-
-  RtlpCaptureContext(&Context);
-
-  ExceptionRecord->ExceptionAddress = (PVOID)(*(((PULONG)Context.Ebp)+1));
-  Context.ContextFlags = CONTEXT_FULL;
-
-  Status = NtRaiseException(ExceptionRecord, &Context, TRUE);
-  RtlRaiseException(ExceptionRecord);
-  RtlRaiseStatus(Status);
+    EXCEPTION_RECORD ExceptionRecord;
+    CONTEXT Context;
+    DPRINT1("RtlRaiseStatus(Status 0x%.08x)\n", Status);
+
+     /* Capture the context */
+    RtlCaptureContext(&Context);
+
+    /* Add one argument to ESP */
+    Context.Esp += sizeof(PVOID);
+
+    /* Create an exception record */
+    ExceptionRecord.ExceptionAddress = RtlpGetExceptionAddress();
+    ExceptionRecord.ExceptionCode  = Status;
+    ExceptionRecord.ExceptionRecord = NULL;
+    ExceptionRecord.NumberParameters = 0;
+    ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+
+    /* Write the context flag */
+    Context.ContextFlags = CONTEXT_FULL;
+
+    /* Check if we're being debugged (user-mode only) */
+    if (!RtlpCheckForActiveDebugger())
+    {
+        /* Raise an exception immediately */
+        ZwRaiseException(&ExceptionRecord, &Context, TRUE);
+    }
+    else
+    {
+        /* Dispatch the exception */
+        RtlDispatchException(&ExceptionRecord, &Context);
+
+        /* Raise exception if we got here */
+        Status = ZwRaiseException(&ExceptionRecord, &Context, FALSE);
+    }
+
+    /* If we returned, raise a status */
+    RtlRaiseStatus(Status);
 }
 
-
 /*
- * @implemented
- */
-VOID STDCALL
-RtlRaiseStatus(NTSTATUS Status)
+* @unimplemented
+*/
+USHORT
+STDCALL
+RtlCaptureStackBackTrace(IN ULONG FramesToSkip,
+                         IN ULONG FramesToCapture,
+                         OUT PVOID *BackTrace,
+                         OUT PULONG BackTraceHash OPTIONAL)
 {
-  EXCEPTION_RECORD ExceptionRecord;
-
-  DPRINT("RtlRaiseStatus(Status 0x%.08x)\n", Status);
-
-  ExceptionRecord.ExceptionCode    = Status;
-  ExceptionRecord.ExceptionRecord  = NULL;
-  ExceptionRecord.NumberParameters = 0;
-  ExceptionRecord.ExceptionFlags   = EXCEPTION_NONCONTINUABLE;
-  RtlRaiseException (& ExceptionRecord);
+    UNIMPLEMENTED;
+    return 0;
 }
 
 /*
@@ -89,15 +128,12 @@ RtlRaiseStatus(NTSTATUS Status)
 */
 ULONG
 STDCALL
-RtlWalkFrameChain (
-       OUT PVOID *Callers,
-       IN ULONG Count,
-       IN ULONG Flags
-       )
+RtlWalkFrameChain(OUT PVOID *Callers,
+                  IN ULONG Count,
+                  IN ULONG Flags)
 {
-       UNIMPLEMENTED;
-       return 0;
+    UNIMPLEMENTED;
+    return 0;
 }
 
-
 /* EOF */
index bd3b631..ac8b384 100644 (file)
-/* $Id$
- *
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * PURPOSE:           User-mode exception support for IA-32
- * FILE:              lib/ntdll/rtl/i386/except.s
- * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
- * NOTES:             This file is shared with ntoskrnl/rtl/i386/except.s.
- *                    Please keep them in sync.
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS NT Library
+ * FILE:            lib/rtl/i386/except.S
+ * PURPOSE:         User-mode exception support for IA-32
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
-#define EXCEPTION_UNWINDING            0x02
-
-#define EREC_FLAGS                             0x04
-
-#define ExceptionContinueExecution 0
-#define ExceptionContinueSearch    1
-#define ExceptionNestedException   2
-#define ExceptionCollidedUnwind    3
-
-.globl _RtlpExecuteHandlerForException
-.globl _RtlpExecuteHandlerForUnwind
-
-#define CONTEXT_FLAGS  0x00
-#define CONTEXT_SEGGS  0x8C
-#define CONTEXT_SEGFS  0x90
-#define CONTEXT_SEGES  0x94
-#define CONTEXT_SEGDS  0x98
-#define CONTEXT_EDI            0x9C
-#define CONTEXT_ESI            0xA0
-#define CONTEXT_EBX            0xA4
-#define CONTEXT_EDX            0xA8
-#define CONTEXT_ECX            0xAC
-#define CONTEXT_EAX            0xB0
-#define CONTEXT_EBP            0xB4
-#define CONTEXT_EIP            0xB8
-#define CONTEXT_SEGCS  0xBC
-#define CONTEXT_EFLAGS 0xC0
-#define CONTEXT_ESP            0xC4
-#define CONTEXT_SEGSS  0xC8
-
-
-#define RCC_CONTEXT            0x08
-
-// EAX = value to print
-_do_debug:
-       pushal
-       pushl   %eax
-       call    _AsmDebug@4
-       popal
-       ret
-
-#ifndef __NTOSKRNL__
-
-//
-// VOID
-// RtlpCaptureContext(PCONTEXT pContext);
-//
-// Parameters:
-//   [ESP+08h] - PCONTEXT_X86 pContext
-// Registers:
-//   None
-// Returns:
-//   Nothing
-// Notes:
-//   Grabs the current CPU context.
-.globl _RtlpCaptureContext
-_RtlpCaptureContext:
-       pushl   %ebp
-    movl       %esp, %ebp
-    pushl   %ebx
-       movl    RCC_CONTEXT(%ebp), %edx         // EDX = Address of context structure
-
-       cld
-       pushf
-       pop             %eax
-       movl    %eax, CONTEXT_EFLAGS(%edx)
-       xorl    %eax, %eax
-       movl    %eax, CONTEXT_EAX(%edx)
-       movl    %eax, CONTEXT_EBX(%edx)
-       movl    %eax, CONTEXT_ECX(%edx)
-       movl    %eax, CONTEXT_EDX(%edx)
-       movl    %eax, CONTEXT_ESI(%edx)
-       movl    %eax, CONTEXT_EDI(%edx)
-       movl    %cs, %eax
-       movl    %eax, CONTEXT_SEGCS(%edx)
-       movl    %ds, %eax
-       movl    %eax, CONTEXT_SEGDS(%edx)
-       movl    %es, %eax
-       movl    %eax, CONTEXT_SEGES(%edx)
-       movl    %fs, %eax
-       movl    %eax, CONTEXT_SEGFS(%edx)
-       movl    %gs, %eax
-       movl    %eax, CONTEXT_SEGGS(%edx)
-       movl    %ss, %eax
-       movl    %eax, CONTEXT_SEGSS(%edx)
-
-       //
-       // STACK LAYOUT: - (ESP to put in context structure)
-       //               - RETURN ADDRESS OF CALLER OF CALLER
-       //               - EBP OF CALLER OF CALLER
-       //                 ...
-       //               - RETURN ADDRESS OF CALLER
-       //               - EBP OF CALLER
-       //                 ...
-       //
-
-       // Get return address of the caller of the caller of this function
-       movl    %ebp, %ebx
-       //movl  4(%ebx), %eax                   // EAX = return address of caller
-       movl    (%ebx), %ebx                    // EBX = EBP of caller
-
-       movl    4(%ebx), %eax                   // EAX = return address of caller of caller
-       movl    (%ebx), %ebx                    // EBX = EBP of caller of caller
-
-       movl    %eax, CONTEXT_EIP(%edx) // EIP = return address of caller of caller
-       movl    %ebx, CONTEXT_EBP(%edx) // EBP = EBP of caller of caller
-       addl    $8, %ebx
-       movl    %ebx, CONTEXT_ESP(%edx) // ESP = EBP of caller of caller + 8
-
-    popl    %ebx
-    movl       %ebp, %esp
-    popl       %ebp
+/* INCLUDES ******************************************************************/
+
+#include <ndk/asm.h>
+#include <ndk/i386/segment.h>
+.intel_syntax noprefix
+
+#define EXCEPTION_UNWINDING         2
+#define EXCEPTION_EXIT_UNWIND       4
+#define EXCEPTION_UNWIND            (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
+
+#define ExceptionContinueExecution  0
+#define ExceptionContinueSearch     1
+#define ExceptionNestedException    2
+#define ExceptionCollidedUnwind     3
+
+/* FUNCTIONS ****************************************************************/
+
+.globl _RtlpGetStackLimits@8
+_RtlpGetStackLimits@8:
+
+    /* Get the stack limits */
+    mov eax, [fs:TEB_STACK_LIMIT]
+    mov ecx, [fs:TEB_STACK_BASE]
+
+    /* Return them */
+    mov edx, [esp+4]
+    mov [edx], eax
+    mov edx, [esp+8]
+    mov [edx], ecx
+
+    /* return */
+    ret 8
+
+.globl _RtlpGetExceptionList@0
+_RtlpGetExceptionList@0:
+
+    /* Return the exception list */
+    mov eax, [fs:TEB_EXCEPTION_LIST]
     ret
 
-#endif /* !__NTOSKRNL__ */
-
-#define REH_ERECORD            0x08
-#define REH_RFRAME             0x0C
-#define REH_CONTEXT            0x10
-#define REH_DCONTEXT   0x14
-#define REH_EROUTINE   0x18
-
-// Parameters:
-//   None
-// Registers:
-//   [EBP+08h] - PEXCEPTION_RECORD ExceptionRecord
-//   [EBP+0Ch] - PEXCEPTION_REGISTRATION RegistrationFrame
-//   [EBP+10h] - PVOID Context
-//   [EBP+14h] - PVOID DispatcherContext
-//   [EBP+18h] - PEXCEPTION_HANDLER ExceptionRoutine
-//   EDX       - Address of protecting exception handler
-// Returns:
-//   EXCEPTION_DISPOSITION
-// Notes:
-//   Setup the protecting exception handler and call the exception
-//   handler in the right context.
-_RtlpExecuteHandler:
-       pushl    %ebp
-    movl     %esp, %ebp
-    pushl    REH_RFRAME(%ebp)
-
-    pushl    %edx
-    pushl    %fs:0x0
-    movl     %esp, %fs:0x0
-
-    // Prepare to call the exception handler
-    pushl    REH_DCONTEXT(%ebp)
-    pushl    REH_CONTEXT(%ebp)
-    pushl    REH_RFRAME(%ebp)
-    pushl    REH_ERECORD(%ebp)
-
-    // Now call the exception handler
-    movl     REH_EROUTINE(%ebp), %eax
-    call    *%eax
-
-       cmpl    $-1, %fs:0x0
-       jne             .reh_stack_looks_ok
-
-       // This should not happen
-       pushl   0
-       pushl   0
-       pushl   0
-       pushl   0
-       call    _RtlAssert@16
-
-.reh_loop:
-       jmp     .reh_loop
-
-.reh_stack_looks_ok:
-    movl     %fs:0x0, %esp
-
-    // Return to the 'front-end' for this function
-    popl     %fs:0x0
-    movl     %ebp, %esp
-    popl     %ebp
+.globl _RtlpSetExceptionList@4
+_RtlpSetExceptionList@4:
+
+    /* Get the new list */
+    mov ecx, [esp+4]
+    mov ecx, [ecx]
+
+    /* Write it */
+    mov [fs:TEB_EXCEPTION_LIST], ecx
+
+    /* Return */
+    ret 4
+
+.globl _RtlpGetExceptionAddress@0
+_RtlpGetExceptionAddress@0:
+
+    /* Return the address from the stack */
+    mov eax, [ebp+4]
+
+    /* Return */
     ret
 
+.globl _RtlCaptureContext@4
+_RtlCaptureContext@4:
+
+    /* Preserve EBX and put the context in it */
+    push ebx
+    mov ebx, [esp+8]
+
+    /* Save the basic register context */
+    mov [ebx+CONTEXT_EAX], eax
+    mov [ebx+CONTEXT_ECX], ecx
+    mov [ebx+CONTEXT_EDX], edx
+    mov eax, [esp]              /* We pushed EBX, remember? ;) */
+    mov [ebx+CONTEXT_EBX], eax
+    mov [ebx+CONTEXT_ESI], esi
+    mov [ebx+CONTEXT_EDI], edi
+
+    /* Capture the other regs */
+    jmp CaptureRest
+
+.globl _RtlpCaptureContext@4
+_RtlpCaptureContext@4:
+
+    /* Preserve EBX and put the context in it */
+    push ebx
+    mov ebx, [esp+8]
+    
+    /* Clear the basic register context */
+    mov dword ptr [ebx+CONTEXT_EAX], 0
+    mov dword ptr [ebx+CONTEXT_ECX], 0
+    mov dword ptr [ebx+CONTEXT_EDX], 0
+    mov dword ptr [ebx+CONTEXT_EBX], 0
+    mov dword ptr [ebx+CONTEXT_ESI], 0
+    mov dword ptr [ebx+CONTEXT_EDI], 0
+    
+CaptureRest:
+    /* Capture the segment registers */
+    mov [ebx+CONTEXT_SEGCS], cs
+    mov [ebx+CONTEXT_SEGDS], ds
+    mov [ebx+CONTEXT_SEGES], es
+    mov [ebx+CONTEXT_SEGFS], fs
+    mov [ebx+CONTEXT_SEGGS], gs
+    mov [ebx+CONTEXT_SEGSS], ss
+    
+    /* Capture flags */
+    pushfd
+    pop [ebx+CONTEXT_EFLAGS]
+
+    /* The return address should be in [ebp+4] */
+    mov eax, [ebp+4]
+    mov [ebx+CONTEXT_EIP], eax
+
+    /* Get EBP */
+    mov eax, [esp]
+    mov [ebx+CONTEXT_EBP], eax
+
+    /* And get ESP */
+    mov eax, [ebp+8]
+    mov [ebx+CONTEXT_ESP], eax
+
+    /* Return to the caller */
+    pop ebx
+    ret 4
+
+.globl _RtlpExecuteHandlerForException@20
+_RtlpExecuteHandlerForException@20:
+
+    /* Copy the routine in EDX */
+    mov edx, offset _RtlpExceptionProtector
+
+    /* Jump to common routine */
+    jmp _RtlpExecuteHandler@20
+
+.globl _RtlpExecuteHandlerForUnwind@20
+_RtlpExecuteHandlerForUnwind@20:
+    
+    /* Copy the routine in EDX */
+    mov edx, offset _RtlpExceptionProtector
+
+    /* Run the common routine */
+_RtlpExecuteHandler@20:
+
+    /* Save non-volatile */
+    push ebx
+    push esi
+    push edi
+    
+    /* Clear registers */
+    xor eax, eax
+    xor ebx, ebx
+    xor esi, esi
+    xor edi, edi
+
+    /* Call the 2nd-stage executer */
+    push [esp+0x20]
+    push [esp+0x20]
+    push [esp+0x20]
+    push [esp+0x20]
+    push [esp+0x20]
+    call _RtlpExecuteHandler2@20
+
+    /* Restore non-volatile */
+    pop edi
+    pop esi
+    pop ebx
+    ret 0x14
+
+.globl _RtlpExecuteHandler2@20
+_RtlpExecuteHandler2@20:
+
+    /* Set up stack frame */
+    push ebp
+    mov ebp, esp
+
+    /* Save the Frame */
+    push [ebp+0xC]
+
+    /* Push handler address */
+    push edx
+
+    /* Push the exception list */
+    push [fs:TEB_EXCEPTION_LIST]
+
+    /* Link us to it */
+    mov [fs:TEB_EXCEPTION_LIST], esp
+
+    /* Call the handler */
+    push [ebp+0x14]
+    push [ebp+0x10]
+    push [ebp+0xC]
+    push [ebp+8]
+    mov ecx, [ebp+0x18]
+    call ecx
+
+    /* Unlink us */
+    mov esp, [fs:TEB_EXCEPTION_LIST]
+
+    /* Restore it */
+    pop [fs:TEB_EXCEPTION_LIST]
+
+    /* Undo stack frame and return */
+    mov esp, ebp
+    pop ebp
+    ret 0x14
 
-#define REP_ERECORD     0x04
-#define REP_RFRAME      0x08
-#define REP_CONTEXT     0x0C
-#define REP_DCONTEXT    0x10
-
-// Parameters:
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
-//   [ESP+0Ch] - PCONTEXT Context
-//   [ESP+10h] - PVOID DispatcherContext
-// Registers:
-//   None
-// Returns:
-//   EXCEPTION_DISPOSITION
-// Notes:
-//    This exception handler protects the exception handling
-//    mechanism by detecting nested exceptions.
 _RtlpExceptionProtector:
-    movl     $ExceptionContinueSearch, %eax
-    movl     REP_ERECORD(%esp), %ecx
-    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
-    jnz      .rep_end
 
-    // Unwinding is not taking place, so return ExceptionNestedException
+    /* Assume we'll continue */
+    mov eax, ExceptionContinueSearch
 
-    // Set DispatcherContext field to the exception registration for the
-    // exception handler that executed when a nested exception occurred
-    movl     REP_DCONTEXT(%esp), %ecx
-    movl     REP_RFRAME(%esp), %eax
-    movl     %eax, (%ecx)
-    movl     $ExceptionNestedException, %eax
+    /* Put the exception record in ECX and check the Flags */
+    mov ecx, [esp+4]
+    test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
+    jnz return
 
-.rep_end:
-    ret
+    /* Save the frame in ECX and Context in EDX */
+    mov ecx, [esp+8]
+    mov edx, [esp+16]
 
+    /* Get the nested frame */
+    mov eax, [ecx+8]
+
+    /* Set it as the dispatcher context */
+    mov [edx], eax
+
+    /* Return nested exception */
+    mov eax, ExceptionNestedException
+
+return:
+    ret 16
 
-// Parameters:
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
-//   [ESP+0Ch] - PCONTEXT Context
-//   [ESP+10h] - PVOID DispatcherContext
-//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
-// Registers:
-//   None
-// Returns:
-//   EXCEPTION_DISPOSITION
-// Notes:
-//   Front-end
-_RtlpExecuteHandlerForException:
-    movl     $_RtlpExceptionProtector, %edx
-    jmp      _RtlpExecuteHandler
-
-
-#define RUP_ERECORD     0x04
-#define RUP_RFRAME      0x08
-#define RUP_CONTEXT     0x0C
-#define RUP_DCONTEXT    0x10
-
-// Parameters:
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
-//   [ESP+0Ch] - PCONTEXT Context
-//   [ESP+10h] - PVOID DispatcherContext
-// Registers:
-//   None
-// Returns:
-//   EXCEPTION_DISPOSITION
-// Notes:
-//    This exception handler protects the exception handling
-//    mechanism by detecting collided unwinds.
 _RtlpUnwindProtector:
-    movl     $ExceptionContinueSearch, %eax
-    movl     %ecx, RUP_ERECORD(%esp)
-    testl    $EXCEPTION_UNWINDING, EREC_FLAGS(%ecx)
-    jz       .rup_end
+    /* Assume we'll continue */
+    mov eax, ExceptionContinueSearch
 
-    // Unwinding is taking place, so return ExceptionCollidedUnwind
+    /* Put the exception record in ECX and check the Flags */
+    mov ecx, [esp+4]
+    test dword ptr [ecx+EXCEPTION_RECORD_EXCEPTION_FLAGS], EXCEPTION_UNWIND
+    jnz .return
 
-    movl     RUP_RFRAME(%esp), %ecx
-    movl     RUP_DCONTEXT(%esp), %edx
+    /* Save the frame in ECX and Context in EDX */
+    mov ecx, [esp+8]
+    mov edx, [esp+16]
 
-    // Set DispatcherContext field to the exception registration for the
-    // exception handler that executed when a collision occurred
-    movl     RUP_RFRAME(%ecx), %eax
-    movl     %eax, (%edx)
-    movl     $ExceptionCollidedUnwind, %eax
+    /* Get the nested frame */
+    mov eax, [ecx+8]
 
-.rup_end:
-    ret
+    /* Set it as the dispatcher context */
+    mov [edx], eax
+
+    /* Return collided unwind */
+    mov eax, ExceptionCollidedUnwind
 
+.return:
+    ret 16
 
-// Parameters:
-//   [ESP+04h] - PEXCEPTION_RECORD ExceptionRecord
-//   [ESP+08h] - PEXCEPTION_REGISTRATION RegistrationFrame
-//   [ESP+0Ch] - PCONTEXT Context
-//   [ESP+10h] - PVOID DispatcherContext
-//   [ESP+14h] - PEXCEPTION_HANDLER ExceptionHandler
-// Registers:
-//   None
-// Returns:
-//   EXCEPTION_DISPOSITION
-_RtlpExecuteHandlerForUnwind:
-    movl     $_RtlpUnwindProtector, %edx
-    jmp      _RtlpExecuteHandler
index a981db3..c0d8be1 100644 (file)
@@ -1,10 +1,10 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
+ * PROJECT:           ReactOS Run-Time Library
  * PURPOSE:           User-mode exception support for IA-32
- * FILE:              lib/ntdll/rtl/i386/exception.c
- * PROGRAMER:         Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * FILE:              lib/rtl/i386/exception.c
+ * PROGRAMERS:        Alex Ionescu (alex@relsoft.net)
+ *                    Casper S. Hornstrup (chorns@users.sourceforge.net)
  */
 
 /* INCLUDES *****************************************************************/
 #define NDEBUG
 #include <debug.h>
 
-/* FUNCTIONS ***************************************************************/
-
-/* Implemented in except.s */
+/* PRIVATE FUNCTIONS *********************************************************/
 
 VOID
-RtlpCaptureContext(PCONTEXT pContext);
+STDCALL
+RtlpGetStackLimits(PULONG_PTR StackBase,
+                   PULONG_PTR StackLimit);
 
-#define SehpGetStackLimits(StackBase, StackLimit) \
-{ \
-       (*(StackBase)) = NtCurrentTeb()->Tib->StackBase; \
-       (*(StackLimit)) = NtCurrentTeb()->Tib->StackLimit; \
-}
+PEXCEPTION_REGISTRATION_RECORD
+STDCALL
+RtlpGetExceptionList(VOID);
 
-#define SehpGetExceptionList() \
-       (PEXCEPTION_REGISTRATION)(NtCurrentTeb()->Tib.ExceptionList)
+VOID
+STDCALL
+RtlpSetExceptionList(PEXCEPTION_REGISTRATION_RECORD NewExceptionList);
 
-#define SehpSetExceptionList(NewExceptionList) \
-       NtCurrentTeb()->Tib.ExceptionList = (PVOID)(NewExceptionList)
+/* PUBLIC FUNCTIONS **********************************************************/
 
-VOID STDCALL
-AsmDebug(ULONG Value)
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+RtlGetCallersAddress(OUT PVOID *CallersAddress,
+                     OUT PVOID *CallersCaller)
 {
-  DbgPrint("Value 0x%.08x\n", Value);
+    UNIMPLEMENTED;
 }
 
-
-/* Declare a few prototypes for the functions in except.s */
-
-EXCEPTION_DISPOSITION
-RtlpExecuteHandlerForException(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION RegistrationFrame,
-  PCONTEXT Context,
-  PVOID DispatcherContext,
-  PEXCEPTION_HANDLER ExceptionHandler);
-
-EXCEPTION_DISPOSITION
-RtlpExecuteHandlerForUnwind(
-  PEXCEPTION_RECORD ExceptionRecord,
-  PEXCEPTION_REGISTRATION RegistrationFrame,
-  PCONTEXT Context,
-  PVOID DispatcherContext,
-  PEXCEPTION_HANDLER ExceptionHandler);
-
-
-#ifndef NDEBUG
-
-VOID RtlpDumpExceptionRegistrations(VOID)
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+RtlDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
+                     IN PCONTEXT Context)
 {
-  PEXCEPTION_REGISTRATION Current;
-
-  DbgPrint("Dumping exception registrations:\n");
-
-  Current = SehpGetExceptionList();
-
-  if ((ULONG_PTR)Current != -1)
-  {
-    while ((ULONG_PTR)Current != -1)
+    PEXCEPTION_REGISTRATION_RECORD RegistrationFrame, NestedFrame = NULL;
+    PEXCEPTION_REGISTRATION_RECORD DispatcherContext;
+    EXCEPTION_RECORD ExceptionRecord2;
+    EXCEPTION_DISPOSITION ReturnValue;
+    ULONG_PTR StackLow, StackHigh;
+    ULONG_PTR RegistrationFrameEnd;
+    DPRINT1("RtlDispatchException(): %p, %p \n", ExceptionRecord, Context);
+
+    /* Get the current stack limits and registration frame */
+    RtlpGetStackLimits(&StackLow, &StackHigh);
+    RegistrationFrame = RtlpGetExceptionList();
+    DPRINT1("RegistrationFrame is 0x%X\n", RegistrationFrame);
+
+    /* Now loop every frame */
+    while (RegistrationFrame != EXCEPTION_CHAIN_END)
     {
-      DbgPrint("   (0x%08X)   HANDLER (0x%08X)\n", Current, Current->handler);
-      Current = Current->prev;
-    }
-    DbgPrint("   End-Of-List\n");
-  } else {
-    DbgPrint("   No exception registrations exists.\n");
-  }
-}
-
-#endif /* NDEBUG */
-
-ULONG
-RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
-       IN PCONTEXT  Context)
-{
-  PEXCEPTION_REGISTRATION RegistrationFrame, NestedFrame = NULL, DispatcherContext;
-  DWORD ReturnValue;
-
-  DPRINT("RtlpDispatchException()\n");
-
-#ifndef NDEBUG
-  RtlpDumpExceptionRegistrations();
-#endif /* NDEBUG */
-
-  RegistrationFrame = SehpGetExceptionList();
+        /* Find out where it ends */
+        RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame +
+                                sizeof(*RegistrationFrame);
+
+        /* Make sure the registration frame is located within the stack */
+        if ((RegistrationFrameEnd > StackHigh) ||
+            ((ULONG_PTR)RegistrationFrame < StackLow) ||
+            ((ULONG_PTR)RegistrationFrame & 0x3))
+        {
+            /* Check if this happened in the DPC Stack */
+            if (RtlpHandleDpcStackException(RegistrationFrame,
+                                            RegistrationFrameEnd,
+                                            &StackLow,
+                                            &StackHigh))
+            {
+                /* Use DPC Stack Limits and restart */
+                continue;
+            }
+
+            /* Set invalid stack and return false */
+            ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
+            DPRINT1("Invalid exception frame\n");
+            return FALSE;
+        }
 
-  DPRINT("RegistrationFrame is 0x%X\n", RegistrationFrame);
+        /* Check if logging is enabled */
+        DPRINT1("Checking for logging\n");
+        RtlpCheckLogException(ExceptionRecord,
+                              Context,
+                              RegistrationFrame,
+                              sizeof(*RegistrationFrame));
+
+        /* Call the handler */
+        DPRINT1("Executing handler: %p\n", RegistrationFrame->Handler);
+        ReturnValue = RtlpExecuteHandlerForException(ExceptionRecord,
+                                                     RegistrationFrame,
+                                                     Context,
+                                                     &DispatcherContext,
+                                                     RegistrationFrame->Handler);
+        DPRINT1("Handler returned: %lx\n", ReturnValue);
+
+        /* Check if this is a nested frame */
+        if (RegistrationFrame == NestedFrame)
+        {
+            /* Mask out the flag and the nested frame */
+            ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;
+            NestedFrame = NULL;
+        }
 
-  while ((ULONG_PTR)RegistrationFrame != (ULONG_PTR)-1)
-  {
-    EXCEPTION_RECORD ExceptionRecord2;
-    //PVOID RegistrationFrameEnd = (PVOID)RegistrationFrame + 8;
+        /* Handle the dispositions */
+        if (ReturnValue == ExceptionContinueExecution)
+        {
+            /* Check if it was non-continuable */
+            if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
+            {
+                /* Set up the exception record */
+                ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+                ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
+                ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+                ExceptionRecord2.NumberParameters = 0;
+
+                /* Raise the exception */
+                DPRINT1("Non-continuable\n");
+                RtlRaiseException(&ExceptionRecord2);
+            }
+            else
+            {
+                /* Return to caller */
+                return TRUE;
+            }
+        }
+        else if (ReturnValue == ExceptionNestedException)
+        {
+            /* Turn the nested flag on */
+            ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;
 
-    // Make sure the registration frame is located within the stack
+            /* Update the current nested frame */
+            if (NestedFrame < DispatcherContext) NestedFrame = DispatcherContext;
+        }
+        else if (ReturnValue == ExceptionContinueSearch)
+        {
+        }
+        else
+        {
+            /* Set up the exception record */
+            ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+            ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
+            ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+            ExceptionRecord2.NumberParameters = 0;
+
+            /* Raise the exception */
+            RtlRaiseException(&ExceptionRecord2);
+        }
 
-    DPRINT("Error checking\n");
-#if 0
-    if (Teb->Tib.StackBase > RegistrationFrameEnd)
-    {
-      DPRINT("Teb->Tib.StackBase (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
-        Teb->Tib.StackBase, RegistrationFrameEnd);
-      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
-      return ExceptionContinueExecution;
-    }
-    // FIXME: Stack top, correct?
-    if (Teb->Tib.StackLimit < RegistrationFrameEnd)
-    {
-      DPRINT("Teb->Tib.StackLimit (0x%.08x) > RegistrationFrameEnd (0x%.08x)\n",
-        Teb->Tib.StackLimit, RegistrationFrameEnd);
-      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
-      return ExceptionContinueExecution;
+        /* Go to the next frame */
+        RegistrationFrame = RegistrationFrame->Next;
     }
 
-    // Make sure stack is DWORD aligned
-    if ((ULONG_PTR)RegistrationFrame & 3)
-    {
-      DPRINT("RegistrationFrameEnd (0x%.08x) is not DWORD aligned.\n",
-        RegistrationFrameEnd);
-      ExceptionRecord->ExceptionFlags |= EXCEPTION_STACK_INVALID;
-      return ExceptionContinueExecution;
-    }
-#endif
-
-#if 0
-    /* FIXME: */
-    if (someFlag)
-      RtlpLogLastExceptionDisposition( hLog, retValue );
-#endif
-
-    DPRINT("Calling handler at 0x%X\n", RegistrationFrame->handler);
-    DPRINT("ExceptionRecord 0x%X\n", ExceptionRecord);
-    DPRINT("RegistrationFrame 0x%X\n", RegistrationFrame);
-    DPRINT("Context 0x%X\n", Context);
-    DPRINT("&DispatcherContext 0x%X\n", &DispatcherContext);
-
-    ReturnValue = RtlpExecuteHandlerForException(
-      ExceptionRecord,
-      RegistrationFrame,
-      Context,
-      &DispatcherContext,
-      RegistrationFrame->handler);
-#ifdef DEBUG
-    DPRINT("Exception handler said 0x%X\n", ReturnValue);
-       DPRINT("RegistrationFrame == 0x%.08x\n", RegistrationFrame);
-       {
-               PULONG sp = (PULONG)((PVOID)RegistrationFrame - 0x08);
-               DPRINT("StandardESP == 0x%.08x\n", sp[0]);
-               DPRINT("Exception Pointers == 0x%.08x\n", sp[1]);
-               DPRINT("PrevFrame == 0x%.08x\n", sp[2]);
-               DPRINT("Handler == 0x%.08x\n", sp[3]);
-               DPRINT("ScopeTable == 0x%.08x\n", sp[4]);
-               DPRINT("TryLevel == 0x%.08x\n", sp[5]);
-               DPRINT("EBP == 0x%.08x\n", sp[6]);
-       }
-#endif
-    if (RegistrationFrame == NestedFrame)
-    {
-      ExceptionRecord->ExceptionFlags &= ~EXCEPTION_NESTED_CALL;  // Turn off flag
-      NestedFrame = NULL;
-    }
+    /* Unhandled, return false */
+    DPRINT1("FALSE:(\n");
+    return FALSE;
+}
 
-    if (ReturnValue == ExceptionContinueExecution)
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+RtlUnwind(PVOID RegistrationFrame OPTIONAL,
+          PVOID ReturnAddress OPTIONAL,
+          PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
+          PVOID EaxValue)
+{
+    PEXCEPTION_REGISTRATION_RECORD RegistrationFrame2, OldFrame;
+    PEXCEPTION_REGISTRATION_RECORD DispatcherContext;
+    EXCEPTION_RECORD ExceptionRecord2, ExceptionRecord3;
+    EXCEPTION_DISPOSITION ReturnValue;
+    ULONG_PTR StackLow, StackHigh;
+    ULONG_PTR RegistrationFrameEnd;
+    CONTEXT LocalContext;
+    PCONTEXT Context;
+    DPRINT1("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
+
+    /* Get the current stack limits */
+    RtlpGetStackLimits(&StackLow, &StackHigh);
+
+    /* Check if we don't have an exception record */
+    if (!ExceptionRecord)
     {
-      DPRINT("ReturnValue == ExceptionContinueExecution\n");
-      if (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)
-      {
-        DPRINT("(ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE) == TRUE\n");
-
-        ExceptionRecord2.ExceptionRecord = ExceptionRecord;
-        ExceptionRecord2.ExceptionCode = STATUS_NONCONTINUABLE_EXCEPTION;
-        ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
-        ExceptionRecord2.NumberParameters = 0;
-        RtlRaiseException(&ExceptionRecord2);
-      }
-      else
-      {
-        /* Copy the (possibly changed) context back to the trap frame and return */
-        ZwContinue(Context, FALSE);
-        return ExceptionContinueExecution;
-      }
+        /* Overwrite the argument */
+        ExceptionRecord = &ExceptionRecord3;
+
+        /* Setup a local one */
+        ExceptionRecord3.ExceptionFlags = 0;
+        ExceptionRecord3.ExceptionCode = STATUS_UNWIND;
+        ExceptionRecord3.ExceptionRecord = NULL;
+        ExceptionRecord3.ExceptionAddress = RtlpGetExceptionAddress();
+        ExceptionRecord3.NumberParameters = 0;
     }
-    else if (ReturnValue == ExceptionContinueSearch)
-    {
-      DPRINT("ReturnValue == ExceptionContinueSearch\n");
 
-      /* Nothing to do here */
-    }
-    else if (ReturnValue == ExceptionNestedException)
+    /* Check if we have a frame */
+    if (RegistrationFrame)
     {
-      DPRINT("ReturnValue == ExceptionNestedException\n");
-
-      ExceptionRecord->ExceptionFlags |= EXCEPTION_NESTED_CALL;
-      if (NestedFrame < DispatcherContext)
-         {
-          NestedFrame = DispatcherContext;
-         }
+        /* Set it as unwinding */
+        ExceptionRecord->ExceptionFlags |= EXCEPTION_UNWINDING;
     }
-    else /* if (ReturnValue == ExceptionCollidedUnwind) */
+    else
     {
-      DPRINT("ReturnValue == ExceptionCollidedUnwind or unknown\n");
-
-      ExceptionRecord2.ExceptionRecord = ExceptionRecord;
-      ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
-      ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
-      ExceptionRecord2.NumberParameters = 0;
-      RtlRaiseException(&ExceptionRecord2);
+        /* Set the Exit Unwind flag as well */
+        ExceptionRecord->ExceptionFlags |= (EXCEPTION_UNWINDING |
+                                            EXCEPTION_EXIT_UNWIND);
     }
 
-    RegistrationFrame = RegistrationFrame->prev;  // Go to previous frame
-  }
+    /* Now capture the context */
+    Context = &LocalContext;
+    LocalContext.ContextFlags = CONTEXT_INTEGER |
+                                CONTEXT_CONTROL |
+                                CONTEXT_SEGMENTS;
+    RtlpCaptureContext(Context);
 
-  /* No exception handler will handle this exception */
+    /* Pop the current arguments off */
+    LocalContext.Esp += sizeof(RegistrationFrame) +
+                        sizeof(ReturnAddress) +
+                        sizeof(ExceptionRecord) +
+                        sizeof(ReturnValue);
 
-  DPRINT("RtlpDispatchException(): Return ExceptionContinueExecution\n");
+    /* Set the new value for EAX */
+    LocalContext.Eax = (ULONG)EaxValue;
 
-  ExceptionRecord->ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+    /* Get the current frame */
+    RegistrationFrame2 = RtlpGetExceptionList();
 
-  return ExceptionContinueExecution;
-}
-
-
-/*
- * @implemented
- */
-VOID STDCALL
-RtlUnwind(PEXCEPTION_REGISTRATION RegistrationFrame,
-  PVOID ReturnAddress,
-  PEXCEPTION_RECORD ExceptionRecord,
-  DWORD EaxValue)
-{
-  PEXCEPTION_REGISTRATION ERHead;
-  PEXCEPTION_RECORD pExceptRec;
-  EXCEPTION_RECORD TempER;
-  CONTEXT Context;
-
-  DPRINT("RtlUnwind(). RegistrationFrame 0x%X\n", RegistrationFrame);
-
-#ifndef NDEBUG
-  RtlpDumpExceptionRegistrations();
-#endif /* NDEBUG */
-
-  ERHead = SehpGetExceptionList();
-
-  DPRINT("ERHead is 0x%X\n", ERHead);
-
-  if (ExceptionRecord == NULL) // The normal case
-  {
-       DPRINT("ExceptionRecord == NULL (normal)\n");
-
-    pExceptRec = &TempER;
-    pExceptRec->ExceptionFlags = 0;
-    pExceptRec->ExceptionCode = STATUS_UNWIND;
-    pExceptRec->ExceptionRecord = NULL;
-    pExceptRec->ExceptionAddress = ReturnAddress;
-    pExceptRec->ExceptionInformation[0] = 0;
-  }
-  else
-  {
-    pExceptRec = ExceptionRecord;
-  }
-
-  if (RegistrationFrame)
-    pExceptRec->ExceptionFlags |= EXCEPTION_UNWINDING;
-  else
-    pExceptRec->ExceptionFlags |= (EXCEPTION_UNWINDING|EXCEPTION_EXIT_UNWIND);
-
-#ifndef NDEBUG
-  DPRINT("ExceptionFlags == 0x%x:\n", pExceptRec->ExceptionFlags);
-  if (pExceptRec->ExceptionFlags & EXCEPTION_UNWINDING)
-  {
-         DPRINT("  * EXCEPTION_UNWINDING (0x%x)\n", EXCEPTION_UNWINDING);
-  }
-  if (pExceptRec->ExceptionFlags & EXCEPTION_EXIT_UNWIND)
-  {
-         DPRINT("  * EXCEPTION_EXIT_UNWIND (0x%x)\n", EXCEPTION_EXIT_UNWIND);
-  }
-#endif /* NDEBUG */
-
-  Context.ContextFlags =
-    (CONTEXT_i386 | CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS);
-
-  RtlpCaptureContext(&Context);
-
-  DPRINT("Context.Eip = 0x%.08x\n", Context.Eip);
-  DPRINT("Context.Ebp = 0x%.08x\n", Context.Ebp);
-  DPRINT("Context.Esp = 0x%.08x\n", Context.Esp);
-
-  Context.Esp += 0x10;
-  Context.Eax = EaxValue;
-
-  // Begin traversing the list of EXCEPTION_REGISTRATION
-  while ((ULONG_PTR)ERHead != (ULONG_PTR)-1 && ERHead != RegistrationFrame)
-  {
-    EXCEPTION_RECORD er2;
-
-    DPRINT("ERHead 0x%X\n", ERHead);
-
-    // If there's an exception frame, but it's lower on the stack
-    // than the head of the exception list, something's wrong!
-    if (RegistrationFrame && (RegistrationFrame <= ERHead))
+    /* Now loop every frame */
+    while (RegistrationFrame2 != EXCEPTION_CHAIN_END)
     {
-      DPRINT("The exception frame is bad\n");
-
-      // Generate an exception to bail out
-      er2.ExceptionRecord = pExceptRec;
-      er2.NumberParameters = 0;
-      er2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
-      er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+        DPRINT1("RegistrationFrame is 0x%X\n", RegistrationFrame2);
 
-      RtlRaiseException(&er2);
-    }
-
-#if 0
-    Stack = ERHead + sizeof(EXCEPTION_REGISTRATION);
-    if ( (Teb->Tib.StackBase <= (PVOID)ERHead )      // Make sure that ERHead
-      && (Teb->Tib.->StackLimit >= (PVOID)Stack )      // is in range, and a multiple
-      && (0 == ((ULONG_PTR)ERHead & 3)) )         // of 4 (i.e., sane)
-#else
-    if (1)
-#endif
-    {
-      PEXCEPTION_REGISTRATION NewERHead;
-      PEXCEPTION_REGISTRATION pCurrExceptReg;
-      EXCEPTION_DISPOSITION ReturnValue;
-
-      DPRINT("Executing handler at 0x%X for unwind\n", ERHead->handler);
-
-      ReturnValue = RtlpExecuteHandlerForUnwind(
-        pExceptRec,
-        ERHead,
-        &Context,
-        &NewERHead,
-        ERHead->handler);
-
-      DPRINT("Handler at 0x%X returned 0x%X\n", ERHead->handler, ReturnValue);
+        /* If this is the target */
+        if (RegistrationFrame2 == RegistrationFrame)
+        {
+            /* Continue execution */
+            ZwContinue(Context, FALSE);
+        }
 
-      if (ReturnValue != ExceptionContinueSearch)
-      {
-        if (ReturnValue != ExceptionCollidedUnwind)
+        /* Check if the frame is too low */
+        if ((RegistrationFrame) && ((ULONG_PTR)RegistrationFrame <
+                                    (ULONG_PTR)RegistrationFrame2))
         {
-          DPRINT("Bad return value\n");
+            /* Create an invalid unwind exception */
+            ExceptionRecord2.ExceptionCode = STATUS_INVALID_UNWIND_TARGET;
+            ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+            ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+            ExceptionRecord2.NumberParameters = 0;
+
+            /* Raise the exception */
+            DPRINT1("Frame is invalid\n");
+            RtlRaiseException(&ExceptionRecord2);
+        }
 
-          er2.ExceptionRecord = pExceptRec;
-          er2.NumberParameters = 0;
-          er2.ExceptionCode = STATUS_INVALID_DISPOSITION;
-          er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+        /* Find out where it ends */
+        RegistrationFrameEnd = (ULONG_PTR)RegistrationFrame2 +
+                                sizeof(*RegistrationFrame2);
 
-          RtlRaiseException(&er2);
+        /* Make sure the registration frame is located within the stack */
+        if ((RegistrationFrameEnd > StackHigh) ||
+            ((ULONG_PTR)RegistrationFrame < StackLow) ||
+            ((ULONG_PTR)RegistrationFrame & 0x3))
+        {
+            /* Check if this happened in the DPC Stack */
+            if (RtlpHandleDpcStackException(RegistrationFrame,
+                                            RegistrationFrameEnd,
+                                            &StackLow,
+                                            &StackHigh))
+            {
+                /* Use DPC Stack Limits and restart */
+                continue;
+            }
+
+            /* Create an invalid stack exception */
+            ExceptionRecord2.ExceptionCode = STATUS_BAD_STACK;
+            ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+            ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+            ExceptionRecord2.NumberParameters = 0;
+
+            /* Raise the exception */
+            DPRINT1("Frame has bad stack\n");
+            RtlRaiseException(&ExceptionRecord2);
         }
         else
         {
-          ERHead = NewERHead;
+            /* Call the handler */
+            DPRINT1("Executing unwind handler: %p\n", RegistrationFrame2->Handler);
+            ReturnValue = RtlpExecuteHandlerForUnwind(ExceptionRecord,
+                                                      RegistrationFrame2,
+                                                      Context,
+                                                      &DispatcherContext,
+                                                      RegistrationFrame2->Handler);
+            DPRINT1("Handler returned: %lx\n", ReturnValue);
+
+            /* Handle the dispositions */
+            if (ReturnValue == ExceptionContinueSearch)
+            {
+                /* Get out of here */
+                break;
+            }
+            else if (ReturnValue == ExceptionCollidedUnwind)
+            {
+                /* Get the previous frame */
+                RegistrationFrame2 = DispatcherContext;
+            }
+            else
+            {
+                /* Set up the exception record */
+                ExceptionRecord2.ExceptionRecord = ExceptionRecord;
+                ExceptionRecord2.ExceptionCode = STATUS_INVALID_DISPOSITION;
+                ExceptionRecord2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+                ExceptionRecord2.NumberParameters = 0;
+
+                /* Raise the exception */
+                RtlRaiseException(&ExceptionRecord2);
+            }
+
+            /* Go to the next frame */
+            OldFrame = RegistrationFrame2;
+            RegistrationFrame2 = RegistrationFrame2->Next;
+
+            /* Remove this handler */
+            RtlpSetExceptionList(OldFrame);
         }
-      }
-
-      pCurrExceptReg = ERHead;
-      ERHead = ERHead->prev;
-
-      DPRINT("New ERHead is 0x%X\n", ERHead);
-
-      DPRINT("Setting exception registration at 0x%X as current\n",
-        /*RegistrationFrame->prev*/ pCurrExceptReg->prev);
+    }
 
-      // Unlink the exception handler
-      SehpSetExceptionList(pCurrExceptReg->prev);
+    /* Check if we reached the end */
+    if (RegistrationFrame == EXCEPTION_CHAIN_END)
+    {
+        /* Unwind completed, so we don't exit */
+        ZwContinue(Context, FALSE);
     }
-    else // The stack looks goofy! Raise an exception to bail out
+    else
     {
-      DPRINT("Bad stack\n");
-
-      er2.ExceptionRecord = pExceptRec;
-      er2.NumberParameters = 0;
-      er2.ExceptionCode = STATUS_BAD_STACK;
-      er2.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
-
-      RtlRaiseException(&er2);
+        /* This is an exit_unwind or the frame wasn't present in the list */
+        ZwRaiseException(ExceptionRecord, Context, FALSE);
     }
-  }
 }
 
 /* EOF */
index 0c4e4a3..367b8fd 100644 (file)
 /* Helper Header */
 #include <reactos/helper.h>
 
-/* FIXME: Move this somewhere else, maybe */
-#ifdef DBG
-extern VOID FASTCALL CHECK_PAGED_CODE_RTL(char *file, int line);
-#define PAGED_CODE_RTL() CHECK_PAGED_CODE_RTL(__FILE__, __LINE__)
-#else
-#define PAGED_CODE_RTL()
-#endif
-
-PVOID STDCALL RtlpAllocateMemory(UINT Bytes, ULONG Tag);
-VOID STDCALL RtlpFreeMemory(PVOID Mem, ULONG Tag);
-KPROCESSOR_MODE STDCALL RtlpGetMode();
-NTSTATUS STDCALL RtlDeleteHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
-NTSTATUS STDCALL RtlEnterHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
-NTSTATUS STDCALL RtlInitializeHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
-NTSTATUS STDCALL RtlLeaveHeapLock(PRTL_CRITICAL_SECTION CriticalSection);
-
-#define RtlpAllocateStringMemory RtlpAllocateMemory
-#define RtlpFreeStringMemory RtlpFreeMemory
-
-#define TAG_USTR        TAG('U', 'S', 'T', 'R')
-#define TAG_ASTR        TAG('A', 'S', 'T', 'R')
-#define TAG_OSTR        TAG('O', 'S', 'T', 'R')
+/* Internal RTL header */
+#include "rtlp.h"
 
 /* EOF */
diff --git a/reactos/lib/rtl/rtlp.h b/reactos/lib/rtl/rtlp.h
new file mode 100644 (file)
index 0000000..5552f94
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS System Libraries\r
+ * FILE:            lib/rtl/rtlp.h\r
+ * PURPOSE:         Run-Time Libary Internal Header\r
+ * PROGRAMMER:      Alex Ionescu\r
+ */\r
+\r
+/* INCLUDES ******************************************************************/\r
+\r
+/* PAGED_CODE equivalent for user-mode RTL */\r
+#ifdef DBG\r
+extern VOID FASTCALL CHECK_PAGED_CODE_RTL(char *file, int line);\r
+#define PAGED_CODE_RTL() CHECK_PAGED_CODE_RTL(__FILE__, __LINE__)\r
+#else\r
+#define PAGED_CODE_RTL()\r
+#endif\r
+\r
+/* These provide support for sharing code between User and Kernel RTL */\r
+PVOID\r
+STDCALL\r
+RtlpAllocateMemory(\r
+    ULONG Bytes,\r
+    ULONG Tag);\r
+\r
+VOID\r
+STDCALL\r
+RtlpFreeMemory(\r
+    PVOID Mem,\r
+    ULONG Tag);\r
+\r
+KPROCESSOR_MODE\r
+STDCALL\r
+RtlpGetMode(VOID);\r
+\r
+NTSTATUS\r
+STDCALL\r
+RtlDeleteHeapLock(PRTL_CRITICAL_SECTION CriticalSection);\r
+\r
+NTSTATUS\r
+STDCALL\r
+RtlEnterHeapLock(PRTL_CRITICAL_SECTION CriticalSection);\r
+\r
+NTSTATUS\r
+STDCALL\r
+RtlInitializeHeapLock(PRTL_CRITICAL_SECTION CriticalSection);\r
+\r
+NTSTATUS\r
+STDCALL\r
+RtlLeaveHeapLock(PRTL_CRITICAL_SECTION CriticalSection);\r
+\r
+BOOLEAN\r
+NTAPI\r
+RtlpCheckForActiveDebugger(VOID);\r
+\r
+BOOLEAN\r
+NTAPI\r
+RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,\r
+                            IN ULONG_PTR RegistrationFrameEnd,\r
+                            IN OUT PULONG_PTR StackLow,\r
+                            IN OUT PULONG_PTR StackHigh);\r
+\r
+#define RtlpAllocateStringMemory RtlpAllocateMemory\r
+#define RtlpFreeStringMemory     RtlpFreeMemory\r
+\r
+/* i386/except.S */\r
+\r
+EXCEPTION_DISPOSITION\r
+STDCALL\r
+RtlpExecuteHandlerForException(PEXCEPTION_RECORD ExceptionRecord,\r
+                               PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,\r
+                               PCONTEXT Context,\r
+                               PVOID DispatcherContext,\r
+                               PEXCEPTION_HANDLER ExceptionHandler);\r
+\r
+EXCEPTION_DISPOSITION\r
+STDCALL\r
+RtlpExecuteHandlerForUnwind(PEXCEPTION_RECORD ExceptionRecord,\r
+                            PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,\r
+                            PCONTEXT Context,\r
+                            PVOID DispatcherContext,\r
+                            PEXCEPTION_HANDLER ExceptionHandler);\r
+\r
+VOID\r
+NTAPI\r
+RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,\r
+                      IN PCONTEXT ContextRecord,\r
+                      IN PVOID ContextData,\r
+                      IN ULONG Size);\r
+\r
+PVOID\r
+NTAPI\r
+RtlpGetExceptionAddress(VOID);\r
+\r
+VOID\r
+NTAPI\r
+RtlpCaptureContext(OUT PCONTEXT ContextRecord);\r
+\r
+/* Tags for the String Allocators */\r
+#define TAG_USTR        TAG('U', 'S', 'T', 'R')\r
+#define TAG_ASTR        TAG('A', 'S', 'T', 'R')\r
+#define TAG_OSTR        TAG('O', 'S', 'T', 'R')\r
+\r
+/* EOF */\r
index 6f9dcbb..c428499 100644 (file)
@@ -29,7 +29,7 @@ STDCALL
 ExRaiseAccessViolation(VOID)
 {
     /* Raise the Right Status */
-    ExRaiseStatus (STATUS_ACCESS_VIOLATION);
+    RtlRaiseStatus(STATUS_ACCESS_VIOLATION);
 }
 
 /*
@@ -40,39 +40,7 @@ STDCALL
 ExRaiseDatatypeMisalignment (VOID)
 {
     /* Raise the Right Status */
-    ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-ExRaiseStatus(IN NTSTATUS Status)
-{
-    EXCEPTION_RECORD ExceptionRecord;
-
-    DPRINT("ExRaiseStatus(%x)\n", Status);
-
-    /* Set up an Exception Record */
-    ExceptionRecord.ExceptionRecord = NULL;
-    ExceptionRecord.NumberParameters = 0;
-    ExceptionRecord.ExceptionCode = Status;
-    ExceptionRecord.ExceptionFlags = 0;
-
-    /* Call the Rtl Function */
-    RtlRaiseException(&ExceptionRecord);
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-ExRaiseException (PEXCEPTION_RECORD ExceptionRecord)
-{
-    /* Call the Rtl function */
-    RtlRaiseException(ExceptionRecord);
+    RtlRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
 }
 
 /*
index a600dba..bd32c1e 100644 (file)
@@ -155,11 +155,9 @@ NtQuerySystemEnvironmentValue (IN  PUNICODE_STRING VariableName,
   /*
    * Copy the name to kernel space if necessary and convert it to ANSI.
    */
-  Status = RtlCaptureUnicodeString(&WName,
-                                   PreviousMode,
-                                   NonPagedPool,
-                                   FALSE,
-                                   VariableName);
+  Status = ProbeAndCaptureUnicodeString(&WName,
+                                        PreviousMode,
+                                        VariableName);
   if(NT_SUCCESS(Status))
   {
     /*
@@ -168,9 +166,8 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
     if(!SeSinglePrivilegeCheck(SeSystemEnvironmentPrivilege,
                                PreviousMode))
     {
-      RtlReleaseCapturedUnicodeString(&WName,
-                                     PreviousMode,
-                                     FALSE);
+      ReleaseCapturedUnicodeString(&WName,
+                                   PreviousMode);
       DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
       return STATUS_PRIVILEGE_NOT_HELD;
     }
@@ -179,9 +176,8 @@ NtQuerySystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
      * convert the value name to ansi
      */
     Status = RtlUnicodeStringToAnsiString(&AName, &WName, TRUE);
-    RtlReleaseCapturedUnicodeString(&WName,
-                                   PreviousMode,
-                                   FALSE);
+    ReleaseCapturedUnicodeString(&WName,
+                                 PreviousMode);
     if(!NT_SUCCESS(Status))
     {
       return Status;
@@ -273,18 +269,14 @@ NtSetSystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
   /*
    * Copy the strings to kernel space if necessary
    */
-  Status = RtlCaptureUnicodeString(&CapturedName,
-                                   PreviousMode,
-                                   NonPagedPool,
-                                   FALSE,
-                                   VariableName);
+  Status = ProbeAndCaptureUnicodeString(&CapturedName,
+                                        PreviousMode,
+                                        VariableName);
   if(NT_SUCCESS(Status))
   {
-    Status = RtlCaptureUnicodeString(&CapturedValue,
-                                     PreviousMode,
-                                     NonPagedPool,
-                                     FALSE,
-                                     Value);
+    Status = ProbeAndCaptureUnicodeString(&CapturedValue,
+                                          PreviousMode,
+                                          Value);
     if(NT_SUCCESS(Status))
     {
       /*
@@ -319,14 +311,12 @@ NtSetSystemEnvironmentValue (IN   PUNICODE_STRING VariableName,
         Status = STATUS_PRIVILEGE_NOT_HELD;
       }
 
-      RtlReleaseCapturedUnicodeString(&CapturedValue,
-                                     PreviousMode,
-                                     FALSE);
+      ReleaseCapturedUnicodeString(&CapturedValue,
+                                   PreviousMode);
     }
 
-    RtlReleaseCapturedUnicodeString(&CapturedName,
-                                   PreviousMode,
-                                   FALSE);
+    ReleaseCapturedUnicodeString(&CapturedName,
+                                 PreviousMode);
   }
 
   return Status;
index 507d5b2..43eeccf 100644 (file)
@@ -287,7 +287,7 @@ VOID inline FASTCALL KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock);
 VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
 
 PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
-BOOLEAN STDCALL KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame);
+BOOLEAN STDCALL KeContextToTrapFrame(PCONTEXT Context, PKEXCEPTION_FRAME ExeptionFrame, PKTRAP_FRAME TrapFrame);
 VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
                   PVOID Reserved,
                   PKTRAP_FRAME TrapFrame);
@@ -308,7 +308,7 @@ KeSetProcess(struct _KPROCESS* Process,
 
 VOID STDCALL KeInitializeEventPair(PKEVENT_PAIR EventPair);
 
-VOID STDCALL KiInitializeUserApc(IN PVOID Reserved,
+VOID STDCALL KiInitializeUserApc(IN PKEXCEPTION_FRAME Reserved,
                         IN PKTRAP_FRAME TrapFrame,
                         IN PKNORMAL_ROUTINE NormalRoutine,
                         IN PVOID NormalContext,
@@ -362,9 +362,10 @@ KiMoveApcState (PKAPC_STATE OldState,
 VOID
 KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Pc);
 VOID
+NTAPI
 KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
-                   PCONTEXT Context,
-                   PKTRAP_FRAME Tf,
+            PKEXCEPTION_FRAME ExceptionFrame,
+            PKTRAP_FRAME Tf,
                    KPROCESSOR_MODE PreviousMode,
                    BOOLEAN SearchFrames);
 VOID KeTrapFrameToContext(PKTRAP_FRAME TrapFrame,
index 2423c5b..6ca0b8a 100644 (file)
@@ -75,33 +75,90 @@ RtlpCreateUnicodeString(
    IN OUT PUNICODE_STRING UniDest,
    IN PCWSTR  Source,
    IN POOL_TYPE PoolType);
-   
-NTSTATUS
-RtlCaptureUnicodeString(
-    OUT PUNICODE_STRING Dest,
-    IN KPROCESSOR_MODE CurrentMode,
-    IN POOL_TYPE PoolType,
-    IN BOOLEAN CaptureIfKernel,
-    IN PUNICODE_STRING UnsafeSrc
-);
 
 VOID
-RtlReleaseCapturedUnicodeString(
-    IN PUNICODE_STRING CapturedString,
-    IN KPROCESSOR_MODE CurrentMode,
-    IN BOOLEAN CaptureIfKernel
-);
+NTAPI
+RtlpLogException(IN PEXCEPTION_RECORD ExceptionRecord,
+                 IN PCONTEXT ContextRecord,
+                 IN PVOID ContextData,
+                 IN ULONG Size);
+
+#define ExRaiseStatus RtlRaiseStatus
 
 /*
  * Inlined Probing Macros
- *
+ */
+static __inline
+NTSTATUS
+NTAPI
+ProbeAndCaptureUnicodeString(OUT PUNICODE_STRING Dest,
+                             KPROCESSOR_MODE CurrentMode,
+                             IN PUNICODE_STRING UnsafeSrc)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PVOID Buffer;
+    ASSERT(Dest != NULL);
+
+    /* Probe the structure and buffer*/
+    if(CurrentMode != KernelMode)
+    {
+        _SEH_TRY
+        {
+            ProbeForRead(UnsafeSrc,
+                         sizeof(UNICODE_STRING),
+                         sizeof(ULONG));
+            *Dest = *UnsafeSrc;
+            if(Dest->Length > 0)
+            {
+                ProbeForRead(Dest->Buffer,
+                             Dest->Length,
+                             sizeof(WCHAR));
+            }
+        }
+        _SEH_HANDLE
+        {
+            Status = _SEH_GetExceptionCode();
+        }
+        _SEH_END;
+
+        if (!NT_SUCCESS(Status)) return Status;
+    }
+    else
+    {
+        /* Just copy it directly */
+        *Dest = *UnsafeSrc;
+    }
+
+    /* Allocate space for the buffer */
+    Buffer = ExAllocatePool(PagedPool, Dest->MaximumLength);
+
+    /* Copy it */
+    RtlCopyMemory(Buffer, Dest->Buffer, Dest->MaximumLength);
+
+    /* Set it as the buffer */
+    Dest->Buffer = Buffer;
+
+    /* Return */
+    return Status;
+}
+
+static __inline
+VOID
+NTAPI
+ReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
+                             KPROCESSOR_MODE CurrentMode)
+{
+    if(CurrentMode != KernelMode) ExFreePool(CapturedString->Buffer);
+}
+
+/*
  * NOTE: Alignment of the pointers is not verified!
  */
 #define ProbeForWriteGenericType(Ptr, Type)                                    \
     do {                                                                       \
         if ((ULONG_PTR)(Ptr) + sizeof(Type) - 1 < (ULONG_PTR)(Ptr) ||          \
             (ULONG_PTR)(Ptr) + sizeof(Type) - 1 >= (ULONG_PTR)MmUserProbeAddress) { \
-            ExRaiseStatus (STATUS_ACCESS_VIOLATION);                           \
+            RtlRaiseStatus (STATUS_ACCESS_VIOLATION);                          \
         }                                                                      \
         *(volatile Type *)(Ptr) = *(volatile Type *)(Ptr);                     \
     } while (0)
index 7c0e360..eb9ec20 100755 (executable)
@@ -21,7 +21,7 @@
 #include <ndk/asm.h>
 
 /* FIXME: Temporary until CC Ros is gone */
-#include <ccros.h>        
+#include <ccros.h>
 
 /* ReactOS Headers */
 #include <reactos/version.h>
index 2ffa663..23f6761 100644 (file)
@@ -1878,11 +1878,9 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
    }
 #endif
 
-   Status = RtlCaptureUnicodeString(&CapturedDriverServiceName,
-                                    PreviousMode,
-                                    PagedPool,
-                                    FALSE,
-                                    DriverServiceName);
+   Status = ProbeAndCaptureUnicodeString(&CapturedDriverServiceName,
+                                         PreviousMode,
+                                         DriverServiceName);
    if (!NT_SUCCESS(Status))
    {
       return Status;
@@ -2021,9 +2019,8 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName)
    Status = IopStartDevice(DeviceNode);
 
 ReleaseCapturedString:
-   RtlReleaseCapturedUnicodeString(&CapturedDriverServiceName,
-                                   PreviousMode,
-                                   FALSE);
+   ReleaseCapturedUnicodeString(&CapturedDriverServiceName,
+                                PreviousMode);
 
    return Status;
 }
index 5c69ba9..a5b6c30 100644 (file)
@@ -1321,7 +1321,7 @@ KdpGdbEnterDebuggerException(PEXCEPTION_RECORD ExceptionRecord,
 #error Unknown compiler for inline assembler
 #endif
 
-                KeContextToTrapFrame(Context, TrapFrame);
+                KeContextToTrapFrame(Context, NULL, TrapFrame);
                 return ((SigVal == 5) ? (kdContinue) : (kdHandleException));
                 break;
               }
@@ -1434,7 +1434,7 @@ GspBreakIn(PKINTERRUPT Interrupt,
 
   KdpGdbEnterDebuggerException (NULL, &Context, TrapFrame);
 
-  KeContextToTrapFrame (&Context, TrapFrame);
+  KeContextToTrapFrame (&Context, NULL, TrapFrame);
 
   KeLowerIrql (OldIrql);
 
index fb60957..dd7b39f 100644 (file)
@@ -793,57 +793,55 @@ KiFreeApcRoutine(PKAPC Apc,
  *--*/
 VOID
 STDCALL
-KiInitializeUserApc(IN PVOID Reserved,
+KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
                     IN PKTRAP_FRAME TrapFrame,
                     IN PKNORMAL_ROUTINE NormalRoutine,
                     IN PVOID NormalContext,
                     IN PVOID SystemArgument1,
                     IN PVOID SystemArgument2)
 {
-    PCONTEXT Context;
-    PULONG Esp;
+    CONTEXT Context;
+    ULONG_PTR Stack;
+    ULONG Size;
 
-    DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, KeGetCurrentThread()->TrapFrame);
+    DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame,
+            KeGetCurrentThread()->TrapFrame);
 
-    /*
-     * Save the thread's current context (in other words the registers
-     * that will be restored when it returns to user mode) so the
-     * APC dispatcher can restore them later
-     */
-    Context = (PCONTEXT)(((PUCHAR)TrapFrame->Esp) - sizeof(CONTEXT));
-    RtlZeroMemory(Context, sizeof(CONTEXT));
-    Context->ContextFlags = CONTEXT_FULL;
-    Context->SegGs = TrapFrame->Gs;
-    Context->SegFs = TrapFrame->Fs;
-    Context->SegEs = TrapFrame->Es;
-    Context->SegDs = TrapFrame->Ds;
-    Context->Edi = TrapFrame->Edi;
-    Context->Esi = TrapFrame->Esi;
-    Context->Ebx = TrapFrame->Ebx;
-    Context->Edx = TrapFrame->Edx;
-    Context->Ecx = TrapFrame->Ecx;
-    Context->Eax = TrapFrame->Eax;
-    Context->Ebp = TrapFrame->Ebp;
-    Context->Eip = TrapFrame->Eip;
-    Context->SegCs = TrapFrame->Cs;
-    Context->EFlags = TrapFrame->Eflags;
-    Context->Esp = TrapFrame->Esp;
-    Context->SegSs = TrapFrame->Ss;
+    /* Don't deliver APCs in V86 mode */
+    if (TrapFrame->Eflags & 2) return;
 
-    /*
-     * Setup the trap frame so the thread will start executing at the
-     * APC Dispatcher when it returns to user-mode
-     */
-    Esp = (PULONG)(((PUCHAR)TrapFrame->Esp) - (sizeof(CONTEXT) + (6 * sizeof(ULONG))));
-    Esp[0] = 0xdeadbeef;
-    Esp[1] = (ULONG)NormalRoutine;
-    Esp[2] = (ULONG)NormalContext;
-    Esp[3] = (ULONG)SystemArgument1;
-    Esp[4] = (ULONG)SystemArgument2;
-    Esp[5] = (ULONG)Context;
-    TrapFrame->Eip = (ULONG)KeUserApcDispatcher;
-    DPRINT("TrapFrame->Eip: %x\n", TrapFrame->Eip);
-    TrapFrame->Esp = (ULONG)Esp;
+    /* Save the full context */
+    Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
+    KeTrapFrameToContext(TrapFrame, &Context);
+
+    /* Protect with SEH */
+    _SEH_TRY
+    {
+        /* Get the aligned size */
+        Size = ((sizeof(CONTEXT) + 3) & ~3) + 4 * sizeof(ULONG_PTR);
+        Stack = (Context.Esp & ~3) - Size;
+
+        /* Probe and copy */
+        ProbeForWrite((PVOID)Stack, Size, 4);
+        RtlMoveMemory((PVOID)(Stack + 4 * sizeof(ULONG_PTR)),
+                      &Context,
+                      sizeof(CONTEXT));
+
+        /* Run at APC dispatcher */
+        TrapFrame->Eip = (ULONG)KeUserApcDispatcher;
+        TrapFrame->Esp = Stack;
+
+        /* Setup the stack */
+        *(PULONG_PTR)(Stack + 0 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalRoutine;
+        *(PULONG_PTR)(Stack + 1 * sizeof(ULONG_PTR)) = (ULONG_PTR)NormalContext;
+        *(PULONG_PTR)(Stack + 2 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument1;
+        *(PULONG_PTR)(Stack + 3 * sizeof(ULONG_PTR)) = (ULONG_PTR)SystemArgument2;
+    }
+    _SEH_HANDLE
+    {
+        /* FIXME: Get the record and raise an exception */
+    }
+    _SEH_END;
 }
 
 /*++
diff --git a/reactos/ntoskrnl/ke/exception.c b/reactos/ntoskrnl/ke/exception.c
new file mode 100644 (file)
index 0000000..7ecf157
--- /dev/null
@@ -0,0 +1,157 @@
+/*\r
+ * COPYRIGHT:       See COPYING in the top level directory\r
+ * PROJECT:         ReactOS Kernel\r
+ * FILE:            ntoskrnl/ke/exception.c\r
+ * PURPOSE:         Platform independent exception handling\r
+ * PROGRAMMER:      Alex Ionescu (alex@relsoft.net)\r
+ */\r
+\r
+/* INCLUDES *****************************************************************/\r
+\r
+#include <ntoskrnl.h>\r
+#define NDEBUG\r
+#include <internal/debug.h>\r
+\r
+/* FUNCTIONS ****************************************************************/\r
+\r
+VOID\r
+NTAPI\r
+KiContinuePreviousModeUser(IN PCONTEXT Context,\r
+                           IN PKEXCEPTION_FRAME ExceptionFrame,\r
+                           IN PKTRAP_FRAME TrapFrame)\r
+{\r
+    CONTEXT LocalContext;\r
+\r
+    /* We'll have to make a copy and probe it */\r
+    ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));\r
+    RtlMoveMemory(&LocalContext, Context, sizeof(CONTEXT));\r
+    Context = &LocalContext;\r
+\r
+    /* Convert the context into Exception/Trap Frames */\r
+    KeContextToTrapFrame(&LocalContext, ExceptionFrame, TrapFrame);\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+KiContinue(IN PCONTEXT Context,\r
+           IN PKEXCEPTION_FRAME ExceptionFrame,\r
+           IN PKTRAP_FRAME TrapFrame)\r
+{\r
+    NTSTATUS Status = STATUS_SUCCESS;\r
+    KIRQL OldIrql = APC_LEVEL;\r
+    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();\r
+\r
+    /* Raise to APC_LEVEL, only if needed */\r
+    if (KeGetCurrentIrql() < APC_LEVEL)\r
+    {\r
+        /* Raise to APC_LEVEL */\r
+        KeRaiseIrql(APC_LEVEL, &OldIrql);\r
+    }\r
+\r
+    /* Set up SEH to validate the context */\r
+    _SEH_TRY\r
+    {\r
+        /* Check the previous mode */\r
+        if (PreviousMode != KernelMode)\r
+        {\r
+            /* Validate from user-mode */\r
+            KiContinuePreviousModeUser(Context,\r
+                                       ExceptionFrame,\r
+                                       TrapFrame);\r
+        }\r
+        else\r
+        {\r
+            /* Convert the context into Exception/Trap Frames */\r
+            KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame);\r
+        }\r
+    }\r
+    _SEH_HANDLE\r
+    {\r
+        Status = _SEH_GetExceptionCode();\r
+    }\r
+    _SEH_END;\r
+\r
+    /* Lower the IRQL if needed */\r
+    if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);\r
+\r
+    /* Return status */\r
+    return Status;\r
+}\r
+\r
+NTSTATUS\r
+NTAPI\r
+KiRaiseException(PEXCEPTION_RECORD ExceptionRecord,\r
+                 PCONTEXT Context,\r
+                 PKEXCEPTION_FRAME ExceptionFrame,\r
+                 PKTRAP_FRAME TrapFrame,\r
+                 BOOLEAN SearchFrames)\r
+{\r
+    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();\r
+    CONTEXT LocalContext;\r
+    EXCEPTION_RECORD LocalExceptionRecord;\r
+    ULONG ParameterCount, Size;\r
+    NTSTATUS Status = STATUS_SUCCESS;\r
+    DPRINT1("KiRaiseException\n");\r
+\r
+    /* Set up SEH */\r
+    _SEH_TRY\r
+    {\r
+        /* Check the previous mode */\r
+        if (PreviousMode != KernelMode)\r
+        {\r
+            /* Probe the context */\r
+            ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));\r
+\r
+            /* Probe the Exception Record */\r
+            ProbeForRead(ExceptionRecord,\r
+                         FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +\r
+                         sizeof(ULONG),\r
+                         sizeof(ULONG));\r
+\r
+            /* Validate the maximum parameters */\r
+            if ((ParameterCount = ExceptionRecord->NumberParameters) >\r
+                EXCEPTION_MAXIMUM_PARAMETERS)\r
+            {\r
+                /* Too large */\r
+                return STATUS_INVALID_PARAMETER;\r
+            }\r
+\r
+            /* Probe the entire parameters now*/\r
+            Size = (sizeof(EXCEPTION_RECORD) - \r
+                    ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));\r
+            ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));\r
+\r
+            /* Now make copies in the stack */\r
+            RtlMoveMemory(&LocalContext, Context, sizeof(CONTEXT));\r
+            RtlMoveMemory(&LocalExceptionRecord, ExceptionRecord, Size);\r
+            Context = &LocalContext;\r
+            ExceptionRecord = &LocalExceptionRecord;\r
+\r
+            /* Update the parameter count */\r
+            ExceptionRecord->NumberParameters = ParameterCount;\r
+        }\r
+    }\r
+    _SEH_HANDLE\r
+    {\r
+        Status = _SEH_GetExceptionCode();\r
+    }\r
+    _SEH_END;\r
+\r
+    if (NT_SUCCESS(Status))\r
+    {\r
+        /* Convert the context record */\r
+        KeContextToTrapFrame(Context, ExceptionFrame, TrapFrame);\r
+\r
+        /* Dispatch the exception */\r
+        KiDispatchException(ExceptionRecord,\r
+                            ExceptionFrame,\r
+                            TrapFrame,\r
+                            PreviousMode,\r
+                            SearchFrames);\r
+    }\r
+\r
+    /* Return the status */\r
+    return Status;\r
+}\r
+\r
+/* EOF */\r
index f21c45e..61f2bba 100644 (file)
 #define NDEBUG
 #include <internal/debug.h>
 
+/*
+ * FIXMES:
+ *  - Clean up file.
+ *  - Add more exception frame support for non-i386 compatibility.
+ *  - Add PSEH handler when an exception occurs in an exception (KiCopyExceptionRecord).
+ *  - Implement official stack trace functions (exported) and remove stuff here.
+ *  - Forward exceptions to user-mode debugger.
+ *  - Wrap Ki NTDLL callbacks in SEH.
+ */
+
 /* GLOBALS *****************************************************************/
 
 #define FLAG_IF (1<<9)
@@ -172,7 +182,7 @@ KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2)
   /* FIXME: Which exceptions are noncontinuable? */
   Er.ExceptionFlags = 0;
 
-  KiDispatchException(&Er, 0, Tf, KernelMode, TRUE);
+  KiDispatchException(&Er, NULL, Tf, KernelMode, TRUE);
 
   return(0);
 }
@@ -559,6 +569,7 @@ KiTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr)
 BOOLEAN
 STDCALL
 KeContextToTrapFrame(PCONTEXT Context,
+                     PKEXCEPTION_FRAME ExceptionFrame,
                      PKTRAP_FRAME TrapFrame)
 {
     /* Start with the basic Registers */
@@ -907,6 +918,158 @@ KeInitExceptions(VOID)
    set_system_call_gate(0x2e,(int)KiSystemService);
 }
 
+VOID
+NTAPI
+KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
+                    PKEXCEPTION_FRAME ExceptionFrame,
+                    PKTRAP_FRAME TrapFrame,
+                    KPROCESSOR_MODE PreviousMode,
+                    BOOLEAN FirstChance)
+{
+    CONTEXT Context;
+    KD_CONTINUE_TYPE Action;
+    ULONG_PTR Stack, NewStack;
+    ULONG Size;
+    DPRINT1("KiDispatchException() called\n");
+
+    /* Increase number of Exception Dispatches */
+    KeGetCurrentPrcb()->KeExceptionDispatchCount++;
+
+    /* Set the context flags */
+    Context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
+
+    /* Check if User Mode */
+    if (PreviousMode == UserMode)
+    {
+        /* Add the FPU Flag */
+        Context.ContextFlags |= CONTEXT_FLOATING_POINT;
+    }
+
+    /* Get a Context */
+    KeTrapFrameToContext(TrapFrame, &Context);
+
+    /* Handle kernel-mode first, it's simpler */
+    if (PreviousMode == KernelMode)
+    {
+        /* Check if this is a first-chance exception */
+        if (FirstChance == TRUE)
+        {
+            /* Break into the debugger for the first time */
+            Action = KdpEnterDebuggerException(ExceptionRecord,
+                                               PreviousMode,
+                                               &Context,
+                                               TrapFrame,
+                                               TRUE,
+                                               TRUE);
+
+            /* If the debugger said continue, then continue */
+            if (Action == kdContinue) goto Handled;
+
+            /* If the Debugger couldn't handle it, dispatch the exception */
+            if (RtlDispatchException(ExceptionRecord, &Context))
+            {
+                /* It was handled by an exception handler, continue */
+                goto Handled;
+            }
+        }
+
+        /* This is a second-chance exception, only for the debugger */
+        Action = KdpEnterDebuggerException(ExceptionRecord,
+                                           PreviousMode,
+                                           &Context,
+                                           TrapFrame,
+                                           FALSE,
+                                           FALSE);
+
+        /* If the debugger said continue, then continue */
+        if (Action == kdContinue) goto Handled;
+
+        /* Third strike; you're out */
+        KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
+                         ExceptionRecord->ExceptionCode,
+                         (ULONG_PTR)ExceptionRecord->ExceptionAddress,
+                         ExceptionRecord->ExceptionInformation[0],
+                         ExceptionRecord->ExceptionInformation[1],
+                         TrapFrame);
+    }
+    else
+    {
+        /* User mode exception, was it first-chance? */
+        if (FirstChance)
+        {
+            /* Enter Debugger if available */
+            Action = KdpEnterDebuggerException(ExceptionRecord,
+                                               PreviousMode,
+                                               &Context,
+                                               TrapFrame,
+                                               TRUE,
+                                               FALSE);
+
+            /* Exit if we're continuing */
+            if (Action == kdContinue) goto Handled;
+
+            /* FIXME: Forward exception to user mode debugger */
+
+            /* Set up the user-stack */
+            _SEH_TRY
+            {
+                /* Align context size and get stack pointer */
+                Size = (sizeof(CONTEXT) + 3) & ~3;
+                Stack = (Context.Esp & ~3) - Size;
+
+                /* Probe stack and copy Context */
+                ProbeForWrite((PVOID)Stack, Size, sizeof(ULONG));
+                RtlMoveMemory((PVOID)Stack, &Context, sizeof(CONTEXT));
+
+                /* Align exception record size and get stack pointer */
+                Size = (sizeof(EXCEPTION_RECORD) - 
+                        (EXCEPTION_MAXIMUM_PARAMETERS - ExceptionRecord->NumberParameters) *
+                        sizeof(ULONG) + 3) & ~3;
+                NewStack = Stack - Size;
+
+                /* Probe stack and copy exception record. Don't forget to add the two params */
+                ProbeForWrite((PVOID)(NewStack - 2 * sizeof(ULONG_PTR)),
+                              Size +  2 * sizeof(ULONG_PTR),
+                              sizeof(ULONG));
+                RtlMoveMemory((PVOID)NewStack, ExceptionRecord, Size);
+
+                /* Now write the two params for the user-mode dispatcher */
+                *(PULONG_PTR)(NewStack - 1 * sizeof(ULONG_PTR)) = Stack;
+                *(PULONG_PTR)(NewStack - 2 * sizeof(ULONG_PTR)) = NewStack;
+
+                /* Set new Stack Pointer */
+                TrapFrame->Esp = NewStack - 2 * sizeof(ULONG_PTR);
+
+                /* Set EIP to the User-mode Dispathcer */
+                TrapFrame->Eip = (ULONG)KeUserExceptionDispatcher;
+                return;
+            }
+            _SEH_HANDLE
+            {
+                /* Do second-chance */
+            }
+            _SEH_END;
+        }
+
+        /* FIXME: Forward the exception to the debugger for 2nd chance */
+
+        /* 3rd strike, kill the thread */
+        DPRINT1("Unhandled UserMode exception, terminating thread\n");
+        ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+        KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
+                         ExceptionRecord->ExceptionCode,
+                         (ULONG_PTR)ExceptionRecord->ExceptionAddress,
+                         ExceptionRecord->ExceptionInformation[0],
+                         ExceptionRecord->ExceptionInformation[1],
+                         TrapFrame);
+    }
+
+Handled:
+    /* Convert the context back into Trap/Exception Frames */
+    KeContextToTrapFrame(&Context, NULL, TrapFrame);
+    return;
+}
+
 /*
  * @implemented
  */
@@ -927,32 +1090,3 @@ KeRaiseUserException(IN NTSTATUS ExceptionCode)
    return((NTSTATUS)OldEip);
 }
 
-/*
- * @implemented
- */
-NTSTATUS
-STDCALL
-NtRaiseException (
-    IN PEXCEPTION_RECORD ExceptionRecord,
-    IN PCONTEXT Context,
-    IN BOOLEAN SearchFrames)
-{
-    PKTHREAD Thread = KeGetCurrentThread();
-    PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
-    PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
-
-    KeGetCurrentKPCR()->Tib.ExceptionList = TrapFrame->ExceptionList;
-
-    KiDispatchException(ExceptionRecord,
-                        Context,
-                        TrapFrame,
-                        KeGetPreviousMode(),
-                        SearchFrames);
-
-    /* Restore the user context */
-    Thread->TrapFrame = PrevTrapFrame;
-    __asm__("mov %%ebx, %%esp;\n" "jmp _KiServiceExit": : "b" (TrapFrame));
-
-    /* We never get here */
-    return(STATUS_SUCCESS);
-}
index 73397ac..c26bb1c 100644 (file)
@@ -569,7 +569,7 @@ KiHandleFpuFault(PKTRAP_FRAME Tf, ULONG ExceptionNr)
 
       /* Dispatch exception */
       DPRINT("Dispatching exception (ExceptionCode = 0x%08x)\n", Er.ExceptionCode);
-      KiDispatchException(&Er, Context, Tf, PreviousMode, TRUE);
+      KiDispatchException(&Er, NULL, Tf, PreviousMode, TRUE);
 
       DPRINT("Math-fault handled!\n");
       return STATUS_SUCCESS;
index 2e6318b..22cb9b9 100644 (file)
@@ -489,3 +489,12 @@ _irq_handler_15:
        iret
 
 #endif /* CONFIG_SMP */
+
+.intel_syntax noprefix
+.globl _KiUnexpectedInterrupt@0
+_KiUnexpectedInterrupt@0:
+
+    /* Bugcheck with invalid interrupt code */
+    push 0x12
+    call _KeBugCheck@4
+
index 0eef143..916d1d3 100644 (file)
@@ -458,3 +458,92 @@ _KiDebugService:
 
     /* Exit through common routine */
     jmp _KiServiceExit2
+
+.globl _NtRaiseException@12
+_NtRaiseException@12:
+
+    /* NOTE: We -must- be called by Zw* to have the right frame! */
+    /* Push the stack frame */
+    push ebp
+
+    /* Get the current thread and restore its trap frame */
+    mov ebx, [fs:KPCR_CURRENT_THREAD]
+    mov edx, [ebp+KTRAP_FRAME_EDX]
+    mov [ebx+KTHREAD_TRAP_FRAME], edx
+
+    /* Set up stack frame */
+    mov ebp, esp
+
+    /* Get the Trap Frame in EBX */
+    mov ebx, [ebp+0]
+
+    /* Get the exception list and restore */
+    mov eax, [ebx+KTRAP_FRAME_EXCEPTION_LIST]
+    mov [fs:KPCR_EXCEPTION_LIST], eax
+
+    /* Get the parameters */
+    mov edx, [ebp+16] /* Search frames */
+    mov ecx, [ebp+12] /* Context */
+    mov eax, [ebp+8]  /* Exception Record */
+
+    /* Raise the exception */
+    push edx
+    push ebx
+    push 0
+    push ecx
+    push eax
+    call _KiRaiseException@20
+
+    /* Restore trap frame in EBP */
+    pop ebp
+    mov esp, ebp
+
+.globl _NtContinue@8
+_NtContinue@8:
+
+    /* NOTE: We -must- be called by Zw* to have the right frame! */
+    /* Push the stack frame */
+    push ebp
+
+    /* Get the current thread and restore its trap frame */
+    mov ebx, [fs:KPCR_CURRENT_THREAD]
+    mov edx, [ebp+KTRAP_FRAME_EDX]
+    mov [ebx+KTHREAD_TRAP_FRAME], edx
+
+    /* Set up stack frame */
+    mov ebp, esp
+
+    /* Save the parameters */
+    mov eax, [ebp+0]
+    mov ecx, [ebp+8]
+
+    /* Call KiContinue */
+    push eax
+    push 0
+    push ecx
+    call _KiContinue@12
+
+    /* Check if we failed (bad context record) */
+    or eax, eax
+    jnz Error
+
+    /* Check if test alert was requested */
+    cmp dword ptr [ebp+12], 0
+    je DontTest
+
+    /* Test alert for the thread */
+    mov al, [ebx+KTHREAD_PREVIOUS_MODE]
+    push eax
+    call _KeTestAlertThread@4
+
+DontTest:
+    /* Return to previous context */
+    pop ebp
+    mov esp, ebp
+    jmp _KiServiceExit2
+
+Error:
+    pop ebp
+    mov esp, ebp
+    jmp _KiServiceExit
+
index d04533e..2e69149 100644 (file)
@@ -85,7 +85,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
         TrapFrame = &InitFrame->TrapFrame;
 
         /* Set up a trap frame from the context. */
-        if (KeContextToTrapFrame(Context, TrapFrame))
+        if (KeContextToTrapFrame(Context, NULL, TrapFrame))
         {
             Thread->NpxState = NPX_STATE_VALID;
         }
index 08d720b..b2c34b6 100644 (file)
@@ -352,5 +352,26 @@ _KiTrapUnknown:
        movl    $255, %esi
        jmp     _KiTrapProlog
 
+.intel_syntax noprefix
+.globl _KiCoprocessorError@0
+_KiCoprocessorError@0:
+
+    /* Get the NPX Thread's Initial stack */
+    mov eax, [fs:KPCR_NPX_THREAD]
+    mov eax, [eax+KTHREAD_INITIAL_STACK]
+
+    /* Make space for the FPU Save area */
+    sub eax, SIZEOF_FX_SAVE_AREA
+
+    /* Set the CR0 State */
+    mov dword ptr [eax+FN_CR0_NPX_STATE], 8
+
+    /* Update it */
+    mov eax, cr0
+    or eax, 8
+    mov cr0, eax
+
+    /* Return to caller */
+    ret
 
 /* EOF */
index a14a812..0a77add 100644 (file)
@@ -792,11 +792,9 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
 
    PreviousMode = ExGetPreviousMode();
 
-   Status = RtlCaptureUnicodeString(&CapturedFileName,
-                                    PreviousMode,
-                                    PagedPool,
-                                    FALSE,
-                                    FileName);
+   Status = ProbeAndCaptureUnicodeString(&CapturedFileName,
+                                         PreviousMode,
+                                         FileName);
    if (!NT_SUCCESS(Status))
    {
       return(Status);
@@ -816,9 +814,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
 
       if (!NT_SUCCESS(Status))
       {
-         RtlReleaseCapturedUnicodeString(&CapturedFileName,
-                                         PreviousMode,
-                                         FALSE);
+         ReleaseCapturedUnicodeString(&CapturedFileName,
+                                      PreviousMode);
          return Status;
       }
    }
@@ -849,9 +846,8 @@ NtCreatePagingFile(IN PUNICODE_STRING FileName,
                          NULL,
                          SL_OPEN_PAGING_FILE | IO_NO_PARAMETER_CHECKING);
 
-   RtlReleaseCapturedUnicodeString(&CapturedFileName,
-                                   PreviousMode,
-                                   FALSE);
+   ReleaseCapturedUnicodeString(&CapturedFileName,
+                                PreviousMode);
    if (!NT_SUCCESS(Status))
    {
       return(Status);
index e84d3bc..993dfe6 100644 (file)
@@ -127,9 +127,9 @@ ExQueryPoolBlockSize@8
 ExQueueWorkItem@8
 ExRaiseAccessViolation@0
 ExRaiseDatatypeMisalignment@0
-ExRaiseException@4
+ExRaiseException@4=RtlRaiseException@4
 ExRaiseHardError@24
-ExRaiseStatus@4
+ExRaiseStatus@4=RtlRaiseStatus@4
 ExRegisterCallback@12
 ExReinitializeResourceLite@4
 @ExReInitializeRundownProtection@4
index f7b673c..697f418 100644 (file)
                </if>
                <file>apc.c</file>
                <file>bug.c</file>
-               <file>catch.c</file>
                <file>clock.c</file>
                <file>device.c</file>
                <file>dpc.c</file>
                <file>event.c</file>
+               <file>exception.c</file>
                <file>gate.c</file>
                <file>gmutex.c</file>
                <file>ipi.c</file>
                <file>power.c</file>
        </directory>
        <directory name="ps">
-               <if property="ARCH" value="i386">
-                       <directory name="i386">
-                               <file>continue.c</file>
-                       </directory>
-               </if>
                <file>debug.c</file>
                <file>idle.c</file>
                <file>job.c</file>
                        </directory>
                </if>
                <file>atom.c</file>
-               <file>capture.c</file>
                <file>debug.c</file>
                <file>libsupp.c</file>
                <file>misc.c</file>
index 64f8b98..896bbe9 100644 (file)
@@ -200,11 +200,9 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
     }
   }
 
-  Status = RtlCaptureUnicodeString(&CapturedLinkTarget,
-                                   PreviousMode,
-                                   PagedPool,
-                                   FALSE,
-                                   LinkTarget);
+  Status = ProbeAndCaptureUnicodeString(&CapturedLinkTarget,
+                                        PreviousMode,
+                                        LinkTarget);
   if(!NT_SUCCESS(Status))
   {
     DPRINT1("NtCreateSymbolicLinkObject: Capturing the target link failed!\n");
@@ -263,9 +261,8 @@ NtCreateSymbolicLinkObject(OUT PHANDLE LinkHandle,
     ObDereferenceObject(SymbolicLink);
   }
 
-  RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
-                                  PreviousMode,
-                                  FALSE);
+  ReleaseCapturedUnicodeString(&CapturedLinkTarget,
+                               PreviousMode);
 
   return Status;
 }
index 487e5d9..30d6761 100644 (file)
@@ -57,7 +57,7 @@ PspGetOrSetContextKernelRoutine(PKAPC Apc,
     } else {
 
         /* Set the Context */
-        KeContextToTrapFrame(Context, KeGetCurrentThread()->TrapFrame);
+        KeContextToTrapFrame(Context, NULL, KeGetCurrentThread()->TrapFrame);
     }
 
     /* Notify the Native API that we are done */
@@ -221,7 +221,7 @@ NtSetContextThread(IN HANDLE ThreadHandle,
              * I don't know if trying to get your own context makes much
              * sense but we can handle it more efficently.
              */
-            KeContextToTrapFrame(&GetSetContext.Context, Thread->Tcb.TrapFrame);
+            KeContextToTrapFrame(&GetSetContext.Context, NULL, Thread->Tcb.TrapFrame);
 
         } else {
 
diff --git a/reactos/ntoskrnl/rtl/capture.c b/reactos/ntoskrnl/rtl/capture.c
deleted file mode 100644 (file)
index 3a7e041..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/rtl/capture.c
- * PURPOSE:         Helper routines for system calls.
- *
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS
-RtlCaptureUnicodeString(OUT PUNICODE_STRING Dest,
-                       IN KPROCESSOR_MODE CurrentMode,
-                       IN POOL_TYPE PoolType,
-                       IN BOOLEAN CaptureIfKernel,
-                       IN PUNICODE_STRING UnsafeSrc)
-{
-  UNICODE_STRING Src;
-  NTSTATUS Status = STATUS_SUCCESS;
-
-  ASSERT(Dest != NULL);
-
-  /*
-   * Copy the source string structure to kernel space.
-   */
-
-  if(CurrentMode != KernelMode)
-  {
-    RtlZeroMemory(&Src, sizeof(Src));
-
-    _SEH_TRY
-    {
-      ProbeForRead(UnsafeSrc,
-                   sizeof(UNICODE_STRING),
-                   sizeof(ULONG));
-      Src = *UnsafeSrc;
-      if(Src.Length > 0)
-      {
-        ProbeForRead(Src.Buffer,
-                     Src.Length,
-                     sizeof(WCHAR));
-      }
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-  else if(!CaptureIfKernel)
-  {
-    /* just copy the UNICODE_STRING structure, the pointers are considered valid */
-    *Dest = *UnsafeSrc;
-    return STATUS_SUCCESS;
-  }
-  else
-  {
-    /* capture the string even though it is considered to be valid */
-    Src = *UnsafeSrc;
-  }
-
-  /*
-   * Initialize the destination string.
-   */
-  Dest->Length = Src.Length;
-  if(Src.Length > 0)
-  {
-    Dest->MaximumLength = Src.Length + sizeof(WCHAR);
-    Dest->Buffer = ExAllocatePool(PoolType, Dest->MaximumLength);
-    if (Dest->Buffer == NULL)
-    {
-      Dest->Length = Dest->MaximumLength = 0;
-      Dest->Buffer = NULL;
-      return STATUS_INSUFFICIENT_RESOURCES;
-    }
-    /*
-     * Copy the source string to kernel space.
-     */
-    _SEH_TRY
-    {
-      RtlCopyMemory(Dest->Buffer, Src.Buffer, Src.Length);
-      Dest->Buffer[Src.Length / sizeof(WCHAR)] = L'\0';
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
-
-    if(!NT_SUCCESS(Status))
-    {
-      ExFreePool(Dest->Buffer);
-      Dest->Buffer = NULL;
-      Dest->Length = Dest->MaximumLength = 0;
-    }
-  }
-  else
-  {
-    Dest->MaximumLength = 0;
-    Dest->Buffer = NULL;
-  }
-
-  return Status;
-}
-
-VOID
-RtlReleaseCapturedUnicodeString(IN PUNICODE_STRING CapturedString,
-                               IN KPROCESSOR_MODE CurrentMode,
-                               IN BOOLEAN CaptureIfKernel)
-{
-  if(CurrentMode != KernelMode || CaptureIfKernel )
-  {
-    ExFreePool(CapturedString->Buffer);
-  }
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-RtlCaptureContext (
-       OUT PCONTEXT ContextRecord
-       )
-{
-       UNIMPLEMENTED;
-}
-
-/*
-* @unimplemented
-*/
-USHORT
-STDCALL
-RtlCaptureStackBackTrace (
-       IN ULONG FramesToSkip,
-       IN ULONG FramesToCapture,
-       OUT PVOID *BackTrace,
-       OUT PULONG BackTraceHash OPTIONAL
-       )
-{
-       UNIMPLEMENTED;
-       return 0;
-}
-
-/* EOF */
-
index f066ac6..f87e6cc 100755 (executable)
@@ -62,7 +62,7 @@ _except_handler2(
  * @implemented
  */
 void __cdecl
-_global_unwind2(PEXCEPTION_REGISTRATION RegistrationFrame)
+_global_unwind2(PEXCEPTION_REGISTRATION_RECORD RegistrationFrame)
 {
    RtlUnwind(RegistrationFrame, &&__ret_label, NULL, 0);
 __ret_label:
index 92d07bb..48f3ac9 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/rtl/libsupp.c
- * PURPOSE:         Rtl library support routines
- *
- * PROGRAMMERS:     No programmer listed.
+ * PURPOSE:         RTL Support Routines
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ *                  Gunnar Dalsnes
  */
 
 /* INCLUDES ******************************************************************/
 #define NDEBUG
 #include <internal/debug.h>
 
+extern ULONG NtGlobalFlag;
+
 /* FUNCTIONS *****************************************************************/
 
+BOOLEAN
+NTAPI
+RtlpCheckForActiveDebugger(VOID)
+{
+    /* This check is meaningless in kernel-mode */
+    return TRUE;
+}
 
 KPROCESSOR_MODE
 STDCALL
@@ -124,6 +132,53 @@ CHECK_PAGED_CODE_RTL(char *file, int line)
 }
 #endif
 
+VOID
+NTAPI
+RtlpCheckLogException(IN PEXCEPTION_RECORD ExceptionRecord,
+                      IN PCONTEXT ContextRecord,
+                      IN PVOID ContextData,
+                      IN ULONG Size)
+{
+    /* Check the global flag */
+    if (NtGlobalFlag & FLG_ENABLE_EXCEPTION_LOGGING)
+    {
+        /* FIXME: Log this exception */
+    }
+}
+
+BOOLEAN
+NTAPI
+RtlpHandleDpcStackException(IN PEXCEPTION_REGISTRATION_RECORD RegistrationFrame,
+                            IN ULONG_PTR RegistrationFrameEnd,
+                            IN OUT PULONG_PTR StackLow,
+                            IN OUT PULONG_PTR StackHigh)
+{
+    PKPRCB Prcb;
+    ULONG_PTR DpcStack;
+
+    /* Check if we are at DISPATCH or higher */
+    if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
+    {
+        /* Get the PRCB and DPC Stack */
+        Prcb = KeGetCurrentPrcb();
+        DpcStack = (ULONG_PTR)Prcb->DpcStack;
+
+        /* Check if we are in a DPC and the stack matches */
+        if ((Prcb->DpcRoutineActive) &&
+            (RegistrationFrameEnd <= DpcStack) &&
+            ((ULONG_PTR)RegistrationFrame >= DpcStack - 4096))
+        {
+            /* Update the limits to the DPC Stack's */
+            *StackHigh = DpcStack;
+            *StackLow = DpcStack - 4096;
+            return TRUE;
+        }
+    }
+
+    /* Not in DPC stack */
+    return FALSE;
+}
+
 /* RTL Atom Tables ************************************************************/
 
 NTSTATUS
index d1c5f90..e6a721f 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <stdarg.h>
 #include <windef.h>
+#include <excpt.h>
 #include <ntdef.h>
 #include <basetyps.h>
 
diff --git a/reactos/w32api/include/excpt.h b/reactos/w32api/include/excpt.h
new file mode 100644 (file)
index 0000000..3c18cd4
--- /dev/null
@@ -0,0 +1,90 @@
+/* 
+ * excpt.h
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is a part of the mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within the package.
+ *
+ * Support for operating system level structured exception handling.
+ *
+ * NOTE: This is very preliminary stuff. I am also pretty sure it is
+ *       completely Intel specific.
+ *
+ */
+
+#ifndef        _EXCPT_H_
+#define        _EXCPT_H_
+
+/* All the headers include this file. */
+#include <_mingw.h>
+
+#include <windef.h>
+
+/*
+ * NOTE: The constants structs and typedefs below should be defined in the
+ *       Win32 API headers.
+ */
+#define        EH_NONCONTINUABLE       0x01
+#define        EH_UNWINDING            0x02
+#define        EH_EXIT_UNWIND          0x04
+#define        EH_STACK_INVALID        0x08
+#define        EH_NESTED_CALL          0x10
+
+#ifndef        RC_INVOKED
+
+typedef enum {
+       ExceptionContinueExecution,
+       ExceptionContinueSearch,
+       ExceptionNestedException,
+       ExceptionCollidedUnwind
+} EXCEPTION_DISPOSITION;
+
+
+/*
+ * End of stuff that should be in the Win32 API files.
+ */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The type of function that is expected as an exception handler to be
+ * installed with _try1.
+ */
+typedef EXCEPTION_DISPOSITION (*PEXCEPTION_HANDLER)
+               (struct _EXCEPTION_RECORD*, void*, struct _CONTEXT*, void*);
+
+
+/*
+ * A macro which installs the supplied exception handler.
+ * Push the pointer to the new handler onto the stack,
+ * then push the pointer to the old registration structure (at fs:0)
+ * onto the stack, then put a pointer to the new registration
+ * structure (i.e. the current stack pointer) at fs:0.
+ */
+#define __try1(pHandler) \
+       __asm__ ("pushl %0;pushl %%fs:0;movl %%esp,%%fs:0;" : : "g" (pHandler));
+
+/*
+ * A macro which (despite its name) *removes* an installed
+ * exception handler. Should be used only in conjunction with the above
+ * install routine __try1.
+ * Move the pointer to the old reg. struct (at the current stack
+ * position) to fs:0, replacing the pointer we installed above,
+ * then add 8 to the stack pointer to get rid of the space we
+ * used when we pushed on our new reg. struct above. Notice that
+ * the stack must be in the exact state at this point that it was
+ * after we did _try1 or this will smash things.
+ */
+#define        __except1       \
+       __asm__ ("movl (%%esp),%%eax;movl %%eax,%%fs:0;addl $8,%%esp;" \
+        : : : "%eax");
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* Not RC_INVOKED */
+
+#endif /* _EXCPT_H_ not defined */