ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

except.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            ntoskrnl/ke/except.c
00005  * PURPOSE:         Platform independent exception handling
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  *                  Alex Ionescu (alex.ionescu@reactos.org)
00008  */
00009 
00010 /* INCLUDES ******************************************************************/
00011 
00012 #include <ntoskrnl.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* FUNCTIONS *****************************************************************/
00017 
00018 VOID
00019 NTAPI
00020 KiContinuePreviousModeUser(IN PCONTEXT Context,
00021                            IN PKEXCEPTION_FRAME ExceptionFrame,
00022                            IN PKTRAP_FRAME TrapFrame)
00023 {
00024     CONTEXT LocalContext;
00025 
00026     /* We'll have to make a copy and probe it */
00027     ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
00028     RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
00029     Context = &LocalContext;
00030 
00031     /* Convert the context into Exception/Trap Frames */
00032     KeContextToTrapFrame(&LocalContext,
00033                          ExceptionFrame,
00034                          TrapFrame,
00035                          LocalContext.ContextFlags,
00036                          UserMode);
00037 }
00038 
00039 NTSTATUS
00040 NTAPI
00041 KiContinue(IN PCONTEXT Context,
00042            IN PKEXCEPTION_FRAME ExceptionFrame,
00043            IN PKTRAP_FRAME TrapFrame)
00044 {
00045     NTSTATUS Status = STATUS_SUCCESS;
00046     KIRQL OldIrql = APC_LEVEL;
00047     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
00048 
00049     /* Raise to APC_LEVEL, only if needed */
00050     if (KeGetCurrentIrql() < APC_LEVEL) KeRaiseIrql(APC_LEVEL, &OldIrql);
00051 
00052     /* Set up SEH to validate the context */
00053     _SEH2_TRY
00054     {
00055         /* Check the previous mode */
00056         if (PreviousMode != KernelMode)
00057         {
00058             /* Validate from user-mode */
00059             KiContinuePreviousModeUser(Context,
00060                                        ExceptionFrame,
00061                                        TrapFrame);
00062         }
00063         else
00064         {
00065             /* Convert the context into Exception/Trap Frames */
00066             KeContextToTrapFrame(Context,
00067                                  ExceptionFrame,
00068                                  TrapFrame,
00069                                  Context->ContextFlags,
00070                                  KernelMode);
00071         }
00072     }
00073     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00074     {
00075         /* Save the exception code */
00076         Status = _SEH2_GetExceptionCode();
00077     }
00078     _SEH2_END;
00079 
00080     /* Lower the IRQL if needed */
00081     if (OldIrql < APC_LEVEL) KeLowerIrql(OldIrql);
00082 
00083     /* Return status */
00084     return Status;
00085 }
00086 
00087 NTSTATUS
00088 NTAPI
00089 KiRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,
00090                  IN PCONTEXT Context,
00091                  IN PKEXCEPTION_FRAME ExceptionFrame,
00092                  IN PKTRAP_FRAME TrapFrame,
00093                  IN BOOLEAN SearchFrames)
00094 {
00095     KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
00096     CONTEXT LocalContext;
00097     EXCEPTION_RECORD LocalExceptionRecord;
00098     ULONG ParameterCount, Size;
00099 
00100     /* Check if we need to probe */
00101     if (PreviousMode != KernelMode)
00102     {
00103         /* Set up SEH */
00104         _SEH2_TRY
00105         {
00106             /* Probe the context */
00107             ProbeForRead(Context, sizeof(CONTEXT), sizeof(ULONG));
00108 
00109             /* Probe the Exception Record */
00110             ProbeForRead(ExceptionRecord,
00111                          FIELD_OFFSET(EXCEPTION_RECORD, NumberParameters) +
00112                          sizeof(ULONG),
00113                          sizeof(ULONG));
00114 
00115             /* Validate the maximum parameters */
00116             if ((ParameterCount = ExceptionRecord->NumberParameters) >
00117                 EXCEPTION_MAXIMUM_PARAMETERS)
00118             {
00119                 /* Too large */
00120                 _SEH2_YIELD(return STATUS_INVALID_PARAMETER);
00121             }
00122 
00123             /* Probe the entire parameters now*/
00124             Size = (sizeof(EXCEPTION_RECORD) - 
00125                     ((EXCEPTION_MAXIMUM_PARAMETERS - ParameterCount) * sizeof(ULONG)));
00126             ProbeForRead(ExceptionRecord, Size, sizeof(ULONG));
00127 
00128             /* Now make copies in the stack */
00129             RtlCopyMemory(&LocalContext, Context, sizeof(CONTEXT));
00130             RtlCopyMemory(&LocalExceptionRecord, ExceptionRecord, Size);
00131             Context = &LocalContext;
00132             ExceptionRecord = &LocalExceptionRecord;
00133 
00134             /* Update the parameter count */
00135             ExceptionRecord->NumberParameters = ParameterCount;
00136         }
00137         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00138         {
00139             /* Don't fail silently */
00140             DPRINT1("KiRaiseException: Failed to Probe\n");
00141             DbgBreakPoint();
00142 
00143             /* Return the exception code */
00144             _SEH2_YIELD(return _SEH2_GetExceptionCode());
00145         }
00146         _SEH2_END;
00147     }
00148 
00149     /* Convert the context record */
00150     KeContextToTrapFrame(Context,
00151                          ExceptionFrame,
00152                          TrapFrame,
00153                          Context->ContextFlags,
00154                          PreviousMode);
00155 
00156     /* Dispatch the exception */
00157     ExceptionRecord->ExceptionCode &= ~KI_EXCEPTION_INTERNAL;
00158     KiDispatchException(ExceptionRecord,
00159                         ExceptionFrame,
00160                         TrapFrame,
00161                         PreviousMode,
00162                         SearchFrames);
00163 
00164     /* We are done */
00165     return STATUS_SUCCESS;
00166 }
00167 
00168 /* SYSTEM CALLS ***************************************************************/
00169 
00170 NTSTATUS
00171 NTAPI
00172 NtRaiseException(IN PEXCEPTION_RECORD ExceptionRecord,
00173                  IN PCONTEXT Context,
00174                  IN BOOLEAN FirstChance)
00175 {
00176     NTSTATUS Status;
00177     PKTHREAD Thread;
00178     PKTRAP_FRAME TrapFrame;
00179 
00180     /* Get trap frame and link previous one*/
00181     Thread = KeGetCurrentThread();
00182     TrapFrame = Thread->TrapFrame;
00183     Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
00184     
00185     /* Set exception list */
00186 #ifdef _M_IX86
00187     KeGetPcr()->NtTib.ExceptionList = TrapFrame->ExceptionList;
00188 #endif
00189     
00190     /* Raise the exception */
00191     Status = KiRaiseException(ExceptionRecord,
00192                               Context,
00193                               NULL,
00194                               TrapFrame,
00195                               FirstChance);
00196     if (NT_SUCCESS(Status))
00197     {
00198         /* It was handled, so exit restoring all state */
00199         KiServiceExit2(TrapFrame);
00200     }
00201     else
00202     {
00203         /* Exit with error */
00204         KiServiceExit(TrapFrame, Status);
00205     }
00206     
00207     /* We don't actually make it here */
00208     return Status;
00209 }
00210 
00211 NTSTATUS
00212 NTAPI
00213 NtContinue(IN PCONTEXT Context,
00214            IN BOOLEAN TestAlert)
00215 {
00216     PKTHREAD Thread;
00217     NTSTATUS Status;
00218     PKTRAP_FRAME TrapFrame;
00219     
00220     /* Get trap frame and link previous one*/
00221     Thread = KeGetCurrentThread();
00222     TrapFrame = Thread->TrapFrame;
00223     Thread->TrapFrame = KiGetLinkedTrapFrame(TrapFrame);
00224     
00225     /* Continue from this point on */
00226     Status = KiContinue(Context, NULL, TrapFrame);
00227     if (NT_SUCCESS(Status))
00228     {
00229         /* Check if alert was requested */
00230         if (TestAlert) KeTestAlertThread(Thread->PreviousMode);
00231         
00232         /* Exit to new trap frame */
00233         KiServiceExit2(TrapFrame);
00234     }
00235     else
00236     {
00237         /* Exit with an error */
00238         KiServiceExit(TrapFrame, Status);
00239     }
00240     
00241     /* We don't actually make it here */
00242     return Status;
00243 }
00244 
00245 /* EOF */

Generated on Sun May 27 2012 04:24:25 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.