Implement IoRaiseHardError, combine error stuff, fix hideously wrong implementatin of Controller Objects.
Modified: trunk/reactos/include/ddk/iotypes.h
Modified: trunk/reactos/include/ddk/ketypes.h
Modified: trunk/reactos/ntoskrnl/Makefile
Deleted: trunk/reactos/ntoskrnl/io/cntrller.c
Added: trunk/reactos/ntoskrnl/io/controller.c
Deleted: trunk/reactos/ntoskrnl/io/errlog.c
Modified: trunk/reactos/ntoskrnl/io/error.c

Modified: trunk/reactos/include/ddk/iotypes.h
--- trunk/reactos/include/ddk/iotypes.h	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/include/ddk/iotypes.h	2005-04-26 14:51:18 UTC (rev 14816)
@@ -684,7 +684,35 @@
    PIO_COMPLETION_CONTEXT CompletionContext;
 } FILE_OBJECT, *PFILE_OBJECT;
 
+typedef IO_ALLOCATION_ACTION STDCALL_FUNC
+(*PDRIVER_CONTROL)(struct _DEVICE_OBJECT *DeviceObject,
+		   struct _IRP *Irp,
+		   PVOID MapRegisterBase,
+		   PVOID Context);
+#if (_WIN32_WINNT >= 0x0400)
+typedef VOID STDCALL_FUNC
+(*PFSDNOTIFICATIONPROC)(IN struct _DEVICE_OBJECT *PtrTargetFileSystemDeviceObject,
+			IN BOOLEAN DriverActive);
+#endif // (_WIN32_WINNT >= 0x0400)
 
+typedef struct _KDEVICE_QUEUE_ENTRY
+{
+   LIST_ENTRY DeviceListEntry;
+   ULONG SortKey;
+   BOOLEAN Inserted;
+} KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY;
+
+typedef struct _WAIT_CONTEXT_BLOCK
+{
+  KDEVICE_QUEUE_ENTRY WaitQueueEntry;
+  PDRIVER_CONTROL DeviceRoutine;
+  PVOID DeviceContext;
+  ULONG NumberOfMapRegisters;
+  PVOID DeviceObject;
+  PVOID CurrentIrp;
+  PKDPC BufferChainingDpc;
+} WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK;
+
 typedef struct _IRP
 {
    CSHORT Type;
@@ -757,7 +785,6 @@
    WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH];
 } VPB, *PVPB;
 
-
 typedef struct _DEVICE_OBJECT
 {
    CSHORT Type;
@@ -1133,18 +1160,6 @@
 } DRIVER_LAYOUT_INFORMATION, *PDRIVER_LAYOUT_INFORMATION;
 
 
-typedef IO_ALLOCATION_ACTION STDCALL_FUNC
-(*PDRIVER_CONTROL)(PDEVICE_OBJECT DeviceObject,
-		   PIRP Irp,
-		   PVOID MapRegisterBase,
-		   PVOID Context);
-#if (_WIN32_WINNT >= 0x0400)
-typedef VOID STDCALL_FUNC
-(*PFSDNOTIFICATIONPROC)(IN PDEVICE_OBJECT PtrTargetFileSystemDeviceObject,
-			IN BOOLEAN DriverActive);
-#endif // (_WIN32_WINNT >= 0x0400)
-
-
 typedef struct _NAMED_PIPE_CREATE_PARAMETERS
 {
   ULONG NamedPipeType;

Modified: trunk/reactos/include/ddk/ketypes.h
--- trunk/reactos/include/ddk/ketypes.h	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/include/ddk/ketypes.h	2005-04-26 14:51:18 UTC (rev 14816)
@@ -285,37 +285,6 @@
   ULONG  DpcCount;
 } KDPC_DATA, *PKDPC_DATA;
 
-typedef struct _KDEVICE_QUEUE_ENTRY
-{
-   LIST_ENTRY DeviceListEntry;
-   ULONG SortKey;
-   BOOLEAN Inserted;
-} KDEVICE_QUEUE_ENTRY, *PKDEVICE_QUEUE_ENTRY;
-
-typedef struct _WAIT_CONTEXT_BLOCK
-{
-  KDEVICE_QUEUE_ENTRY WaitQueueEntry;
-  /*
-   * XXX THIS IS WRONG XXX
-   *
-   * Our headers have enough circular dependancies that
-   * I can't figure out, given 5 minutes of testing, what
-   * order to include them in to get PDRIVER_CONTROL to be
-   * defined here.  The proper definition of the next item
-   * is:
-   *
-   * PDRIVER_CONTROL DeviceRoutine;
-   *
-   * but instead we use PVOID until headers are fixed.
-   */
-  PVOID DeviceRoutine;
-  PVOID DeviceContext;
-  ULONG NumberOfMapRegisters;
-  PVOID DeviceObject;
-  PVOID CurrentIrp;
-  PKDPC BufferChainingDpc;
-} WAIT_CONTEXT_BLOCK, *PWAIT_CONTEXT_BLOCK;
-
 typedef enum _KBUGCHECK_CALLBACK_REASON {
     KbCallbackInvalid,
     KbCallbackReserved1,

Modified: trunk/reactos/ntoskrnl/Makefile
--- trunk/reactos/ntoskrnl/Makefile	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/ntoskrnl/Makefile	2005-04-26 14:51:18 UTC (rev 14816)
@@ -149,14 +149,13 @@
 	io/buildirp.o \
 	io/cancel.o \
 	io/cleanup.o \
-	io/cntrller.o \
+	io/controller.o \
 	io/create.o \
 	io/device.o \
 	io/deviface.o \
 	io/dir.o \
 	io/driver.o \
 	io/efi.o \
-	io/errlog.o \
 	io/error.o \
 	io/event.o \
 	io/file.o \

Deleted: trunk/reactos/ntoskrnl/io/cntrller.c
--- trunk/reactos/ntoskrnl/io/cntrller.c	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/ntoskrnl/io/cntrller.c	2005-04-26 14:51:18 UTC (rev 14816)
@@ -1,175 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/cntrller.c
- * PURPOSE:         Implements the controller object
- * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#include <internal/debug.h>
-
-/* GLOBALS *******************************************************************/
-
-#define TAG_CQE                    TAG('C', 'Q', 'E', ' ')
-#define TAG_CONTROLLER             TAG('C', 'N', 'T', 'R')
-#define TAG_CONTROLLER_EXTENSION   TAG('C', 'E', 'X', 'T')
-
-/* TYPES ********************************************************************/
-
-typedef struct
-/*
- * PURPOSE: A entry in the queue waiting for a controller object
- */
-{
-   KDEVICE_QUEUE_ENTRY Entry;
-   PDEVICE_OBJECT DeviceObject;
-   PDRIVER_CONTROL ExecutionRoutine;
-   PVOID Context;
-} CONTROLLER_QUEUE_ENTRY, *PCONTROLLER_QUEUE_ENTRY;
-
-/* FUNCTIONS *****************************************************************/
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
-			  PDEVICE_OBJECT DeviceObject,
-			  PDRIVER_CONTROL ExecutionRoutine,
-			  PVOID Context)
-/*
- * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
- * as soon as the device controller, represented by the given controller
- * object, is available to carry out an I/O operation for the target device,
- * represented by the given device object.
- * ARGUMENTS:
- *       ControllerObject = Driver created controller object
- *       DeviceObject = Target device for the current irp
- *       ExecutionRoutine = Routine to be called when the device is available
- *       Context = Driver supplied context to be passed on to the above routine
- * NOTE: Is the below implementation correct. 
- */
-{
-   PCONTROLLER_QUEUE_ENTRY entry;
-   IO_ALLOCATION_ACTION Result;
-
-   ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
-   entry = 
-     ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_QUEUE_ENTRY),
-			   TAG_CQE);
-   ASSERT(entry!=NULL);
-   
-   entry->DeviceObject = DeviceObject;
-   entry->ExecutionRoutine = ExecutionRoutine;
-   entry->Context = Context;
-   
-   if (KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,&entry->Entry))
-     {
-	return;
-     }   
-   Result = ExecutionRoutine(DeviceObject,DeviceObject->CurrentIrp,
-			     NULL,Context);
-   if (Result == DeallocateObject)
-     {
-	IoFreeController(ControllerObject);
-     }
-   ExFreePool(entry);
-}
-
-/*
- * @implemented
- */
-PCONTROLLER_OBJECT
-STDCALL
-IoCreateController(ULONG Size)
-/*
- * FUNCTION: Allocates memory and initializes a controller object
- * ARGUMENTS:
- *        Size = Size (in bytes) to be allocated for the controller extension
- * RETURNS: A pointer to the created object
- */
-{
-   PCONTROLLER_OBJECT controller;
-   
-   ASSERT_IRQL(PASSIVE_LEVEL);
-   
-   controller = 
-     ExAllocatePoolWithTag(NonPagedPool, sizeof(CONTROLLER_OBJECT),
-			   TAG_CONTROLLER);
-   if (controller==NULL)
-     {
-	return(NULL);
-     }
-   
-   controller->ControllerExtension = 
-     ExAllocatePoolWithTag(NonPagedPool, Size, TAG_CONTROLLER_EXTENSION);
-   if (controller->ControllerExtension==NULL)
-     {
-	ExFreePool(controller);
-	return(NULL);
-     }
-
-   KeInitializeDeviceQueue(&controller->DeviceWaitQueue);
-   return(controller);
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
-/*
- * FUNCTION: Removes a given controller object from the system
- * ARGUMENTS:
- *        ControllerObject = Controller object to be released
- */
-{
-   ASSERT_IRQL(PASSIVE_LEVEL);
-
-   ExFreePool(ControllerObject->ControllerExtension);
-   ExFreePool(ControllerObject);
-}
-
-/*
- * @implemented
- */
-VOID
-STDCALL
-IoFreeController(PCONTROLLER_OBJECT ControllerObject)
-/*
- * FUNCTION: Releases a previously allocated controller object when a 
- * device has finished an I/O request
- * ARGUMENTS:
- *       ControllerObject = Controller object to be released
- */
-{
-   PKDEVICE_QUEUE_ENTRY QEntry;
-   CONTROLLER_QUEUE_ENTRY* Entry;
-   IO_ALLOCATION_ACTION Result;
-
-   do
-     {
-	QEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue);
-	Entry = CONTAINING_RECORD(QEntry,CONTROLLER_QUEUE_ENTRY,Entry);
-	if (QEntry==NULL)
-	  {
-	     return;
-	  }
-	Result = Entry->ExecutionRoutine(Entry->DeviceObject,
-					 Entry->DeviceObject->CurrentIrp,
-					 NULL,
-					 Entry->Context);
-	ExFreePool(Entry);
-     } while (Result == DeallocateObject);
-}
-
-
-/* EOF */

Copied: trunk/reactos/ntoskrnl/io/controller.c (from rev 14808, trunk/reactos/ntoskrnl/io/cntrller.c)
--- trunk/reactos/ntoskrnl/io/cntrller.c	2005-04-25 20:35:37 UTC (rev 14808)
+++ trunk/reactos/ntoskrnl/io/controller.c	2005-04-26 14:51:18 UTC (rev 14816)
@@ -0,0 +1,178 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS kernel
+ * FILE:            ntoskrnl/io/contrller.c
+ * PURPOSE:         Implements the controller object
+ * 
+ * PROGRAMMERS:     Alex Ionescu (alex@relsoft.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#include <internal/debug.h>
+
+/* GLOBALS *******************************************************************/
+
+POBJECT_TYPE IoControllerObjectType;
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Sets up a call to a driver-supplied ControllerControl routine
+ * as soon as the device controller, represented by the given controller
+ * object, is available to carry out an I/O operation for the target device,
+ * represented by the given device object.
+ * ARGUMENTS:
+ *       ControllerObject = Driver created controller object
+ *       DeviceObject = Target device for the current irp
+ *       ExecutionRoutine = Routine to be called when the device is available
+ *       Context = Driver supplied context to be passed on to the above routine
+ */
+VOID
+STDCALL
+IoAllocateController(PCONTROLLER_OBJECT ControllerObject,
+                     PDEVICE_OBJECT DeviceObject,
+                     PDRIVER_CONTROL ExecutionRoutine,
+                     PVOID Context)
+{
+    IO_ALLOCATION_ACTION Result;
+
+    ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+    /* Initialize the Wait Context Block */
+    DeviceObject->Queue.Wcb.DeviceContext = Context;
+    DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
+    
+    /* Insert the Device Queue */
+    if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,
+                             &DeviceObject->Queue.Wcb.WaitQueueEntry));
+    {
+        Result = ExecutionRoutine(DeviceObject,
+                                  DeviceObject->CurrentIrp,
+                                  NULL,
+                                  Context); 
+    }
+       
+    if (Result == DeallocateObject)
+    {
+        IoFreeController(ControllerObject);
+    }
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Allocates memory and initializes a controller object
+ * ARGUMENTS:
+ *        Size = Size (in bytes) to be allocated for the controller extension
+ * RETURNS: A pointer to the created object
+ */
+PCONTROLLER_OBJECT
+STDCALL
+IoCreateController(ULONG Size)
+
+{
+   PCONTROLLER_OBJECT Controller;
+   OBJECT_ATTRIBUTES ObjectAttributes;
+   HANDLE Handle;
+   NTSTATUS Status;
+   ASSERT_IRQL(PASSIVE_LEVEL);
+
+   /* Initialize an empty OBA */
+   InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+   
+   /* Create the Object */
+   Status = ObCreateObject(KernelMode,
+                           IoControllerObjectType,
+                           &ObjectAttributes,
+                           KernelMode,
+                           NULL,
+                           sizeof(CONTROLLER_OBJECT) + Size,
+                           0,
+                           0,
+                           (PVOID*)&Controller);
+    if (!NT_SUCCESS(Status)) return NULL;
+    
+    /* Insert it */
+    Status = ObInsertObject(Controller,
+                            NULL,
+                            FILE_READ_DATA | FILE_WRITE_DATA,
+                            0,
+                            NULL,
+                            &Handle);
+   if (!NT_SUCCESS(Status)) return NULL;
+   
+    /* Close the dummy handle */
+    NtClose(Handle);
+        
+    /* Zero the Object and set its data */
+    RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
+    Controller->Type = IO_TYPE_CONTROLLER;
+    Controller->Size = sizeof(CONTROLLER_OBJECT) + Size;
+    Controller->ControllerExtension = (Controller + 1);
+    
+    /* Initialize its Queue */
+    KeInitializeDeviceQueue(&Controller->DeviceWaitQueue);
+
+    /* Return Controller */
+    return Controller;
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Removes a given controller object from the system
+ * ARGUMENTS:
+ *        ControllerObject = Controller object to be released
+ */
+VOID
+STDCALL
+IoDeleteController(PCONTROLLER_OBJECT ControllerObject)
+
+{
+    /* Just Dereference it */
+    ObDereferenceObject(ControllerObject);
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Releases a previously allocated controller object when a 
+ * device has finished an I/O request
+ * ARGUMENTS:
+ *       ControllerObject = Controller object to be released
+ */
+VOID
+STDCALL
+IoFreeController(PCONTROLLER_OBJECT ControllerObject)
+{
+    PKDEVICE_QUEUE_ENTRY QueueEntry;
+    PDEVICE_OBJECT DeviceObject;
+    IO_ALLOCATION_ACTION Result;
+
+    /* Remove the Queue */
+    if ((QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue)))
+    {
+        /* Get the Device Object */
+        DeviceObject = CONTAINING_RECORD(QueueEntry, 
+                                         DEVICE_OBJECT, 
+                                         Queue.Wcb.WaitQueueEntry);
+        /* Call the routine */
+        Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
+                                                       DeviceObject->CurrentIrp,
+                                                       NULL,
+                                                       DeviceObject->Queue.Wcb.DeviceContext);
+        /* Check the result */
+        if (Result == DeallocateObject)
+        {
+            /* Free it again */
+            IoFreeController(ControllerObject);
+        }
+    }
+}
+
+
+/* EOF */

Deleted: trunk/reactos/ntoskrnl/io/errlog.c
--- trunk/reactos/ntoskrnl/io/errlog.c	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/ntoskrnl/io/errlog.c	2005-04-26 14:51:18 UTC (rev 14816)
@@ -1,450 +0,0 @@
-/* $Id$
- *
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/errlog.c
- * PURPOSE:         Error logging
- *
- * PROGRAMMERS:     David Welch (welch@cwcom.net)
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-
-/* TYPES *********************************************************************/
-
-typedef struct _ERROR_LOG_ENTRY
-{
-  LIST_ENTRY Entry;
-  LARGE_INTEGER TimeStamp;
-  PVOID IoObject;
-  ULONG PacketSize;
-} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
-
-typedef struct _LOG_WORKER_DPC
-{
-  KDPC Dpc;
-  KTIMER Timer;
-} LOG_WORKER_DPC, *PLOG_WORKER_DPC;
-
-
-static VOID STDCALL
-IopLogWorker (PVOID Parameter);
-
-
-/* GLOBALS *******************************************************************/
-
-static KSPIN_LOCK IopAllocationLock;
-static ULONG IopTotalLogSize;
-
-static KSPIN_LOCK IopLogListLock;
-static LIST_ENTRY IopLogListHead;
-
-static BOOLEAN IopLogWorkerRunning = FALSE;
-static BOOLEAN IopLogPortConnected = FALSE;
-static HANDLE IopLogPort;
-
-
-/* FUNCTIONS *****************************************************************/
-
-NTSTATUS
-IopInitErrorLog (VOID)
-{
-  IopTotalLogSize = 0;
-  KeInitializeSpinLock (&IopAllocationLock);
-
-  KeInitializeSpinLock (&IopLogListLock);
-  InitializeListHead (&IopLogListHead);
-
-  return STATUS_SUCCESS;
-}
-
-
-static VOID STDCALL
-IopLogDpcRoutine (PKDPC Dpc,
-		  PVOID DeferredContext,
-		  PVOID SystemArgument1,
-		  PVOID SystemArgument2)
-{
-  PWORK_QUEUE_ITEM LogWorkItem;
-
-  DPRINT ("\nIopLogDpcRoutine() called\n");
-
-  /* Release the WorkerDpc struct */
-  ExFreePool (DeferredContext);
-
-  /* Allocate, initialize and restart a work item */
-  LogWorkItem = ExAllocatePool (NonPagedPool,
-				sizeof(WORK_QUEUE_ITEM));
-  if (LogWorkItem == NULL)
-    {
-      IopLogWorkerRunning = FALSE;
-      return;
-    }
-
-  ExInitializeWorkItem (LogWorkItem,
-			IopLogWorker,
-			LogWorkItem);
-
-  ExQueueWorkItem (LogWorkItem,
-		   DelayedWorkQueue);
-}
-
-
-static VOID
-IopRestartLogWorker (VOID)
-{
-  PLOG_WORKER_DPC WorkerDpc;
-  LARGE_INTEGER Timeout;
-
-  DPRINT ("IopRestartWorker() called\n");
-
-  WorkerDpc = ExAllocatePool (NonPagedPool,
-			      sizeof(LOG_WORKER_DPC));
-  if (WorkerDpc == NULL)
-    {
-      IopLogWorkerRunning = FALSE;
-      return;
-    }
-
-  /* Initialize DPC and Timer */
-  KeInitializeDpc (&WorkerDpc->Dpc,
-		   IopLogDpcRoutine,
-		   WorkerDpc);
-  KeInitializeTimer (&WorkerDpc->Timer);
-
-  /* Restart after 30 seconds */
-  Timeout.QuadPart = (LONGLONG)-300000000;
-  KeSetTimer (&WorkerDpc->Timer,
-	      Timeout,
-	      &WorkerDpc->Dpc);
-}
-
-
-static BOOLEAN
-IopConnectLogPort (VOID)
-{
-  UNICODE_STRING PortName;
-  NTSTATUS Status;
-
-  DPRINT ("IopConnectLogPort() called\n");
-
-  RtlInitUnicodeString (&PortName,
-			L"\\ErrorLogPort");
-
-  Status = ZwConnectPort (&IopLogPort,
-			  &PortName,
-			  NULL,
-			  NULL,
-			  NULL,
-			  NULL,
-			  NULL,
-			  NULL);
-  if (!NT_SUCCESS(Status))
-    {
-      DPRINT ("ZwConnectPort() failed (Status %lx)\n", Status);
-      return FALSE;
-    }
-
-  DPRINT ("IopConnectLogPort() done\n");
-
-  return TRUE;
-}
-
-
-static VOID STDCALL
-IopLogWorker (PVOID Parameter)
-{
-  PERROR_LOG_ENTRY LogEntry;
-  PLPC_MAX_MESSAGE Request;
-  PIO_ERROR_LOG_MESSAGE Message;
-  PIO_ERROR_LOG_PACKET Packet;
-  KIRQL Irql;
-  NTSTATUS Status;
-
-  UCHAR Buffer[256];
-  POBJECT_NAME_INFORMATION ObjectNameInfo;
-  ULONG ReturnedLength;
-  PWCHAR DriverName;
-  ULONG DriverNameLength;
-
-  DPRINT ("IopLogWorker() called\n");
-
-  /* Release the work item */
-  ExFreePool (Parameter);
-
-  /* Connect to the error log port */
-  if (IopLogPortConnected == FALSE)
-    {
-      if (IopConnectLogPort () == FALSE)
-	{
-	  IopRestartLogWorker ();
-	  return;
-	}
-
-      IopLogPortConnected = TRUE;
-    }
-
-  while (TRUE)
-    {
-      /* Remove last entry from the list */
-      KeAcquireSpinLock (&IopLogListLock,
-			 &Irql);
-
-      if (!IsListEmpty (&IopLogListHead))
-	{
-	  LogEntry = CONTAINING_RECORD (IopLogListHead.Blink,
-					ERROR_LOG_ENTRY,
-					Entry);
-	  RemoveEntryList (&LogEntry->Entry);
-	}
-      else
-	{
-	  LogEntry = NULL;
-	}
-
-      KeReleaseSpinLock (&IopLogListLock,
-			 Irql);
-
-      if (LogEntry == NULL)
-	{
-	  DPRINT ("No message in log list\n");
-	  break;
-	}
-
-      /* Get pointer to the log packet */
-      Packet = (PIO_ERROR_LOG_PACKET)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY));
-
-
-      /* Get driver or device name */
-      ObjectNameInfo = (POBJECT_NAME_INFORMATION)Buffer;
-      Status = ObQueryNameString (LogEntry->IoObject,
-				  ObjectNameInfo,
-				  256,
-				  &ReturnedLength);
-      if (NT_SUCCESS(Status))
-	{
-	  DPRINT ("ReturnedLength: %lu\n", ReturnedLength);
-	  DPRINT ("Length: %hu\n", ObjectNameInfo->Name.Length);
-	  DPRINT ("MaximumLength: %hu\n", ObjectNameInfo->Name.MaximumLength);
-	  DPRINT ("Object: %wZ\n", &ObjectNameInfo->Name);
-
-	  DriverName = wcsrchr(ObjectNameInfo->Name.Buffer, L'\\');
-	  if (DriverName != NULL)
-	    DriverName++;
-	  else
-	    DriverName = ObjectNameInfo->Name.Buffer;
-
-	  DriverNameLength = wcslen (DriverName) * sizeof(WCHAR);
-	  DPRINT ("Driver name '%S'\n", DriverName);
-	}
-      else
-	{
-	  DriverName = NULL;
-	  DriverNameLength = 0;
-	}
-
-      /* Allocate request buffer */
-      Request = ExAllocatePool (NonPagedPool,
-				sizeof(LPC_MAX_MESSAGE));
-      if (Request == NULL)
-	{
-	  DPRINT ("Failed to allocate request buffer!\n");
-
-	  /* Requeue log message and restart the worker */
-	  ExInterlockedInsertTailList (&IopLogListHead,
-				       &LogEntry->Entry,
-				       &IopLogListLock);
-	  IopRestartLogWorker ();
-
-	  return;
-	}
-
-      /* Initialize the log message */
-      Message = (PIO_ERROR_LOG_MESSAGE)Request->Data;
-      Message->Type = 0xC; //IO_TYPE_ERROR_MESSAGE;
-      Message->Size =
-	sizeof(IO_ERROR_LOG_MESSAGE) - sizeof(IO_ERROR_LOG_PACKET) +
-	LogEntry->PacketSize + DriverNameLength;
-      Message->DriverNameLength = (USHORT)DriverNameLength;
-      Message->TimeStamp.QuadPart = LogEntry->TimeStamp.QuadPart;
-      Message->DriverNameOffset = (DriverName != NULL) ? LogEntry->PacketSize : 0;
-
-      /* Copy error log packet */
-      RtlCopyMemory (&Message->EntryData,
-		     Packet,
-		     LogEntry->PacketSize);
-
-      /* Copy driver or device name */
-      RtlCopyMemory ((PVOID)((ULONG_PTR)Message + Message->DriverNameOffset),
-		     DriverName,
-		     DriverNameLength);
-
-      DPRINT ("SequenceNumber %lx\n", Packet->SequenceNumber);
-
-      Request->Header.DataSize = Message->Size;
-      Request->Header.MessageSize =
-	Request->Header.DataSize + sizeof(LPC_MESSAGE);
-
-      /* Send the error message to the log port */
-      Status = ZwRequestPort (IopLogPort,
-			      &Request->Header);
-
-      /* Release request buffer */
-      ExFreePool (Request);
-
-      if (!NT_SUCCESS(Status))
-	{
-	  DPRINT ("ZwRequestPort() failed (Status %lx)\n", Status);
-
-	  /* Requeue log message and restart the worker */
-	  ExInterlockedInsertTailList (&IopLogListHead,
-				       &LogEntry->Entry,
-				       &IopLogListLock);
-	  IopRestartLogWorker ();
-
-	  return;
-	}
-
-      /* Release error log entry */
-      KeAcquireSpinLock (&IopAllocationLock,
-			 &Irql);
-
-      IopTotalLogSize -= (LogEntry->PacketSize - sizeof(ERROR_LOG_ENTRY));
-      ExFreePool (LogEntry);
-
-      KeReleaseSpinLock (&IopAllocationLock,
-			 Irql);
-    }
-
-  IopLogWorkerRunning = FALSE;
-
-  DPRINT ("IopLogWorker() done\n");
-}
-
-
-/*
- * @implemented
- */
-PVOID STDCALL
-IoAllocateErrorLogEntry (IN PVOID IoObject,
-			 IN UCHAR EntrySize)
-{
-  PERROR_LOG_ENTRY LogEntry;
-  ULONG LogEntrySize;
-  KIRQL Irql;
-
-  DPRINT("IoAllocateErrorLogEntry() called\n");
-
-  if (IoObject == NULL)
-    return NULL;
-
-  KeAcquireSpinLock (&IopAllocationLock,
-		     &Irql);
-
-  if (IopTotalLogSize > PAGE_SIZE)
-    {
-      KeReleaseSpinLock (&IopAllocationLock,
-			 Irql);
-      return NULL;
-    }
-
-  LogEntrySize = sizeof(ERROR_LOG_ENTRY) + EntrySize;
-  LogEntry = ExAllocatePool (NonPagedPool,
-			     LogEntrySize);
-  if (LogEntry == NULL)
-    {
-      KeReleaseSpinLock (&IopAllocationLock,
-			 Irql);
-      return NULL;
-    }
-
-  IopTotalLogSize += EntrySize;
-
-  LogEntry->IoObject = IoObject;
-  LogEntry->PacketSize = LogEntrySize;
-
-  KeReleaseSpinLock (&IopAllocationLock,
-		     Irql);
-
-  return (PVOID)((ULONG_PTR)LogEntry + sizeof(ERROR_LOG_ENTRY));
-}
-
-
-/*
- * @implemented
- */
-VOID STDCALL
-IoFreeErrorLogEntry(IN PVOID ElEntry)
-{
-  PERROR_LOG_ENTRY LogEntry;
-  KIRQL Irql;
-
-  DPRINT("IoFreeErrorLogEntry() called\n");
-
-  if (ElEntry == NULL)
-    return;
-
-  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
-
-  KeAcquireSpinLock(&IopAllocationLock,
-		    &Irql);
-
-  IopTotalLogSize -= (LogEntry->PacketSize - sizeof(ERROR_LOG_ENTRY));
-  ExFreePool(LogEntry);
-
-  KeReleaseSpinLock(&IopAllocationLock,
-		    Irql);
-}
-
-
-/*
- * @implemented
- */
-VOID STDCALL
-IoWriteErrorLogEntry (IN PVOID ElEntry)
-{
-  PWORK_QUEUE_ITEM LogWorkItem;
-  PERROR_LOG_ENTRY LogEntry;
-  KIRQL Irql;
-
-  DPRINT("IoWriteErrorLogEntry() called\n");
-
-  LogEntry = (PERROR_LOG_ENTRY)((ULONG_PTR)ElEntry - sizeof(ERROR_LOG_ENTRY));
-
-  /* Get time stamp */
-  KeQuerySystemTime (&LogEntry->TimeStamp);
-
-  KeAcquireSpinLock (&IopLogListLock,
-		     &Irql);
-
-  InsertHeadList (&IopLogListHead,
-		  &LogEntry->Entry);
-
-  if (IopLogWorkerRunning == FALSE)
-    {
-      LogWorkItem = ExAllocatePool (NonPagedPool,
-				    sizeof(WORK_QUEUE_ITEM));
-      if (LogWorkItem != NULL)
-	{
-	  ExInitializeWorkItem (LogWorkItem,
-				IopLogWorker,
-				LogWorkItem);
-
-	  ExQueueWorkItem (LogWorkItem,
-			   DelayedWorkQueue);
-
-	  IopLogWorkerRunning = TRUE;
-	}
-    }
-
-  KeReleaseSpinLock (&IopLogListLock,
-		     Irql);
-
-  DPRINT("IoWriteErrorLogEntry() done\n");
-}
-
-/* EOF */

Modified: trunk/reactos/ntoskrnl/io/error.c
--- trunk/reactos/ntoskrnl/io/error.c	2005-04-26 13:17:44 UTC (rev 14815)
+++ trunk/reactos/ntoskrnl/io/error.c	2005-04-26 14:51:18 UTC (rev 14816)
@@ -2,49 +2,530 @@
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
- * FILE:            ntoskrnl/io/error.c
- * PURPOSE:         Handle media errors
- * 
- * PROGRAMMERS:     David Welch (welch@mcmail.com)
+ * FILE:            ntoskrnl/io/errlog.c
+ * PURPOSE:         Error logging
+ *
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <ntoskrnl.h>
+#define NDEBUG
 #include <internal/debug.h>
 
+/* TYPES *********************************************************************/
+
+typedef struct _ERROR_LOG_ENTRY
+{
+  LIST_ENTRY Entry;
+  LARGE_INTEGER TimeStamp;
+  PVOID IoObject;
+  ULONG PacketSize;
+} ERROR_LOG_ENTRY, *PERROR_LOG_ENTRY;
+
+typedef struct _LOG_WORKER_DPC
+{
+  KDPC Dpc;
+  KTIMER Timer;
+} LOG_WORKER_DPC, *PLOG_WORKER_DPC;
+
+
+static VOID STDCALL
+IopLogWorker (PVOID Parameter);
+
+
+/* GLOBALS *******************************************************************/
+
+static KSPIN_LOCK IopAllocationLock;
+static ULONG IopTotalLogSize;
+
+static KSPIN_LOCK IopLogListLock;
+static LIST_ENTRY IopLogListHead;
+
[truncated at 1000 lines; 502 more skipped]