Test commit. Not official branch release -- it will follow shortly in 15 minutes...
authorAlex Ionescu <aionescu@gmail.com>
Mon, 28 Feb 2005 16:44:38 +0000 (16:44 +0000)
committerAlex Ionescu <aionescu@gmail.com>
Mon, 28 Feb 2005 16:44:38 +0000 (16:44 +0000)
svn path=/trunk/; revision=13776

56 files changed:
reactos/config
reactos/drivers/storage/floppy/floppy.c
reactos/include/ddk/extypes.h
reactos/include/ddk/iotypes.h
reactos/include/ddk/ketypes.h
reactos/include/ntos/zwtypes.h
reactos/lib/ntdll/def/ntdll.def
reactos/ntoskrnl/Makefile
reactos/ntoskrnl/cm/registry.c
reactos/ntoskrnl/ex/error.c [new file with mode: 0644]
reactos/ntoskrnl/ex/event.c
reactos/ntoskrnl/ex/evtpair.c
reactos/ntoskrnl/ex/init.c
reactos/ntoskrnl/ex/mutant.c
reactos/ntoskrnl/ex/rundown.c
reactos/ntoskrnl/ex/sem.c
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/ex/timer.c
reactos/ntoskrnl/ex/work.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/id.h
reactos/ntoskrnl/include/internal/io.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/nls.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/include/internal/ps.h
reactos/ntoskrnl/io/bootlog.c
reactos/ntoskrnl/io/create.c
reactos/ntoskrnl/io/driver.c
reactos/ntoskrnl/io/iocomp.c
reactos/ntoskrnl/io/iomgr.c
reactos/ntoskrnl/io/wmi.c
reactos/ntoskrnl/ke/alert.c [deleted file]
reactos/ntoskrnl/ke/apc.c
reactos/ntoskrnl/ke/bug.c
reactos/ntoskrnl/ke/catch.c
reactos/ntoskrnl/ke/critical.c [deleted file]
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/ke/error.c [deleted file]
reactos/ntoskrnl/ke/event.c
reactos/ntoskrnl/ke/i386/tskswitch.S
reactos/ntoskrnl/ke/kthread.c
reactos/ntoskrnl/ke/main.c
reactos/ntoskrnl/ke/mutex.c
reactos/ntoskrnl/ke/queue.c
reactos/ntoskrnl/ke/sem.c
reactos/ntoskrnl/ke/timer.c
reactos/ntoskrnl/ke/wait.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.mc
reactos/ntoskrnl/ob/wait.c [new file with mode: 0644]
reactos/ntoskrnl/ps/kill.c
reactos/ntoskrnl/ps/process.c
reactos/ntoskrnl/ps/thread.c
reactos/ntoskrnl/rtl/nls.c
reactos/tools/nci/sysfuncs.lst

index 5a8c1f6..9a6cdff 100644 (file)
@@ -15,7 +15,7 @@ ARCH := i386
 # be optimze for. 
 #
 
-OARCH := i486
+OARCH := pentium2
 
 #
 # Whether to compile in the kernel debugger
@@ -30,7 +30,7 @@ DBG := 0
 #
 # Whether to compile with optimizations
 #
-OPTIMIZED := 0
+OPTIMIZED := 1
 
 #
 # Whether to compile a multiprocessor or single processor version
index 987eb2f..3447930 100644 (file)
@@ -58,7 +58,7 @@ static ULONG gNumberOfControllers = 0;
 
 /* Queue thread management */
 static KEVENT QueueThreadTerminate;
-static PVOID ThreadObject;
+static PVOID QueueThreadObject;
 
 \f
 static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc,
@@ -378,8 +378,8 @@ static VOID NTAPI Unload(PDRIVER_OBJECT DriverObject)
   KdPrint(("floppy: unloading\n"));
 
   KeSetEvent(&QueueThreadTerminate, 0, FALSE);
-  KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, 0);
-  ObDereferenceObject(ThreadObject);
+  KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode, FALSE, 0);
+  ObDereferenceObject(QueueThreadObject);
 
   for(i = 0; i < gNumberOfControllers; i++)
     {
@@ -1152,7 +1152,7 @@ NTSTATUS NTAPI DriverEntry(PDRIVER_OBJECT DriverObject,
       return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-  if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS)
+  if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS)
     {
       KdPrint(("floppy: Unable to reference returned thread handle; failing init\n"));
       return STATUS_UNSUCCESSFUL;
index 4db6f6d..2c438f6 100644 (file)
@@ -30,6 +30,23 @@ typedef enum _WORK_QUEUE_TYPE {
     MaximumWorkQueue
 } WORK_QUEUE_TYPE;
 
+typedef struct _EX_QUEUE_WORKER_INFO {
+    UCHAR QueueDisabled:1;
+    UCHAR MakeThreadsAsNecessary:1;
+    UCHAR WaitMode:1;
+    ULONG WorkerCount:29;
+} EX_QUEUE_WORKER_INFO, *PEX_QUEUE_WORKER_INFO;
+
+typedef struct _EX_WORK_QUEUE {
+    KQUEUE WorkerQueue;
+    ULONG DynamicThreadCount;
+    ULONG WorkItemsProcessed;
+    ULONG WorkItemsProcessedLastPass;
+    ULONG QueueDepthLastPass;
+    EX_QUEUE_WORKER_INFO Info;    
+} EX_WORK_QUEUE, *PEX_WORK_QUEUE;
+
+
 typedef ULONG_PTR ERESOURCE_THREAD, *PERESOURCE_THREAD;
 
 typedef struct _OWNER_ENTRY
@@ -240,6 +257,10 @@ typedef VOID STDCALL_FUNC
                      PVOID Argument1,
                      PVOID Argument2);
 
+extern struct _OBJECT_TYPE EXPORTED *ExMutantObjectType;
+extern struct _OBJECT_TYPE EXPORTED *ExSemaphoreObjectType;
+extern struct _OBJECT_TYPE EXPORTED *ExTimerType;
+
 #endif /* __INCLUDE_DDK_EXTYPES_H */
 
 /* EOF */
index bca0769..379cfc8 100644 (file)
@@ -886,6 +886,8 @@ struct _FAST_IO_DISPATCH_TABLE
 #endif
 
 #define IO_TYPE_DRIVER 4L
+#define IO_TYPE_FILE 0x0F5L
+
 #define DRVO_UNLOAD_INVOKED 0x1L
 #define DRVO_LEGACY_DRIVER  0x2L
 #define DRVO_BUILTIN_DRIVER 0x4L
index ce77b02..b938fc6 100644 (file)
@@ -36,23 +36,34 @@ typedef VOID STDCALL_FUNC
 
 struct _DISPATCHER_HEADER;
 
-typedef enum _KERNEL_OBJECTS {
-       KNotificationEvent = 0,
-       KSynchronizationEvent = 1,
-       KMutant = 2,
-       KProcess = 3,
-       KQueue = 4,
-       KSemaphore = 5,
-       KThread = 6,
-       KNotificationTimer = 8,
-       KSynchronizationTimer = 9,
-       KApc = 18,
-       KDpc = 19,
-       KDeviceQueue = 20,
-       KEventPair = 21,
-       KInterrupt = 22,
-       KProfile = 23
-} KERNEL_OBJECTS;
+typedef enum _KOBJECTS {
+   EventNotificationObject = 0,
+   EventSynchronizationObject = 1,
+   MutantObject = 2,
+   ProcessObject = 3,
+   QueueObject = 4,
+   SemaphoreObject = 5,
+   ThreadObject = 6,
+   GateObject = 7,
+   TimerNotificationObject = 8,
+   TimerSynchronizationObject = 9,
+   Spare2Object = 10,
+   Spare3Object = 11,
+   Spare4Object = 12,
+   Spare5Object = 13,
+   Spare6Object = 14,
+   Spare7Object = 15,
+   Spare8Object = 16,
+   Spare9Object = 17,
+   ApcObject = 18,
+   DpcObject = 19,
+   DeviceQueueObject = 20,
+   EventPairObject = 21,
+   InterruptObject = 22,
+   ProfileObject = 23,
+   ThreadedDpcObject = 24,
+   MaximumKernelObject = 25
+} KOBJECTS;
 
 #include <pshpack1.h>
 
index 37ba0b1..78f6d1e 100755 (executable)
@@ -1262,9 +1262,9 @@ typedef enum _MUTANT_INFORMATION_CLASS
 
 typedef struct _MUTANT_BASIC_INFORMATION
 {
-  LONG Count;
-  BOOLEAN Owned;
-  BOOLEAN Abandoned;
+  LONG CurrentCount;
+  BOOLEAN OwnedByCaller;
+  BOOLEAN AbandonedState;
 } MUTANT_BASIC_INFORMATION, *PMUTANT_BASIC_INFORMATION;
 
 
index f9101ba..66e909c 100644 (file)
@@ -225,7 +225,6 @@ NtSetEaFile@16
 NtSetEvent@8
 NtSetHighEventPair@4
 NtSetHighWaitLowEventPair@4
-NtSetHighWaitLowThread@0
 NtSetInformationFile@20
 NtSetInformationJobObject@16
 NtSetInformationKey@16
@@ -238,7 +237,6 @@ NtSetIoCompletion@20
 NtSetLdtEntries@24
 NtSetLowEventPair@4
 NtSetLowWaitHighEventPair@4
-NtSetLowWaitHighThread@0
 NtSetSecurityObject@12
 NtSetSystemEnvironmentValue@8
 NtSetSystemInformation@12
@@ -849,7 +847,6 @@ ZwSetEaFile@16
 ZwSetEvent@8
 ZwSetHighEventPair@4
 ZwSetHighWaitLowEventPair@4
-ZwSetHighWaitLowThread@0
 ZwSetInformationFile@20
 ZwSetInformationKey@16
 ZwSetInformationObject@16
@@ -861,7 +858,6 @@ ZwSetIoCompletion@20
 ZwSetLdtEntries@24
 ZwSetLowEventPair@4
 ZwSetLowWaitHighEventPair@4
-ZwSetLowWaitHighThread@0
 ZwSetSecurityObject@12
 ZwSetSystemEnvironmentValue@8
 ZwSetSystemInformation@12
index 9dc41bf..ca48237 100644 (file)
@@ -101,10 +101,8 @@ OBJECTS_KE = \
        ke/bug.o \
        ke/catch.o \
        ke/clock.o \
-       ke/critical.o \
        ke/dpc.o \
        ke/device.o \
-       ke/error.o \
        ke/event.o \
        ke/kqueue.o \
        ke/kthread.o \
@@ -118,7 +116,6 @@ OBJECTS_KE = \
        ke/spinlock.o \
        ke/timer.o \
        ke/wait.o \
-       ke/alert.o
 
 # Memory Manager (Mm)
 OBJECTS_MM = \
@@ -219,7 +216,8 @@ OBJECTS_OB = \
        ob/object.o \
        ob/sdcache.o \
        ob/security.o \
-       ob/symlink.o
+       ob/symlink.o \
+       ob/wait.o
 
 # Process Manager (Ps)
 OBJECTS_PS = \
@@ -242,6 +240,7 @@ OBJECTS_PS = \
 OBJECTS_EX = \
        ex/btree.o \
        ex/callback.o \
+       ex/error.o \
        ex/event.o \
        ex/evtpair.o \
        ex/fmutex.o \
index 304192c..919c307 100644 (file)
@@ -241,6 +241,29 @@ CmiCheckRegistry(BOOLEAN Verbose)
   CmiCheckByName(Verbose, L"User");
 }
 
+VOID
+INIT_FUNCTION
+STDCALL
+CmInitHives(BOOLEAN SetupBoot)
+{
+    PCHAR BaseAddress;
+    
+    /* Load Registry Hives */
+    BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
+    CmImportSystemHive(BaseAddress,
+                       CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    
+    BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
+    CmImportHardwareHive(BaseAddress,
+                         CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    
+
+    /* Create dummy keys if no hardware hive was found */
+    CmImportHardwareHive (NULL, 0);
+
+    /* Initialize volatile registry settings */
+    if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+}   
 
 VOID INIT_FUNCTION
 CmInitializeRegistry(VOID)
diff --git a/reactos/ntoskrnl/ex/error.c b/reactos/ntoskrnl/ex/error.c
new file mode 100644 (file)
index 0000000..d1d99a5
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/ex/error.c
+ * PURPOSE:         Error Functions and Status/Exception Dispatching/Raising
+ *
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Created File
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <internal/debug.h>
+
+/* GLOBALS ****************************************************************/
+
+BOOLEAN ExReadyForErrors = FALSE;
+PEPORT ExpDefaultErrorPort = NULL;
+PEPROCESS ExpDefaultErrorPortProcess = NULL;
+
+/* FUNCTIONS ****************************************************************/
+
+/*
+ * @implemented
+ */
+VOID 
+STDCALL
+ExRaiseAccessViolation(VOID)
+{
+    /* Raise the Right Status */
+    ExRaiseStatus (STATUS_ACCESS_VIOLATION);
+}
+
+/*
+ * @implemented
+ */
+VOID
+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);
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+ExSystemExceptionFilter(VOID)
+{
+    return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+ExRaiseHardError(IN NTSTATUS ErrorStatus,
+                 IN ULONG NumberOfParameters, 
+                 IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
+                 IN PVOID *Parameters, 
+                 IN HARDERROR_RESPONSE_OPTION ResponseOption, 
+                 OUT PHARDERROR_RESPONSE Response)
+{
+    UNIMPLEMENTED;
+}
+
+NTSTATUS 
+STDCALL 
+NtRaiseHardError(IN NTSTATUS ErrorStatus,
+                 IN ULONG NumberOfParameters,
+                 IN PUNICODE_STRING UnicodeStringParameterMask  OPTIONAL,
+                 IN PVOID *Parameters,
+                 IN HARDERROR_RESPONSE_OPTION ResponseOption,
+                 OUT PHARDERROR_RESPONSE Response)
+{
+    DPRINT1("Hard error %x\n", ErrorStatus);
+  
+    /* Call the Executive Function (WE SHOULD PUT SEH HERE/CAPTURE!) */
+    ExRaiseHardError(ErrorStatus,
+                     NumberOfParameters,
+                     UnicodeStringParameterMask,
+                     Parameters,
+                     ResponseOption,
+                     Response);
+  
+    /* Return Success */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS 
+STDCALL 
+NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
+{
+    
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
+  
+    /* Check if we have the Privilege */
+    if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) {
+        
+        DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n");
+        return STATUS_PRIVILEGE_NOT_HELD;
+    }
+  
+    /* Only called once during bootup, make sure we weren't called yet */
+    if(!ExReadyForErrors) {
+        
+        Status = ObReferenceObjectByHandle(PortHandle,
+                                           0,
+                                           LpcPortObjectType,
+                                           PreviousMode,
+                                           (PVOID*)&ExpDefaultErrorPort,
+                                           NULL);
+        
+        /* Check for Success */
+        if(NT_SUCCESS(Status)) {
+            
+            /* Save the data */
+            ExpDefaultErrorPortProcess = PsGetCurrentProcess();
+            ExReadyForErrors = TRUE;
+        }
+    }
+  
+    return Status;
+}
+
+/* EOF */
index 4db20f5..c05fedb 100644 (file)
 POBJECT_TYPE EXPORTED ExEventObjectType = NULL;
 
 static GENERIC_MAPPING ExpEventMapping = {
-       STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
-       EVENT_ALL_ACCESS};
-
-static const INFORMATION_CLASS_INFO ExEventInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* EventBasicInformation */
+    STANDARD_RIGHTS_READ | SYNCHRONIZE | EVENT_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE | SYNCHRONIZE | EVENT_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | EVENT_QUERY_STATE,
+    EVENT_ALL_ACCESS};
+
+static const INFORMATION_CLASS_INFO ExEventInfoClass[] = {
+    
+    /* EventBasicInformation */
+    ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
 };
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STDCALL
-NtpCreateEvent(PVOID ObjectBody,
-              PVOID Parent,
-              PWSTR RemainingPath,
-              POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateEvent(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeEventImplementation(VOID)
 {
-   ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExEventObjectType->TypeName, L"Event", NonPagedPool);
-   
-   ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
-   ExEventObjectType->PeakObjects = 0;
-   ExEventObjectType->PeakHandles = 0;
-   ExEventObjectType->TotalObjects = 0;
-   ExEventObjectType->TotalHandles = 0;
-   ExEventObjectType->PagedPoolCharge = 0;
-   ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
-   ExEventObjectType->Mapping = &ExpEventMapping;
-   ExEventObjectType->Dump = NULL;
-   ExEventObjectType->Open = NULL;
-   ExEventObjectType->Close = NULL;
-   ExEventObjectType->Delete = NULL;
-   ExEventObjectType->Parse = NULL;
-   ExEventObjectType->Security = NULL;
-   ExEventObjectType->QueryName = NULL;
-   ExEventObjectType->OkayToClose = NULL;
-   ExEventObjectType->Create = NtpCreateEvent;
-   ExEventObjectType->DuplicationNotify = NULL;
-
-   ObpCreateTypeObject(ExEventObjectType);
+    /* Create the Event Object Type */
+    ExEventObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlpCreateUnicodeString(&ExEventObjectType->TypeName, L"Event", NonPagedPool);
+    ExEventObjectType->Tag = TAG('E', 'V', 'T', 'T');
+    ExEventObjectType->PeakObjects = 0;
+    ExEventObjectType->PeakHandles = 0;
+    ExEventObjectType->TotalObjects = 0;
+    ExEventObjectType->TotalHandles = 0;
+    ExEventObjectType->PagedPoolCharge = 0;
+    ExEventObjectType->NonpagedPoolCharge = sizeof(KEVENT);
+    ExEventObjectType->Mapping = &ExpEventMapping;
+    ExEventObjectType->Dump = NULL;
+    ExEventObjectType->Open = NULL;
+    ExEventObjectType->Close = NULL;
+    ExEventObjectType->Delete = NULL;
+    ExEventObjectType->Parse = NULL;
+    ExEventObjectType->Security = NULL;
+    ExEventObjectType->QueryName = NULL;
+    ExEventObjectType->OkayToClose = NULL;
+    ExEventObjectType->Create = NULL;
+    ExEventObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExEventObjectType);
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtClearEvent(IN HANDLE EventHandle)
 {
-   PKEVENT Event;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
+    PKEVENT Event;
+    NTSTATUS Status;
+    
+    PAGED_CODE();
    
+    /* Reference the Object */
    Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     ExGetPreviousMode(),
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeClearEvent(Event);
-     ObDereferenceObject(Event);
-   }
+                                      EVENT_MODIFY_STATE,
+                                      ExEventObjectType,
+                                      ExGetPreviousMode(),
+                                      (PVOID*)&Event,
+                                      NULL);
    
-   return Status;
+   /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Clear the Event and Dereference */
+        KeClearEvent(Event);
+        ObDereferenceObject(Event);
+    }
+   
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateEvent(OUT PHANDLE EventHandle,
-             IN ACCESS_MASK DesiredAccess,
-             IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-             IN EVENT_TYPE EventType,
-             IN BOOLEAN InitialState)
+              IN ACCESS_MASK DesiredAccess,
+              IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+              IN EVENT_TYPE EventType,
+              IN BOOLEAN InitialState)
 {
-   KPROCESSOR_MODE PreviousMode;
-   PKEVENT Event;
-   HANDLE hEvent;
-   NTSTATUS Status = STATUS_SUCCESS;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    HANDLE hEvent;
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
+    PAGED_CODE();
  
-   PreviousMode = ExGetPreviousMode();
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-   Status = ObCreateObject(PreviousMode,
-                           ExEventObjectType,
-                           ObjectAttributes,
-                           PreviousMode,
-                           NULL,
-                           sizeof(KEVENT),
-                           0,
-                           0,
-                           (PVOID*)&Event);
-   if(NT_SUCCESS(Status))
-   {
-     KeInitializeEvent(Event,
-                       EventType,
-                       InitialState);
-     Status = ObInsertObject((PVOID)Event,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hEvent);
-     ObDereferenceObject(Event);
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *EventHandle = hEvent;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Create the Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExEventObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KEVENT),
+                            0,
+                            0,
+                            (PVOID*)&Event);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Event */
+        KeInitializeEvent(Event,
+                          EventType,
+                          InitialState);
+        
+        /* Insert it */
+        Status = ObInsertObject((PVOID)Event,
+                                 NULL,
+                                 DesiredAccess,
+                                 0,
+                                 NULL,
+                                 &hEvent);
+        ObDereferenceObject(Event);
  
-   return Status;
-}
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *EventHandle = hEvent;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
 
+    /* Return Status */
+    return Status;
+}
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenEvent(OUT PHANDLE EventHandle,
-           IN ACCESS_MASK DesiredAccess,
-           IN POBJECT_ATTRIBUTES ObjectAttributes)
+            IN ACCESS_MASK DesiredAccess,
+            IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hEvent;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hEvent;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-   
-   DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();
+    DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExEventObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hEvent);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExEventObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hEvent);
              
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *EventHandle = hEvent;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *EventHandle = hEvent;
+                
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtPulseEvent(IN HANDLE EventHandle,
-            OUT PLONG PreviousState  OPTIONAL)
+             OUT PLONG PreviousState OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+    DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
+            EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
-     ObDereferenceObject(Event);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Pulse the Event */
+        LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
+        ObDereferenceObject(Event);
      
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
@@ -320,230 +306,202 @@ NtPulseEvent(IN HANDLE EventHandle,
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtQueryEvent(IN HANDLE EventHandle,
-            IN EVENT_INFORMATION_CLASS EventInformationClass,
-            OUT PVOID EventInformation,
-            IN ULONG EventInformationLength,
-            OUT PULONG ReturnLength  OPTIONAL)
+             IN EVENT_INFORMATION_CLASS EventInformationClass,
+             OUT PVOID EventInformation,
+             IN ULONG EventInformationLength,
+             OUT PULONG ReturnLength  OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
+    
+    /* Check buffers and class validity */
+    DefaultQueryInfoBufferCheck(EventInformationClass,
+                                ExEventInfoClass,
+                                EventInformation,
+                                EventInformationLength,
+                                ReturnLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        /* Invalid buffers */
+        DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
    
-   DefaultQueryInfoBufferCheck(EventInformationClass,
-                               ExEventInfoClass,
-                               EventInformation,
-                               EventInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQueryEvent() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_QUERY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(EventInformationClass)
-     {
-       case EventBasicInformation:
-       {
-         PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
-         
-         _SEH_TRY
-         {
-           if (Event->Header.Type == InternalNotificationEvent)
-             BasicInfo->EventType = NotificationEvent;
-           else
-             BasicInfo->EventType = SynchronizationEvent;
-           BasicInfo->EventState = KeReadStateEvent(Event);
-
-           if(ReturnLength != NULL)
-           {
-             *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Event);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_QUERY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+
+        _SEH_TRY {
+            
+            /* Return Event Type and State */
+            BasicInfo->EventType = Event->Header.Type;
+            BasicInfo->EventState = KeReadStateEvent(Event);
+
+            /* Return length */
+            if(ReturnLength) *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+     
+        /* Dereference the Object */
+        ObDereferenceObject(Event);
    }
 
+   /* Return status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtResetEvent(IN HANDLE EventHandle,
-            OUT PLONG PreviousState  OPTIONAL)
+             OUT PLONG PreviousState OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+
+    DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
+            EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeResetEvent(Event);
-     ObDereferenceObject(Event);
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Reset the Event */
+        LONG Prev = KeResetEvent(Event);
+        ObDereferenceObject(Event);
      
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtSetEvent(IN HANDLE EventHandle,
-          OUT PLONG PreviousState  OPTIONAL)
+           OUT PLONG PreviousState  OPTIONAL)
 {
-   PKEVENT Event;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKEVENT Event;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
-         EventHandle, PreviousState);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousState != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousState,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-     
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+
+    DPRINT1("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
+            EventHandle, PreviousState);
+
+    /* Check buffer validity */
+    if(PreviousState != NULL && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousState,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
 
-   Status = ObReferenceObjectByHandle(EventHandle,
-                                     EVENT_MODIFY_STATE,
-                                     ExEventObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Event,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
-     ObDereferenceObject(Event);
-
-     if(PreviousState != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousState = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventHandle,
+                                       EVENT_MODIFY_STATE,
+                                       ExEventObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Event,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+
+        /* Set the Event */
+        LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
+        ObDereferenceObject(Event);
+
+        /* Return it */        
+        if(PreviousState) {
+            
+            _SEH_TRY {
+                
+                *PreviousState = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
    }
 
+   /* Return Status */
    return Status;
 }
 
-
-/*
- * @unimplemented
- */
-NTSTATUS
-STDCALL
-NtTraceEvent(
-       IN ULONG TraceHandle,
-       IN ULONG Flags,
-       IN ULONG TraceHeaderLength,
-       IN struct _EVENT_TRACE_HEADER* TraceHeader
-       )
-{
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
-}
-
-
 /* EOF */
index 15b05e6..05876a7 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id: evtpair.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/evtpair.c
  * PURPOSE:         Support for event pairs
  *
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (Commented, reorganized, removed Thread Pair, used KeInitializeEventPair, added SEH)
+ *                  David Welch (welch@mcmail.com)
  *                  Skywing (skywing@valhallalegends.com)
  */
 
 #define NDEBUG
 #include <internal/debug.h>
 
-#ifndef NTSYSAPI
-#define NTSYSAPI
-#endif
-
-#ifndef NTAPI
-#define NTAPI STDCALL
-#endif
-
-
 /* GLOBALS *******************************************************************/
 
 POBJECT_TYPE EXPORTED ExEventPairObjectType = NULL;
 
 static GENERIC_MAPPING ExEventPairMapping = {
-       STANDARD_RIGHTS_READ,
-       STANDARD_RIGHTS_WRITE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
-       EVENT_PAIR_ALL_ACCESS};
+    STANDARD_RIGHTS_READ,
+    STANDARD_RIGHTS_WRITE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
+    EVENT_PAIR_ALL_ACCESS};
 
-static KSPIN_LOCK ExThreadEventPairSpinLock;
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS STDCALL
-ExpCreateEventPair(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("ExpCreateEventPair(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-  
-  return(STATUS_SUCCESS);
-}
-
-VOID INIT_FUNCTION
+VOID
+INIT_FUNCTION
 ExpInitializeEventPairImplementation(VOID)
 {
-   ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair", NonPagedPool);
-   ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
-   ExEventPairObjectType->PeakObjects = 0;
-   ExEventPairObjectType->PeakHandles = 0;
-   ExEventPairObjectType->TotalObjects = 0;
-   ExEventPairObjectType->TotalHandles = 0;
-   ExEventPairObjectType->PagedPoolCharge = 0;
-   ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
-   ExEventPairObjectType->Mapping = &ExEventPairMapping;
-   ExEventPairObjectType->Dump = NULL;
-   ExEventPairObjectType->Open = NULL;
-   ExEventPairObjectType->Close = NULL;
-   ExEventPairObjectType->Delete = NULL;
-   ExEventPairObjectType->Parse = NULL;
-   ExEventPairObjectType->Security = NULL;
-   ExEventPairObjectType->QueryName = NULL;
-   ExEventPairObjectType->OkayToClose = NULL;
-   ExEventPairObjectType->Create = ExpCreateEventPair;
-   ExEventPairObjectType->DuplicationNotify = NULL;
-
-   KeInitializeSpinLock(&ExThreadEventPairSpinLock);
-   ObpCreateTypeObject(ExEventPairObjectType);
+    /* Create the Event Pair Object Type */
+    ExEventPairObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+    RtlpCreateUnicodeString(&ExEventPairObjectType->TypeName, L"EventPair", NonPagedPool);
+    ExEventPairObjectType->Tag = TAG('E', 'v', 'P', 'a');
+    ExEventPairObjectType->PeakObjects = 0;
+    ExEventPairObjectType->PeakHandles = 0;
+    ExEventPairObjectType->TotalObjects = 0;
+    ExEventPairObjectType->TotalHandles = 0;
+    ExEventPairObjectType->PagedPoolCharge = 0;
+    ExEventPairObjectType->NonpagedPoolCharge = sizeof(KEVENT_PAIR);
+    ExEventPairObjectType->Mapping = &ExEventPairMapping;
+    ExEventPairObjectType->Dump = NULL;
+    ExEventPairObjectType->Open = NULL;
+    ExEventPairObjectType->Close = NULL;
+    ExEventPairObjectType->Delete = NULL;
+    ExEventPairObjectType->Parse = NULL;
+    ExEventPairObjectType->Security = NULL;
+    ExEventPairObjectType->QueryName = NULL;
+    ExEventPairObjectType->OkayToClose = NULL;
+    ExEventPairObjectType->Create = NULL;
+    ExEventPairObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExEventPairObjectType);
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtCreateEventPair(OUT PHANDLE EventPairHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes)
+                  IN ACCESS_MASK DesiredAccess,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   PKEVENT_PAIR EventPair;
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
+    PKEVENT_PAIR EventPair;
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    DPRINT1("NtCreateEventPair: %x\n", EventPairHandle);
    
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventPairHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObCreateObject(PreviousMode,
-                          ExEventPairObjectType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(KEVENT_PAIR),
-                          0,
-                          0,
-                          (PVOID*)&EventPair);
-   if(NT_SUCCESS(Status))
-   {
-     KeInitializeEvent(&EventPair->LowEvent,
-                      SynchronizationEvent,
-                      FALSE);
-     KeInitializeEvent(&EventPair->HighEvent,
-                      SynchronizationEvent,
-                      FALSE);
-
-     Status = ObInsertObject ((PVOID)EventPair,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hEventPair);
-     ObDereferenceObject(EventPair);
-     
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *EventPairHandle = hEventPair;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
-   return Status;
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Create the Object */
+    DPRINT1("Creating EventPair\n");
+    Status = ObCreateObject(PreviousMode,
+                            ExEventPairObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KEVENT_PAIR),
+                            0,
+                            0,
+                            (PVOID*)&EventPair);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Event */
+        DPRINT1("Initializing EventPair\n");
+        KeInitializeEventPair(EventPair);
+        
+        /* Insert it */
+        Status = ObInsertObject((PVOID)EventPair,
+                                 NULL,
+                                 DesiredAccess,
+                                 0,
+                                 NULL,
+                                 &hEventPair);
+        ObDereferenceObject(EventPair);
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *EventPairHandle = hEventPair;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
+
+    /* Return Status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenEventPair(OUT PHANDLE EventPairHandle,
-               IN ACCESS_MASK DesiredAccess,
-               IN POBJECT_ATTRIBUTES ObjectAttributes)
+                IN ACCESS_MASK DesiredAccess,
+                IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hEventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hEventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(EventPairHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(EventPairHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExEventPairObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hEventPair);
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *EventPairHandle = hEventPair;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExEventPairObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hEventPair);
+             
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *EventPairHandle = hEventPair;
+                
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtSetHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
 
-   PreviousMode = ExGetPreviousMode();
+    DPRINT1("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
    
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtSetHighWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    DPRINT1("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
+        
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtSetLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
 
-   DPRINT("NtSetLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               FALSE);
-
-     ObDereferenceObject(EventPair);
-   }
+    DPRINT1("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
    
-   return Status;
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
+    
+    /* Return status */
+    return Status;
 }
 
 
 NTSTATUS STDCALL
 NtSetLowWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtSetLowWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    DPRINT1("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Set the Event */
+        KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
+        
+        /* Wait for the Other one */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
 
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtWaitLowEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitLowEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
-   
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->LowEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    DPRINT1("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+               
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->LowEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   return Status;
+    /* Return status */
+    return Status;
 }
 
-
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtWaitHighEventPair(IN HANDLE EventPairHandle)
 {
-   PKEVENT_PAIR EventPair;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status;
-   
-   PAGED_CODE();
-
-   DPRINT("NtWaitHighEventPair(EventPairHandle %x)\n",
-         EventPairHandle);
-
-   PreviousMode = ExGetPreviousMode();
+    PKEVENT_PAIR EventPair;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    DPRINT1("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(EventPairHandle,
+                                       SYNCHRONIZE,
+                                       ExEventPairObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&EventPair,
+                                       NULL);
+    
+    /* Check for Success */
+    if(NT_SUCCESS(Status)) {
+               
+        /* Wait for the Event */
+        KeWaitForSingleObject(&EventPair->HighEvent,
+                              WrEventPair,
+                              PreviousMode,
+                              FALSE,
+                              NULL);
+
+        /* Dereference Object */
+        ObDereferenceObject(EventPair);
+    }
    
-   Status = ObReferenceObjectByHandle(EventPairHandle,
-                                     SYNCHRONIZE,
-                                     ExEventPairObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&EventPair,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     KeWaitForSingleObject(&EventPair->HighEvent,
-                          WrEventPair,
-                          PreviousMode,
-                          FALSE,
-                          NULL);
-
-     ObDereferenceObject(EventPair);
-   }
-
-   return Status;
-}
-
-#ifdef _ENABLE_THRDEVTPAIR
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
-{
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-       
-       PreviousMode = ExGetPreviousMode();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = Thread->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->LowEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->HighEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
-
-       ObDereferenceObject(EventPair);
-
-       return Status;
+    /* Return status */
+    return Status;
 }
 
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when setting the thread
- * eventpair via NtSetInformationThread.
- * @implemented
- */
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
-{
-       PETHREAD Thread;
-       PKEVENT_PAIR EventPair;
-       NTSTATUS Status;
-       KIRQL Irql;
-       
-       PAGED_CODE();
-
-       Thread = PsGetCurrentThread();
-
-       if(!Thread->EventPair)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       EventPair = PsGetCurrentThread()->EventPair;
-
-       if(EventPair)
-               ObReferenceObjectByPointer(EventPair,
-                                          EVENT_PAIR_ALL_ACCESS,
-                                          ExEventPairObjectType,
-                                          UserMode);
-       
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-
-       if(EventPair == NULL)
-               return STATUS_NO_EVENT_PAIR;
-
-       KeSetEvent(&EventPair->HighEvent,
-               EVENT_INCREMENT,
-               TRUE);
-
-       Status = KeWaitForSingleObject(&EventPair->LowEvent,
-                                      WrEventPair,
-                                      UserMode,
-                                      FALSE,
-                                      NULL);
-
-       ObDereferenceObject(EventPair);
-
-       return Status;
-}
-
-/*
- * Author: Skywing (skywing@valhallalegends.com), 09/08/2003
- * Note that the eventpair spinlock must be acquired when waiting on the
- * eventpair via NtSetLow/HighWaitHigh/LowThread.  Additionally, when
- * deleting a thread object, NtpSwapThreadEventPair(Thread, NULL) should
- * be called to release any preexisting eventpair object associated with
- * the thread.  The Microsoft name for this function is not known.
- */
-VOID
-ExpSwapThreadEventPair(
-       IN PETHREAD Thread,
-       IN PKEVENT_PAIR EventPair
-       )
-{
-       PKEVENT_PAIR OriginalEventPair;
-       KIRQL Irql;
-
-       KeAcquireSpinLock(&ExThreadEventPairSpinLock, &Irql);
-
-       OriginalEventPair = Thread->EventPair;
-       Thread->EventPair = EventPair;
-
-       if(OriginalEventPair)
-               ObDereferenceObject(OriginalEventPair);
-
-       KeReleaseSpinLock(&ExThreadEventPairSpinLock, Irql);
-}
-
-#else /* !_ENABLE_THRDEVTPAIR */
-
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetLowWaitHighThread(
-       VOID
-       )
-{
-        DPRINT1("NtSetLowWaitHighThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTSYSAPI
-NTAPI
-NtSetHighWaitLowThread(
-       VOID
-       )
-{
-        DPRINT1("NtSetHighWaitLowThread() not supported anymore (NT4 only)!\n");
-        return STATUS_NOT_IMPLEMENTED;
-}
-
-#endif /* _ENABLE_THRDEVTPAIR */
-
 /* EOF */
index c47ef4f..878be04 100644 (file)
-/* $Id:$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/init.c
  * PURPOSE:         Executive initalization
  * 
- * PROGRAMMERS:     Eric Kohl (ekohl@abo.rhein-zeitung.de)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
+ *                                                    and optimized/cleaned it.
+ *                  Eric Kohl (ekohl@abo.rhein-zeitung.de)
  */
 
 #include <ntoskrnl.h>
+#include <ntos/bootvid.h>
 #define NDEBUG
 #include <internal/debug.h>
 
 /* DATA **********************************************************************/
 
+extern ULONG MmCoreDumpType;
+extern CHAR KiTimerSystemAuditing;
+extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
+extern ADDRESS_RANGE KeMemoryMap[64];
+extern ULONG KeMemoryMapRangeCount;
+extern ULONG_PTR FirstKrnlPhysAddr;
+extern ULONG_PTR LastKrnlPhysAddr;
+extern ULONG_PTR LastKernelAddress;
+extern LOADER_MODULE KeLoaderModules[64];
+
 /* FUNCTIONS ****************************************************************/
 
+static 
+VOID 
+INIT_FUNCTION
+InitSystemSharedUserPage (PCSZ ParameterLine)
+{
+    UNICODE_STRING ArcDeviceName;
+    UNICODE_STRING ArcName;
+    UNICODE_STRING BootPath;
+    UNICODE_STRING DriveDeviceName;
+    UNICODE_STRING DriveName;
+    WCHAR DriveNameBuffer[20];
+    PCHAR ParamBuffer;
+    PWCHAR ArcNameBuffer;
+    PCHAR p;
+    NTSTATUS Status;
+    ULONG Length;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    HANDLE Handle;
+    ULONG i;
+    BOOLEAN BootDriveFound = FALSE;
+
+   /*
+    * NOTE:
+    *   The shared user page has been zeroed-out right after creation.
+    *   There is NO need to do this again.
+    */
+    Ki386SetProcessorFeatures();
+    
+    /* Set the Version Data */
+    SharedUserData->NtProductType = NtProductWinNt;
+    SharedUserData->ProductTypeIsValid = TRUE;
+    SharedUserData->NtMajorVersion = 5;
+    SharedUserData->NtMinorVersion = 0;
+   
+    /*
+     * Retrieve the current dos system path
+     * (e.g.: C:\reactos) from the given arc path
+     * (e.g.: multi(0)disk(0)rdisk(0)partititon(1)\reactos)
+     * Format: "<arc_name>\<path> [options...]"
+     */
+
+    /* Create local parameter line copy */
+    ParamBuffer = ExAllocatePool(PagedPool, 256);
+    strcpy (ParamBuffer, (char *)ParameterLine);
+    DPRINT("%s\n", ParamBuffer);
+
+    /* Cut options off */
+    p = strchr (ParamBuffer, ' ');
+    if (p) *p = 0;
+    DPRINT("%s\n", ParamBuffer);
+
+    /* Extract path */
+    p = strchr (ParamBuffer, '\\');
+    if (p) {
+        
+        DPRINT("Boot path: %s\n", p);
+        RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
+        *p = 0;
+    
+    } else {
+        
+        DPRINT("Boot path: %s\n", "\\");
+        RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
+    }
+    DPRINT("Arc name: %s\n", ParamBuffer);
+   
+    /* Only ARC Name left - Build full ARC Name */
+    ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+    swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
+    RtlInitUnicodeString (&ArcName, ArcNameBuffer);
+    DPRINT("Arc name: %wZ\n", &ArcName);
+
+    /* Free ParamBuffer */
+    ExFreePool (ParamBuffer);
+
+    /* Allocate ARC Device Name string */
+    ArcDeviceName.Length = 0;
+    ArcDeviceName.MaximumLength = 256 * sizeof(WCHAR);
+    ArcDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+
+    /* Open the Symbolic Link */
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &ArcName,
+                               OBJ_OPENLINK,
+                               NULL,
+                               NULL);
+    Status = NtOpenSymbolicLinkObject(&Handle,
+                                      SYMBOLIC_LINK_ALL_ACCESS,
+                                      &ObjectAttributes);
+    
+    /* Free the String */
+    RtlFreeUnicodeString (&ArcName);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    
+    /* Query the Link */
+    Status = NtQuerySymbolicLinkObject(Handle,
+                                       &ArcDeviceName,
+                                       &Length);
+    NtClose (Handle);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        /* Free the Strings */
+        RtlFreeUnicodeString(&BootPath);
+        RtlFreeUnicodeString(&ArcDeviceName);
+        CPRINT("NtQuerySymbolicLinkObject() failed (Status %x)\n", Status);
+        KEBUGCHECK(0);
+    }
+    DPRINT("Length: %lu ArcDeviceName: %wZ\n", Length, &ArcDeviceName);
+
+    /* Allocate Device Name string */
+    DriveDeviceName.Length = 0;
+    DriveDeviceName.MaximumLength = 256 * sizeof(WCHAR);
+    DriveDeviceName.Buffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
+
+    /* Loop Drives */
+    for (i = 0; i < 26; i++)  {
+        
+        /* Setup the String */
+        swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
+        RtlInitUnicodeString(&DriveName,
+                             DriveNameBuffer);
+        
+        /* Open the Symbolic Link */
+        InitializeObjectAttributes(&ObjectAttributes,
+                                   &DriveName,
+                                   OBJ_OPENLINK,
+                                   NULL,
+                                   NULL);
+        Status = NtOpenSymbolicLinkObject(&Handle,
+                                          SYMBOLIC_LINK_ALL_ACCESS,
+                                          &ObjectAttributes);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to open link %wZ\n", &DriveName);
+            continue;
+        }
+        
+        /* Query it */
+        Status = NtQuerySymbolicLinkObject(Handle,
+                                           &DriveDeviceName,
+                                           &Length);
+        
+        /* If it failed, skip to the next drive */
+        if (!NT_SUCCESS(Status)) {
+            DPRINT("Failed to query link %wZ\n", &DriveName);
+            continue;
+        }
+        DPRINT("Opened link: %wZ ==> %wZ\n", &DriveName, &DriveDeviceName);
+
+        /* See if we've found the boot drive */
+        if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) {
+            
+            DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
+            swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath);
+            BootDriveFound = TRUE;
+        }
+
+        /* Close this Link */
+        NtClose (Handle);
+    }
+    
+    /* Free all the Strings we have in memory */
+    RtlFreeUnicodeString (&BootPath);
+    RtlFreeUnicodeString (&DriveDeviceName);
+    RtlFreeUnicodeString (&ArcDeviceName);
+
+    /* Make sure we found the Boot Drive */
+    if (BootDriveFound == FALSE) {
+        
+        DbgPrint("No system drive found!\n");
+        KEBUGCHECK (NO_BOOT_DEVICE);
+    }
+}
+
+inline
+VOID
+STDCALL
+ExecuteRuntimeAsserts(VOID)
+{
+    /*
+     * Fail at runtime if someone has changed various structures without
+     * updating the offsets used for the assembler code.
+     */
+    ASSERT(FIELD_OFFSET(KTHREAD, InitialStack) == KTHREAD_INITIAL_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, Teb) == KTHREAD_TEB);
+    ASSERT(FIELD_OFFSET(KTHREAD, KernelStack) == KTHREAD_KERNEL_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, NpxState) == KTHREAD_NPX_STATE);
+    ASSERT(FIELD_OFFSET(KTHREAD, ServiceTable) == KTHREAD_SERVICE_TABLE);
+    ASSERT(FIELD_OFFSET(KTHREAD, PreviousMode) == KTHREAD_PREVIOUS_MODE);
+    ASSERT(FIELD_OFFSET(KTHREAD, TrapFrame) == KTHREAD_TRAP_FRAME);
+    ASSERT(FIELD_OFFSET(KTHREAD, CallbackStack) == KTHREAD_CALLBACK_STACK);
+    ASSERT(FIELD_OFFSET(KTHREAD, ApcState.Process) == KTHREAD_APCSTATE_PROCESS);
+    ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_BASE);
+    ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
+    ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
+    ASSERT(FIELD_OFFSET(KTRAP_FRAME, Reserved9) == KTRAP_FRAME_RESERVED9);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, regs) == TF_REGS);
+    ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
+    ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
+    ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
+    ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);  
+    ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
+    ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
+    ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
+    ASSERT(FIELD_OFFSET(KTSS, IoMapBase) == KTSS_IOMAPBASE);
+    ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
+}
+
+inline
+VOID
+STDCALL
+ParseAndCacheLoadedModules(PBOOLEAN SetupBoot)
+{
+    ULONG i;
+    PCHAR Name;
+    
+    /* Loop the Module List and get the modules we want */
+    for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
+       
+        /* Get the Name of this Module */
+        if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'))) {
+      
+            /* Save the name */
+            Name = (PCHAR)KeLoaderModules[i].String;
+          
+        } else {
+      
+            /* No name, skip */
+            Name++;
+        }
+      
+        /* Now check for any of the modules we will need later */
+        if (!_stricmp(Name, "ansi.nls")) {
+          
+            CachedModules[AnsiCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "oem.nls")) {
+          
+            CachedModules[OemCodepage] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "casemap.nls")) {
+      
+            CachedModules[UnicodeCasemap] = &KeLoaderModules[i];
+      
+        } else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv")) {
+      
+            CachedModules[SystemRegistry] = &KeLoaderModules[i];
+            *SetupBoot = FALSE;
+      
+        } else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv")) {
+      
+            CachedModules[HardwareRegistry] = &KeLoaderModules[i];
+        }
+    }    
+}
+
+inline
+VOID
+STDCALL
+ParseCommandLine(PULONG MaxMem, PBOOLEAN NoGuiBoot, PBOOLEAN BootLog)
+{
+    PCHAR p1, p2; 
+    
+    p1 = (PCHAR)KeLoaderBlock.CommandLine;
+    while(*p1 && (p2 = strchr(p1, '/'))) {
+        
+        p2++;
+        if (!_strnicmp(p2, "MAXMEM", 6)) {
+            
+            p2 += 6;
+            while (isspace(*p2)) p2++;
+            
+            if (*p2 == '=') {
+                
+                p2++;
+                
+                while(isspace(*p2)) p2++;
+                
+                if (isdigit(*p2)) {
+                    while (isdigit(*p2)) {
+                        *MaxMem = *MaxMem * 10 + *p2 - '0';
+                        p2++;
+                    }                
+                    break;
+                }
+            }
+        } else if (!_strnicmp(p2, "NOGUIBOOT", 9)) {
+            
+            p2 += 9;
+            *NoGuiBoot = TRUE;
+            
+        } else if (!_strnicmp(p2, "CRASHDUMP", 9)) {
+            
+            p2 += 9;
+            if (*p2 == ':') {
+                
+                p2++;
+                if (!_strnicmp(p2, "FULL", 4)) {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
+                    
+                } else {
+                    
+                    MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
+                }
+            }
+        } else if (!_strnicmp(p2, "BOOTLOG", 7)) {
+            
+            p2 += 7;
+            *BootLog = TRUE;
+        }
+        
+        p1 = p2;
+    }
+}
+
+VOID 
+INIT_FUNCTION
+STDCALL
+ExpInitializeExecutive(VOID)
+{
+    CHAR str[50];
+    UNICODE_STRING EventName;
+    HANDLE InitDoneEventHandle;
+    OBJECT_ATTRIBUTES ObjectAttributes;
+    BOOLEAN NoGuiBoot = FALSE;
+    BOOLEAN BootLog = FALSE;
+    ULONG MaxMem = 0;
+    BOOLEAN SetupBoot = TRUE;
+    LARGE_INTEGER Timeout;
+    HANDLE ProcessHandle;
+    HANDLE ThreadHandle;
+    NTSTATUS Status;
+
+    /* Check if the structures match the ASM offset constants */
+    ExecuteRuntimeAsserts();
+    
+    /* Sets up the Text Sections of the Kernel and HAL for debugging */
+    LdrInit1();
+    
+    /* Lower the IRQL to Dispatch Level */
+    KeLowerIrql(DISPATCH_LEVEL);
+    
+    /* Sets up the VDM Data */
+    NtEarlyInitVdm();
+
+    /* Parse Command Line Settings */
+    ParseCommandLine(&MaxMem, &NoGuiBoot, &BootLog);
+    
+    /* Initialize Kernel Memory Address Space */
+    MmInit1(FirstKrnlPhysAddr,
+            LastKrnlPhysAddr,
+            LastKernelAddress,
+            (PADDRESS_RANGE)&KeMemoryMap,
+            KeMemoryMapRangeCount,
+            MaxMem > 8 ? MaxMem : 4096);
+
+    /* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
+    ParseAndCacheLoadedModules(&SetupBoot);
+    
+    /* Initialize the kernel debugger */
+    KdInitSystem (1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+    /* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
+    KeInit2();
+
+    /* Bring back the IRQL to Passive */
+    KeLowerIrql(PASSIVE_LEVEL);
+    
+    /* Load basic Security for other Managers */
+    if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
+
+    /* Create the Basic Object Manager Types to allow new Object Types */
+    ObInit();
+    
+    /* Initialize Lookaside Lists */
+    ExInit2();
+    
+    /* Set up Region Maps, Sections and the Paging File */
+    MmInit2();
+
+    /* Initialize Tokens now that the Object Manager is ready */
+    if (!SeInit2()) KEBUGCHECK(SECURITY1_INITIALIZATION_FAILED);
+
+    /* Set 1 CPU for now, we'll increment this later */
+    KeNumberProcessors = 1;
+    
+    /* Initalize the Process Manager */
+    PiInitProcessManager();
+
+    /* Break into the Debugger if requested */
+    if (KdPollBreakIn()) DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
+
+    /* Initialize all processors */
+    while (!HalAllProcessorsStarted()) {
+        
+        PVOID ProcessorStack;
+
+        /* Set up the Kernel and Process Manager for this CPU */
+        KePrepareForApplicationProcessorInit(KeNumberProcessors);
+        PsPrepareForApplicationProcessorInit(KeNumberProcessors);
+
+        /* Allocate a stack for use when booting the processor */
+        ProcessorStack = Ki386InitialStackArray[((int)KeNumberProcessors)] + MM_STACK_SIZE;
+
+        /* Tell HAL a new CPU is being started */
+        HalStartNextProcessor(0, (ULONG)ProcessorStack - 2*sizeof(FX_SAVE_AREA));
+        KeNumberProcessors++;
+    }
+
+    /* Do Phase 1 HAL Initalization */
+    HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+    
+    /* Initialize Basic System Objects and Worker Threads */
+    ExInit3();
+    
+    /* Initialize the GDB Stub and break */
+    KdInit1();
+  
+    /* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
+    IoInit();
+    
+    /* TBD */
+    PoInit();
+  
+    /* Initialize the Registry (Hives are NOT yet loaded!) */
+    CmInitializeRegistry();
+  
+    /* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
+    MmInit3();
+  
+    /* Initialize Cache Views */
+    CcInit();
+  
+    /* Hook System Interrupt for the Debugger */
+    KdInit2();
+    
+    /* Initialize File Locking */
+    FsRtlpInitFileLockingImplementation();
+
+    /* Report all resources used by hal */
+    HalReportResourceUsage();  
+
+    /* Clear the screen to blue */
+    HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+
+    /* Display version number and copyright/warranty message */
+    HalDisplayString("Starting ReactOS "KERNEL_VERSION_STR" (Build "
+                     KERNEL_VERSION_BUILD_STR")\n");
+    HalDisplayString(RES_STR_LEGAL_COPYRIGHT);
+    HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
+                     "Public License, and you\n");
+    HalDisplayString("are welcome to change it and/or distribute copies of it "
+                     "under certain\n"); 
+    HalDisplayString("conditions. There is absolutely no warranty for "
+                      "ReactOS.\n\n");
+
+    /* Display number of Processors */
+    sprintf(str,
+            "Found %d system processor(s). [%lu MB Memory]\n",
+            KeNumberProcessors,
+            (KeLoaderBlock.MemHigher + 1088)/ 1024);
+    HalDisplayString(str);
+
+    /* Print which Debugger is being used */
+    KdInit3();
+
+    /* Import and create NLS Data and Sections */
+    RtlpInitNls();
+
+    /* Import and Load Registry Hives */
+    CmInitHives(SetupBoot);
+    
+    /* Initialize the time zone information from the registry */
+    ExpInitTimeZoneInfo();
+   
+  /* Enter the kernel debugger before starting up the boot drivers */
+#ifdef KDBG
+    KdbEnter();
+#endif /* KDBG */
+
+    /* Setup Drivers and Root Device Node */
+    IoInit2(BootLog);
+
+    /* Display the boot screen image if not disabled */
+    if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
+    
+    /* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
+    IoInit3();
+       
+    /* Initialize the Default Locale */
+    PiInitDefaultLocale();
+    
+    /* Initialize shared user page. Set dos system path, dos device map, etc. */
+    InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
+
+    /* Create 'ReactOSInitDone' event */
+    RtlInitUnicodeString(&EventName, L"\\ReactOSInitDone");
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &EventName,
+                               0,
+                               NULL,
+                               NULL);
+    Status = ZwCreateEvent(&InitDoneEventHandle,
+                           EVENT_ALL_ACCESS,
+                           &ObjectAttributes,
+                           SynchronizationEvent,
+                           FALSE);
+    
+    /* Check for Success */
+    if (!NT_SUCCESS(Status)) {
+        
+        DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
+        InitDoneEventHandle = INVALID_HANDLE_VALUE;
+    }
+
+    /* Launch initial process */
+    Status = LdrLoadInitialProcess(&ProcessHandle,
+                                   &ThreadHandle);
+    
+    /* Check for success, Bugcheck if we failed */
+    if (!NT_SUCCESS(Status)) {
+        
+        KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
+    }
+
+    /* Wait on the Completion Event */
+    if (InitDoneEventHandle != INVALID_HANDLE_VALUE) {
+
+        HANDLE Handles[2]; /* Init event, Initial process */
+
+        /* Setup the Handles to wait on */
+        Handles[0] = InitDoneEventHandle;
+        Handles[1] = ProcessHandle;
+
+        /* Wait for the system to be initialized */
+        Timeout.QuadPart = (LONGLONG)-1200000000;  /* 120 second timeout */
+        Status = ZwWaitForMultipleObjects(2,
+                                          Handles,
+                                          WaitAny,
+                                          FALSE,
+                                          &Timeout);
+        if (!NT_SUCCESS(Status)) {
+            
+            DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
+        
+        } else if (Status == STATUS_TIMEOUT) {
+            
+            DPRINT1("WARNING: System not initialized after 120 seconds.\n");
+        
+        } else if (Status == STATUS_WAIT_0 + 1) {
+            
+            /* Crash the system if the initial process was terminated. */
+            KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
+        }
+
+        /* Disable the Boot Logo */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Signal the Event and close the handle */
+        ZwSetEvent(InitDoneEventHandle, NULL);
+        ZwClose(InitDoneEventHandle);
+    
+    } else {
+        
+        /* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
+        if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
+
+        /* Crash the system if the initial process terminates within 5 seconds. */
+        Timeout.QuadPart = (LONGLONG)-50000000;  /* 5 second timeout */
+        Status = ZwWaitForSingleObject(ProcessHandle,
+                                       FALSE,
+                                       &Timeout);
+        
+        /* Check for timeout, crash if the initial process didn't initalize */
+        if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
+    }
+    
+    /* Enable the Clock, close remaining handles */
+    KiTimerSystemAuditing = 1;
+    ZwClose(ThreadHandle);
+    ZwClose(ProcessHandle);
+}
+
 VOID INIT_FUNCTION
 ExInit2(VOID)
 {
@@ -25,7 +634,7 @@ ExInit2(VOID)
 VOID INIT_FUNCTION
 ExInit3 (VOID)
 {
-  ExInitializeWorkerThreads();
+  ExpInitializeWorkerThreads();
   ExpInitializeEventImplementation();
   ExpInitializeEventPairImplementation();
   ExpInitializeMutantImplementation();
@@ -35,28 +644,7 @@ ExInit3 (VOID)
   ExpInitializeProfileImplementation();
   ExpWin32kInit();
   ExpInitUuids();
-}
-
-
-/*
- * @implemented
- */
-BOOLEAN STDCALL
-ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
-{
-  if (ProcessorFeature >= PROCESSOR_FEATURE_MAX)
-    return(FALSE);
-
-  return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
-}
-
-
-VOID STDCALL
-ExPostSystemEvent (ULONG       Unknown1,
-                  ULONG        Unknown2,
-                  ULONG        Unknown3)
-{
-  /* doesn't do anything */
+  ExpInitializeCallbacks();
 }
 
 /* EOF */
index f6a2d4b..8c125e2 100644 (file)
@@ -1,11 +1,13 @@
-/* $Id:$
- * 
+/* 
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/mutant.c
- * PURPOSE:         Synchronization primitives
+ * PURPOSE:         Executive Management of Mutants
  * 
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
+ * PROGRAMMERS:     
+ *                  Alex Ionescu - Fix tab/space mismatching, tiny fixes to query function and
+ *                                 add more debug output.
+ *                  David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 POBJECT_TYPE ExMutantObjectType = NULL;
 
 static GENERIC_MAPPING ExpMutantMapping = {
-       STANDARD_RIGHTS_READ | SYNCHRONIZE | MUTANT_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SYNCHRONIZE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
-       MUTANT_ALL_ACCESS};
+    STANDARD_RIGHTS_READ    | SYNCHRONIZE | MUTANT_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | SYNCHRONIZE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | MUTANT_QUERY_STATE,
+    MUTANT_ALL_ACCESS};
 
-static const INFORMATION_CLASS_INFO ExMutantInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* MutantBasicInformation */
+static const INFORMATION_CLASS_INFO ExMutantInfoClass[] = {
+    
+     /* MutantBasicInformation */
+    ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
 };
 
 /* FUNCTIONS *****************************************************************/
 
-
-NTSTATUS STDCALL
-ExpCreateMutant(PVOID ObjectBody,
-               PVOID Parent,
-               PWSTR RemainingPath,
-               POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateMutant(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-
-VOID STDCALL
+VOID 
+STDCALL
 ExpDeleteMutant(PVOID ObjectBody)
 {
-  DPRINT("NtpDeleteMutant(ObjectBody %x)\n", ObjectBody);
 
-  KeReleaseMutant((PKMUTANT)ObjectBody,
-                 MUTANT_INCREMENT,
-                 TRUE,
-                 FALSE);
-}
+    DPRINT("ExpDeleteMutant(ObjectBody %x)\n", ObjectBody);
 
+    /* Make sure to release the Mutant */
+    KeReleaseMutant((PKMUTANT)ObjectBody,
+                    MUTANT_INCREMENT,
+                    TRUE,
+                    FALSE);
+}
 
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeMutantImplementation(VOID)
 {
-  ExMutantObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
-  RtlpCreateUnicodeString(&ExMutantObjectType->TypeName, L"Mutant", NonPagedPool);
-
-  ExMutantObjectType->Tag = TAG('M', 'T', 'N', 'T');
-  ExMutantObjectType->PeakObjects = 0;
-  ExMutantObjectType->PeakHandles = 0;
-  ExMutantObjectType->TotalObjects = 0;
-  ExMutantObjectType->TotalHandles = 0;
-  ExMutantObjectType->PagedPoolCharge = 0;
-  ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
-  ExMutantObjectType->Mapping = &ExpMutantMapping;
-  ExMutantObjectType->Dump = NULL;
-  ExMutantObjectType->Open = NULL;
-  ExMutantObjectType->Close = NULL;
-  ExMutantObjectType->Delete = ExpDeleteMutant;
-  ExMutantObjectType->Parse = NULL;
-  ExMutantObjectType->Security = NULL;
-  ExMutantObjectType->QueryName = NULL;
-  ExMutantObjectType->OkayToClose = NULL;
-  ExMutantObjectType->Create = ExpCreateMutant;
-  ExMutantObjectType->DuplicationNotify = NULL;
-
-  ObpCreateTypeObject(ExMutantObjectType);
-}
 
+    /* Allocate the Object Type */
+    ExMutantObjectType = ExAllocatePoolWithTag(NonPagedPool, sizeof(OBJECT_TYPE), TAG('M', 't', 'n', 't'));
+
+    /* Create the Object Type */
+    RtlpCreateUnicodeString(&ExMutantObjectType->TypeName, L"Mutant", NonPagedPool);
+    ExMutantObjectType->Tag = TAG('M', 't', 'n', 't');
+    ExMutantObjectType->PeakObjects = 0;
+    ExMutantObjectType->PeakHandles = 0;
+    ExMutantObjectType->TotalObjects = 0;
+    ExMutantObjectType->TotalHandles = 0;
+    ExMutantObjectType->PagedPoolCharge = 0;
+    ExMutantObjectType->NonpagedPoolCharge = sizeof(KMUTANT);
+    ExMutantObjectType->Mapping = &ExpMutantMapping;
+    ExMutantObjectType->Dump = NULL;
+    ExMutantObjectType->Open = NULL;
+    ExMutantObjectType->Close = NULL;
+    ExMutantObjectType->Delete = ExpDeleteMutant;
+    ExMutantObjectType->Parse = NULL;
+    ExMutantObjectType->Security = NULL;
+    ExMutantObjectType->QueryName = NULL;
+    ExMutantObjectType->OkayToClose = NULL;
+    ExMutantObjectType->Create = NULL;
+    ExMutantObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExMutantObjectType);
+}
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateMutant(OUT PHANDLE MutantHandle,
-              IN ACCESS_MASK DesiredAccess,
-              IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-              IN BOOLEAN InitialOwner)
+               IN ACCESS_MASK DesiredAccess,
+               IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+               IN BOOLEAN InitialOwner)
 {
-  KPROCESSOR_MODE PreviousMode;
-  HANDLE hMutant;
-  PKMUTEX Mutant;
-  NTSTATUS Status = STATUS_SUCCESS;
-  
-  PAGED_CODE();
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    HANDLE hMutant;
+    PKMUTANT Mutant;
+    NTSTATUS Status = STATUS_SUCCESS;
+    
+    DPRINT("NtCreateMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
   
-  PreviousMode = ExGetPreviousMode();
-
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(MutantHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(MutantHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
     }
-    _SEH_END;
-     
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  Status = ObCreateObject(PreviousMode,
-                         ExMutantObjectType,
-                         ObjectAttributes,
-                         PreviousMode,
-                         NULL,
-                         sizeof(KMUTANT),
-                         0,
-                         0,
-                         (PVOID*)&Mutant);
-  if(NT_SUCCESS(Status))
-  {
-    KeInitializeMutant(Mutant,
-                      InitialOwner);
-
-    Status = ObInsertObject((PVOID)Mutant,
-                           NULL,
-                           DesiredAccess,
-                           0,
-                           NULL,
-                           &hMutant);
-    ObDereferenceObject(Mutant);
     
-    if(NT_SUCCESS(Status))
-    {
-      _SEH_TRY
-      {
-        *MutantHandle = hMutant;
-      }
-      _SEH_HANDLE
-      {
-        Status = _SEH_GetExceptionCode();
-      }
-      _SEH_END;
+    /* Create the Mutant Object*/
+    Status = ObCreateObject(PreviousMode,
+                            ExMutantObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KMUTANT),
+                            0,
+                            0,
+                            (PVOID*)&Mutant);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Initalize the Kernel Mutant */
+        DPRINT("Initializing the Mutant\n");
+        KeInitializeMutant(Mutant, InitialOwner);
+
+        /* Insert the Object */
+        Status = ObInsertObject((PVOID)Mutant,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                &hMutant);
+        ObDereferenceObject(Mutant);
+    
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *MutantHandle = hMutant;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
     }
-  }
 
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenMutant(OUT PHANDLE MutantHandle,
-            IN ACCESS_MASK DesiredAccess,
-            IN POBJECT_ATTRIBUTES ObjectAttributes)
+             IN ACCESS_MASK DesiredAccess,
+             IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-  HANDLE hMutant;
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hMutant;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
   
-  PAGED_CODE();
-
-  DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
-
-  PreviousMode = ExGetPreviousMode();
-
-  if(PreviousMode == UserMode)
-  {
-    _SEH_TRY
-    {
-      ProbeForWrite(MutantHandle,
-                    sizeof(HANDLE),
-                    sizeof(ULONG));
-    }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
-    }
-    _SEH_END;
+   PAGED_CODE();
 
-    if(!NT_SUCCESS(Status))
-    {
-      return Status;
-    }
-  }
-
-  Status = ObOpenObjectByName(ObjectAttributes,
-                             ExMutantObjectType,
-                             NULL,
-                             PreviousMode,
-                             DesiredAccess,
-                             NULL,
-                             &hMutant);
-
-  if(NT_SUCCESS(Status))
-  {
-    _SEH_TRY
-    {
-      *MutantHandle = hMutant;
+    DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(MutantHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
     }
-    _SEH_HANDLE
-    {
-      Status = _SEH_GetExceptionCode();
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExMutantObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hMutant);
+
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *MutantHandle = hMutant;
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
     }
-    _SEH_END;
-  }
 
-  return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtQueryMutant(IN HANDLE MutantHandle,
-             IN MUTANT_INFORMATION_CLASS MutantInformationClass,
-             OUT PVOID MutantInformation,
-             IN ULONG MutantInformationLength,
-             OUT PULONG ResultLength  OPTIONAL)
+              IN MUTANT_INFORMATION_CLASS MutantInformationClass,
+              OUT PVOID MutantInformation,
+              IN ULONG MutantInformationLength,
+              OUT PULONG ResultLength  OPTIONAL)
 {
-   PKMUTANT Mutant;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKMUTANT Mutant;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
+    PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
+    
+    /* Check buffers and parameters */
+    DefaultQueryInfoBufferCheck(MutantInformationClass,
+                                ExMutantInfoClass,
+                                MutantInformation,
+                                MutantInformationLength,
+                                ResultLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
    
    PAGED_CODE();
 
-   PreviousMode = ExGetPreviousMode();
-
-   DefaultQueryInfoBufferCheck(MutantInformationClass,
-                               ExMutantInfoClass,
-                               MutantInformation,
-                               MutantInformationLength,
-                               ResultLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQueryMutant() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(MutantHandle,
-                                     MUTANT_QUERY_STATE,
-                                     ExMutantObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Mutant,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(MutantInformationClass)
-     {
-       case MutantBasicInformation:
-       {
-         PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
-
-         _SEH_TRY
-         {
-           BasicInfo->Count = KeReadStateMutant(Mutant);
-           BasicInfo->Owned = (Mutant->OwnerThread != NULL);
-           BasicInfo->Abandoned = Mutant->Abandoned;
-
-           if(ResultLength != NULL)
-           {
-             *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Mutant);
-   }
-
-   return Status;
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(MutantHandle,
+                                       MUTANT_QUERY_STATE,
+                                       ExMutantObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Mutant,
+                                       NULL);
+    /* Check for Status */
+    if(NT_SUCCESS(Status)) {
+
+         _SEH_TRY {
+             
+            /* Fill out the Basic Information Requested */
+            DPRINT1("Returning Mutant Information\n");
+            BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
+            BasicInfo->OwnedByCaller = (Mutant->OwnerThread == KeGetCurrentThread());
+            BasicInfo->AbandonedState = Mutant->Abandoned;
+
+            /* Return the Result Length if requested */
+           if(ResultLength) *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        /* Release the Object */
+        ObDereferenceObject(Mutant);
+    }
+    
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtReleaseMutant(IN HANDLE MutantHandle,
-               IN PLONG PreviousCount  OPTIONAL)
+                IN PLONG PreviousCount  OPTIONAL)
 {
-   PKMUTANT Mutant;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKMUTANT Mutant;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
-         MutantHandle, PreviousCount);
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousCount != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousCount,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();
+
+    DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n", 
+            MutantHandle, 
+            PreviousCount);
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode && PreviousCount) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousCount,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
      
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObReferenceObjectByHandle(MutantHandle,
-                                     MUTANT_QUERY_STATE,
-                                     ExMutantObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Mutant,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     LONG Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, 0, FALSE);
-     ObDereferenceObject(Mutant);
-
-     if(PreviousCount != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousCount = Prev;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
-
-   return Status;
+        if(!NT_SUCCESS(Status)) return Status;
+    } 
+
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(MutantHandle,
+                                       MUTANT_QUERY_STATE,
+                                       ExMutantObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Mutant,
+                                       NULL);
+    
+    /* Check for Success and release if such */
+    if(NT_SUCCESS(Status)) {
+        
+        /* Save the Old State */
+        DPRINT1("Releasing Mutant\n");
+        LONG Prev = KeReleaseMutant(Mutant, MUTANT_INCREMENT, FALSE, FALSE);
+        ObDereferenceObject(Mutant);
+
+        /* Return it */        
+        if(PreviousCount) {
+            
+            _SEH_TRY {
+                
+                *PreviousCount = Prev;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
+    }
+
+    /* Return Status */
+    return Status;
 }
 
 /* EOF */
index baf8a38..580d9bb 100644 (file)
@@ -1,11 +1,10 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/rundown.c
  * PURPOSE:         Rundown Protection Functions
  * 
- * PROGRAMMERS:     No programmer listed.
+ * PROGRAMMERS:     Alex Ionescu & Thomas Weidenmueller - Implementation
  */
 
 /* INCLUDES *****************************************************************/
index 274ce8a..ef9a41c 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id: ntsem.c 12779 2005-01-04 04:45:00Z gdalsnes $
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ex/sem.c
  * PURPOSE:         Synchronization primitives
  * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes.
+ *                  David Welch (welch@mcmail.com)
  */
 
 /* INCLUDES *****************************************************************/
 POBJECT_TYPE ExSemaphoreObjectType;
 
 static GENERIC_MAPPING ExSemaphoreMapping = {
-       STANDARD_RIGHTS_READ | SEMAPHORE_QUERY_STATE,
-       STANDARD_RIGHTS_WRITE | SEMAPHORE_MODIFY_STATE,
-       STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
-       SEMAPHORE_ALL_ACCESS};
-
-static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] =
-{
-  ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ), /* SemaphoreBasicInformation */
+    STANDARD_RIGHTS_READ    | SEMAPHORE_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | SEMAPHORE_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | SEMAPHORE_QUERY_STATE,
+    SEMAPHORE_ALL_ACCESS};
+
+static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
+    
+     /* SemaphoreBasicInformation */
+    ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
 };
 
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS STDCALL
-ExpCreateSemaphore(PVOID ObjectBody,
-                  PVOID Parent,
-                  PWSTR RemainingPath,
-                  POBJECT_ATTRIBUTES ObjectAttributes)
-{
-  DPRINT("NtpCreateSemaphore(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-        ObjectBody, Parent, RemainingPath);
-
-  if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-    {
-      return(STATUS_UNSUCCESSFUL);
-    }
-
-  return(STATUS_SUCCESS);
-}
-
-VOID INIT_FUNCTION
+VOID 
+INIT_FUNCTION
 ExpInitializeSemaphoreImplementation(VOID)
 {
-   ExSemaphoreObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExSemaphoreObjectType->TypeName, L"Semaphore", NonPagedPool);
-   
-   ExSemaphoreObjectType->Tag = TAG('S', 'E', 'M', 'T');
-   ExSemaphoreObjectType->PeakObjects = 0;
-   ExSemaphoreObjectType->PeakHandles = 0;
-   ExSemaphoreObjectType->TotalObjects = 0;
-   ExSemaphoreObjectType->TotalHandles = 0;
-   ExSemaphoreObjectType->PagedPoolCharge = 0;
-   ExSemaphoreObjectType->NonpagedPoolCharge = sizeof(KSEMAPHORE);
-   ExSemaphoreObjectType->Mapping = &ExSemaphoreMapping;
-   ExSemaphoreObjectType->Dump = NULL;
-   ExSemaphoreObjectType->Open = NULL;
-   ExSemaphoreObjectType->Close = NULL;
-   ExSemaphoreObjectType->Delete = NULL;
-   ExSemaphoreObjectType->Parse = NULL;
-   ExSemaphoreObjectType->Security = NULL;
-   ExSemaphoreObjectType->QueryName = NULL;
-   ExSemaphoreObjectType->OkayToClose = NULL;
-   ExSemaphoreObjectType->Create = ExpCreateSemaphore;
-   ExSemaphoreObjectType->DuplicationNotify = NULL;
-
-   ObpCreateTypeObject(ExSemaphoreObjectType);
+    
+    /* Create the Semaphore Object */
+    ExSemaphoreObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+    RtlpCreateUnicodeString(&ExSemaphoreObjectType->TypeName, L"Semaphore", NonPagedPool);
+    ExSemaphoreObjectType->Tag = TAG('S', 'E', 'M', 'T');
+    ExSemaphoreObjectType->PeakObjects = 0;
+    ExSemaphoreObjectType->PeakHandles = 0;
+    ExSemaphoreObjectType->TotalObjects = 0;
+    ExSemaphoreObjectType->TotalHandles = 0;
+    ExSemaphoreObjectType->PagedPoolCharge = 0;
+    ExSemaphoreObjectType->NonpagedPoolCharge = sizeof(KSEMAPHORE);
+    ExSemaphoreObjectType->Mapping = &ExSemaphoreMapping;
+    ExSemaphoreObjectType->Dump = NULL;
+    ExSemaphoreObjectType->Open = NULL;
+    ExSemaphoreObjectType->Close = NULL;
+    ExSemaphoreObjectType->Delete = NULL;
+    ExSemaphoreObjectType->Parse = NULL;
+    ExSemaphoreObjectType->Security = NULL;
+    ExSemaphoreObjectType->QueryName = NULL;
+    ExSemaphoreObjectType->OkayToClose = NULL;
+    ExSemaphoreObjectType->Create = NULL;
+    ExSemaphoreObjectType->DuplicationNotify = NULL;
+    ObpCreateTypeObject(ExSemaphoreObjectType);
 }
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
-                 IN ACCESS_MASK DesiredAccess,
-                 IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
-                 IN LONG InitialCount,
-                 IN LONG MaximumCount)
+                  IN ACCESS_MASK DesiredAccess,
+                  IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
+                  IN LONG InitialCount,
+                  IN LONG MaximumCount)
 {
-   PKSEMAPHORE Semaphore;
-   HANDLE hSemaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKSEMAPHORE Semaphore;
+    HANDLE hSemaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(SemaphoreHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-
-   Status = ObCreateObject(PreviousMode,
-                          ExSemaphoreObjectType,
-                          ObjectAttributes,
-                          PreviousMode,
-                          NULL,
-                          sizeof(KSEMAPHORE),
-                          0,
-                          0,
-                          (PVOID*)&Semaphore);
-   if (NT_SUCCESS(Status))
-   {
-     KeInitializeSemaphore(Semaphore,
-                          InitialCount,
-                          MaximumCount);
-
-     Status = ObInsertObject ((PVOID)Semaphore,
-                             NULL,
-                             DesiredAccess,
-                             0,
-                             NULL,
-                             &hSemaphore);
-
-     ObDereferenceObject(Semaphore);
+    PAGED_CODE();
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(SemaphoreHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Make sure the counts make sense */
+    if (!MaximumCount || !InitialCount || InitialCount > MaximumCount) {
+    
+        DPRINT("Invalid Count Data!\n");
+        return STATUS_INVALID_PARAMETER;
+    }
 
-     if(NT_SUCCESS(Status))
-     {
-       _SEH_TRY
-       {
-         *SemaphoreHandle = hSemaphore;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+    /* Create the Semaphore Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExSemaphoreObjectType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KSEMAPHORE),
+                            0,
+                            0,
+                            (PVOID*)&Semaphore);
+    
+    /* Check for Success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Initialize it */
+        KeInitializeSemaphore(Semaphore,
+                              InitialCount,
+                              MaximumCount);
+        
+        /* Insert it into the Object Tree */
+        Status = ObInsertObject((PVOID)Semaphore,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                &hSemaphore);
+        ObDereferenceObject(Semaphore);
+
+        /* Check for success and return handle */
+        if(NT_SUCCESS(Status)) {
+            
+            _SEH_TRY {
+                
+                *SemaphoreHandle = hSemaphore;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+                
+            } _SEH_END;
+        }
+    }
 
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
 
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
-               IN ACCESS_MASK  DesiredAccess,
-               IN POBJECT_ATTRIBUTES ObjectAttributes)
+                IN ACCESS_MASK DesiredAccess,
+                IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   HANDLE hSemaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    HANDLE hSemaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status = STATUS_SUCCESS;
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   if(PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(SemaphoreHandle,
-                     sizeof(HANDLE),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
+    PAGED_CODE();
+
+    /* Check Output Safety */
+    if(PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(SemaphoreHandle,
+                          sizeof(HANDLE),
+                          sizeof(ULONG));
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+        
+        } _SEH_END;
+     
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExSemaphoreObjectType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                &hSemaphore);
+    
+    /* Check for success and return handle */
+    if(NT_SUCCESS(Status)) {
+            
+        _SEH_TRY {
+            
+            *SemaphoreHandle = hSemaphore;
+        
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+    }
 
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
-   
-   Status = ObOpenObjectByName(ObjectAttributes,
-                              ExSemaphoreObjectType,
-                              NULL,
-                              PreviousMode,
-                              DesiredAccess,
-                              NULL,
-                              &hSemaphore);
-   if(NT_SUCCESS(Status))
-   {
-     _SEH_TRY
-     {
-       *SemaphoreHandle = hSemaphore;
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-   }
-   
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS
+STDCALL
 NtQuerySemaphore(IN HANDLE SemaphoreHandle,
-                IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
-                OUT PVOID SemaphoreInformation,
-                IN ULONG SemaphoreInformationLength,
-                OUT PULONG ReturnLength  OPTIONAL)
+                 IN SEMAPHORE_INFORMATION_CLASS SemaphoreInformationClass,
+                 OUT PVOID SemaphoreInformation,
+                 IN ULONG SemaphoreInformationLength,
+                 OUT PULONG ReturnLength  OPTIONAL)
 {
-   PKSEMAPHORE Semaphore;
-   KPROCESSOR_MODE PreviousMode;
-   NTSTATUS Status = STATUS_SUCCESS;
+    PKSEMAPHORE Semaphore;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+               
+    /* Check buffers and class validity */
+    DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
+                                ExSemaphoreInfoClass,
+                                SemaphoreInformation,
+                                SemaphoreInformationLength,
+                                ReturnLength,
+                                PreviousMode,
+                                &Status);
+    if(!NT_SUCCESS(Status)) {
+        
+        /* Invalid buffers */
+        DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
+        return Status;
+    }
    
-   PAGED_CODE();
-
-   PreviousMode = ExGetPreviousMode();
-
-   DefaultQueryInfoBufferCheck(SemaphoreInformationClass,
-                               ExSemaphoreInfoClass,
-                               SemaphoreInformation,
-                               SemaphoreInformationLength,
-                               ReturnLength,
-                               PreviousMode,
-                               &Status);
-   if(!NT_SUCCESS(Status))
-   {
-     DPRINT1("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
-     return Status;
-   }
-
-   Status = ObReferenceObjectByHandle(SemaphoreHandle,
-                                     SEMAPHORE_QUERY_STATE,
-                                     ExSemaphoreObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Semaphore,
-                                     NULL);
-   if(NT_SUCCESS(Status))
-   {
-     switch(SemaphoreInformationClass)
-     {
-       case SemaphoreBasicInformation:
-       {
-         PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
-
-         _SEH_TRY
-         {
-           BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
-           BasicInfo->MaximumCount = Semaphore->Limit;
-
-           if(ReturnLength != NULL)
-           {
-             *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
-           }
-         }
-         _SEH_HANDLE
-         {
-           Status = _SEH_GetExceptionCode();
-         }
-         _SEH_END;
-         break;
-       }
-
-       default:
-         Status = STATUS_NOT_IMPLEMENTED;
-         break;
-     }
-
-     ObDereferenceObject(Semaphore);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(SemaphoreHandle,
+                                       SEMAPHORE_QUERY_STATE,
+                                       ExSemaphoreObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Semaphore,
+                                       NULL);
+    
+    /* Check for success */
+    if(NT_SUCCESS(Status)) {
+   
+        _SEH_TRY {
+            
+             /* Return the basic information */             
+            BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
+            BasicInfo->MaximumCount = Semaphore->Limit;
+
+            /* Return length */
+            if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
+            
+        } _SEH_HANDLE {
+            
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+     
+        /* Dereference the Object */
+        ObDereferenceObject(Semaphore);
    }
 
+   /* Return status */
    return Status;
 }
 
-
 /*
  * @implemented
  */
-NTSTATUS STDCALL
+NTSTATUS 
+STDCALL
 NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
-                  IN LONG ReleaseCount,
-                  OUT PLONG PreviousCount  OPTIONAL)
+                   IN LONG ReleaseCount,
+                   OUT PLONG PreviousCount  OPTIONAL)
 {
-   KPROCESSOR_MODE PreviousMode;
-   PKSEMAPHORE Semaphore;
-   NTSTATUS Status = STATUS_SUCCESS;
-   
-   PAGED_CODE();
-   
-   PreviousMode = ExGetPreviousMode();
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();;
+    PKSEMAPHORE Semaphore;
+    NTSTATUS Status = STATUS_SUCCESS; 
    
-   if(PreviousCount != NULL && PreviousMode == UserMode)
-   {
-     _SEH_TRY
-     {
-       ProbeForWrite(PreviousCount,
-                     sizeof(LONG),
-                     sizeof(ULONG));
-     }
-     _SEH_HANDLE
-     {
-       Status = _SEH_GetExceptionCode();
-     }
-     _SEH_END;
-
-     if(!NT_SUCCESS(Status))
-     {
-       return Status;
-     }
-   }
+    PAGED_CODE();
+
+    /* Check buffer validity */
+    if(PreviousCount != NULL && PreviousMode == UserMode) {
+        
+        _SEH_TRY {
+            
+            ProbeForWrite(PreviousCount,
+                          sizeof(LONG),
+                          sizeof(ULONG));
+         } _SEH_HANDLE {
+             
+            Status = _SEH_GetExceptionCode();
+            
+        } _SEH_END;
+
+        if(!NT_SUCCESS(Status)) return Status;
+    }
+    
+    /* Make sure count makes sense */
+    if (!ReleaseCount) {
+    
+        DPRINT("Invalid Release Count\n");
+        return STATUS_INVALID_PARAMETER;
+    }
    
-   Status = ObReferenceObjectByHandle(SemaphoreHandle,
-                                     SEMAPHORE_MODIFY_STATE,
-                                     ExSemaphoreObjectType,
-                                     PreviousMode,
-                                     (PVOID*)&Semaphore,
-                                     NULL);
-   if (NT_SUCCESS(Status))
-   {
-     LONG PrevCount = KeReleaseSemaphore(Semaphore,
-                                         IO_NO_INCREMENT,
-                                         ReleaseCount,
-                                         FALSE);
-     ObDereferenceObject(Semaphore);
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(SemaphoreHandle,
+                                       SEMAPHORE_MODIFY_STATE,
+                                       ExSemaphoreObjectType,
+                                       PreviousMode,
+                                       (PVOID*)&Semaphore,
+                                       NULL);
+    
+    /* Check for success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Release the semaphore */
+        LONG PrevCount = KeReleaseSemaphore(Semaphore,
+                                            IO_NO_INCREMENT,
+                                            ReleaseCount,
+                                            FALSE);
+        ObDereferenceObject(Semaphore);
      
-     if(PreviousCount != NULL)
-     {
-       _SEH_TRY
-       {
-         *PreviousCount = PrevCount;
-       }
-       _SEH_HANDLE
-       {
-         Status = _SEH_GetExceptionCode();
-       }
-       _SEH_END;
-     }
-   }
+        /* Return it */        
+        if(PreviousCount) {
+            
+            _SEH_TRY {
+                
+                *PreviousCount = PrevCount;
+            
+            } _SEH_HANDLE {
+                
+                Status = _SEH_GetExceptionCode();
+            
+            } _SEH_END;
+        }
+    }
 
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
 /* EOF */
index 2efe729..352e3a8 100644 (file)
@@ -86,6 +86,20 @@ ExGetCurrentProcessorCounts (
        ProcessorNumber = &ProcNumber;
 }
 
+/*
+ * @implemented
+ */
+BOOLEAN 
+STDCALL
+ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
+{
+    /* Quick check to see if it exists at all */
+    if (ProcessorFeature >= PROCESSOR_FEATURE_MAX) return(FALSE);
+
+    /* Return our support for it */
+    return(SharedUserData->ProcessorFeatures[ProcessorFeature]);
+}
+
 NTSTATUS STDCALL
 NtQuerySystemEnvironmentValue (IN      PUNICODE_STRING VariableName,
                               OUT      PWCHAR          ValueBuffer,
index fa0a254..c2ecdd5 100644 (file)
@@ -473,7 +473,7 @@ NtQueryTimer(IN HANDLE TimerHandle,
     PreviousMode = ExGetPreviousMode();
 
     DPRINT("NtQueryTimer(TimerHandle: %x, Class: %d)\n", TimerHandle, TimerInformationClass);
-    
+
     /* Check Validity */
     DefaultQueryInfoBufferCheck(TimerInformationClass,
                                 ExTimerInfoClass,
@@ -498,27 +498,23 @@ NtQueryTimer(IN HANDLE TimerHandle,
     
     /* Check for Success */
     if(NT_SUCCESS(Status)) {
-        
-        switch(TimerInformationClass) {
-           case TimerBasicInformation: {
-              /* Return the Basic Information */
-               _SEH_TRY {
 
-                  /* FIXME: Interrupt correction based on Interrupt Time */
-                  DPRINT("Returning Information for Timer: %x. Time Remaining: %d\n", Timer, Timer->KeTimer.DueTime.QuadPart);
-                  BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart;
-                  BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
+        /* Return the Basic Information */
+        _SEH_TRY {
+
+            /* FIXME: Interrupt correction based on Interrupt Time */
+            DPRINT("Returning Information for Timer: %x. Time Remaining: %d\n", Timer, Timer->KeTimer.DueTime.QuadPart);
+            BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart;
+            BasicInfo->SignalState = KeReadStateTimer(&Timer->KeTimer);
 
-                  if(ReturnLength != NULL) {
-                      *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
-                  }
+            if(ReturnLength != NULL) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
 
-              } _SEH_HANDLE {
+        } _SEH_HANDLE {
+            
                   Status = _SEH_GetExceptionCode();
-              } _SEH_END;
-           }
-        }
+        } _SEH_END;
         
+        /* Dereference Object */
         ObDereferenceObject(Timer);
     }
    
index 8d7bac1..0a5f82f 100644 (file)
@@ -1,11 +1,11 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:          See COPYING in the top level directory
  * PROJECT:            ReactOS kernel
  * FILE:               ntoskrnl/ex/work.c
  * PURPOSE:            Manage system work queues
  * 
- * PROGRAMMERS:        David Welch (welch@mcmail.com)
+ * PROGRAMMERS:        Alex Ionescu - Used correct work queue array and added some fixes and checks.
+ *                     Gunnar Dalsnes - Implemented
  */
 
 /* INCLUDES ******************************************************************/
 /*
  * PURPOSE: Queue of items waiting to be processed at normal priority
  */
-KQUEUE EiNormalWorkQueue;
-
-KQUEUE EiCriticalWorkQueue;
-
-KQUEUE EiHyperCriticalWorkQueue;
+EX_WORK_QUEUE ExWorkerQueue[MaximumWorkQueue];
 
 /* FUNCTIONS ****************************************************************/
 
-//static NTSTATUS STDCALL
-static VOID STDCALL
-ExWorkerThreadEntryPoint(IN PVOID context)
 /*
  * FUNCTION: Entry point for a worker thread
  * ARGUMENTS:
@@ -44,138 +37,138 @@ ExWorkerThreadEntryPoint(IN PVOID context)
  * NOTE: To kill a worker thread you must queue an item whose callback
  * calls PsTerminateSystemThread
  */
+static
+VOID 
+STDCALL
+ExpWorkerThreadEntryPoint(IN PVOID Context)
 {
-
-   PWORK_QUEUE_ITEM item;
-   PLIST_ENTRY current;
+    PWORK_QUEUE_ITEM WorkItem;
+    PLIST_ENTRY QueueEntry;
+    WORK_QUEUE_TYPE WorkQueueType;
+    PEX_WORK_QUEUE WorkQueue;
    
-   while (TRUE) 
-   {
-      current = KeRemoveQueue( (PKQUEUE)context, KernelMode, NULL );
-      
-      /* can't happend since we do a KernelMode wait (and we're a system thread) */
-      ASSERT((NTSTATUS)current != STATUS_USER_APC);
-      
-      /* this should never happend either, since we wait with NULL timeout,
-       * but there's a slight possibility that STATUS_TIMEOUT is returned
-       * at queue rundown in NT (unlikely) -Gunnar
-       */
-      ASSERT((NTSTATUS)current != STATUS_TIMEOUT);
-      
-      /* based on INVALID_WORK_QUEUE_ITEM bugcheck desc. */
-      if (current->Flink == NULL || current->Blink == NULL)
-      {
-         KeBugCheck(INVALID_WORK_QUEUE_ITEM);
-      }
-      
-      /* "reinitialize" item (same as done in ExInitializeWorkItem) */
-      current->Flink = NULL;
+    /* Get Queue Type and Worker Queue */
+    WorkQueueType = (WORK_QUEUE_TYPE)Context;
+    WorkQueue = &ExWorkerQueue[WorkQueueType];
+    
+    /* Loop forever */
+    while (TRUE) {
+        
+        /* Wait for Something to Happen on the Queue */
+        QueueEntry = KeRemoveQueue(&WorkQueue->WorkerQueue, KernelMode, NULL);
       
-      item = CONTAINING_RECORD( current, WORK_QUEUE_ITEM, List);
-      item->WorkerRoutine(item->Parameter);
+        /* Can't happen since we do a KernelMode wait (and we're a system thread) */
+        ASSERT((NTSTATUS)QueueEntry != STATUS_USER_APC);
       
-      if (KeGetCurrentIrql() != PASSIVE_LEVEL)
-      {
-         KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
-      }
-   }
-   
+        /* this should never happen either, since we wait with NULL timeout,
+         * but there's a slight possibility that STATUS_TIMEOUT is returned
+         * at queue rundown in NT (unlikely) -Gunnar
+         */
+        ASSERT((NTSTATUS)QueueEntry != STATUS_TIMEOUT);
+    
+        /* Increment Processed Work Items */
+        InterlockedIncrement(&WorkQueue->WorkItemsProcessed);
+
+        /* Get the Work Item */
+        WorkItem = CONTAINING_RECORD(QueueEntry, WORK_QUEUE_ITEM, List);
+        
+        /* Call the Worker Routine */
+        WorkItem->WorkerRoutine(WorkItem->Parameter);
+    
+        /* Make sure it returned at right IRQL */
+        if (KeGetCurrentIrql() != PASSIVE_LEVEL) {
+        
+            /* FIXME: Make this an Ex */
+            KEBUGCHECK(WORKER_THREAD_RETURNED_AT_BAD_IRQL);
+        }
+    
+        /* Make sure it returned with Impersionation Disabled */
+        if (PsGetCurrentThread()->ActiveImpersonationInfo) {
+            
+            /* FIXME: Make this an Ex */
+            KEBUGCHECK(IMPERSONATING_WORKER_THREAD);
+        }
+    }
 }
 
-static VOID ExInitializeWorkQueue(PKQUEUE WorkQueue,
-                                 KPRIORITY Priority)
+static 
+VOID 
+STDCALL
+ExpInitializeWorkQueue(WORK_QUEUE_TYPE WorkQueueType,
+                       KPRIORITY Priority)
 {
-   ULONG i;
-   PETHREAD Thread;
-   HANDLE   hThread;
+    ULONG i;
+    PETHREAD Thread;
+    HANDLE hThread;
    
-   
-   for (i=0; i<NUMBER_OF_WORKER_THREADS; i++)
-     {
+    /* Loop through how many threads we need to create */
+    for (i = 0; i < NUMBER_OF_WORKER_THREADS; i++) {
+        
+        /* Create the System Thread */
+        PsCreateSystemThread(&hThread,
+                             THREAD_ALL_ACCESS,
+                             NULL,
+                             NULL,
+                             NULL,
+                             ExpWorkerThreadEntryPoint,
+                             (PVOID)WorkQueueType);
+        
+        /* Get the Thread */
+        ObReferenceObjectByHandle(hThread,
+                                  THREAD_SET_INFORMATION,
+                                  PsThreadType,
+                                  KernelMode,
+                                  (PVOID*)&Thread,
+                                  NULL);
+        
+        /* Set the Priority */
+        KeSetPriorityThread(&Thread->Tcb, Priority);
         
-   PsCreateSystemThread(&hThread,
-                            THREAD_ALL_ACCESS,
-                            NULL,
-                            NULL,
-                            NULL,
-                            ExWorkerThreadEntryPoint,
-              WorkQueue);
-   ObReferenceObjectByHandle(hThread,
-                                 THREAD_ALL_ACCESS,
-                                 PsThreadType,
-                                 KernelMode,
-                                 (PVOID*)&Thread,
-                                 NULL);
-       KeSetPriorityThread(&Thread->Tcb,
-                           Priority);
-       ObDereferenceObject(Thread);
-   ZwClose(hThread);
-     }
+        /* Dereference and close handle */
+        ObDereferenceObject(Thread);
+        ZwClose(hThread);
+    }
 }
 
-VOID INIT_FUNCTION
-ExInitializeWorkerThreads(VOID)
+VOID 
+INIT_FUNCTION
+ExpInitializeWorkerThreads(VOID)
 {
-   KeInitializeQueue( &EiNormalWorkQueue, NUMBER_OF_WORKER_THREADS );
-   KeInitializeQueue( &EiCriticalWorkQueue , NUMBER_OF_WORKER_THREADS );
-   KeInitializeQueue( &EiHyperCriticalWorkQueue , NUMBER_OF_WORKER_THREADS );
-
-   ExInitializeWorkQueue(&EiNormalWorkQueue,
-                        LOW_PRIORITY);
-   ExInitializeWorkQueue(&EiCriticalWorkQueue,
-                        LOW_REALTIME_PRIORITY);
-   ExInitializeWorkQueue(&EiHyperCriticalWorkQueue,
-                        HIGH_PRIORITY);
+    ULONG WorkQueueType;
+    
+    /* Initialize the Array */
+    for (WorkQueueType = 0; WorkQueueType < MaximumWorkQueue; WorkQueueType++) {
+    
+        RtlZeroMemory(&ExWorkerQueue[WorkQueueType], sizeof(EX_WORK_QUEUE));
+        KeInitializeQueue(&ExWorkerQueue[WorkQueueType].WorkerQueue, 0);
+    }
+    
+    /* Create the built-in worker threads for each work queue */
+    ExpInitializeWorkQueue(CriticalWorkQueue, LOW_REALTIME_PRIORITY);
+    ExpInitializeWorkQueue(DelayedWorkQueue, LOW_PRIORITY);
+    ExpInitializeWorkQueue(HyperCriticalWorkQueue, HIGH_PRIORITY);
 }
 
 /*
  * @implemented
- */
-VOID STDCALL
-ExQueueWorkItem (PWORK_QUEUE_ITEM      WorkItem,
-                WORK_QUEUE_TYPE                QueueType)
-/*
+ *
  * FUNCTION: Inserts a work item in a queue for one of the system worker
  * threads to process
  * ARGUMENTS:
  *        WorkItem = Item to insert
  *        QueueType = Queue to insert it in
  */
+VOID 
+STDCALL
+ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem,
+                WORK_QUEUE_TYPE QueueType)
 {
     ASSERT(WorkItem!=NULL);
     ASSERT_IRQL(DISPATCH_LEVEL);
     ASSERT(WorkItem->List.Flink == NULL);
-   /*
-    * Insert the item in the appropiate queue and wake up any thread
-    * waiting for something to do
-    */
-    switch(QueueType)
-    {
-    case DelayedWorkQueue:
-      KeInsertQueue (
-          &EiNormalWorkQueue,
-          &WorkItem->List
-            );
-       break;
-       
-    case CriticalWorkQueue:
-            KeInsertQueue (
-              &EiCriticalWorkQueue,
-              &WorkItem->List
-              );
-           break;
-
-    case HyperCriticalWorkQueue:
-            KeInsertQueue (
-             &EiHyperCriticalWorkQueue,
-             &WorkItem->List
-             );
-               break;
-     
-    default:
-        break;
-
-    }
+    
+    /* Insert the Queue */
+    KeInsertQueue(&ExWorkerQueue[QueueType].WorkerQueue, &WorkItem->List);
 }
 
 /* EOF */
index 3596bfe..d42decd 100644 (file)
@@ -98,24 +98,19 @@ ExInit3(VOID);
 VOID
 ExpInitTimeZoneInfo(VOID);
 VOID
-ExInitializeWorkerThreads(VOID);
+ExpInitializeWorkerThreads(VOID);
 VOID
 ExpInitLookasideLists(VOID);
 VOID
 ExpInitializeCallbacks(VOID);
 VOID
 ExpInitUuids(VOID);
+VOID
+STDCALL
+ExpInitializeExecutive(VOID);
 
 /* OTHER FUNCTIONS **********************************************************/
 
-#ifdef _ENABLE_THRDEVTPAIR
-VOID
-ExpSwapThreadEventPair(
-       IN struct _ETHREAD* Thread,
-       IN struct _KEVENT_PAIR* EventPair
-       );
-#endif /* _ENABLE_THRDEVTPAIR */
-
 LONGLONG 
 FASTCALL
 ExfpInterlockedExchange64(LONGLONG volatile * Destination,
index 43a2958..5f86d91 100644 (file)
@@ -2,18 +2,5 @@
  * Structure ids
  */
 
-#define InternalBaseType                      (0xcc)
-#define InternalNotificationEvent             (InternalBaseType + 1)
-#define InternalSynchronizationEvent          (InternalBaseType + 2)
-#define InternalSemaphoreType                 (InternalBaseType + 3)
-#define InternalProcessType                   (InternalBaseType + 4)
-#define InternalThreadType                    (InternalBaseType + 5)
-#define InternalFileType                      (InternalBaseType + 6)
-#define InternalDriverType                    (InternalBaseType + 7)
-#define InternalDeviceType                    (InternalBaseType + 8)
-#define InternalMutexType                     (InternalBaseType + 9)
-#define InternalNotificationTimer             (InternalBaseType + 10)
-#define InternalSynchronizationTimer          (InternalBaseType + 11)
-#define InternalQueueType                     (InternalBaseType + 12)
 
 
index 823c153..95d129c 100644 (file)
@@ -412,7 +412,7 @@ IoDestroyDriverList(VOID);
 /* bootlog.c */
 
 VOID
-IopInitBootLog(VOID);
+IopInitBootLog(BOOLEAN StartBootLog);
 
 VOID
 IopStartBootLog(VOID);
index e9e78f6..c4f48ea 100644 (file)
@@ -115,6 +115,17 @@ typedef struct _KPROFILE
   struct _EPROCESS *Process;
 } KPROFILE, *PKPROFILE;
 
+/* Cached modules from the loader block */
+typedef enum _CACHED_MODULE_TYPE {
+    AnsiCodepage,
+    OemCodepage,
+    UnicodeCasemap,
+    SystemRegistry,
+    HardwareRegistry,
+    MaximumCachedModuleType,        
+} CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
+extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
+
 VOID STDCALL 
 DbgBreakPointNoBugCheck(VOID);
 
@@ -144,30 +155,42 @@ VOID STDCALL KeUpdateRunTime(PKTRAP_FRAME TrapFrame, KIRQL Irql);
 
 VOID STDCALL KiExpireTimers(PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2);
 
-KIRQL KeAcquireDispatcherDatabaseLock(VOID);
-VOID KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
-VOID KeReleaseDispatcherDatabaseLock(KIRQL Irql);
-VOID KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
+KIRQL inline FASTCALL KeAcquireDispatcherDatabaseLock(VOID);
+VOID inline FASTCALL KeAcquireDispatcherDatabaseLockAtDpcLevel(VOID);
+VOID inline FASTCALL KeReleaseDispatcherDatabaseLock(KIRQL Irql);
+VOID inline FASTCALL KeReleaseDispatcherDatabaseLockFromDpcLevel(VOID);
 
 BOOLEAN KiDispatcherObjectWake(DISPATCHER_HEADER* hdr, KPRIORITY increment);
 VOID STDCALL KeExpireTimers(PKDPC Apc,
                            PVOID Arg1,
                            PVOID Arg2,
                            PVOID Arg3);
-VOID KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
+VOID inline FASTCALL KeInitializeDispatcherHeader(DISPATCHER_HEADER* Header, ULONG Type,
                                  ULONG Size, ULONG SignalState);
 VOID KeDumpStackFrames(PULONG Frame);
 BOOLEAN KiTestAlert(VOID);
 
-BOOLEAN KiAbortWaitThread(struct _KTHREAD* Thread, NTSTATUS WaitStatus);
+VOID FASTCALL KiAbortWaitThread(struct _KTHREAD* Thread, NTSTATUS WaitStatus);
+
+BOOLEAN STDCALL KiInsertTimer(PKTIMER Timer, LARGE_INTEGER DueTime);
+
+VOID inline FASTCALL KiSatisfyObjectWait(PDISPATCHER_HEADER Object, PKTHREAD Thread);
+
+BOOLEAN inline FASTCALL KiIsObjectSignaled(PDISPATCHER_HEADER Object, PKTHREAD Thread);
+
+VOID inline FASTCALL KiSatisifyMultipleObjectWaits(PKWAIT_BLOCK WaitBlock);
+
+VOID FASTCALL KiWaitTest(PDISPATCHER_HEADER Object, KPRIORITY Increment);
 
 PULONG KeGetStackTopThread(struct _ETHREAD* Thread);
 VOID KeContextToTrapFrame(PCONTEXT Context, PKTRAP_FRAME TrapFrame);
 VOID STDCALL KiDeliverApc(KPROCESSOR_MODE PreviousMode,
                   PVOID Reserved,
                   PKTRAP_FRAME TrapFrame);
+                  
+VOID STDCALL KeInitializeEventPair(PKEVENT_PAIR EventPair);
                  
-VOID KiInitializeUserApc(IN PVOID Reserved,
+VOID STDCALL KiInitializeUserApc(IN PVOID Reserved,
                         IN PKTRAP_FRAME TrapFrame,
                         IN PKNORMAL_ROUTINE NormalRoutine,
                         IN PVOID NormalContext,
@@ -183,6 +206,7 @@ STDCALL
 KeTestAlertThread(IN KPROCESSOR_MODE AlertMode);
 
 BOOLEAN STDCALL KeRemoveQueueApc (PKAPC Apc);
+VOID FASTCALL KiWakeQueue(IN PKQUEUE Queue);
 PLIST_ENTRY STDCALL KeRundownQueue(IN PKQUEUE Queue);
 
 extern LARGE_INTEGER SystemBootTime;
@@ -194,7 +218,7 @@ VOID KeInitInterrupts(VOID);
 VOID KeInitTimer(VOID);
 VOID KeInitDpc(struct _KPCR* Pcr);
 VOID KeInitDispatcher(VOID);
-VOID KeInitializeDispatcher(VOID);
+VOID inline FASTCALL KeInitializeDispatcher(VOID);
 VOID KiInitializeSystemClock(VOID);
 VOID KeInitializeBugCheck(VOID);
 VOID Phase1Initialization(PVOID Context);
index 46906e3..84787cb 100644 (file)
@@ -29,6 +29,7 @@ extern ULONG NlsUnicodeTableOffset;
 extern PUSHORT NlsUnicodeUpcaseTable;
 extern PUSHORT NlsUnicodeLowercaseTable;
 
+VOID STDCALL RtlpInitNls(VOID);
 VOID RtlpImportAnsiCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportOemCodePage(PUSHORT TableBase, ULONG Size);
 VOID RtlpImportUnicodeCasemap(PUSHORT TableBase, ULONG Size);
index a98537f..972b42a 100644 (file)
@@ -49,10 +49,12 @@ VOID ExpInitializeProfileImplementation(VOID);
  */
 VOID MmInitSystem(ULONG Phase, PLOADER_PARAMETER_BLOCK LoaderBlock, ULONG LastKernelAddress);
 VOID IoInit(VOID);
-VOID IoInit2(VOID);
+VOID IoInit2(BOOLEAN BootLog);
+VOID STDCALL IoInit3(VOID);
 VOID ObInit(VOID);
 VOID PsInit(VOID);
 VOID CmInitializeRegistry(VOID);
+VOID STDCALL CmInitHives(BOOLEAN SetupBoot);
 VOID CmInit2(PCHAR CommandLine);
 VOID CmShutdownRegistry(VOID);
 BOOLEAN CmImportSystemHive(PCHAR ChunkBase, ULONG ChunkSize);
index 1be0eee..c954fb7 100644 (file)
@@ -498,7 +498,9 @@ VOID STDCALL PsExitSpecialApc(PKAPC Apc,
 
 
 VOID 
+STDCALL
 KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First);
+
 NTSTATUS KeReleaseThread(PKTHREAD Thread);
 
 VOID
@@ -525,8 +527,11 @@ VOID PsUnfreezeProcessThreads(PEPROCESS Process);
 ULONG PsEnumThreadsByProcess(PEPROCESS Process);
 PEPROCESS PsGetNextProcess(PEPROCESS OldProcess);
 VOID
-PsBlockThread(PNTSTATUS Status, UCHAR Alertable, ULONG WaitMode, 
-             BOOLEAN DispatcherLock, KIRQL WaitIrql, UCHAR WaitReason);
+STDCALL
+PsBlockThread(PNTSTATUS Status, 
+              UCHAR Alertable, 
+              ULONG WaitMode,
+              UCHAR WaitReason);
 VOID
 PsUnblockThread(PETHREAD Thread, PNTSTATUS WaitStatus, KPRIORITY Increment);
 VOID
index 71dc17b..9324dd9 100644 (file)
@@ -27,13 +27,14 @@ static ERESOURCE IopBootLogResource;
 /* FUNCTIONS ****************************************************************/
 
 VOID INIT_FUNCTION
-IopInitBootLog(VOID)
+IopInitBootLog(BOOLEAN StartBootLog)
 {
   ExInitializeResourceLite(&IopBootLogResource);
+  if (StartBootLog) IopStartBootLog();
 }
 
 
-VOID
+VOID INIT_FUNCTION
 IopStartBootLog(VOID)
 {
   IopBootLogCreate = TRUE;
index b507fc5..6a2919e 100644 (file)
@@ -176,7 +176,7 @@ IopCreateFile(PVOID                 ObjectBody,
         FileObject,
         DeviceObject);
   FileObject->Vpb = DeviceObject->Vpb;
-  FileObject->Type = InternalFileType;
+  FileObject->Type = IO_TYPE_FILE;
 
   return(STATUS_SUCCESS);
 }
@@ -240,7 +240,7 @@ IoCreateStreamFileObject(PFILE_OBJECT FileObject,
 
   CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
   CreatedFileObject->Vpb = DeviceObject->Vpb;
-  CreatedFileObject->Type = InternalFileType;
+  CreatedFileObject->Type = IO_TYPE_FILE;
   CreatedFileObject->Flags |= FO_DIRECT_DEVICE_OPEN;
 
   // shouldn't we initialize the lock event, and several other things here too?
index 7cab4e6..9e29e1c 100644 (file)
@@ -160,7 +160,7 @@ IopCreateDriver(
 
    RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION));
 
-   Object->Type = InternalDriverType;
+   Object->Type = IO_TYPE_DRIVER;
 
    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
       Object->MajorFunction[i] = IopInvalidDeviceRequest;
index de412e5..d52fcc4 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- * 
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/io/iocomp.c
 
 POBJECT_TYPE ExIoCompletionType;
 
-NPAGED_LOOKASIDE_LIST  IoCompletionPacketLookaside;
+NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
 
 static GENERIC_MAPPING ExIoCompletionMapping = 
 {
-   STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
-   STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
-   STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
-   IO_COMPLETION_ALL_ACCESS
+    STANDARD_RIGHTS_READ    | IO_COMPLETION_QUERY_STATE,
+    STANDARD_RIGHTS_WRITE   | IO_COMPLETION_MODIFY_STATE,
+    STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | IO_COMPLETION_QUERY_STATE,
+    IO_COMPLETION_ALL_ACCESS
 };
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS 
+VOID 
 STDCALL
-IopCreateIoCompletion(
-   PVOID                ObjectBody,
-   PVOID                Parent,
-   PWSTR                RemainingPath,
-   POBJECT_ATTRIBUTES   ObjectAttributes
-   )
-{
-   DPRINT("IopCreateIoCompletion(ObjectBody %x, Parent %x, RemainingPath %S)\n",
-      ObjectBody, Parent, RemainingPath);
-
-   if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL)
-   {
-      return STATUS_UNSUCCESSFUL;
-   }
-
-   return STATUS_SUCCESS;
-}
-
-VOID STDCALL
 IopDeleteIoCompletion(PVOID ObjectBody)
 {
-   PKQUEUE Queue = ObjectBody;
-
-   DPRINT("IopDeleteIoCompletion()\n");
-
-   KeRundownQueue(Queue);
+    PKQUEUE Queue = ObjectBody;
+    PLIST_ENTRY FirstEntry;
+    PLIST_ENTRY CurrentEntry;
+    PIO_COMPLETION_PACKET Packet;
+
+    DPRINT("IopDeleteIoCompletion()\n");
+
+    /* Rundown the Queue */
+    FirstEntry = KeRundownQueue(Queue);
+    
+    /* Clean up the IRPs */
+    if (FirstEntry) {
+    
+        CurrentEntry = FirstEntry;
+        do {
+        
+            /* Get the Packet */
+            Packet = CONTAINING_RECORD(CurrentEntry, IO_COMPLETION_PACKET, ListEntry);
+            
+            /* Go to next Entry */
+            CurrentEntry = CurrentEntry->Flink;
+            
+            /* Free it */
+            ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+        } while (FirstEntry != CurrentEntry);
+    }
 }
 
-
 /*
- * @unimplemented
+ * @implemented
  */
 NTSTATUS
 STDCALL
-IoSetCompletionRoutineEx(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN PIO_COMPLETION_ROUTINE CompletionRoutine,
-    IN PVOID Context,
-    IN BOOLEAN InvokeOnSuccess,
-    IN BOOLEAN InvokeOnError,
-    IN BOOLEAN InvokeOnCancel
-    )
+IoSetIoCompletion(IN PVOID IoCompletion,
+                  IN PVOID KeyContext,
+                  IN PVOID ApcContext,
+                  IN NTSTATUS IoStatus,
+                  IN ULONG_PTR IoStatusInformation,
+                  IN BOOLEAN Quota)
 {
-       UNIMPLEMENTED;
-       return STATUS_NOT_IMPLEMENTED;
+    PKQUEUE Queue = (PKQUEUE)IoCompletion;
+    PIO_COMPLETION_PACKET Packet;
+
+    /* Allocate the Packet */
+    Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
+    if (NULL == Packet) return STATUS_NO_MEMORY;
+    
+    /* Set up the Packet */
+    Packet->Key = KeyContext;
+    Packet->Context = ApcContext;
+    Packet->IoStatus.Status = IoStatus;
+    Packet->IoStatus.Information = IoStatusInformation;
+    
+    /* Insert the Queue */
+    KeInsertQueue(Queue, &Packet->ListEntry);
+
+    /* Return Success */
+    return STATUS_SUCCESS;
 }
 
 /*
- * @implemented
+ * @unimplemented
  */
 NTSTATUS
 STDCALL
-IoSetIoCompletion (
-       IN PVOID IoCompletion,
-       IN PVOID KeyContext,
-       IN PVOID ApcContext,
-       IN NTSTATUS IoStatus,
-       IN ULONG_PTR IoStatusInformation,
-       IN BOOLEAN Quota
-       )
+IoSetCompletionRoutineEx(IN PDEVICE_OBJECT DeviceObject,
+                         IN PIRP Irp,
+                         IN PIO_COMPLETION_ROUTINE CompletionRoutine,
+                         IN PVOID Context,
+                         IN BOOLEAN InvokeOnSuccess,
+                         IN BOOLEAN InvokeOnError,
+                         IN BOOLEAN InvokeOnCancel)
 {
-   PKQUEUE Queue = (PKQUEUE) IoCompletion;
-   PIO_COMPLETION_PACKET   Packet;
-
-   Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
-   if (NULL == Packet)
-   {
-     return STATUS_NO_MEMORY;
-   }
-
-   Packet->Key = KeyContext;
-   Packet->Context = ApcContext;
-   Packet->IoStatus.Status = IoStatus;
-   Packet->IoStatus.Information = IoStatusInformation;
-   
-   KeInsertQueue(Queue, &Packet->ListEntry);
-
-   return STATUS_SUCCESS;
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 VOID
 FASTCALL
 IopInitIoCompletionImplementation(VOID)
 {
-   ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-   
-   RtlpCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion", NonPagedPool);
-   
-   ExIoCompletionType->Tag = IOC_TAG;
-   ExIoCompletionType->PeakObjects = 0;
-   ExIoCompletionType->PeakHandles = 0;
-   ExIoCompletionType->TotalObjects = 0;
-   ExIoCompletionType->TotalHandles = 0;
-   ExIoCompletionType->PagedPoolCharge = 0;
-   ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
-   ExIoCompletionType->Mapping = &ExIoCompletionMapping;
-   ExIoCompletionType->Dump = NULL;
-   ExIoCompletionType->Open = NULL;
-   ExIoCompletionType->Close = NULL;
-   ExIoCompletionType->Delete = IopDeleteIoCompletion;
-   ExIoCompletionType->Parse = NULL;
-   ExIoCompletionType->Security = NULL;
-   ExIoCompletionType->QueryName = NULL;
-   ExIoCompletionType->OkayToClose = NULL;
-   ExIoCompletionType->Create = IopCreateIoCompletion;
-   ExIoCompletionType->DuplicationNotify = NULL;
-
-   ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
-                                   NULL,
-                                   NULL,
-                                   0,
-                                   sizeof(IO_COMPLETION_PACKET),
-                                   IOC_TAG,
-                                   0);
+    /* Create the IO Completion Type */
+    ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));   
+    RtlpCreateUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion", NonPagedPool);
+    ExIoCompletionType->Tag = IOC_TAG;
+    ExIoCompletionType->PeakObjects = 0;
+    ExIoCompletionType->PeakHandles = 0;
+    ExIoCompletionType->TotalObjects = 0;
+    ExIoCompletionType->TotalHandles = 0;
+    ExIoCompletionType->PagedPoolCharge = 0;
+    ExIoCompletionType->NonpagedPoolCharge = sizeof(KQUEUE);
+    ExIoCompletionType->Mapping = &ExIoCompletionMapping;
+    ExIoCompletionType->Dump = NULL;
+    ExIoCompletionType->Open = NULL;
+    ExIoCompletionType->Close = NULL;
+    ExIoCompletionType->Delete = IopDeleteIoCompletion;
+    ExIoCompletionType->Parse = NULL;
+    ExIoCompletionType->Security = NULL;
+    ExIoCompletionType->QueryName = NULL;
+    ExIoCompletionType->OkayToClose = NULL;
+    ExIoCompletionType->Create = NULL;
+    ExIoCompletionType->DuplicationNotify = NULL;
+
+    /* Initialize the Lookaside List we'll use for packets */
+    ExInitializeNPagedLookasideList(&IoCompletionPacketLookaside,
+                                    NULL,
+                                    NULL,
+                                    0,
+                                    sizeof(IO_COMPLETION_PACKET),
+                                    IOC_TAG,
+                                    0);
 }
 
-
 NTSTATUS
 STDCALL
-NtCreateIoCompletion(
-   OUT PHANDLE             IoCompletionHandle,
-   IN  ACCESS_MASK         DesiredAccess,
-   IN  POBJECT_ATTRIBUTES  ObjectAttributes,
-   IN  ULONG               NumberOfConcurrentThreads
-   )
+NtCreateIoCompletion(OUT PHANDLE IoCompletionHandle,
+                     IN  ACCESS_MASK DesiredAccess,
+                     IN  POBJECT_ATTRIBUTES ObjectAttributes,
+                     IN  ULONG NumberOfConcurrentThreads)
 {
-   PKQUEUE     Queue;
-   NTSTATUS    Status;
-
-   Status = ObCreateObject(ExGetPreviousMode(),
-                           ExIoCompletionType,
-                           ObjectAttributes,
-                           ExGetPreviousMode(),
-                           NULL,
-                           sizeof(KQUEUE),
-                           0,
-                           0,
-                           (PVOID*)&Queue);
-   if (!NT_SUCCESS(Status))
-   {
-     return Status;
-   }
-
-   Status = ObInsertObject ((PVOID)Queue,
-                           NULL,
-                           DesiredAccess,
-                           0,
-                           NULL,
-                           IoCompletionHandle);
-   if (!NT_SUCCESS(Status))
-   {
-     ObDereferenceObject(Queue);
-     return Status;
+    PKQUEUE Queue;
+    NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+
+    /* Create the Object */
+    Status = ObCreateObject(PreviousMode,
+                            ExIoCompletionType,
+                            ObjectAttributes,
+                            PreviousMode,
+                            NULL,
+                            sizeof(KQUEUE),
+                            0,
+                            0,
+                            (PVOID*)&Queue);
+    
+    /* Check for success */
+    if (!NT_SUCCESS(Status)) {
+   
+        /* Initialize the Queue */
+        KeInitializeQueue(Queue, NumberOfConcurrentThreads);
+
+        /* Insert it */
+        Status = ObInsertObject(Queue,
+                                NULL,
+                                DesiredAccess,
+                                0,
+                                NULL,
+                                IoCompletionHandle);   
+        ObDereferenceObject(Queue);
    }
-
-   KeInitializeQueue(Queue, NumberOfConcurrentThreads);
-   ObDereferenceObject(Queue);
-
+   
+   /* Return Status */
    return STATUS_SUCCESS;
-   /*
-
-  CompletionPort = NULL OR ExistingCompletionPort
-
-  */
-
 }
 
-/*
-DesiredAccess:
-ZERO
-IO_COMPLETION_QUERY_STATE Query access
-IO_COMPLETION_MODIFY_STATE Modify access
-IO_COMPLETION_ALL_ACCESS All of the preceding + STANDARD_RIGHTS_ALL
-
-ObjectAttributes
-OBJ_OPENLINK and OBJ_PERMANENT are not valid attributes
-
-Return Value
-STATUS_SUCCESS or an error status, such as STATUS_ACCESS_DENIED or
-STATUS_OBJECT_NAME_NOT_FOUND.
-*/
 NTSTATUS
 STDCALL
-NtOpenIoCompletion(
-   OUT PHANDLE             IoCompletionHandle,
-   IN  ACCESS_MASK         DesiredAccess,
-   IN  POBJECT_ATTRIBUTES  ObjectAttributes
-   )
+NtOpenIoCompletion(OUT PHANDLE IoCompletionHandle,
+                   IN ACCESS_MASK DesiredAccess,
+                   IN POBJECT_ATTRIBUTES ObjectAttributes)
 {
-   NTSTATUS Status;
-   
-   Status = ObOpenObjectByName(ObjectAttributes,
-                               ExIoCompletionType,
-                               NULL,
-                               UserMode,
-                               DesiredAccess,
-                               NULL,
-                               IoCompletionHandle);  //<- ???
-   
-   return Status;
+    NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    
+    /* Open the Object */
+    Status = ObOpenObjectByName(ObjectAttributes,
+                                ExIoCompletionType,
+                                NULL,
+                                PreviousMode,
+                                DesiredAccess,
+                                NULL,
+                                IoCompletionHandle);
+    /* Return Status */  
+    return Status;
 }
 
-
 NTSTATUS
 STDCALL
-NtQueryIoCompletion(
-   IN  HANDLE                          IoCompletionHandle,
-   IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
-   OUT PVOID                           IoCompletionInformation,
-   IN  ULONG                           IoCompletionInformationLength,
-   OUT PULONG                          ResultLength OPTIONAL
-   )
+NtQueryIoCompletion(IN  HANDLE IoCompletionHandle,
+                    IN  IO_COMPLETION_INFORMATION_CLASS IoCompletionInformationClass,
+                    OUT PVOID IoCompletionInformation,
+                    IN  ULONG IoCompletionInformationLength,
+                    OUT PULONG ResultLength OPTIONAL)
 {
-   PKQUEUE  Queue;
-   NTSTATUS Status;
+    PKQUEUE Queue;
+    NTSTATUS Status;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
 
-   if (IoCompletionInformationClass != IoCompletionBasicInformation)
-   {
-      return STATUS_INVALID_INFO_CLASS;
-   }
-   if (IoCompletionInformationLength < sizeof(IO_COMPLETION_BASIC_INFORMATION))
-   {
-      return STATUS_INFO_LENGTH_MISMATCH;
-   }
-
-   Status = ObReferenceObjectByHandle( IoCompletionHandle,
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                        IO_COMPLETION_QUERY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-   if (NT_SUCCESS(Status))
-   {
-      ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = 
-         Queue->Header.SignalState;
-
-      ObDereferenceObject(Queue);
+    
+    /* Check for Success */
+   if (NT_SUCCESS(Status)) {
+      
+        /* Return Info */
+        ((PIO_COMPLETION_BASIC_INFORMATION)IoCompletionInformation)->Depth = KeReadStateQueue(Queue);
+        ObDereferenceObject(Queue);
 
-      if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
-   }
+        /* Return Result Length if needed */
+        if (ResultLength) *ResultLength = sizeof(IO_COMPLETION_BASIC_INFORMATION);
+    }
 
-   return Status;
+    /* Return Status */
+    return Status;
 }
 
-
 /*
  * Dequeues an I/O completion message from an I/O completion object
  */
 NTSTATUS
 STDCALL
-NtRemoveIoCompletion(
-   IN  HANDLE           IoCompletionHandle,
-   OUT PVOID            *CompletionKey,
-   OUT PVOID            *CompletionContext,
-   OUT PIO_STATUS_BLOCK IoStatusBlock,
-   IN  PLARGE_INTEGER   Timeout OPTIONAL
-   )
+NtRemoveIoCompletion(IN  HANDLE IoCompletionHandle,
+                     OUT PVOID *CompletionKey,
+                     OUT PVOID *CompletionContext,
+                     OUT PIO_STATUS_BLOCK IoStatusBlock,
+                     IN  PLARGE_INTEGER Timeout OPTIONAL)
 {
-   PKQUEUE  Queue;
-   NTSTATUS Status;
-   PIO_COMPLETION_PACKET   Packet;
-   PLIST_ENTRY             ListEntry;
-
-   Status = ObReferenceObjectByHandle( IoCompletionHandle,
+    PKQUEUE Queue;
+    NTSTATUS Status;
+    PIO_COMPLETION_PACKET Packet;
+    PLIST_ENTRY ListEntry;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    
+    /* Open the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionHandle,
                                        IO_COMPLETION_MODIFY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       PreviousMode,
                                        (PVOID*)&Queue,
                                        NULL);
-   if (!NT_SUCCESS(Status))
-   {
-      return Status;
-   }
-
-   /*
-   Try 2 remove packet from queue. Wait (optionaly) if
-   no packet in queue or max num of threads allready running.
-   */
-      
-   do {
-      
-      ListEntry = KeRemoveQueue(Queue, UserMode, Timeout );
-
-      /* Nebbets book says nothing about NtRemoveIoCompletion returning STATUS_USER_APC,
-      and the umode equivalent GetQueuedCompletionStatus says nothing about this either,
-      so my guess it we should restart the operation. Need further investigation. -Gunnar
-      */
-
-   } while((NTSTATUS)ListEntry == STATUS_USER_APC);
-
-   ObDereferenceObject(Queue);
-   
-   if ((NTSTATUS)ListEntry == STATUS_TIMEOUT)
-   {
-      return STATUS_TIMEOUT;
-   }
-   
-   ASSERT(ListEntry);
+    
+    /* Check for success */
+    if (NT_SUCCESS(Status)) {
+
+        /* Remove queue */
+        ListEntry = KeRemoveQueue(Queue, PreviousMode, Timeout);
+
+        /* If we got a timeout or user_apc back, return the status */
+        if ((NTSTATUS)ListEntry == STATUS_TIMEOUT || (NTSTATUS)ListEntry == STATUS_USER_APC) {
+            
+            Status = (NTSTATUS)ListEntry; 
+            
+        } else {
+            
+            /* Get the Packet Data */
+            Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
+            
+            /* Return it */
+           if (CompletionKey) *CompletionKey = Packet->Key;
+           if (CompletionContext) *CompletionContext = Packet->Context;
+           if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
+           
+           /* Free packet */
+           ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
+        }
    
-   Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
-
-   if (CompletionKey) *CompletionKey = Packet->Key;
-   if (CompletionContext) *CompletionContext = Packet->Context;
-   if (IoStatusBlock) *IoStatusBlock = Packet->IoStatus;
-
-   ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
-
-   return STATUS_SUCCESS;
+        /* Dereference the Object */
+        ObDereferenceObject(Queue);
+    }
+    
+    /* Return status */
+    return Status;
 }
 
-
-/*
-ASSOSIERT MED FOB's IoCompletionContext
-
-typedef struct _IO_COMPLETION_CONTEXT {
-        PVOID Port; 
-        ULONG Key; 
-} IO_COMPLETION_CONTEXT, *PIO_COMPLETION_CONTEXT;
-
-*/
-
-
 /*
  * Queues an I/O completion message to an I/O completion object
  */
 NTSTATUS
 STDCALL
-NtSetIoCompletion(
-   IN HANDLE   IoCompletionPortHandle,
-   IN PVOID    CompletionKey,
-   IN PVOID    CompletionContext,
-   IN NTSTATUS CompletionStatus,
-   IN ULONG    CompletionInformation
-   )
+NtSetIoCompletion(IN HANDLE IoCompletionPortHandle,
+                  IN PVOID CompletionKey,
+                  IN PVOID CompletionContext,
+                  IN NTSTATUS CompletionStatus,
+                  IN ULONG CompletionInformation)
 {
-   NTSTATUS                Status;
-   PKQUEUE                 Queue;
-
-   Status = ObReferenceObjectByHandle( IoCompletionPortHandle,
+    NTSTATUS Status;
+    PKQUEUE Queue;
+    
+    /* Get the Object */
+    Status = ObReferenceObjectByHandle(IoCompletionPortHandle,
                                        IO_COMPLETION_MODIFY_STATE,
                                        ExIoCompletionType,
-                                       UserMode,
+                                       ExGetPreviousMode(),
                                        (PVOID*)&Queue,
                                        NULL);
-   if (NT_SUCCESS(Status))
-   {
-      Status = IoSetIoCompletion(Queue, CompletionKey, CompletionContext,
-                                 CompletionStatus, CompletionInformation, TRUE);
-      ObDereferenceObject(Queue);
-   }
-
-   return Status;
+    
+    /* Check for Success */
+    if (NT_SUCCESS(Status)) {
+        
+        /* Set the Completion */
+        Status = IoSetIoCompletion(Queue, 
+                                   CompletionKey, 
+                                   CompletionContext,
+                                   CompletionStatus, 
+                                   CompletionInformation, 
+                                   TRUE);
+        ObDereferenceObject(Queue);
+    }
+    
+    /* Return status */
+    return Status;
 }
index 81852d2..4cc4d60 100644 (file)
@@ -553,14 +553,17 @@ IoInit (VOID)
 }
 
 
-VOID INIT_FUNCTION
-IoInit2(VOID)
+VOID 
+INIT_FUNCTION
+IoInit2(BOOLEAN BootLog)
 {
   PDEVICE_NODE DeviceNode;
   PDRIVER_OBJECT DriverObject;
   MODULE_OBJECT ModuleObject;
   NTSTATUS Status;
 
+  IoCreateDriverList();
+          
   KeInitializeSpinLock (&IoStatisticsLock);
 
   /* Initialize raw filesystem driver */
@@ -605,6 +608,56 @@ IoInit2(VOID)
   IopInvalidateDeviceRelations(
     IopRootDeviceNode,
     BusRelations);
+  
+     /* Start boot logging */
+    IopInitBootLog(BootLog);
+  
+    /* Load boot start drivers */
+    IopInitializeBootDrivers();
+}
+
+VOID
+STDCALL
+INIT_FUNCTION
+IoInit3(VOID)
+{
+    NTSTATUS Status;
+    
+    /* Create ARC names for boot devices */
+    IoCreateArcNames();
+
+    /* Create the SystemRoot symbolic link */
+    CPRINT("CommandLine: %s\n", (PCHAR)KeLoaderBlock.CommandLine);
+    Status = IoCreateSystemRootLink((PCHAR)KeLoaderBlock.CommandLine);
+    if (!NT_SUCCESS(Status)) {
+        DbgPrint("IoCreateSystemRootLink FAILED: (0x%x) - ", Status);
+        DbgPrintErrorMessage (Status);
+        KEBUGCHECK(INACCESSIBLE_BOOT_DEVICE);
+    }
+
+    /* Start Profiling on a Debug Build */
+#if defined(KDBG) || defined(DBG)
+    KdbInitProfiling2();
+#endif /* KDBG */
+
+    /* I/O is now setup for disk access, so start the debugging logger thread. */
+    if ((KdDebuggerEnabled == TRUE) && (KdDebugState & KD_DEBUG_BOOTLOG)) DebugLogInit2();
+
+    /* Load services for devices found by PnP manager */
+    IopInitializePnpServices(IopRootDeviceNode, FALSE);
+
+    /* Load system start drivers */
+    IopInitializeSystemDrivers();
+    IoDestroyDriverList();
+
+    /* Stop boot logging */
+    IopStopBootLog();
+
+    /* Assign drive letters */
+    IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
+                         NULL,
+                         NULL,
+                         NULL);    
 }
 
 /*
index 8b90882..9d01c6b 100644 (file)
@@ -249,4 +249,18 @@ IoWMIDeviceObjectToInstanceName(
        return STATUS_NOT_IMPLEMENTED;
 }
 
+/*
+ * @unimplemented
+ */
+NTSTATUS
+STDCALL
+NtTraceEvent(IN ULONG TraceHandle,
+             IN ULONG Flags,
+             IN ULONG TraceHeaderLength,
+             IN struct _EVENT_TRACE_HEADER* TraceHeader)
+{
+    UNIMPLEMENTED;
+    return STATUS_NOT_IMPLEMENTED;
+}
+
 /*Eof*/
diff --git a/reactos/ntoskrnl/ke/alert.c b/reactos/ntoskrnl/ke/alert.c
deleted file mode 100644 (file)
index 99084a8..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/* $Id:$
- * 
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/alert.c
- * PURPOSE:         Alerts
- * 
- * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-
-/* FUNCTIONS *****************************************************************/
-
-
-BOOLEAN
-STDCALL
-KeTestAlertThread(IN KPROCESSOR_MODE AlertMode)
-/*
- * FUNCTION: Tests whether there are any pending APCs for the current thread
- * and if so the APCs will be delivered on exit from kernel mode
- */
-{
-   KIRQL OldIrql;
-   PKTHREAD Thread = KeGetCurrentThread();
-   BOOLEAN OldState;
-   
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-   
-   OldIrql = KeAcquireDispatcherDatabaseLock();
-   KiAcquireSpinLock(&Thread->ApcQueueLock);
-   
-   OldState = Thread->Alerted[AlertMode];
-   
-   /* If the Thread is Alerted, Clear it */
-   if (OldState) {
-      Thread->Alerted[AlertMode] = FALSE;
-   } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) {
-      /* If the mode is User and the Queue isn't empty, set Pending */
-      Thread->ApcState.UserApcPending = TRUE;
-   }
-   
-   KiReleaseSpinLock(&Thread->ApcQueueLock);
-   KeReleaseDispatcherDatabaseLock(OldIrql);
-   return OldState;
-}
-
-
-VOID
-KeAlertThread(PKTHREAD Thread, KPROCESSOR_MODE AlertMode)
-{
-   KIRQL oldIrql;
-
-   
-   oldIrql = KeAcquireDispatcherDatabaseLock();
-      
-
-   /* Return if thread is already alerted. */
-   if (Thread->Alerted[AlertMode] == FALSE)
-   {
-      if (Thread->State == THREAD_STATE_BLOCKED &&
-          (AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
-          Thread->Alertable)
-      {
-         KiAbortWaitThread(Thread, STATUS_ALERTED);
-      }
-      else
-      {
-         Thread->Alerted[AlertMode] = TRUE;
-      }
-   }
-   
-   KeReleaseDispatcherDatabaseLock(oldIrql);
-}
-
-
-/* 
- *
- * NOT EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertResumeThread(IN  HANDLE ThreadHandle,
-          OUT PULONG SuspendCount)
-{
-   UNIMPLEMENTED;
-   return(STATUS_NOT_IMPLEMENTED);
-
-}
-
-/* 
- * @implemented
- *
- * EXPORTED
- */
-NTSTATUS STDCALL
-NtAlertThread (IN HANDLE ThreadHandle)
-{
-   KPROCESSOR_MODE PreviousMode;
-   PETHREAD Thread;
-   NTSTATUS Status;
-   
-   PreviousMode = ExGetPreviousMode();
-
-   Status = ObReferenceObjectByHandle(ThreadHandle,
-                  THREAD_SUSPEND_RESUME,
-                  PsThreadType,
-                  PreviousMode,
-                  (PVOID*)&Thread,
-                  NULL);
-   if (!NT_SUCCESS(Status))
-     {
-   return(Status);
-     }
-
-   /* do an alert depending on the processor mode. If some kmode code wants to
-      enforce a umode alert it should call KeAlertThread() directly. If kmode
-      code wants to do a kmode alert it's sufficient to call it with Zw or just
-      use KeAlertThread() directly */
-
-   KeAlertThread(&Thread->Tcb, PreviousMode);
-   
-   ObDereferenceObject(Thread);
-   return(STATUS_SUCCESS);
-}
-
-
-/* 
- * NOT EXPORTED
- */
-NTSTATUS
-STDCALL
-NtTestAlert(VOID)
-{
-   KPROCESSOR_MODE PreviousMode;
-   
-   PreviousMode = ExGetPreviousMode();
-   
-   /* Check and Alert Thread if needed */
-   
-   return KeTestAlertThread(PreviousMode) ? STATUS_ALERTED : STATUS_SUCCESS;
-}
-
index 5b47908..04d9786 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/apc.c
 
 VOID PsTerminateCurrentThread(NTSTATUS ExitStatus);
 
-#define TAG_KAPC     TAG('K', 'A', 'P', 'C')
-
 /* FUNCTIONS *****************************************************************/
 
-/*
- * @implemented
- */
+/*++
+ * KeEnterCriticalRegion 
+ * @implemented NT4
+ *
+ *     The KeEnterCriticalRegion routine temporarily disables the delivery of 
+ *      normal kernel APCs; special kernel-mode APCs are still delivered.
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     Highest-level drivers can call this routine while running in the context
+ *     of the thread that requested the current I/O operation. Any caller of 
+ *     this routine should call KeLeaveCriticalRegion as quickly as possible.
+ *
+ *     Callers of KeEnterCriticalRegion must be running at IRQL <= APC_LEVEL.
+ *
+ *--*/
+VOID 
+STDCALL 
+KeEnterCriticalRegion(VOID)
+{
+    /* Disable Kernel APCs */
+    PKTHREAD Thread = KeGetCurrentThread();
+    if (Thread) Thread->KernelApcDisable--;
+}
+
+/*++
+ * KeInitializeApc 
+ * @implemented NT4
+ *
+ *     The The KeInitializeApc routine initializes an APC object, and registers
+ *     the Kernel, Rundown and Normal routines for that object.
+ *
+ * Params:
+ *     Apc - Pointer to a KAPC structure that represents the APC object to 
+ *           initialize. The caller must allocate storage for the structure
+ *           from resident memory.
+ *
+ *     Thread - Thread to which to deliver the APC.
+ *
+ *     TargetEnvironment - APC Environment to be used.
+ *
+ *     KernelRoutine - Points to the KernelRoutine to associate with the APC.
+ *                     This routine is executed for all APCs.
+ *
+ *     RundownRoutine - Points to the RundownRoutine to associate with the APC.
+ *                      This routine is executed when the Thread exists with
+ *                      the APC executing.
+ *
+ *     NormalRoutine - Points to the NormalRoutine to associate with the APC.
+ *                     This routine is executed at PASSIVE_LEVEL. If this is
+ *                     not specifed, the APC becomes a Special APC and the
+ *                     Mode and Context parameters are ignored.
+ *
+ *     Mode - Specifies the processor mode at which to run the Normal Routine.
+ *
+ *     Context - Specifices the value to pass as Context parameter to the 
+ *               registered routines.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     The caller can queue an initialized APC with KeInsertQueueApc.
+ *
+ *     Storage for the APC object must be resident, such as nonpaged pool 
+ *     allocated by the caller.
+ *
+ *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
 VOID
 STDCALL
-KeInitializeApc(
-       IN PKAPC  Apc,
-       IN PKTHREAD  Thread,
-       IN KAPC_ENVIRONMENT  TargetEnvironment,
-       IN PKKERNEL_ROUTINE  KernelRoutine,
-       IN PKRUNDOWN_ROUTINE  RundownRoutine OPTIONAL,
-       IN PKNORMAL_ROUTINE  NormalRoutine,
-       IN KPROCESSOR_MODE  Mode,
-       IN PVOID  Context)
-/*
- * FUNCTION: Initialize an APC object
- * ARGUMENTS:
- *       Apc = Pointer to the APC object to initialized
- *       Thread = Thread the APC is to be delivered to
- *       TargetEnvironment = APC environment to use
- *       KernelRoutine = Routine to be called for a kernel-mode APC
- *       RundownRoutine = Routine to be called if the thread has exited with
- *                        the APC being executed
- *       NormalRoutine = Routine to be called for a user-mode APC
- *       Mode = APC mode
- *       Context = Parameter to be passed to the APC routine
- */
+KeInitializeApc(IN PKAPC Apc,
+                IN PKTHREAD Thread,
+                IN KAPC_ENVIRONMENT TargetEnvironment,
+                IN PKKERNEL_ROUTINE KernelRoutine,
+                IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
+                IN PKNORMAL_ROUTINE NormalRoutine,
+                IN KPROCESSOR_MODE Mode,
+                IN PVOID Context)
 {
-       DPRINT ("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
-               "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
-               "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine,
-               NormalRoutine,Mode,Context);
-
-       /* Set up the basic APC Structure Data */
-       RtlZeroMemory(Apc, sizeof(KAPC));
-       Apc->Type = KApc;
-       Apc->Size = sizeof(KAPC);
-       
-       /* Set the Environment */
-       if (TargetEnvironment == CurrentApcEnvironment) {
-               Apc->ApcStateIndex = Thread->ApcStateIndex;
-       } else {
-               Apc->ApcStateIndex = TargetEnvironment;
-       }
-       
-       /* Set the Thread and Routines */
-       Apc->Thread = Thread;
-       Apc->KernelRoutine = KernelRoutine;
-       Apc->RundownRoutine = RundownRoutine;
-       Apc->NormalRoutine = NormalRoutine;
+    DPRINT("KeInitializeApc(Apc %x, Thread %x, Environment %d, "
+           "KernelRoutine %x, RundownRoutine %x, NormalRoutine %x, Mode %d, "
+           "Context %x)\n",Apc,Thread,TargetEnvironment,KernelRoutine,RundownRoutine,
+            NormalRoutine,Mode,Context);
+
+    /* Set up the basic APC Structure Data */
+    RtlZeroMemory(Apc, sizeof(KAPC));
+    Apc->Type = ApcObject;
+    Apc->Size = sizeof(KAPC);
+    
+    /* Set the Environment */
+    if (TargetEnvironment == CurrentApcEnvironment) {
+        
+        Apc->ApcStateIndex = Thread->ApcStateIndex;
+        
+    } else {
+        
+        Apc->ApcStateIndex = TargetEnvironment;
+    }
+    
+    /* Set the Thread and Routines */
+    Apc->Thread = Thread;
+    Apc->KernelRoutine = KernelRoutine;
+    Apc->RundownRoutine = RundownRoutine;
+    Apc->NormalRoutine = NormalRoutine;
    
-       /* Check if this is a Special APC, in which case we use KernelMode and no Context */
-       if (ARGUMENT_PRESENT(NormalRoutine)) {
-               Apc->ApcMode = Mode;
-               Apc->NormalContext = Context;
-       } else {
-               Apc->ApcMode = KernelMode;
-       }  
+    /* Check if this is a Special APC, in which case we use KernelMode and no Context */
+    if (ARGUMENT_PRESENT(NormalRoutine)) {
+        
+        Apc->ApcMode = Mode;
+        Apc->NormalContext = Context;
+        
+    } else {
+        
+        Apc->ApcMode = KernelMode;
+    }  
 }
 
-/*
- * @implemented
- */
+/*++
+ * KeInsertQueueApc 
+ * @implemented NT4
+ *
+ *     The KeInsertQueueApc routine queues a APC for execution when the right
+ *     scheduler environment exists.
+ *
+ * Params:
+ *     Apc - Pointer to an initialized control object of type DPC for which the
+ *           caller provides the storage. 
+ *
+ *     SystemArgument[1,2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ *     PriorityBoost - Priority Boost to apply to the Thread.
+ *
+ * Returns:
+ *     If the APC is already inserted or APC queueing is disabled, FALSE.
+ *     Otherwise, TRUE.
+ *
+ * Remarks:
+ *     The APC will execute at APC_LEVEL for the KernelRoutine registered, and
+ *     at PASSIVE_LEVEL for the NormalRoutine registered.
+ *
+ *     Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
+ *
+ *--*/
 BOOLEAN
 STDCALL
-KeInsertQueueApc (PKAPC        Apc,
-                 PVOID SystemArgument1,
-                 PVOID SystemArgument2,
-                 KPRIORITY PriorityBoost)
-/*
- * FUNCTION: Queues an APC for execution
- * ARGUMENTS:
- *         Apc = APC to be queued
- *         SystemArgument[1-2] = Arguments we ignore and simply pass on.
- *         PriorityBoost = Priority Boost to give to the Thread
- */
+KeInsertQueueApc(PKAPC Apc,
+                 PVOID SystemArgument1,
+                 PVOID SystemArgument2,
+                 KPRIORITY PriorityBoost)
+
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread;
-       PLIST_ENTRY ApcListEntry;
-       PKAPC QueuedApc;
+    KIRQL OldIrql;
+    PKTHREAD Thread;
+    PLIST_ENTRY ApcListEntry;
+    PKAPC QueuedApc;
    
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-       DPRINT ("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
-               "SystemArgument2 %x)\n",Apc,SystemArgument1,
-               SystemArgument2);
-
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       
-       /* Get the Thread specified in the APC */
-       Thread = Apc->Thread;
-          
-       /* Make sure the thread allows APC Queues.
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+    DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
+           "SystemArgument2 %x)\n",Apc,SystemArgument1,
+            SystemArgument2);
+
+    /* Lock the Dispatcher Database */
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    
+    /* Get the Thread specified in the APC */
+    Thread = Apc->Thread;
+       
+    /* Make sure the thread allows APC Queues.
     * The thread is not apc queueable, for instance, when it's (about to be) terminated.
     */
-       if (Thread->ApcQueueable == FALSE) {
-               DPRINT("Thread doesn't allow APC Queues\n");
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return FALSE;
-       }
-       
-       /* Set the System Arguments */
-       Apc->SystemArgument1 = SystemArgument1;
-       Apc->SystemArgument2 = SystemArgument2;
-
-       /* Don't do anything if the APC is already inserted */
-       if (Apc->Inserted) {
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return FALSE;
-       }
-       
-       /* Three scenarios: 
-          1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
-          2) User APC which is PsExitSpecialApc = Put it at the front of the List
-          3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
-       */
-       if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
-               DPRINT ("Inserting the Process Exit APC into the Queue\n");
-               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
-               InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
-                              &Apc->ApcListEntry);
-       } else if (Apc->NormalRoutine == NULL) {
-               DPRINT ("Inserting Special APC %x into the Queue\n", Apc);
-               for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
-                    ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
-                    ApcListEntry = ApcListEntry->Flink) {
-
-                       QueuedApc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-                       if (Apc->NormalRoutine != NULL) break;
-               }
-               
-               /* We found the first "Normal" APC, so write right before it */
-               ApcListEntry = ApcListEntry->Blink;
-               InsertHeadList(ApcListEntry, &Apc->ApcListEntry);
-       } else {
-               DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
-               InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
-                              &Apc->ApcListEntry);
-       }
-       
-       /* Confirm Insertion */ 
-       Apc->Inserted = TRUE;
-
-       /* Three possibilites here again:
-          1) Kernel APC, The thread is Running: Request an Interrupt
-          2) Kernel APC, The Thread is Waiting at PASSIVE_LEVEL and APCs are enabled and not in progress: Unwait the Thread
-          3) User APC, Unwait the Thread if it is alertable
-       */ 
-       if (Apc->ApcMode == KernelMode) { 
-               Thread->ApcState.KernelApcPending = TRUE;
-               if (Thread->State == THREAD_STATE_RUNNING) { 
-                       /* FIXME: Use IPI */
-                       DPRINT ("Requesting APC Interrupt for Running Thread \n");
-                       HalRequestSoftwareInterrupt(APC_LEVEL);
-      } else if ((Thread->State == THREAD_STATE_BLOCKED) && 
+    if (Thread->ApcQueueable == FALSE) {
+        DPRINT("Thread doesn't allow APC Queues\n");
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        return FALSE;
+    }
+    
+    /* Set the System Arguments */
+    Apc->SystemArgument1 = SystemArgument1;
+    Apc->SystemArgument2 = SystemArgument2;
+
+    /* Don't do anything if the APC is already inserted */
+    if (Apc->Inserted) {
+        
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        return FALSE;
+    }
+    
+    /* Three scenarios: 
+       1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
+       2) User APC which is PsExitSpecialApc = Put it at the front of the List
+       3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
+    */
+    if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
+        
+        DPRINT ("Inserting the Process Exit APC into the Queue\n");
+        Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
+        InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
+                       &Apc->ApcListEntry);
+        
+    } else if (Apc->NormalRoutine == NULL) {
+        
+        DPRINT ("Inserting Special APC %x into the Queue\n", Apc);
+        
+        for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
+             ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
+             ApcListEntry = ApcListEntry->Flink) {
+
+            QueuedApc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+            if (Apc->NormalRoutine != NULL) break;
+        }
+        
+        /* We found the first "Normal" APC, so write right before it */
+        ApcListEntry = ApcListEntry->Blink;
+        InsertHeadList(ApcListEntry, &Apc->ApcListEntry);
+        
+    } else {
+        
+        DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
+        InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
+                   &Apc->ApcListEntry);
+    }
+    
+    /* Confirm Insertion */    
+    Apc->Inserted = TRUE;
+
+    /*
+     * Three possibilites here again:
+     *  1) Kernel APC, The thread is Running: Request an Interrupt
+     *  2) Kernel APC, The Thread is Waiting at PASSIVE_LEVEL and APCs are enabled and not in progress: Unwait the Thread
+     *  3) User APC, Unwait the Thread if it is alertable
+     */ 
+    if (Apc->ApcMode == KernelMode) { 
+        
+        /* Set Kernel APC pending */
+        Thread->ApcState.KernelApcPending = TRUE;
+        
+        /* Check the Thread State */
+        if (Thread->State == THREAD_STATE_RUNNING) { 
+            
+            /* FIXME: Use IPI */
+            DPRINT ("Requesting APC Interrupt for Running Thread \n");
+            HalRequestSoftwareInterrupt(APC_LEVEL);
+            
+        } else if ((Thread->State == THREAD_STATE_BLOCKED) && 
                  (Thread->WaitIrql < APC_LEVEL) && 
-                 (Apc->NormalRoutine == NULL)) 
-      {
-                       DPRINT ("Waking up Thread for Kernel-Mode APC Delivery \n");
-                       KiAbortWaitThread(Thread, STATUS_KERNEL_APC);
-               }
+                 (Apc->NormalRoutine == NULL)) {
+          
+            DPRINT("Waking up Thread for Kernel-Mode APC Delivery \n");
+            KiAbortWaitThread(Thread, STATUS_KERNEL_APC);
+        }
+        
    } else if ((Thread->State == THREAD_STATE_BLOCKED) && 
               (Thread->WaitMode == UserMode) && 
-              (Thread->Alertable)) 
-   {
-               DPRINT ("Waking up Thread for User-Mode APC Delivery \n");
-               Thread->ApcState.UserApcPending = TRUE;
-      KiAbortWaitThread(Thread, STATUS_USER_APC);
-       }
-
-       /* Return Sucess if we are here */
-       KeReleaseDispatcherDatabaseLock(OldIrql);
-       return TRUE;
+              (Thread->Alertable)) {
+       
+        DPRINT("Waking up Thread for User-Mode APC Delivery \n");
+        Thread->ApcState.UserApcPending = TRUE;
+        KiAbortWaitThread(Thread, STATUS_USER_APC);
+    }
+
+    /* Return Sucess if we are here */
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return TRUE;
 }
 
-BOOLEAN STDCALL
-KeRemoveQueueApc (PKAPC Apc)
-/*
- * FUNCTION: Removes APC object from the apc queue
- * ARGUMENTS:
- *          Apc = APC to remove
- * RETURNS: TRUE if the APC was in the queue
- *          FALSE otherwise
- * NOTE: This function is not exported.
- */
+/*++
+ * KeLeaveCriticalRegion 
+ * @implemented NT4
+ *
+ *     The KeLeaveCriticalRegion routine reenables the delivery of normal 
+ *     kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion.
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     Highest-level drivers can call this routine while running in the context
+ *     of the thread that requested the current I/O operation. 
+ *
+ *     Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL.
+ *
+ *--*/
+VOID 
+STDCALL 
+KeLeaveCriticalRegion (VOID)
 {
-       KIRQL OldIrql;
-       PKTHREAD Thread = Apc->Thread;
-
-   ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-       DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
-       
-       OldIrql = KeAcquireDispatcherDatabaseLock();
-       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-       
-       /* Remove it from the Queue if it's inserted */
-       if (!Apc->Inserted == FALSE) {
-               RemoveEntryList(&Apc->ApcListEntry);
-               Apc->Inserted = FALSE;
-               
-               /* If the Queue is completely empty, then no more APCs are pending */
-               if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) {
-                       if (Apc->ApcMode == KernelMode) {
-                               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->KernelApcPending = FALSE;
-                       } else {
-                               Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = FALSE;
-                       }
-               }
-       } else {
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-               KeReleaseDispatcherDatabaseLock(OldIrql);
-               return(FALSE);
-       }
-       
-       /* Restore IRQL and Return */
-       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-       KeReleaseDispatcherDatabaseLock(OldIrql);
-       return(TRUE);
+    PKTHREAD Thread = KeGetCurrentThread(); 
+
+    /* Check if Kernel APCs are now enabled */
+    if((Thread) && (++Thread->KernelApcDisable == 0)) { 
+        
+        /* Check if we need to request an APC Delivery */
+        if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) { 
+            
+            /* Set APC Pending */
+            Thread->ApcState.KernelApcPending = TRUE; 
+            HalRequestSoftwareInterrupt(APC_LEVEL); 
+        } 
+    } 
 }
 
+/*++
+ * KeRemoveQueueApc 
+ *
+ *     The KeRemoveQueueApc routine removes a given APC object from the system 
+ *     APC queue.
+ *
+ * Params:
+ *     APC - Pointer to an initialized APC object that was queued by calling
+ *           KeInsertQueueApc.
+ *
+ * Returns:
+ *     TRUE if the APC Object is in the APC Queue. If it isn't, no operation is
+ *     performed and FALSE is returned.
+ *
+ * Remarks:
+ *     If the given APC Object is currently queued, it is removed from the queue
+ *     and any calls to the registered routines are cancelled.
+ *
+ *     Callers of KeLeaveCriticalRegion can be running at any IRQL.
+ *
+ *--*/
+BOOLEAN 
+STDCALL
+KeRemoveQueueApc(PKAPC Apc)
+{
+    KIRQL OldIrql;
+    PKTHREAD Thread = Apc->Thread;
+
+    ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+    DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
+    
+    OldIrql = KeAcquireDispatcherDatabaseLock();
+    KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+    
+    /* Check if it's inserted */
+    if (Apc->Inserted) {
+        
+        /* Remove it from the Queue*/
+        RemoveEntryList(&Apc->ApcListEntry);
+        Apc->Inserted = FALSE;
+        
+        /* If the Queue is completely empty, then no more APCs are pending */
+        if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) {
+            
+            /* Set the correct State based on the Apc Mode */
+            if (Apc->ApcMode == KernelMode) {
+                
+                Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->KernelApcPending = FALSE;
+                
+            } else {
+                
+                Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = FALSE;
+            }
+        }
+        
+    } else {
+        
+        /* It's not inserted, fail */
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+        KeReleaseDispatcherDatabaseLock(OldIrql);
+        return(FALSE);
+    }
+    
+    /* Restore IRQL and Return */
+    KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    KeReleaseDispatcherDatabaseLock(OldIrql);
+    return(TRUE);
+}
 
-/*
- * @implemented
- */
+/*++
+ * KiDeliverApc 
+ * @implemented @NT4
+ *    
+ *     The KiDeliverApc routine is called from IRQL switching code if the
+ *     thread is returning from an IRQL >= APC_LEVEL and Kernel-Mode APCs are
+ *     pending. 
+ *
+ * Params:
+ *     DeliveryMode - Specifies the current processor mode.
+ *
+ *     Reserved - Pointer to the Exception Frame on non-i386 builds.
+ *
+ *     TrapFrame - Pointer to the Trap Frame.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     First, Special APCs are delivered, followed by Kernel-Mode APCs and
+ *     User-Mode APCs. Note that the TrapFrame is only valid if the previous
+ *     mode is User.
+ *
+ *     Upon entry, this routine executes at APC_LEVEL.
+ *
+ *--*/
 VOID 
 STDCALL
 KiDeliverApc(KPROCESSOR_MODE DeliveryMode,
              PVOID Reserved,
              PKTRAP_FRAME TrapFrame)
-/*
- * FUNCTION: Deliver an APC to the current thread.
- * NOTES: This is called from the IRQL switching code if the current thread
- * is returning from an IRQL greater than or equal to APC_LEVEL to 
- * PASSIVE_LEVEL and there are kernel-mode APCs pending. This means any
- * pending APCs will be delivered after a thread gets a new quantum and
- * after it wakes from a wait. Note that the TrapFrame is only valid if
- * the previous mode is User.
- */
 {
-       PKTHREAD Thread = KeGetCurrentThread();
-       PLIST_ENTRY ApcListEntry;
-       PKAPC Apc;
-       KIRQL OldIrql;
-       PKKERNEL_ROUTINE KernelRoutine;
-       PVOID NormalContext;
-       PKNORMAL_ROUTINE NormalRoutine;
-       PVOID SystemArgument1;
-       PVOID SystemArgument2;
+    PKTHREAD Thread = KeGetCurrentThread();
+    PLIST_ENTRY ApcListEntry;
+    PKAPC Apc;
+    KIRQL OldIrql;
+    PKKERNEL_ROUTINE KernelRoutine;
+    PVOID NormalContext;
+    PKNORMAL_ROUTINE NormalRoutine;
+    PVOID SystemArgument1;
+    PVOID SystemArgument2;
    
-   ASSERT_IRQL_EQUAL(APC_LEVEL);
-
-       /* Lock the APC Queue and Raise IRQL to Synch */
-       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-
-       /* Clear APC Pending */
-       Thread->ApcState.KernelApcPending = FALSE;
-       
-       /* Do the Kernel APCs first */
-       while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) {
-       
-               /* Get the next Entry */
-               ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
-               Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-               
-               /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
-               NormalRoutine   = Apc->NormalRoutine;
-               KernelRoutine   = Apc->KernelRoutine;
-               NormalContext   = Apc->NormalContext;
-               SystemArgument1 = Apc->SystemArgument1;
-               SystemArgument2 = Apc->SystemArgument2;
+    ASSERT_IRQL_EQUAL(APC_LEVEL);
+
+    /* Lock the APC Queue and Raise IRQL to Synch */
+    KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+
+    /* Clear APC Pending */
+    Thread->ApcState.KernelApcPending = FALSE;
+    
+    /* Do the Kernel APCs first */
+    while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) {
+    
+        /* Get the next Entry */
+        ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
+        Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+        
+        /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
+        NormalRoutine   = Apc->NormalRoutine;
+        KernelRoutine   = Apc->KernelRoutine;
+        NormalContext   = Apc->NormalContext;
+        SystemArgument1 = Apc->SystemArgument1;
+        SystemArgument2 = Apc->SystemArgument2;
        
-               /* Special APC */
-       if (NormalRoutine == NULL) {
-                       /* Remove the APC from the list */
-                       Apc->Inserted = FALSE;
-                       RemoveEntryList(ApcListEntry);
-                       
-                       /* Go back to APC_LEVEL */
-                       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                       
-                       /* Call the Special APC */
-                       DPRINT("Delivering a Special APC: %x\n", Apc);
-                       KernelRoutine(Apc,
-                                     &NormalRoutine,
-                                     &NormalContext,
-                                     &SystemArgument1,
-                                     &SystemArgument2);
-
-                       /* Raise IRQL and Lock again */
-                       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-               } else {
-                        /* Normal Kernel APC */
-                       if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
+        /* Special APC */
+       if (NormalRoutine == NULL) {
+           
+            /* Remove the APC from the list */
+            Apc->Inserted = FALSE;
+            RemoveEntryList(ApcListEntry);
+            
+            /* Go back to APC_LEVEL */
+            KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+            
+            /* Call the Special APC */
+            DPRINT("Delivering a Special APC: %x\n", Apc);
+            KernelRoutine(Apc,
+                      &NormalRoutine,
+                      &NormalContext,
+                      &SystemArgument1,
+                      &SystemArgument2);
+
+            /* Raise IRQL and Lock again */
+            KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
             
-            /*
-             * DeliveryMode must be KernelMode in this case, since one may not
-             * return to umode while being inside a critical section or while 
-             * a regular kmode apc is running (the latter should be impossible btw).
-             * -Gunnar
-             */
-            ASSERT(DeliveryMode == KernelMode);
-
-                               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                               return;
-                       }
-                       
-                       /* Dequeue the APC */
-                       RemoveEntryList(ApcListEntry);
-                       Apc->Inserted = FALSE;
-                       
-                       /* Go back to APC_LEVEL */
-                       KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-                       
-                       /* Call the Kernel APC */
-                       DPRINT("Delivering a Normal APC: %x\n", Apc);
-                       KernelRoutine(Apc,
-                                     &NormalRoutine,
-                                     &NormalContext,
-                                     &SystemArgument1,
-                                     &SystemArgument2);
-                       
-                       /* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */
-                       if (NormalRoutine != NULL) {
-                               /* At Passive Level, this APC can be prempted by a Special APC */
-                               Thread->ApcState.KernelApcInProgress = TRUE;
-                               KeLowerIrql(PASSIVE_LEVEL);
-                               
-                               /* Call and Raise IRQ back to APC_LEVEL */
-                               DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc);
-                               NormalRoutine(&NormalContext, &SystemArgument1, &SystemArgument2);
-                               KeRaiseIrql(APC_LEVEL, &OldIrql);
-                       }
-
-                       /* Raise IRQL and Lock again */
-                       KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-                       Thread->ApcState.KernelApcInProgress = FALSE;
-               }
-       }
-       
-       /* Now we do the User APCs */
-       if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
-          (DeliveryMode == UserMode) &&
-                        (Thread->ApcState.UserApcPending == TRUE)) {
-                        
-               /* It's not pending anymore */
-               Thread->ApcState.UserApcPending = FALSE;
-
-               /* Get the APC Object */
-               ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
-               Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-               
-               /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
-               NormalRoutine   = Apc->NormalRoutine;
-               KernelRoutine   = Apc->KernelRoutine;
-               NormalContext   = Apc->NormalContext;
-               SystemArgument1 = Apc->SystemArgument1;
-               SystemArgument2 = Apc->SystemArgument2; 
-               
-               /* Remove the APC from Queue, restore IRQL and call the APC */
-               RemoveEntryList(ApcListEntry);
-      Apc->Inserted = FALSE;
+        } else {
+            
+             /* Normal Kernel APC */
+            if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
+            
+                /*
+                 * DeliveryMode must be KernelMode in this case, since one may not
+                 * return to umode while being inside a critical section or while 
+                 * a regular kmode apc is running (the latter should be impossible btw).
+                 * -Gunnar
+                 */
+                ASSERT(DeliveryMode == KernelMode);
+
+                KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+                return;
+            }
+            
+            /* Dequeue the APC */
+            RemoveEntryList(ApcListEntry);
+            Apc->Inserted = FALSE;
+            
+            /* Go back to APC_LEVEL */
+            KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+            
+            /* Call the Kernel APC */
+            DPRINT("Delivering a Normal APC: %x\n", Apc);
+            KernelRoutine(Apc,
+                      &NormalRoutine,
+                      &NormalContext,
+                      &SystemArgument1,
+                      &SystemArgument2);
+            
+            /* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */
+            if (NormalRoutine != NULL) {
+                
+                /* At Passive Level, this APC can be prempted by a Special APC */
+                Thread->ApcState.KernelApcInProgress = TRUE;
+                KeLowerIrql(PASSIVE_LEVEL);
+                
+                /* Call and Raise IRQ back to APC_LEVEL */
+                DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc);
+                NormalRoutine(&NormalContext, &SystemArgument1, &SystemArgument2);
+                KeRaiseIrql(APC_LEVEL, &OldIrql);
+            }
+
+            /* Raise IRQL and Lock again */
+            KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
+            Thread->ApcState.KernelApcInProgress = FALSE;
+        }
+    }
+    
+    /* Now we do the User APCs */
+    if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
+        (DeliveryMode == UserMode) && (Thread->ApcState.UserApcPending == TRUE)) {
+             
+        /* It's not pending anymore */
+        Thread->ApcState.UserApcPending = FALSE;
+
+        /* Get the APC Object */
+        ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
+        Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
+        
+        /* Save Parameters so that it's safe to free the Object in Kernel Routine*/
+        NormalRoutine   = Apc->NormalRoutine;
+        KernelRoutine   = Apc->KernelRoutine;
+        NormalContext   = Apc->NormalContext;
+        SystemArgument1 = Apc->SystemArgument1;
+        SystemArgument2 = Apc->SystemArgument2; 
+        
+        /* Remove the APC from Queue, restore IRQL and call the APC */
+        RemoveEntryList(ApcListEntry);
+        Apc->Inserted = FALSE;
       
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-               DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
-               KernelRoutine(Apc,
-                             &NormalRoutine,
-                             &NormalContext,
-                             &SystemArgument1,
-                             &SystemArgument2);
-
-               if (NormalRoutine == NULL) {
-                       /* Check if more User APCs are Pending */
-                       KeTestAlertThread(UserMode);
-               } else {
-                       /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
-                       DPRINT("Delivering a User APC: %x\n", Apc);
-                       KiInitializeUserApc(Reserved, 
-                                           TrapFrame,
-                                           NormalRoutine,
-                                           NormalContext,
-                                           SystemArgument1,
-                                           SystemArgument2);
-               }
-       } else {
-               /* Go back to APC_LEVEL */
-               KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-       }
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+        DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
+        KernelRoutine(Apc,
+                  &NormalRoutine,
+                  &NormalContext,
+                  &SystemArgument1,
+                  &SystemArgument2);
+
+        if (NormalRoutine == NULL) {
+            
+            /* Check if more User APCs are Pending */
+            KeTestAlertThread(UserMode);
+            
+        } else {
+            
+            /* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
+            DPRINT("Delivering a User APC: %x\n", Apc);
+            KiInitializeUserApc(Reserved, 
+                        TrapFrame,
+                        NormalRoutine,
+                        NormalContext,
+                        SystemArgument1,
+                        SystemArgument2);
+        }
+        
+    } else {
+        
+        /* Go back to APC_LEVEL */
+        KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
+    }
 }
 
 VOID 
 STDCALL
 KiFreeApcRoutine(PKAPC Apc,
-                PKNORMAL_ROUTINE* NormalRoutine,
-                PVOID* NormalContext,
-                PVOID* SystemArgument1,
-                PVOID* SystemArgument2)
+                 PKNORMAL_ROUTINE* NormalRoutine,
+                 PVOID* NormalContext,
+                 PVOID* SystemArgument1,
+                 PVOID* SystemArgument2)
 {
-       /* Free the APC and do nothing else */
-       ExFreePool(Apc);
+    /* Free the APC and do nothing else */
+    ExFreePool(Apc);
 }
 
-VOID 
+/*++
+ * KiInitializeUserApc 
+ *    
+ *     Prepares the Context for a User-Mode APC called through NTDLL.DLL
+ *
+ * Params:
+ *     Reserved - Pointer to the Exception Frame on non-i386 builds.
+ *
+ *     TrapFrame - Pointer to the Trap Frame.
+ *
+ *     NormalRoutine - Pointer to the NormalRoutine to call.
+ *
+ *     NormalContext - Pointer to the context to send to the Normal Routine.
+ *
+ *     SystemArgument[1-2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ * Returns:
+ *     None.
+ *
+ * Remarks:
+ *     None.
+ *
+ *--*/
+VOID
+STDCALL
 KiInitializeUserApc(IN PVOID Reserved,
-                   IN PKTRAP_FRAME TrapFrame,
-                   IN PKNORMAL_ROUTINE NormalRoutine,
-                   IN PVOID NormalContext,
-                   IN PVOID SystemArgument1,
-                   IN PVOID SystemArgument2)  
-/*
- * FUNCTION: Prepares the Context for a user mode APC through ntdll.dll
- */
+                    IN PKTRAP_FRAME TrapFrame,
+                    IN PKNORMAL_ROUTINE NormalRoutine,
+                    IN PVOID NormalContext,
+                    IN PVOID SystemArgument1,
+                    IN PVOID SystemArgument2)  
 {
-       PCONTEXT Context;
-       PULONG Esp;
+    PCONTEXT Context;
+    PULONG Esp;
 
-       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;
+    /*
+     * 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;
        
-       /*
-        * 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)LdrpGetSystemDllApcDispatcher();
-       TrapFrame->Esp = (ULONG)Esp;
+    /*
+     * 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)LdrpGetSystemDllApcDispatcher();
+    TrapFrame->Esp = (ULONG)Esp;
 }
 
-/*
- * @implemented
- */
+/*++
+ * KeAreApcsDisabled 
+ * @implemented NT4
+ *    
+ *     Prepares the Context for a User-Mode APC called through NTDLL.DLL
+ *
+ * Params:
+ *     None.
+ *
+ * Returns:
+ *     KeAreApcsDisabled returns TRUE if the thread is within a critical region
+ *     or a guarded region, and FALSE otherwise.
+ *
+ * Remarks:
+ *     A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled to 
+ *     determine if normal kernel APCs are disabled. A thread that is inside a 
+ *     critical region has both user APCs and normal kernel APCs disabled, but 
+ *     not special kernel APCs. A thread that is inside a guarded region has 
+ *     all APCs disabled, including special kernel APCs.
+ *
+ *     Callers of this routine must be running at IRQL <= APC_LEVEL.
+ *
+ *--*/
 BOOLEAN
 STDCALL
-KeAreApcsDisabled(
-       VOID
-       )
+KeAreApcsDisabled(VOID)
 {
-       return KeGetCurrentThread()->KernelApcDisable ? TRUE : FALSE;
+    /* Return the Kernel APC State */
+    return KeGetCurrentThread()->KernelApcDisable ? TRUE : FALSE;
 }
 
+/*++
+ * NtQueueApcThread 
+ * NT4
+ *    
+ *    This routine is used to queue an APC from user-mode for the specified 
+ *    thread.
+ *
+ * Params:
+ *     Thread Handle - Handle to the Thread. This handle must have THREAD_SET_CONTEXT privileges.
+ *
+ *     ApcRoutine - Pointer to the APC Routine to call when the APC executes.
+ *
+ *     NormalContext - Pointer to the context to send to the Normal Routine.
+ *
+ *     SystemArgument[1-2] - Pointer to a set of two parameters that contain
+ *                           untyped data.
+ *
+ * Returns:
+ *     STATUS_SUCCESS or failure cute from associated calls.
+ *
+ * Remarks:
+ *      The thread must enter an alertable wait before the APC will be 
+ *      delivered.
+ *
+ *--*/
 NTSTATUS 
 STDCALL
-NtQueueApcThread(HANDLE                        ThreadHandle,
-                PKNORMAL_ROUTINE       ApcRoutine,
-                PVOID                  NormalContext,
-                PVOID                  SystemArgument1,
-                PVOID                  SystemArgument2)
-/*
- * FUNCTION: 
- *           This function is used to queue an APC from user-mode for the specified thread.
- *           The thread must enter an alertable wait before the APC will be delivered.
- *
- * ARGUMENTS:
- *           Thread Handle - Handle to the Thread. This handle must have THREAD_SET_CONTEXT privileges.
- *           ApcRoutine - Pointer to the APC Routine to call when the APC executes.
- *           NormalContext - User-defined value to pass to the APC Routine
- *           SystemArgument1 - User-defined value to pass to the APC Routine
- *           SystemArgument2 - User-defined value to pass to the APC Routine
- *
- * RETURNS:  NTSTATUS SUCCESS or Failure Code from included calls.
- */
+NtQueueApcThread(HANDLE ThreadHandle,
+         PKNORMAL_ROUTINE ApcRoutine,
+         PVOID NormalContext,
+         PVOID SystemArgument1,
+         PVOID SystemArgument2)
 {
-
-       PKAPC Apc;
-       PETHREAD Thread;
-       KPROCESSOR_MODE PreviousMode;
-       NTSTATUS Status;
-       
-       PreviousMode = ExGetPreviousMode();
-
-       /* Get ETHREAD from Handle */
-       Status = ObReferenceObjectByHandle(ThreadHandle,
-                                          THREAD_SET_CONTEXT,
-                                          PsThreadType,
-                                          PreviousMode,
-                                          (PVOID)&Thread,
-                                          NULL);
-       
-       /* Fail if the Handle is invalid for some reason */
-       if (!NT_SUCCESS(Status)) {
-               return(Status);
-       }
-       
-       /* If this is a Kernel or System Thread, then fail */
-       if (Thread->Tcb.Teb == NULL) {
-               ObDereferenceObject(Thread);
-               return STATUS_INVALID_HANDLE;
-       }
+    PKAPC Apc;
+    PETHREAD Thread;
+    KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+    NTSTATUS Status;
+
+    /* Get ETHREAD from Handle */
+    Status = ObReferenceObjectByHandle(ThreadHandle,
+                       THREAD_SET_CONTEXT,
+                       PsThreadType,
+                       PreviousMode,
+                       (PVOID)&Thread,
+                       NULL);
+    
+    /* Fail if the Handle is invalid for some reason */
+    if (!NT_SUCCESS(Status)) {
+        
+        return(Status);
+    }
+    
+    /* If this is a Kernel or System Thread, then fail */
+    if (Thread->Tcb.Teb == NULL) {
+        
+        ObDereferenceObject(Thread);
+        return STATUS_INVALID_HANDLE;
+    }
    
-       /* Allocate an APC */
-       Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_KAPC);
-       if (Apc == NULL) {
-               ObDereferenceObject(Thread);
-               return(STATUS_NO_MEMORY);
-       }
+    /* Allocate an APC */
+    Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('P', 's', 'a', 'p'));
+    if (Apc == NULL) {
+        
+        ObDereferenceObject(Thread);
+        return(STATUS_NO_MEMORY);
+    }
    
-       /* Initialize and Queue a user mode apc (always!) */
-       KeInitializeApc(Apc,
-                       &Thread->Tcb,
-                       OriginalApcEnvironment,
-                       KiFreeApcRoutine,
-                       NULL,
-                       ApcRoutine,
-                       UserMode,
-                       NormalContext);
-       if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) {
-               Status = STATUS_UNSUCCESSFUL;
-       } else {
-               Status = STATUS_SUCCESS;
-       }
+    /* Initialize and Queue a user mode apc (always!) */
+    KeInitializeApc(Apc,
+                    &Thread->Tcb,
+                    OriginalApcEnvironment,
+                    KiFreeApcRoutine,
+                    NULL,
+                    ApcRoutine,
+                    UserMode,
+                    NormalContext);
+    
+    if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) {
+        
+        Status = STATUS_UNSUCCESSFUL;
+        
+    } else {
+        
+        Status = STATUS_SUCCESS;
+    }
    
-       /* Dereference Thread and Return */
-       ObDereferenceObject(Thread);
-       return Status;
+    /* Dereference Thread and Return */
+    ObDereferenceObject(Thread);
+    return Status;
 }
 
-
-static inline VOID RepairList(PLIST_ENTRY Original, 
-                             PLIST_ENTRY Copy,
-                             KPROCESSOR_MODE Mode)
+static inline 
+VOID RepairList(PLIST_ENTRY Original, 
+                PLIST_ENTRY Copy,
+                KPROCESSOR_MODE Mode)
 {
-       /* Copy Source to Desination */
-       if (IsListEmpty(&Original[(int)Mode])) {
-               InitializeListHead(&Copy[(int)Mode]);
-       } else {
-               Copy[(int)Mode].Flink = Original[(int)Mode].Flink; 
-               Copy[(int)Mode].Blink = Original[(int)Mode].Blink;
-               Original[(int)Mode].Flink->Blink = &Copy[(int)Mode];
-               Original[(int)Mode].Blink->Flink = &Copy[(int)Mode];
-       }
+    /* Copy Source to Desination */
+    if (IsListEmpty(&Original[(int)Mode])) {
+        
+        InitializeListHead(&Copy[(int)Mode]);
+        
+    } else {
+        
+        Copy[(int)Mode].Flink = Original[(int)Mode].Flink; 
+        Copy[(int)Mode].Blink = Original[(int)Mode].Blink;
+        Original[(int)Mode].Flink->Blink = &Copy[(int)Mode];
+        Original[(int)Mode].Blink->Flink = &Copy[(int)Mode];
+    }
 }
 
 VOID
 STDCALL
-KiMoveApcState (PKAPC_STATE OldState,
-               PKAPC_STATE NewState)
+KiMoveApcState(PKAPC_STATE OldState,
+               PKAPC_STATE NewState)
 {
-       /* Restore backup of Original Environment */
-       *NewState = *OldState;
+    /* Restore backup of Original Environment */
+    *NewState = *OldState;
     
-       /* Repair Lists */
-       RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode);
-       RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode);
+    /* Repair Lists */
+    RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode);
+    RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode);
 }
 
index 2af3e26..fd2f58c 100644 (file)
@@ -47,6 +47,17 @@ KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
        return FALSE;
 }
 
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+KeDeregisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
 /*
  * @implemented
  */
@@ -74,6 +85,20 @@ KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
        return(FALSE);
 }
 
+/*
+ * @unimplemented
+ */
+BOOLEAN
+STDCALL
+KeRegisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
+                                 IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
+                                 IN KBUGCHECK_CALLBACK_REASON Reason,
+                                 IN PUCHAR Component)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
 VOID STDCALL
 KeBugCheckWithTf(ULONG BugCheckCode,        
                 ULONG BugCheckParameter1,
index 1d4ca92..1657b5f 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/catch.c
@@ -21,282 +20,206 @@ ULONG
 RtlpDispatchException(IN PEXCEPTION_RECORD  ExceptionRecord,
        IN PCONTEXT  Context);
 
+/*
+ * @unimplemented
+ */
 VOID
-KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
-                   PCONTEXT Context,
-                   PKTRAP_FRAME Tf,
-                   KPROCESSOR_MODE PreviousMode,
-                   BOOLEAN SearchFrames)
+STDCALL
+KiCoprocessorError(VOID)
 {
-  EXCEPTION_DISPOSITION Value;
-  CONTEXT TContext;
-  KD_CONTINUE_TYPE Action = kdHandleException;
-
-  DPRINT("KiDispatchException() called\n");
-
+    UNIMPLEMENTED;
+}
 
-  /* PCR->KeExceptionDispatchCount++; */
+/*
+ * @unimplemented
+ */
+VOID
+STDCALL
+KiUnexpectedInterrupt(VOID)
+{
+    UNIMPLEMENTED;
+}
 
-  if (Context == NULL)
-    {
-      TContext.ContextFlags = CONTEXT_FULL;
-      if (PreviousMode == UserMode)
-       {
-         TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
-       }
+VOID
+KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
+                    PCONTEXT Context,
+                    PKTRAP_FRAME Tf,
+                    KPROCESSOR_MODE PreviousMode,
+                    BOOLEAN SearchFrames)
+{
+    EXCEPTION_DISPOSITION Value;
+    CONTEXT TContext;
+    KD_CONTINUE_TYPE Action = kdHandleException;
+
+    DPRINT("KiDispatchException() called\n");
+
+    /* Increase number of Exception Dispatches */
+    KeGetCurrentKPCR()->PrcbData.KeExceptionDispatchCount++;
+
+    if (!Context) {
+        
+        /* Assume Full context */
+        TContext.ContextFlags = CONTEXT_FULL;
+        
+        /* Check the mode */
+        if (PreviousMode == UserMode) {
+            
+            /* Add Debugger Registers if this is User Mode */
+            TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
+        }
   
-      KeTrapFrameToContext(Tf, &TContext);
+        /* Convert the Trapframe into a Context */
+        KeTrapFrameToContext(Tf, &TContext);
 
-      Context = &TContext;
+        /* Use local stack context */
+        Context = &TContext;
     }
 
-#if 0
-  if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) 
-    {
-      Context->Eip--;
+#if 0 /* FIXME: Isn't this right? With a break after? */
+    if (ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) {
+        Context->Eip--;
     }
 #endif
-      
-  if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB)
-    {
-      Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
-    }
 
-  if (Action == kdContinue)
-    {
-      return;
+    /* Check if a Debugger is enabled */
+    if (KdDebuggerEnabled && KdDebugState & KD_DEBUG_GDB) {
+    
+        /* Break into it */
+        Action = KdEnterDebuggerException (ExceptionRecord, Context, Tf);
     }
-
-  if (Action != kdDoNotHandleException)
-    {
-      if (PreviousMode == UserMode)
-       {
-         if (SearchFrames)
-           {
-             PULONG Stack;
-             ULONG CDest;
-             char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
-             PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
-             NTSTATUS StatusOfCopy;
+    
+    /* If the debugger said continue, then continue */
+    if (Action == kdContinue) return;
+    
+    /* If the Debugger couldn't handle it... */
+    if (Action != kdDoNotHandleException) {
+        
+        /* See what kind of Exception this is */
+        if (PreviousMode == UserMode) {
+            
+            /* User mode exception, search the frames if we have to */
+            if (SearchFrames) {
+
+                PULONG Stack;
+                ULONG CDest;
+                char temp_space[12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)]; /* FIXME: HACKHACK */
+                PULONG pNewUserStack = (PULONG)(Tf->Esp - (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
+                NTSTATUS StatusOfCopy;
 
 #ifdef KDBG
-             Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                                 Context, Tf, FALSE);
-              if (Action == kdContinue)
-                {
-                  return;
-                }
+                /* Enter KDB if available */
+                Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                   PreviousMode,
+                                                   Context, 
+                                                   Tf, 
+                                                   FALSE);
+
+                /* Exit if we're continuing */
+                if (Action == kdContinue) return;
 #endif
 
-             /* FIXME: Forward exception to user mode debugger */
-
-             /* FIXME: Check user mode stack for enough space */
-         
-             /*
-              * Let usermode try and handle the exception
-              */
-             Stack = (PULONG)temp_space;
-             CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
-             /* Return address */
-             Stack[0] = 0;    
-             /* Pointer to EXCEPTION_RECORD structure */
-             Stack[1] = (ULONG)&pNewUserStack[3];
-             /* Pointer to CONTEXT structure */
-             Stack[2] = (ULONG)&pNewUserStack[CDest];
-             memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
-             memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
-
-             StatusOfCopy = MmCopyToCaller(pNewUserStack,
-                                           temp_space,
-                                           (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
-             if (NT_SUCCESS(StatusOfCopy))
-               {
-                 Tf->Esp = (ULONG)pNewUserStack;
-               }
-             else
-               {
-                 /* Now it really hit the ventilation device. Sorry,
-                  * can do nothing but kill the sucker.
-                  */
-                 ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
-                 DPRINT1("User-mode stack was invalid. Terminating target thread\n");
-               }
-             Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
-             return;
-           }
+            /* FIXME: Forward exception to user mode debugger */
+
+            /* FIXME: Check user mode stack for enough space */
+    
+            /* Let usermode try and handle the exception. Setup Stack */
+            Stack = (PULONG)temp_space;
+            CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
+            /* Return Address */
+            Stack[0] = 0;
+            /* Pointer to EXCEPTION_RECORD structure */
+            Stack[1] = (ULONG)&pNewUserStack[3];
+            /* Pointer to CONTEXT structure */
+            Stack[2] = (ULONG)&pNewUserStack[CDest];
+            memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
+            memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
+            
+            /* Copy Stack */
+            StatusOfCopy = MmCopyToCaller(pNewUserStack,
+                                          temp_space,
+                                          (12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
+            
+            /* Check for success */
+            if (NT_SUCCESS(StatusOfCopy)) {
+                
+                /* Set new Stack Pointer */
+                Tf->Esp = (ULONG)pNewUserStack;
+                
+            } else {
+                
+                /*
+                 * Now it really hit the ventilation device. Sorry,
+                 * can do nothing but kill the sucker.
+                 */
+                ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+                DPRINT1("User-mode stack was invalid. Terminating target thread\n");
+            }
+            
+            /* Set EIP to the User-mode Dispathcer */
+            Tf->Eip = (ULONG)LdrpGetSystemDllExceptionDispatcher();
+            return;
+        }
 
-         /* FIXME: Forward the exception to the debugger */
+        /* FIXME: Forward the exception to the debugger */
 
-         /* FIXME: Forward the exception to the process exception port */
+        /* FIXME: Forward the exception to the process exception port */
 
+                  
 #ifdef KDBG
-         Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                             Context, Tf, TRUE);
-          if (Action == kdContinue)
-            {
-              return;
-            }
+        /* Enter KDB if available */
+        Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                            PreviousMode,
+                                            Context, 
+                                            Tf, 
+                                            TRUE);
+
+        /* Exit if we're continuing */
+        if (Action == kdContinue) return;
 #endif
 
-         /* Terminate the offending thread */
-         DPRINT1("Unhandled UserMode exception, terminating thread\n");
-         ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
-       }
-      else
-       {
-         /* PreviousMode == KernelMode */
+        /* Terminate the offending thread */
+        DPRINT1("Unhandled UserMode exception, terminating thread\n");
+        ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
+        
+        } else {
+
+            /* This is Kernel Mode */            
 #ifdef KDBG
-         Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                             Context, Tf, FALSE);
-          if (Action == kdContinue)
-            {
-              return;
-            }
+            /* Enter KDB if available */
+            Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                PreviousMode,
+                                                Context, 
+                                                Tf, 
+                                                FALSE);
+
+            /* Exit if we're continuing */
+            if (Action == kdContinue) return;
 #endif
 
-         Value = RtlpDispatchException (ExceptionRecord, Context);
-         
-         DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
-         /* 
-          * If RtlpDispatchException() does not handle the exception then 
-          * bugcheck 
-          */
-         if (Value != ExceptionContinueExecution ||
-             0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
-           {
-             DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n",
-                    ExceptionRecord->ExceptionAddress );
+            /* Dispatch the Exception */
+            Value = RtlpDispatchException (ExceptionRecord, Context);
+            DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
+        
+            /* If RtlpDispatchException() did not handle the exception then bugcheck */
+            if (Value != ExceptionContinueExecution ||
+                0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE)) {
+            
+                DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress);
 #ifdef KDBG
-              Action = KdbEnterDebuggerException (ExceptionRecord, PreviousMode,
-                                                  Context, Tf, TRUE);
-              if (Action == kdContinue)
-                {
-                  return;
-                }
+                /* Enter KDB if available */
+                Action = KdbEnterDebuggerException(ExceptionRecord, 
+                                                   PreviousMode,
+                                                   Context, 
+                                                   Tf, 
+                                                   TRUE);
+
+                /* Exit if we're continuing */
+                if (Action == kdContinue) return;
 #endif
-             KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf);
-           }
-       }
+                KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED, 0, 0, 0, 0, Tf);
+            }
+        }
     }
 }
 
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseAccessViolation (VOID)
-{
-  ExRaiseStatus (STATUS_ACCESS_VIOLATION);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseDatatypeMisalignment (VOID)
-{
-  ExRaiseStatus (STATUS_DATATYPE_MISALIGNMENT);
-}
-
-/*
- * @implemented
- */
-VOID STDCALL
-ExRaiseStatus (IN NTSTATUS Status)
-{
-  EXCEPTION_RECORD ExceptionRecord;
-
-  DPRINT("ExRaiseStatus(%x)\n", Status);
-
-  ExceptionRecord.ExceptionRecord = NULL;
-  ExceptionRecord.NumberParameters = 0;
-  ExceptionRecord.ExceptionCode = Status;
-  ExceptionRecord.ExceptionFlags = 0;
-
-  RtlRaiseException(&ExceptionRecord);
-}
-
-
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-ExRaiseException (
-       PEXCEPTION_RECORD ExceptionRecord
-       )
-{
-    RtlRaiseException(ExceptionRecord);
-}
-
-/*
- * @implemented
- */
-BOOLEAN
-STDCALL
-ExSystemExceptionFilter(VOID)
-{
-  return KeGetPreviousMode() != KernelMode ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-ExRaiseHardError (
-       IN NTSTATUS ErrorStatus,
-       IN ULONG NumberOfParameters, 
-       IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
-       IN PVOID *Parameters, 
-       IN HARDERROR_RESPONSE_OPTION ResponseOption, 
-       OUT PHARDERROR_RESPONSE Response 
-       )
-{
-       UNIMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-BOOLEAN
-STDCALL
-KeDeregisterBugCheckReasonCallback(
-    IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
-    )
-{
-       UNIMPLEMENTED;
-       return FALSE;
-}
-
-/*
- * @unimplemented
- */
-ULONG
-STDCALL
-KeGetRecommendedSharedDataAlignment(
-       VOID
-       )
-{
-       UNIMPLEMENTED;
-       return 0;
-}
-
-/*
- * @unimplemented
- */
-BOOLEAN
-STDCALL
-KeRegisterBugCheckReasonCallback(
-    IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
-    IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
-    IN KBUGCHECK_CALLBACK_REASON Reason,
-    IN PUCHAR Component
-    )
-{
-       UNIMPLEMENTED;
-       return FALSE;
-}
-
 /* EOF */
diff --git a/reactos/ntoskrnl/ke/critical.c b/reactos/ntoskrnl/ke/critical.c
deleted file mode 100644 (file)
index e242854..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/critical.c
- * PURPOSE:         Implement critical regions
- * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-VOID STDCALL KeEnterCriticalRegion (VOID)
-{
-   PKTHREAD Thread = KeGetCurrentThread(); 
-   
-   DPRINT("KeEnterCriticalRegion()\n");
-   
-   if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
-
-   Thread->KernelApcDisable--;
-}
-
-/*
- * @implemented
- */
-VOID STDCALL KeLeaveCriticalRegion (VOID)
-{
-  PKTHREAD Thread = KeGetCurrentThread(); 
-
-  DPRINT("KeLeaveCriticalRegion()\n");
-  
-  if (!Thread) return; /* <-Early in the boot process the current thread is obseved to be NULL */
-
-  /* Reference: http://www.ntfsd.org/archive/ntfsd0104/msg0203.html */
-  if(++Thread->KernelApcDisable == 0) 
-  { 
-    if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) 
-    { 
-      Thread->ApcState.KernelApcPending = TRUE; 
-      HalRequestSoftwareInterrupt(APC_LEVEL); 
-    } 
-  } 
-
-}
-
-/* EOF */
index 2aee866..0d68ce6 100644 (file)
 /* TYPES *******************************************************************/
 
 #define MAX_QUANTUM 0x7F
-/* GLOBALS ******************************************************************/
 
 /* FUNCTIONS ****************************************************************/
 
-VOID INIT_FUNCTION
-KeInitDpc(PKPCR Pcr)
 /*
  * FUNCTION: Initialize DPC handling
  */
+VOID
+INIT_FUNCTION
+KeInitDpc(PKPCR Pcr)
 {
    InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead);
    KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0);
@@ -47,9 +47,9 @@ KeInitDpc(PKPCR Pcr)
  */
 VOID
 STDCALL
-KeInitializeThreadedDpc(PKDPC                  Dpc,
-                       PKDEFERRED_ROUTINE      DeferredRoutine,
-                       PVOID                   DeferredContext)
+KeInitializeThreadedDpc(PKDPC Dpc,
+                        PKDEFERRED_ROUTINE DeferredRoutine,
+                        PVOID DeferredContext)
 /*
  * FUNCTION: 
  *          Initalizes a Threaded DPC and registers the DeferredRoutine for it.
@@ -60,24 +60,18 @@ KeInitializeThreadedDpc(PKDPC                       Dpc,
  * NOTE: Callers can be running at any IRQL.
  */
 {
-       DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
-       //Dpc->Type = KThreadedDpc;
-       Dpc->Number= 0;
-       Dpc->Importance= MediumImportance;
-       Dpc->DeferredRoutine = DeferredRoutine;
-       Dpc->DeferredContext = DeferredContext;
-       Dpc->DpcData = NULL;
+    DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
+    Dpc->Type = ThreadedDpcObject;
+    Dpc->Number= 0;
+    Dpc->Importance= MediumImportance;
+    Dpc->DeferredRoutine = DeferredRoutine;
+    Dpc->DeferredContext = DeferredContext;
+    Dpc->DpcData = NULL;
 }
 
 /*
  * @implemented
- */
-VOID
-STDCALL
-KeInitializeDpc (PKDPC                 Dpc,
-                PKDEFERRED_ROUTINE     DeferredRoutine,
-                PVOID                  DeferredContext)
-/*
+ *
  * FUNCTION: 
  *          Initalizes a DPC and registers the DeferredRoutine for it.
  * ARGUMENTS:
@@ -86,24 +80,24 @@ KeInitializeDpc (PKDPC                      Dpc,
  *          DeferredContext = Parameter to be passed to the callback routine.
  * NOTE: Callers can be running at any IRQL.
  */
+VOID
+STDCALL
+KeInitializeDpc(PKDPC Dpc,
+                PKDEFERRED_ROUTINE DeferredRoutine,
+                PVOID DeferredContext)
 {
-       DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
-       Dpc->Type = KDpc;
-       Dpc->Number= 0;
-       Dpc->Importance= MediumImportance;
-       Dpc->DeferredRoutine = DeferredRoutine;
-       Dpc->DeferredContext = DeferredContext;
-       Dpc->DpcData = NULL;
+    DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
+    Dpc->Type = DpcObject;
+    Dpc->Number= 0;
+    Dpc->Importance= MediumImportance;
+    Dpc->DeferredRoutine = DeferredRoutine;
+    Dpc->DeferredContext = DeferredContext;
+    Dpc->DpcData = NULL;
 }
 
 /*
  * @implemented
- */
-BOOLEAN STDCALL
-KeInsertQueueDpc (PKDPC        Dpc,
-                 PVOID SystemArgument1,
-                 PVOID SystemArgument2)
-/*
+ *
  * FUNCTION: 
  *          Queues a DPC for execution when the IRQL of a processor
  *          drops below DISPATCH_LEVEL
@@ -155,124 +149,141 @@ KeInsertQueueDpc (PKDPC Dpc,
  * is greater that the target depth or the minimum DPC rate is less than the
  * target rate.
  */
+BOOLEAN 
+STDCALL
+KeInsertQueueDpc(PKDPC Dpc,
+                 PVOID SystemArgument1,
+                 PVOID SystemArgument2)
 {
-       KIRQL OldIrql;
-       PKPCR Pcr;
-
-       DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
-               Dpc, SystemArgument1, SystemArgument2);
-
-       /* Check IRQL and Raise it to HIGH_LEVEL */
-       ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-       
-       /* Check if this is a Thread DPC, which we don't support (yet) */
-       //if (Dpc->Type == KThreadedDpc) {
-       //      return FALSE;
-       //      KeLowerIrql(OldIrql);
-       //}
+    KIRQL OldIrql;
+    PKPCR Pcr;
+
+    DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
+        Dpc, SystemArgument1, SystemArgument2);
+
+    /* Check IRQL and Raise it to HIGH_LEVEL */
+    ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    
+    /* Check if this is a Thread DPC, which we don't support (yet) */
+    if (Dpc->Type == ThreadedDpcObject) {
+        return FALSE;
+        KeLowerIrql(OldIrql);
+    }
 
 #ifdef CONFIG_SMP
-       /* Get the right PCR for this CPU */
-       if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-               ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
-               Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
-       } else {
-               ASSERT (Dpc->Number < KeNumberProcessors);
-               Pcr = KeGetCurrentKPCR();
-               Dpc->Number = KeGetCurrentProcessorNumber();
-       }
-       KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    /* Get the right PCR for this CPU */
+    if (Dpc->Number >= MAXIMUM_PROCESSORS) {
+    
+        ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
+        Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE);
+        
+    } else {
+        
+        ASSERT (Dpc->Number < KeNumberProcessors);
+        Pcr = KeGetCurrentKPCR();
+        Dpc->Number = KeGetCurrentProcessorNumber();
+    }
+    
+    KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #else
-       Pcr = (PKPCR)KPCR_BASE;
+    Pcr = (PKPCR)KPCR_BASE;
 #endif
 
-       /* Get the DPC Data */
-       if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) {
-               DPRINT("DPC Already Inserted");
+    /* Get the DPC Data */
+    if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) {
+    
+        DPRINT("DPC Already Inserted");
 #ifdef CONFIG_SMP
-               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+        KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #endif
-               KeLowerIrql(OldIrql);
-               return(FALSE);
-       }
-       
-       /* Make sure the lists are free if the Queue is 0 */
-       if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) {
-               ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
-       } else {
-               ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));    
-       }
-
-       /* Now we can play with the DPC safely */
-       Dpc->SystemArgument1=SystemArgument1;
-       Dpc->SystemArgument2=SystemArgument2;
-       Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
-       Pcr->PrcbData.DpcData[0].DpcCount++;
-       
-       /* Insert the DPC into the list. HighImportance DPCs go at the beginning  */
-       if (Dpc->Importance == HighImportance) {
-               InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
-       } else { 
-               InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
-       }
-       DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
+        KeLowerIrql(OldIrql);
+        return(FALSE);
+    }
+    
+    /* Make sure the lists are free if the Queue is 0 */
+    if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) {
+        
+        ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));
+    } else {
+        
+        ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead));    
+    }
+
+    /* Now we can play with the DPC safely */
+    Dpc->SystemArgument1=SystemArgument1;
+    Dpc->SystemArgument2=SystemArgument2;
+    Pcr->PrcbData.DpcData[0].DpcQueueDepth++;
+    Pcr->PrcbData.DpcData[0].DpcCount++;
+    
+    /* Insert the DPC into the list. HighImportance DPCs go at the beginning  */
+    if (Dpc->Importance == HighImportance) {
+        
+        InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
+    } else { 
+        
+        InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry);
+    }
+    DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
    
-       /* Make sure a DPC isn't executing already and respect rules outlined above. */
-       if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) {
-               
-#ifdef CONFIG_SMP      
-               /* Check if this is the same CPU */
-               if (Pcr != KeGetCurrentKPCR()) {
-                       /* Send IPI if High Importance */
-                       if ((Dpc->Importance == HighImportance) ||
-                           (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) {
-                               if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-                                   KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
-                               } else {
-                                   KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
-                               }
-
-                       }
-               } else {
-                       /* Request an Interrupt only if the DPC isn't low priority */
-                       if ((Dpc->Importance != LowImportance) || 
-                            (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
-                               (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
-                       
-                               /* Request Interrupt */
-                               HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-                               Pcr->PrcbData.DpcInterruptRequested = TRUE;
-                       }
-               }
+    /* Make sure a DPC isn't executing already and respect rules outlined above. */
+    if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) {
+        
+#ifdef CONFIG_SMP    
+        /* Check if this is the same CPU */
+        if (Pcr != KeGetCurrentKPCR()) {
+    
+            /* Send IPI if High Importance */
+            if ((Dpc->Importance == HighImportance) ||
+                (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) {
+                
+                if (Dpc->Number >= MAXIMUM_PROCESSORS) {
+                    
+                    KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
+                } else {
+                    
+                    KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
+                }
+
+            }
+        } else {
+            
+            /* Request an Interrupt only if the DPC isn't low priority */
+            if ((Dpc->Importance != LowImportance) || 
+                 (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
+                (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
+            
+                /* Request Interrupt */
+                HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+                Pcr->PrcbData.DpcInterruptRequested = TRUE;
+            }
+        }
 #else
-               DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate);
-               /* Request an Interrupt only if the DPC isn't low priority */
-               if ((Dpc->Importance != LowImportance) || 
-                    (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
-                       (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
-                       
-                       /* Request Interrupt */
-                       DPRINT("Requesting Interrupt\n");
-                       HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-                       Pcr->PrcbData.DpcInterruptRequested = TRUE;
-               }
+        DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate);
+        
+        /* Request an Interrupt only if the DPC isn't low priority */
+        if ((Dpc->Importance != LowImportance) || 
+            (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) ||
+            (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) {
+            
+            /* Request Interrupt */
+            DPRINT("Requesting Interrupt\n");
+            HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+            Pcr->PrcbData.DpcInterruptRequested = TRUE;
+        }
 #endif
-       }
+    }
 #ifdef CONFIG_SMP
-       KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #endif
-       /* Lower IRQL */        
-       KeLowerIrql(OldIrql);
-       return(TRUE);
+    /* Lower IRQL */    
+    KeLowerIrql(OldIrql);
+    return(TRUE);
 }
 
 /*
  * @implemented
- */
-BOOLEAN STDCALL
-KeRemoveQueueDpc (PKDPC        Dpc)
-/*
+ *
  * FUNCTION: 
  *          Removes DPC object from the system dpc queue
  * ARGUMENTS:
@@ -281,33 +292,36 @@ KeRemoveQueueDpc (PKDPC   Dpc)
  *          TRUE if the DPC was in the queue
  *          FALSE otherwise
  */
+BOOLEAN 
+STDCALL
+KeRemoveQueueDpc(PKDPC Dpc)
 {
-       BOOLEAN WasInQueue;
-       KIRQL OldIrql;
-       
-       /* Raise IRQL */
-       DPRINT("Removing DPC: %x\n", Dpc);
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+    BOOLEAN WasInQueue;
+    KIRQL OldIrql;
+    
+    /* Raise IRQL */
+    DPRINT("Removing DPC: %x\n", Dpc);
+    KeRaiseIrql(HIGH_LEVEL, &OldIrql);
 #ifdef CONFIG_SMP
-       KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
+    KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
 #endif
-       
-       /* First make sure the DPC lock isn't being held */
-       WasInQueue = Dpc->DpcData ? TRUE : FALSE;
-       if (Dpc->DpcData) {     
-               
-               /* Remove the DPC */
-               ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
-               RemoveEntryList(&Dpc->DpcListEntry);
-
-       }
+    
+    /* First make sure the DPC lock isn't being held */
+    WasInQueue = Dpc->DpcData ? TRUE : FALSE;
+    if (Dpc->DpcData) {    
+        
+        /* Remove the DPC */
+        ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
+        RemoveEntryList(&Dpc->DpcListEntry);
+
+    }
 #ifdef CONFIG_SMP
         KiReleaseSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
 #endif
 
-       /* Return if the DPC was in the queue or not */
-       KeLowerIrql(OldIrql);
-       return WasInQueue;
+    /* Return if the DPC was in the queue or not */
+    KeLowerIrql(OldIrql);
+    return WasInQueue;
 }
 
 /*
@@ -323,7 +337,8 @@ KeFlushQueuedDpcs(VOID)
  *          Called when deleting a Driver.
  */
 {
-       if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+    /* Request an interrupt if needed */
+    if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
 }
 
 /*
@@ -332,10 +347,11 @@ KeFlushQueuedDpcs(VOID)
 BOOLEAN 
 STDCALL
 KeIsExecutingDpc(
-       VOID
+    VOID
 )
 {
-       return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive;
+    /* Return if the Dpc Routine is active */
+    return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive;
 }
 
 /*
@@ -349,39 +365,41 @@ KeIsExecutingDpc(
  */
 VOID 
 STDCALL
-KeSetImportanceDpc (IN PKDPC           Dpc,
-                   IN  KDPC_IMPORTANCE Importance)
+KeSetImportanceDpc (IN PKDPC Dpc,
+            IN KDPC_IMPORTANCE Importance)
 {
-       Dpc->Importance = Importance;
+    /* Set the DPC Importance */
+    Dpc->Importance = Importance;
 }
 
 /*
+ * @implemented
+ *
  * FUNCTION: Specifies on which processor the DPC will run
  * ARGUMENTS:
  *          Dpc = Initalizes DPC
  *          Number = Processor number
  * RETURNS: None
- *
- * @implemented
  */
-VOID STDCALL
-KeSetTargetProcessorDpc (IN    PKDPC   Dpc,
-                        IN     CCHAR   Number)
+VOID 
+STDCALL
+KeSetTargetProcessorDpc(IN PKDPC Dpc,
+                        IN CCHAR Number)
 {
-   if (Number >= MAXIMUM_PROCESSORS)
-   {
-      Dpc->Number = 0;
-   }
-   else
-   {
-      ASSERT(Number < KeNumberProcessors);
-      Dpc->Number = Number + MAXIMUM_PROCESSORS;
-   }
+    /* Check how many CPUs are on the system */
+    if (Number >= MAXIMUM_PROCESSORS) {
+        
+        /* No CPU Number */
+        Dpc->Number = 0;
+        
+    } else {
+       
+        /* Set the Number Specified */
+        ASSERT(Number < KeNumberProcessors);
+        Dpc->Number = Number + MAXIMUM_PROCESSORS;
+    }
 }
 
-VOID
-STDCALL
-KiQuantumEnd(VOID)
 /*
  * FUNCTION: 
  *          Called when a quantum end occurs to check if priority should be changed
@@ -389,152 +407,173 @@ KiQuantumEnd(VOID)
  * NOTES:
  *          Called when deleting a Driver.
  */
+VOID
+STDCALL
+KiQuantumEnd(VOID)
 {
-       PKPRCB Prcb;
-       PKTHREAD CurrentThread;
-       KIRQL OldIrql;
-       PKPROCESS Process;
-       KPRIORITY OldPriority;
-       KPRIORITY NewPriority;
-       
-       /* Lock dispatcher, get current thread */
-       Prcb = &KeGetCurrentKPCR()->PrcbData;
-       CurrentThread = KeGetCurrentThread();
-       OldIrql = KeRaiseIrqlToSynchLevel();
-       
-       /* Get the Thread's Process */
-       Process = CurrentThread->ApcState.Process;
-       
-       /* Set DPC Event if requested */
-       if (Prcb->DpcSetEventRequest) {
-               KeSetEvent(Prcb->DpcEvent, 0, 0);
-       }
-       
-       /* Check if Quantum expired */
-       if (CurrentThread->Quantum <= 0) {
-               /* Set the new Quantum */
-               CurrentThread->Quantum = Process->ThreadQuantum;
-               
-               /* Calculate new priority */
-               OldPriority = CurrentThread->Priority;
-               if (OldPriority < LOW_REALTIME_PRIORITY) {
-                       NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
-                       if (NewPriority < CurrentThread->BasePriority) {
-                               NewPriority = CurrentThread->BasePriority;
-                       }
-                       CurrentThread->PriorityDecrement = 0;
-                       if (OldPriority != NewPriority) {
-                               /* Set new Priority */
-                               CurrentThread->Priority = NewPriority;
-                       } else {
-                               /* Queue new thread if none is already */
-                               if (Prcb->NextThread == NULL) {
-                                       /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
-                               } else {
-                                       /* Make the current thread non-premeptive if a new thread is queued */
-                                       CurrentThread->Preempted = FALSE;
-                               }
-                       }
-               } else {
-                       /* Set the Quantum back to Maximum */
-                       //if (CurrentThread->DisableQuantum) {
-                       //      CurrentThread->Quantum = MAX_QUANTUM;
-                       //}
-               }
-       }
-       /* Dispatch the Thread */
-       KeLowerIrql(DISPATCH_LEVEL);
-       PsDispatchThread(THREAD_STATE_READY);
-}      
+    PKPRCB Prcb;
+    PKTHREAD CurrentThread;
+    KIRQL OldIrql;
+    PKPROCESS Process;
+    KPRIORITY OldPriority;
+    KPRIORITY NewPriority;
+    
+    /* Lock dispatcher, get current thread */
+    Prcb = &KeGetCurrentKPCR()->PrcbData;
+    CurrentThread = KeGetCurrentThread();
+    OldIrql = KeRaiseIrqlToSynchLevel();
+    
+    /* Get the Thread's Process */
+    Process = CurrentThread->ApcState.Process;
+    
+    /* Set DPC Event if requested */
+    if (Prcb->DpcSetEventRequest) {
+        KeSetEvent(Prcb->DpcEvent, 0, 0);
+    }
+    
+    /* Check if Quantum expired */
+    if (CurrentThread->Quantum <= 0) {
+        /* Set the new Quantum */
+        CurrentThread->Quantum = Process->ThreadQuantum;
+        
+        /* Calculate new priority */
+        OldPriority = CurrentThread->Priority;
+        if (OldPriority < LOW_REALTIME_PRIORITY) {
+            
+            /* Set the New Priority and add the Priority Decrement */
+            NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
+            
+            /* Don't go out of bounds */
+            if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority;
+            
+            /* Reset the priority decrement */
+            CurrentThread->PriorityDecrement = 0;
+            
+            /* Set a new priority if needed */
+            if (OldPriority != NewPriority) {
+                
+                /* Set new Priority */
+                CurrentThread->Priority = NewPriority;
+            
+            } else {
+                
+                /* Queue new thread if none is already */
+                if (Prcb->NextThread == NULL) {
+                    
+                    /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
+                               
+                } else {
+                           
+                    /* Make the current thread non-premeptive if a new thread is queued */
+                    CurrentThread->Preempted = FALSE;
+                }
+            }
+
+            
+        } else {
+            /* Set the Quantum back to Maximum */
+            //if (CurrentThread->DisableQuantum) {
+            //    CurrentThread->Quantum = MAX_QUANTUM;
+            //}
+        }
+    }
+
+    /* Dispatch the Thread */
+    KeLowerIrql(DISPATCH_LEVEL);
+    PsDispatchThread(THREAD_STATE_READY);
+}    
 
 /*
  * @implemented
- */
-VOID
-STDCALL
-KiDispatchInterrupt(VOID)
-/*
+ *
  * FUNCTION: 
  *          Called whenever a system interrupt is generated at DISPATCH_LEVEL.
  *          It delivers queued DPCs and dispatches a new thread if need be.
  */
+VOID
+STDCALL
+KiDispatchInterrupt(VOID)
 {
-       PLIST_ENTRY DpcEntry;
-       PKDPC Dpc;
-       KIRQL OldIrql;
-       PKPCR Pcr;
-
-       DPRINT("Dispatching Interrupts\n");
-       ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
-       /* Set DPC Deliver to Active */
-       Pcr = KeGetCurrentKPCR();
-
-       if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) {
-               /* Raise IRQL */
-               KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-#ifdef CONFIG_SMP              
-               KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+    PLIST_ENTRY DpcEntry;
+    PKDPC Dpc;
+    KIRQL OldIrql;
+    PKPCR Pcr;
+
+    DPRINT("Dispatching Interrupts\n");
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+    /* Set DPC Deliver to Active */
+    Pcr = KeGetCurrentKPCR();
+
+    if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) {
+        /* Raise IRQL */
+        KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+#ifdef CONFIG_SMP        
+        KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #endif
-               Pcr->PrcbData.DpcRoutineActive = TRUE;
-
-               DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead);
-               /* Loop while we have entries */
-               while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) {
-                       ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
-                       DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth);
-                       
-                       /* Get the DPC call it */
-                       DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead);
-                       Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
-                       DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
-                       Dpc->DpcData = NULL;
-                       Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
+            Pcr->PrcbData.DpcRoutineActive = TRUE;
+
+        DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead);
+        /* Loop while we have entries */
+        while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) {
+            
+            ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0);
+            DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth);
+            
+            /* Get the DPC call it */
+            DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead);
+            Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
+            DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
+            Dpc->DpcData = NULL;
+            Pcr->PrcbData.DpcData[0].DpcQueueDepth--;
 #ifdef CONFIG_SMP
-                       KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+            KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #endif
-                       /* Disable/Enabled Interrupts and Call the DPC */
-                       KeLowerIrql(OldIrql);
-                       DPRINT("Calling DPC: %x\n", Dpc);
-                       Dpc->DeferredRoutine(Dpc,
-                                            Dpc->DeferredContext,
-                                            Dpc->SystemArgument1,
-                                            Dpc->SystemArgument2);
-                       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-                       
+            /* Disable/Enabled Interrupts and Call the DPC */
+            KeLowerIrql(OldIrql);
+            DPRINT("Calling DPC: %x\n", Dpc);
+            Dpc->DeferredRoutine(Dpc,
+                         Dpc->DeferredContext,
+                         Dpc->SystemArgument1,
+                         Dpc->SystemArgument2);
+            KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+            
 #ifdef CONFIG_SMP
-                       KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                       /* 
-                        * If the dpc routine drops the irql below DISPATCH_LEVEL,
-                        * a thread switch can occur and after the next thread switch 
-                        * the execution may start on an other processor.
-                        */
-                       if (Pcr != KeGetCurrentKPCR()) {
-                               Pcr->PrcbData.DpcRoutineActive = FALSE;
-                               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                               Pcr = KeGetCurrentKPCR();
-                               KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
-                               Pcr->PrcbData.DpcRoutineActive = TRUE;
-                       }
+            KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+            /* 
+             * If the dpc routine drops the irql below DISPATCH_LEVEL,
+             * a thread switch can occur and after the next thread switch 
+             * the execution may start on an other processor.
+             */
+            if (Pcr != KeGetCurrentKPCR()) {
+                
+                Pcr->PrcbData.DpcRoutineActive = FALSE;
+                KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+                Pcr = KeGetCurrentKPCR();
+                KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+                Pcr->PrcbData.DpcRoutineActive = TRUE;
+            }
 #endif
-               }
-               /* Clear DPC Flags */
-               Pcr->PrcbData.DpcRoutineActive = FALSE;
-               Pcr->PrcbData.DpcInterruptRequested = FALSE;
+        }
+        /* Clear DPC Flags */
+        Pcr->PrcbData.DpcRoutineActive = FALSE;
+        Pcr->PrcbData.DpcInterruptRequested = FALSE;
 #ifdef CONFIG_SMP
-               KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
+        KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock);
 #endif
-               
-               /* DPC Dispatching Ended, re-enable interrupts */
-               KeLowerIrql(OldIrql);
-       }
-       
-       DPRINT("Checking for Quantum End\n");
-       /* If we have Quantum End, call the function */
-       if (Pcr->PrcbData.QuantumEnd) {
-               Pcr->PrcbData.QuantumEnd = FALSE;
-               KiQuantumEnd();
-       }
+        
+        /* DPC Dispatching Ended, re-enable interrupts */
+        KeLowerIrql(OldIrql);
+    }
+    
+    DPRINT("Checking for Quantum End\n");
+    
+    /* If we have Quantum End, call the function */
+    if (Pcr->PrcbData.QuantumEnd) {
+        
+        Pcr->PrcbData.QuantumEnd = FALSE;
+        KiQuantumEnd();
+    }
 }
 
 /* EOF */
diff --git a/reactos/ntoskrnl/ke/error.c b/reactos/ntoskrnl/ke/error.c
deleted file mode 100644 (file)
index d6172aa..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/ke/error.c
- * PURPOSE:         Error reason setting/getting
- *
- * PROGRAMMERS:     David Welch
- */
-
-/* INCLUDE *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* FUNCTIONS ***************************************************************/
-
-BOOLEAN ExReadyForErrors = FALSE;
-PEPORT ExpDefaultErrorPort = NULL;
-PEPROCESS ExpDefaultErrorPortProcess = NULL;
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-KiCoprocessorError(
-    VOID
-)
-{
-       UNIMPLEMENTED;
-}
-
-/*
- * @unimplemented
- */
-VOID
-STDCALL
-KiUnexpectedInterrupt(
-    VOID
-)
-{
-       UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL 
-NtRaiseHardError(IN NTSTATUS ErrorStatus,
-                 IN ULONG NumberOfParameters,
-                 IN PUNICODE_STRING UnicodeStringParameterMask  OPTIONAL,
-                 IN PVOID *Parameters,
-                 IN HARDERROR_RESPONSE_OPTION ResponseOption,
-                 OUT PHARDERROR_RESPONSE Response)
-{
-  DPRINT1("Hard error %x\n", ErrorStatus);
-  return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL 
-NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
-{
-  KPROCESSOR_MODE PreviousMode;
-  NTSTATUS Status;
-  
-  PreviousMode = ExGetPreviousMode();
-  
-  if(!SeSinglePrivilegeCheck(SeTcbPrivilege,
-                             PreviousMode))
-  {
-    DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n");
-    return STATUS_PRIVILEGE_NOT_HELD;
-  }
-  
-  /* serialization shouldn't be required here as it usually is just called once
-     during startup */
-  
-  if(!ExReadyForErrors)
-  {
-    Status = ObReferenceObjectByHandle(PortHandle,
-                                       0,
-                                       LpcPortObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&ExpDefaultErrorPort,
-                                       NULL);
-    if(NT_SUCCESS(Status))
-    {
-      ExpDefaultErrorPortProcess = PsGetCurrentProcess();
-      ExReadyForErrors = TRUE;
-    }
-  }
-  else
-  {
-    Status = STATUS_UNSUCCESSFUL;
-  }
-  
-  return Status;
-}
-
-/* EOF */
index 75dde7b..7683afa 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id:$
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
 /*
  * @implemented
  */
-VOID STDCALL KeClearEvent (PKEVENT Event)
+VOID 
+STDCALL 
+KeClearEvent(PKEVENT Event)
 {
-   DPRINT("KeClearEvent(Event %x)\n", Event);
-   Event->Header.SignalState = FALS