svn will drive me nuts, part 1/x
authorJérôme Gardou <jerome.gardou@reactos.org>
Sat, 27 Mar 2010 23:28:24 +0000 (23:28 +0000)
committerJérôme Gardou <jerome.gardou@reactos.org>
Sat, 27 Mar 2010 23:28:24 +0000 (23:28 +0000)
svn path=/branches/reactos-yarotows/; revision=46505

14 files changed:
drivers/bus/acpi/cmbatt/cmbpnp.c
drivers/bus/acpi/compbatt/compbatt.c
drivers/bus/acpi/compbatt/compbatt.h
drivers/bus/acpi/compbatt/comppnp.c
drivers/bus/acpi/eval.c [new file with mode: 0644]
drivers/bus/acpi/interface.c [new file with mode: 0644]
drivers/storage/scsiport/scsiport.pspec [new file with mode: 0644]
drivers/storage/scsiport/stubs.c [new file with mode: 0644]
hal/halx86/up/pic.c [new file with mode: 0644]
hal/halx86/up/processor.c [new file with mode: 0644]
include/dxsdk/bdatif.idl [new file with mode: 0644]
include/ndk/peb_teb.h [new file with mode: 0644]
media/inf/machine.inf
ntoskrnl/io/pnpmgr/pnpmgr.c

index 55d3ae6..bbeee79 100644 (file)
@@ -567,8 +567,7 @@ CmBattCreateFdo(IN PDRIVER_OBJECT DriverObject,
     }
     
     /* Set FDO flags */
     }
     
     /* Set FDO flags */
-    FdoDeviceObject->Flags |= DO_BUFFERED_IO;
-    FdoDeviceObject->Flags |= DO_MAP_IO_BUFFER;
+    FdoDeviceObject->Flags |= (DO_POWER_PAGABLE | DO_BUFFERED_IO);
     FdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
     /* Initialize the extension */
     FdoDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
 
     /* Initialize the extension */
index 03d587c..d8f8920 100644 (file)
@@ -21,8 +21,17 @@ NTAPI
 CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
 {
 CompBattOpenClose(IN PDEVICE_OBJECT DeviceObject,
                   IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PAGED_CODE();
+    if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING OpenClose\n");
+    
+    /* Complete the IRP with success */
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IofCompleteRequest(Irp, IO_NO_INCREMENT);
+    
+    /* Return success */
+    if (CompBattDebug & 0x100) DbgPrint("CompBatt: Exiting OpenClose\n");
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -30,8 +39,28 @@ NTAPI
 CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
 {
 CompBattSystemControl(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    NTSTATUS Status;
+    PAGED_CODE();
+    if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING System Control\n");
+    
+    /* Are we attached yet? */
+    if (DeviceExtension->AttachedDevice)
+    {
+        /* Send it up the stack */
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+    }
+    else
+    {
+        /* We don't support WMI */
+        Status = STATUS_NOT_SUPPORTED;
+        Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+        IofCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+    
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -65,8 +94,23 @@ NTAPI
 CompBattIoctl(IN PDEVICE_OBJECT DeviceObject,
               IN PIRP Irp)
 {
 CompBattIoctl(IN PDEVICE_OBJECT DeviceObject,
               IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    NTSTATUS Status;
+    if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING Ioctl\n");
+
+    /* Let the class driver handle it */
+    Status = BatteryClassIoctl(DeviceExtension->ClassData, Irp);
+    if (Status == STATUS_NOT_SUPPORTED)
+    {
+        /* It failed, try the next driver up the stack */
+        Irp->IoStatus.Status = Status;
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+    }
+
+    /* Return status */
+    if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING Ioctl\n");
+    return Status;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -161,8 +205,18 @@ NTAPI
 DriverEntry(IN PDRIVER_OBJECT DriverObject,
             IN PUNICODE_STRING RegistryPath)
 {
 DriverEntry(IN PDRIVER_OBJECT DriverObject,
             IN PUNICODE_STRING RegistryPath)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    /* Register add device routine */
+    DriverObject->DriverExtension->AddDevice = CompBattAddDevice;
+    
+    /* Register other handlers */
+    DriverObject->MajorFunction[0] = CompBattOpenClose;
+    DriverObject->MajorFunction[2] = CompBattOpenClose;
+    DriverObject->MajorFunction[14] = CompBattIoctl;
+    DriverObject->MajorFunction[22] = CompBattPowerDispatch;
+    DriverObject->MajorFunction[23] = CompBattSystemControl;
+    DriverObject->MajorFunction[27] = CompBattPnpDispatch;
+    
+    return STATUS_SUCCESS;
 }
 
 /* EOF */
 }
 
 /* EOF */
index 701f136..015195b 100644 (file)
@@ -52,6 +52,68 @@ typedef struct _COMPBATT_DEVICE_EXTENSION
     PVOID NotificationEntry;
 } COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION;
 
     PVOID NotificationEntry;
 } COMPBATT_DEVICE_EXTENSION, *PCOMPBATT_DEVICE_EXTENSION;
 
-extern ULONG CmBattDebug;
+NTSTATUS
+NTAPI
+CompBattAddDevice(
+    IN PDRIVER_OBJECT DriverObject,
+    IN PDEVICE_OBJECT PdoDeviceObject
+);
+
+NTSTATUS
+NTAPI
+CompBattPowerDispatch(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp
+);
+
+NTSTATUS
+NTAPI
+CompBattPnpDispatch(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp
+);
+
+NTSTATUS
+NTAPI
+CompBattQueryInformation(
+    IN PCOMPBATT_DEVICE_EXTENSION FdoExtension,
+    IN ULONG Tag,
+    IN BATTERY_QUERY_INFORMATION_LEVEL InfoLevel,
+    IN OPTIONAL LONG AtRate,
+    IN PVOID Buffer,
+    IN ULONG BufferLength,
+    OUT PULONG ReturnedLength
+);
+                       
+NTSTATUS
+NTAPI
+CompBattQueryStatus(
+    IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
+    IN ULONG Tag,
+    IN PBATTERY_STATUS BatteryStatus
+);
+
+NTSTATUS
+NTAPI
+CompBattSetStatusNotify(
+    IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
+    IN ULONG BatteryTag,
+    IN PBATTERY_NOTIFY BatteryNotify
+);
+
+NTSTATUS
+NTAPI
+CompBattDisableStatusNotify(
+    IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension
+);
+
+NTSTATUS
+NTAPI
+CompBattQueryTag(
+    IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension,
+    OUT PULONG Tag
+);
+
+extern ULONG CompBattDebug;
 
 /* EOF */
 
 /* EOF */
index a767c18..156ee3f 100644 (file)
@@ -17,8 +17,15 @@ NTAPI
 CompBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
 {
 CompBattPowerDispatch(IN PDEVICE_OBJECT DeviceObject,
                       IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    if (CompBattDebug & 1) DbgPrint("CompBatt: PowerDispatch recieved power IRP.\n");
+     
+    /* Start the next IRP */
+    PoStartNextPowerIrp(Irp);
+    
+    /* Call the next driver in the stack */
+    IoSkipCurrentIrpStackLocation(Irp);
+    return PoCallDriver(DeviceExtension->AttachedDevice, Irp);
 }
 
 PCOMPBATT_BATTERY_ENTRY
 }
 
 PCOMPBATT_BATTERY_ENTRY
@@ -79,8 +86,82 @@ NTAPI
 CompBattAddDevice(IN PDRIVER_OBJECT DriverObject,
                   IN PDEVICE_OBJECT PdoDeviceObject)
 {
 CompBattAddDevice(IN PDRIVER_OBJECT DriverObject,
                   IN PDEVICE_OBJECT PdoDeviceObject)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    NTSTATUS Status;
+    UNICODE_STRING DeviceName;
+    PCOMPBATT_DEVICE_EXTENSION DeviceExtension;
+    PDEVICE_OBJECT DeviceObject;
+    UNICODE_STRING SymbolicLinkName;
+    BATTERY_MINIPORT_INFO MiniportInfo;
+    if (CompBattDebug & 2) DbgPrint("CompBatt: Got an AddDevice - %x\n", PdoDeviceObject);
+    
+    /* Create the device */
+    RtlInitUnicodeString(&DeviceName, L"\\Device\\CompositeBattery");
+    Status = IoCreateDevice(DriverObject,
+                            sizeof(COMPBATT_DEVICE_EXTENSION),
+                            &DeviceName, 
+                            FILE_DEVICE_BATTERY,
+                            FILE_DEVICE_SECURE_OPEN,
+                            FALSE,
+                            &DeviceObject);
+    if (!NT_SUCCESS(Status)) return Status;
+
+    /* Setup symbolic link for Win32 access */
+    RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\CompositeBattery");
+    IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
+    
+    /* Initialize the device extension */
+    DeviceExtension = DeviceObject->DeviceExtension;
+    RtlZeroMemory(DeviceExtension, 0x1B0u);
+    
+    /* Attach to device stack and set DO pointers */
+    DeviceExtension->AttachedDevice = IoAttachDeviceToDeviceStack(DeviceObject,
+                                                                  PdoDeviceObject);
+    DeviceExtension->DeviceObject = DeviceObject;
+    if (!DeviceExtension->AttachedDevice)
+    {
+        /* Fail */
+        if (CompBattDebug & 8)
+            DbgPrint("CompBattAddDevice: Could not attach to LowerDevice.\n");
+        IoDeleteDevice(DeviceObject);
+        return STATUS_UNSUCCESSFUL; 
+    }
+
+    /* Set device object flags */
+    DeviceObject->Flags |= (DO_POWER_PAGABLE | DO_BUFFERED_IO);
+    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
+
+    /* Setup the device extension */
+    ExInitializeFastMutex(&DeviceExtension->Lock);
+    InitializeListHead(&DeviceExtension->BatteryList);
+    DeviceExtension->Flags = 0;
+    DeviceExtension->NextTag = 1;
+    
+    /* Setup the miniport data */
+    RtlZeroMemory(&MiniportInfo, sizeof(MiniportInfo));
+    MiniportInfo.MajorVersion = BATTERY_CLASS_MAJOR_VERSION;
+    MiniportInfo.MinorVersion = BATTERY_CLASS_MINOR_VERSION;
+    MiniportInfo.Context = DeviceExtension;
+    MiniportInfo.DeviceName = &DeviceName;
+    MiniportInfo.QueryTag = (BCLASS_QUERY_TAG)CompBattQueryTag;
+    MiniportInfo.QueryInformation = (BCLASS_QUERY_INFORMATION)CompBattQueryInformation;
+    MiniportInfo.SetInformation = NULL;
+    MiniportInfo.QueryStatus = (BCLASS_QUERY_STATUS)CompBattQueryStatus;
+    MiniportInfo.SetStatusNotify = (BCLASS_SET_STATUS_NOTIFY)CompBattSetStatusNotify;
+    MiniportInfo.DisableStatusNotify = (BCLASS_DISABLE_STATUS_NOTIFY)CompBattDisableStatusNotify;
+    MiniportInfo.Pdo = NULL;
+    
+    /* Register with the class driver */
+    Status = BatteryClassInitializeDevice(&MiniportInfo,
+                                          &DeviceExtension->ClassData);
+    if (!NT_SUCCESS(Status))
+    {
+        /* Undo everything */
+        IoDetachDevice(DeviceExtension->AttachedDevice);
+        IoDeleteDevice(DeviceObject);
+    }
+
+    /* Return status */
+    return Status;
 }
 
 NTSTATUS
 }
 
 NTSTATUS
@@ -88,8 +169,94 @@ NTAPI
 CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
 {
 CompBattPnpDispatch(IN PDEVICE_OBJECT DeviceObject,
                     IN PIRP Irp)
 {
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
+    PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
+    NTSTATUS Status;
+    PCOMPBATT_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
+    if (CompBattDebug & 1) DbgPrint("CompBatt: ENTERING PnpDispatch\n");
+
+    /* Set default error */
+    Status = STATUS_NOT_SUPPORTED;
+
+    /* Check what kind of PnP function this is */
+    switch (IoStackLocation->MinorFunction)
+    {
+        case IRP_MN_START_DEVICE:
+        
+            /* Device is starting, register for new batteries and pick up current ones */
+            Status = IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange,
+                                                    0,
+                                                    (PVOID)&GUID_DEVICE_BATTERY,
+                                                    DeviceObject->DriverObject,
+                                                    (PDRIVER_NOTIFICATION_CALLBACK_ROUTINE)CompBattPnpEventHandler,
+                                                    DeviceExtension,
+                                                    &DeviceExtension->NotificationEntry);
+            if (NT_SUCCESS(Status))
+            {
+                /* Now go get the batteries */
+                if (CompBattDebug & 2)
+                    DbgPrint("CompBatt: Successfully registered for PnP notification\n");
+                Status = CompBattGetBatteries(DeviceExtension);
+            }
+            else
+            {
+                /* We failed */
+                if (CompBattDebug & 8)
+                    DbgPrint("CompBatt: Couldn't register for PnP notification - %x\n",
+                             Status);
+            }
+        
+        case IRP_MN_CANCEL_STOP_DEVICE:
+        
+            /* Explicitly say ok */
+            Status = STATUS_SUCCESS;
+            break;
+            
+        case IRP_MN_CANCEL_REMOVE_DEVICE:
+
+            /* Explicitly say ok */
+            Status = STATUS_SUCCESS;
+            break;
+            
+        case IRP_MN_SURPRISE_REMOVAL:
+        
+            /* Explicitly say ok */
+            Status = STATUS_SUCCESS;
+            break;
+            
+        case IRP_MN_QUERY_PNP_DEVICE_STATE:
+        
+            /* Add this in */
+            Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
+            Status = STATUS_SUCCESS;
+            break;
+            
+        default:
+        
+            /* Not supported */
+            Status = STATUS_INVALID_DEVICE_REQUEST;
+            break;
+    }
+
+    /* Set IRP status if we have one */
+    if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;
+
+    /* Did someone pick it up? */    
+    if ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED))
+    {
+        /* Still unsupported, try ACPI */
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(DeviceExtension->AttachedDevice, Irp);
+    }
+    else
+    {
+        /* Complete the request */
+        Status = Irp->IoStatus.Status;
+        IofCompleteRequest(Irp, IO_NO_INCREMENT);
+    }
+
+    /* Release the remove lock and return status */
+    if (CompBattDebug & 1) DbgPrint("CompBatt: EXITING PnpDispatch\n");
+    return Status;
 }
 
 /* EOF */
 }
 
 /* EOF */
diff --git a/drivers/bus/acpi/eval.c b/drivers/bus/acpi/eval.c
new file mode 100644 (file)
index 0000000..68af857
--- /dev/null
@@ -0,0 +1,180 @@
+#include <ntddk.h>
+
+#include <acpi.h>
+
+#include <acpisys.h>
+#include <acpi_bus.h>
+#include <acpi_drivers.h>
+#include <acpiioct.h>
+
+#include <glue.h>
+#include <accommon.h>
+#include <acobject.h>
+#include <actypes.h>
+
+#include <wdmguid.h>
+#define NDEBUG
+#include <debug.h>
+
+NTSTATUS
+NTAPI
+Bus_PDO_EvalMethod(PPDO_DEVICE_DATA DeviceData,
+                   PIRP Irp)
+{
+  ULONG Signature;
+  NTSTATUS Status;
+  ACPI_OBJECT_LIST ParamList;
+  PACPI_EVAL_INPUT_BUFFER EvalInputBuff = Irp->AssociatedIrp.SystemBuffer;
+  ACPI_BUFFER RetBuff = {ACPI_ALLOCATE_BUFFER, NULL};
+  PACPI_EVAL_OUTPUT_BUFFER OutputBuf;
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER *SimpleInt;
+  ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING *SimpleStr;
+
+  if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ULONG))
+      return STATUS_INVALID_PARAMETER;
+
+  Signature = *((PULONG)Irp->AssociatedIrp.SystemBuffer);
+
+  switch (Signature)
+  {
+     case ACPI_EVAL_INPUT_BUFFER_SIGNATURE:
+        if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ACPI_EVAL_INPUT_BUFFER))
+            return STATUS_INVALID_PARAMETER;
+
+        ParamList.Count = 0;
+        break;
+
+     case ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER_SIGNATURE:
+        SimpleInt = Irp->AssociatedIrp.SystemBuffer;
+
+        if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_INTEGER))
+            return STATUS_INVALID_PARAMETER;
+
+        ParamList.Count = 1;
+
+        ParamList.Pointer = ExAllocatePool(NonPagedPool, sizeof(ACPI_OBJECT));
+        if (!ParamList.Pointer) return STATUS_INSUFFICIENT_RESOURCES;
+
+        ParamList.Pointer[0].Type = ACPI_TYPE_INTEGER;
+        ParamList.Pointer[0].Integer.Value = SimpleInt->IntegerArgument;
+        break;
+
+     case ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING_SIGNATURE:
+        SimpleStr = Irp->AssociatedIrp.SystemBuffer;
+
+        if (IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(ACPI_EVAL_INPUT_BUFFER_SIMPLE_STRING))
+            return STATUS_INVALID_PARAMETER;
+
+        ParamList.Count = 1;
+
+        ParamList.Pointer = ExAllocatePool(NonPagedPool, sizeof(ACPI_OBJECT));
+        if (!ParamList.Pointer) return STATUS_INSUFFICIENT_RESOURCES;
+
+        ParamList.Pointer[0].String.Pointer = (CHAR*)SimpleStr->String;
+        ParamList.Pointer[0].String.Length = SimpleStr->StringLength;
+        break;
+
+     default:
+        DPRINT1("Unsupported input buffer signature: %d\n", Signature);
+        return STATUS_NOT_IMPLEMENTED;
+  }
+
+  Status = AcpiEvaluateObject(DeviceData->AcpiHandle,
+                              (CHAR*)EvalInputBuff->MethodName,
+                              &ParamList,
+                              &RetBuff);
+
+  if (ParamList.Count != 0)
+      ExFreePool(ParamList.Pointer);
+
+  if (ACPI_SUCCESS(Status))
+  {
+      ACPI_OBJECT *Obj = RetBuff.Pointer;
+      ULONG ExtraParamLength;
+
+      /* If we didn't get anything back then we're done */
+      if (!RetBuff.Pointer || RetBuff.Length == 0)
+          return STATUS_SUCCESS;
+
+      switch (Obj->Type)
+      {
+          case ACPI_TYPE_INTEGER:
+             ExtraParamLength = sizeof(ULONG);
+             break;
+
+          case ACPI_TYPE_STRING:
+             ExtraParamLength = Obj->String.Length;
+             break;
+
+          case ACPI_TYPE_BUFFER:
+             ExtraParamLength = Obj->Buffer.Length;
+             break;
+
+          case ACPI_TYPE_PACKAGE:
+             DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
+             return STATUS_UNSUCCESSFUL;
+
+          default:
+             ASSERT(FALSE);
+             return STATUS_UNSUCCESSFUL;
+      }
+
+      /* Enough space for a ULONG is always included */
+      if (ExtraParamLength >= sizeof(ULONG))
+          ExtraParamLength -= sizeof(ULONG);
+      else
+          ExtraParamLength = 0;
+
+      OutputBuf = ExAllocatePool(NonPagedPool, sizeof(ACPI_EVAL_OUTPUT_BUFFER) +
+                                               ExtraParamLength);
+      if (!OutputBuf) return STATUS_INSUFFICIENT_RESOURCES;
+
+      OutputBuf->Signature = ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE;
+      OutputBuf->Length = ExtraParamLength + sizeof(ACPI_METHOD_ARGUMENT);
+      OutputBuf->Count = 1;
+
+      switch (Obj->Type)
+      {
+          case ACPI_TYPE_INTEGER:
+             ACPI_METHOD_SET_ARGUMENT_INTEGER(OutputBuf->Argument, Obj->Integer.Value);
+             break;
+
+          case ACPI_TYPE_STRING:
+             ACPI_METHOD_SET_ARGUMENT_STRING(OutputBuf->Argument, Obj->String.Pointer);
+             break;
+
+          case ACPI_TYPE_BUFFER:
+             ACPI_METHOD_SET_ARGUMENT_BUFFER(OutputBuf->Argument, Obj->Buffer.Pointer, Obj->Buffer.Length);
+             break;
+
+          case ACPI_TYPE_PACKAGE:
+             DPRINT1("ACPI_TYPE_PACKAGE not supported yet!\n");
+             return STATUS_UNSUCCESSFUL;
+
+          default:
+             ASSERT(FALSE);
+             return STATUS_UNSUCCESSFUL;
+      }
+
+      if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ACPI_EVAL_OUTPUT_BUFFER) +
+                                                                  ExtraParamLength)
+      {
+          RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, OutputBuf, sizeof(ACPI_EVAL_OUTPUT_BUFFER) +
+                                                                    ExtraParamLength);
+          Irp->IoStatus.Information = sizeof(ACPI_EVAL_OUTPUT_BUFFER) + ExtraParamLength;
+          ExFreePool(OutputBuf);
+          return STATUS_SUCCESS;
+      }
+      else
+      {
+          ExFreePool(OutputBuf);
+          return STATUS_BUFFER_TOO_SMALL;
+      }
+  }
+  else
+  {
+      DPRINT1("Query method %s failed on %p\n", EvalInputBuff->MethodName, DeviceData->AcpiHandle);
+      return STATUS_UNSUCCESSFUL; 
+  }
+}
diff --git a/drivers/bus/acpi/interface.c b/drivers/bus/acpi/interface.c
new file mode 100644 (file)
index 0000000..5971705
--- /dev/null
@@ -0,0 +1,138 @@
+#include <ntddk.h>
+
+#include <acpi.h>
+
+#include <acpisys.h>
+#include <acpi_bus.h>
+#include <acpi_drivers.h>
+
+#include <wdmguid.h>
+#define NDEBUG
+#include <debug.h>
+
+VOID
+NTAPI
+AcpiInterfaceReference(PVOID Context)
+{
+  UNIMPLEMENTED
+}
+
+VOID
+NTAPI
+AcpiInterfaceDereference(PVOID Context)
+{
+  UNIMPLEMENTED
+}
+
+NTSTATUS
+AcpiInterfaceConnectVector(PDEVICE_OBJECT Context,
+                           ULONG GpeNumber,
+                           KINTERRUPT_MODE Mode,
+                           BOOLEAN Shareable,
+                           PGPE_SERVICE_ROUTINE ServiceRoutine,
+                           PVOID ServiceContext,
+                           PVOID *ObjectContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+AcpiInterfaceDisconnectVector(PDEVICE_OBJECT Context,
+                              PVOID ObjectContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+AcpiInterfaceEnableEvent(PDEVICE_OBJECT Context,
+                         PVOID ObjectContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+AcpiInterfaceDisableEvent(PDEVICE_OBJECT Context,
+                          PVOID ObjectContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+AcpiInterfaceClearStatus(PDEVICE_OBJECT Context,
+                         PVOID ObjectContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
+AcpiInterfaceNotificationsRegister(PDEVICE_OBJECT Context,
+                                   PDEVICE_NOTIFY_CALLBACK NotificationHandler,
+                                   PVOID NotificationContext)
+{
+  UNIMPLEMENTED
+
+  return STATUS_NOT_IMPLEMENTED;
+}
+
+VOID
+AcpiInterfaceNotificationsUnregister(PDEVICE_OBJECT Context,
+                                     PDEVICE_NOTIFY_CALLBACK NotificationHandler)
+{
+  UNIMPLEMENTED
+}
+
+NTSTATUS
+Bus_PDO_QueryInterface(PPDO_DEVICE_DATA DeviceData,
+                       PIRP Irp)
+{
+  PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
+  PACPI_INTERFACE_STANDARD AcpiInterface;
+
+  if (IrpSp->Parameters.QueryInterface.Version != 1)
+  {
+      DPRINT1("Invalid version number: %d\n",
+              IrpSp->Parameters.QueryInterface.Version);
+      return STATUS_INVALID_PARAMETER;
+  }
+
+  if (RtlCompareMemory(IrpSp->Parameters.QueryInterface.InterfaceType,
+                        &GUID_ACPI_INTERFACE_STANDARD, sizeof(GUID)) == sizeof(GUID))
+  {
+      DPRINT("GUID_ACPI_INTERFACE_STANDARD\n");
+
+      if (IrpSp->Parameters.QueryInterface.Size < sizeof(ACPI_INTERFACE_STANDARD))
+      {
+          DPRINT1("Buffer too small! (%d)\n", IrpSp->Parameters.QueryInterface.Size);
+          return STATUS_BUFFER_TOO_SMALL;
+      }
+
+     AcpiInterface = (PACPI_INTERFACE_STANDARD)IrpSp->Parameters.QueryInterface.Interface;
+
+     AcpiInterface->InterfaceReference = AcpiInterfaceReference;
+     AcpiInterface->InterfaceDereference = AcpiInterfaceDereference;
+     AcpiInterface->GpeConnectVector = AcpiInterfaceConnectVector;
+     AcpiInterface->GpeDisconnectVector = AcpiInterfaceDisconnectVector;
+     AcpiInterface->GpeEnableEvent = AcpiInterfaceEnableEvent;
+     AcpiInterface->GpeDisableEvent = AcpiInterfaceDisableEvent;
+     AcpiInterface->GpeClearStatus = AcpiInterfaceClearStatus;
+     AcpiInterface->RegisterForDeviceNotifications = AcpiInterfaceNotificationsRegister;
+     AcpiInterface->UnregisterForDeviceNotifications = AcpiInterfaceNotificationsUnregister;
+
+     return STATUS_SUCCESS;
+  }
+  else
+  {
+      DPRINT1("Invalid GUID\n");
+      return STATUS_INVALID_PARAMETER;
+  }
+}
diff --git a/drivers/storage/scsiport/scsiport.pspec b/drivers/storage/scsiport/scsiport.pspec
new file mode 100644 (file)
index 0000000..65c7547
--- /dev/null
@@ -0,0 +1,51 @@
+#ifdef __x86_64__
+#define MAYBEFWD(x)
+#else
+#define MAYBEFWD(x) x
+#endif
+
+@ cdecl ScsiDebugPrint()
+@ stdcall ScsiPortCompleteRequest(ptr long long long long)
+@ stdcall ScsiPortConvertPhysicalAddressToUlong(long long)
+@ stdcall ScsiPortConvertUlongToPhysicalAddress(long) MAYBEFWD(NTOSKRNL.RtlConvertUlongToLargeInteger)
+@ stdcall ScsiPortFlushDma(ptr)
+@ stdcall ScsiPortFreeDeviceBase(ptr ptr)
+@ stdcall ScsiPortGetBusData(ptr long long long ptr long)
+@ stdcall ScsiPortGetDeviceBase(ptr long long long long long long)
+@ stdcall ScsiPortGetLogicalUnit(ptr long long long)
+@ stdcall ScsiPortGetPhysicalAddress(ptr ptr ptr long)
+@ stdcall ScsiPortGetSrb(ptr long long long long)
+@ stdcall ScsiPortGetUncachedExtension(ptr ptr long)
+@ stdcall ScsiPortGetVirtualAddress(ptr long long)
+@ stdcall ScsiPortInitialize(ptr ptr ptr ptr)
+@ stdcall ScsiPortIoMapTransfer(ptr ptr long long)
+@ stdcall ScsiPortLogError(ptr ptr long long long long long)
+@ stdcall ScsiPortMoveMemory(ptr ptr long)
+@ cdecl ScsiPortNotification()
+@ stdcall ScsiPortReadPortBufferUchar(ptr ptr long) MAYBEFWD(HAL.READ_PORT_BUFFER_UCHAR)
+@ stdcall ScsiPortReadPortBufferUshort(ptr ptr long) MAYBEFWD(HAL.READ_PORT_BUFFER_USHORT)
+@ stdcall ScsiPortReadPortBufferUlong(ptr ptr long) MAYBEFWD(HAL.READ_PORT_BUFFER_ULONG)
+@ stdcall ScsiPortReadPortUchar(ptr) MAYBEFWD(HAL.READ_PORT_UCHAR)
+@ stdcall ScsiPortReadPortUshort(ptr) MAYBEFWD(HAL.READ_PORT_USHORT)
+@ stdcall ScsiPortReadPortUlong(ptr) MAYBEFWD(HAL.READ_PORT_ULONG)
+@ stdcall ScsiPortReadRegisterBufferUchar(ptr ptr long) MAYBEFWD(NTOSKRNL.READ_REGISTER_BUFFER_UCHAR)
+@ stdcall ScsiPortReadRegisterBufferUshort(ptr ptr long) MAYBEFWD(NTOSKRNL.READ_REGISTER_BUFFER_USHORT)
+@ stdcall ScsiPortReadRegisterBufferUlong(ptr ptr long) MAYBEFWD(NTOSKRNL.READ_REGISTER_BUFFER_ULONG)
+@ stdcall ScsiPortReadRegisterUchar(ptr) MAYBEFWD(NTOSKRNL.READ_REGISTER_UCHAR)
+@ stdcall ScsiPortReadRegisterUshort(ptr) MAYBEFWD(NTOSKRNL.READ_REGISTER_USHORT)
+@ stdcall ScsiPortReadRegisterUlong(ptr) MAYBEFWD(NTOSKRNL.READ_REGISTER_ULONG)
+@ stdcall ScsiPortSetBusDataByOffset(ptr long long long ptr long long)
+@ stdcall ScsiPortStallExecution(long) HAL.KeStallExecutionProcessor
+@ stdcall ScsiPortValidateRange(ptr long long long long long long)
+@ stdcall ScsiPortWritePortBufferUchar(ptr ptr long) MAYBEFWD(HAL.WRITE_PORT_BUFFER_UCHAR)
+@ stdcall ScsiPortWritePortBufferUshort(ptr ptr long) MAYBEFWD(HAL.WRITE_PORT_BUFFER_USHORT)
+@ stdcall ScsiPortWritePortBufferUlong(ptr ptr long) MAYBEFWD(HAL.WRITE_PORT_BUFFER_ULONG)
+@ stdcall ScsiPortWritePortUchar(ptr long) MAYBEFWD(HAL.WRITE_PORT_UCHAR)
+@ stdcall ScsiPortWritePortUshort(ptr long) MAYBEFWD(HAL.WRITE_PORT_USHORT)
+@ stdcall ScsiPortWritePortUlong(ptr long) MAYBEFWD(HAL.WRITE_PORT_ULONG)
+@ stdcall ScsiPortWriteRegisterBufferUchar(ptr ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_BUFFER_UCHAR)
+@ stdcall ScsiPortWriteRegisterBufferUshort(ptr ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_BUFFER_USHORT)
+@ stdcall ScsiPortWriteRegisterBufferUlong(ptr ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_BUFFER_ULONG)
+@ stdcall ScsiPortWriteRegisterUchar(ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_UCHAR)
+@ stdcall ScsiPortWriteRegisterUshort(ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_USHORT)
+@ stdcall ScsiPortWriteRegisterUlong(ptr long) MAYBEFWD(NTOSKRNL.WRITE_REGISTER_ULONG)
diff --git a/drivers/storage/scsiport/stubs.c b/drivers/storage/scsiport/stubs.c
new file mode 100644 (file)
index 0000000..9e286d1
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * COPYRIGHT:       See COPYING in the top level directory
+ * PROJECT:         ReactOS Storage Stack
+ * FILE:            drivers/storage/scsiport/stubs.c
+ * PURPOSE:         SCSI port driver
+ * PROGRAMMER:      Timo Kreuzer (timo.kreuzer@reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntddk.h>
+#include <srb.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#ifdef _MSC_VER
+  #define DDKAPI
+#endif
+
+SCSI_PHYSICAL_ADDRESS
+DDKAPI
+ScsiPortConvertUlongToPhysicalAddress(
+    IN ULONG  UlongAddress)
+{
+    return RtlConvertUlongToLargeInteger(UlongAddress);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUchar(
+    IN PUCHAR Port,
+    IN PUCHAR Buffer,
+    IN ULONG  Count)
+{
+    READ_PORT_BUFFER_UCHAR(Port, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUshort(
+    IN PUSHORT Port,
+    IN PUSHORT Buffer,
+    IN ULONG   Count)
+{
+    READ_PORT_BUFFER_USHORT(Port, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadPortBufferUlong(
+    IN PULONG Port,
+    IN PULONG Buffer,
+    IN ULONG  Count)
+{
+    READ_PORT_BUFFER_ULONG(Port, Buffer, Count);
+}
+
+UCHAR
+DDKAPI
+ScsiPortReadPortUchar(
+    IN PUCHAR Port)
+{
+    return READ_PORT_UCHAR(Port);
+}
+
+USHORT
+DDKAPI
+ScsiPortReadPortUshort(
+    IN PUSHORT Port)
+{
+    return READ_PORT_USHORT(Port);
+}
+
+ULONG
+DDKAPI
+ScsiPortReadPortUlong(
+    IN PULONG Port)
+{
+    return READ_PORT_ULONG(Port);
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUchar(
+    IN PUCHAR Register,
+    IN PUCHAR Buffer,
+    IN ULONG Count)
+{
+    READ_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUshort(
+    IN PUSHORT Register,
+    IN PUSHORT Buffer,
+    IN ULONG Count)
+{
+    READ_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortReadRegisterBufferUlong(
+    IN PULONG Register,
+    IN PULONG Buffer,
+    IN ULONG Count)
+{
+    READ_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
+}
+
+UCHAR
+DDKAPI
+ScsiPortReadRegisterUchar(
+    IN PUCHAR Register)
+{
+    return READ_REGISTER_UCHAR(Register);
+}
+
+USHORT
+DDKAPI
+ScsiPortReadRegisterUshort(
+    IN PUSHORT Register)
+{
+    return READ_REGISTER_USHORT(Register);
+}
+
+ULONG
+DDKAPI
+ScsiPortReadRegisterUlong(
+    IN PULONG Register)
+{
+    return READ_REGISTER_ULONG(Register);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUchar(
+    IN PUCHAR Port,
+    IN PUCHAR Buffer,
+    IN ULONG Count)
+{
+    WRITE_PORT_BUFFER_UCHAR(Port, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUshort(
+    IN PUSHORT Port,
+    IN PUSHORT Buffer,
+    IN ULONG Count)
+{
+    WRITE_PORT_BUFFER_USHORT(Port, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortBufferUlong(
+    IN PULONG Port,
+    IN PULONG Buffer,
+    IN ULONG Count)
+{
+    WRITE_PORT_BUFFER_ULONG(Port, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUchar(
+    IN PUCHAR Port,
+    IN UCHAR Value)
+{
+    WRITE_PORT_UCHAR(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUshort(
+    IN PUSHORT Port,
+    IN USHORT Value)
+{
+    WRITE_PORT_USHORT(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWritePortUlong(
+    IN PULONG Port,
+    IN ULONG Value)
+{
+    WRITE_PORT_ULONG(Port, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUchar(
+    IN PUCHAR Register,
+    IN PUCHAR Buffer,
+    IN ULONG Count)
+{
+    WRITE_REGISTER_BUFFER_UCHAR(Register, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUshort(
+    IN PUSHORT Register,
+    IN PUSHORT Buffer,
+    IN ULONG Count)
+{
+    WRITE_REGISTER_BUFFER_USHORT(Register, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterBufferUlong(
+    IN PULONG Register,
+    IN PULONG Buffer,
+    IN ULONG Count)
+{
+    WRITE_REGISTER_BUFFER_ULONG(Register, Buffer, Count);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUchar(
+    IN PUCHAR  Register,
+    IN ULONG  Value)
+{
+    WRITE_REGISTER_UCHAR(Register, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUshort(
+    IN PUSHORT Register,
+    IN USHORT Value)
+{
+    WRITE_REGISTER_USHORT(Register, Value);
+}
+
+VOID
+DDKAPI
+ScsiPortWriteRegisterUlong(
+    IN PULONG Register,
+    IN ULONG Value)
+{
+    WRITE_REGISTER_ULONG(Register, Value);
+}
+
diff --git a/hal/halx86/up/pic.c b/hal/halx86/up/pic.c
new file mode 100644 (file)
index 0000000..a710d86
--- /dev/null
@@ -0,0 +1,1363 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         BSD - See COPYING.ARM in the top level directory
+ * FILE:            hal/halx86/generic/pic.c
+ * PURPOSE:         HAL PIC Management and Control Code
+ * PROGRAMMERS:     ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS ********************************************************************/
+
+#ifndef _MINIHAL_
+/*
+ * This table basically keeps track of level vs edge triggered interrupts.
+ * Windows has 250+ entries, but it seems stupid to replicate that since the PIC
+ * can't actually have that many.
+ *
+ * When a level interrupt is registered, the respective pointer in this table is
+ * modified to point to a dimiss routine for level interrupts instead.
+ *
+ * The other thing this table does is special case IRQ7, IRQ13 and IRQ15:
+ *
+ * - If an IRQ line is deasserted before it is acknowledged due to a noise spike
+ *   generated by an expansion device (since the IRQ line is low during the 1st
+ *   acknowledge bus cycle), the i8259 will keep the line low for at least 100ns
+ *   When the spike passes, a pull-up resistor will return the IRQ line to high.
+ *   Since the PIC requires the input be high until the first acknowledge, the
+ *   i8259 knows that this was a spurious interrupt, and on the second interrupt
+ *   acknowledge cycle, it reports this to the CPU. Since no valid interrupt has
+ *   actually happened Intel hardcoded the chip to report IRQ7 on the master PIC
+ *   and IRQ15 on the slave PIC (IR7 either way).
+ *
+ *   "ISA System Architecture", 3rd Edition, states that these cases should be
+ *   handled by reading the respective Interrupt Service Request (ISR) bits from
+ *   the affected PIC, and validate whether or not IR7 is set. If it isn't, then
+ *   the interrupt is spurious and should be ignored.
+ *
+ *   Note that for a spurious IRQ15, we DO have to send an EOI to the master for
+ *   IRQ2 since the line was asserted by the slave when it received the spurious
+ *   IRQ15!
+ *
+ * - When the 80287/80387 math co-processor generates an FPU/NPX trap, this is 
+ *   connected to IRQ13, so we have to clear the busy latch on the NPX port.
+ */
+PHAL_DISMISS_INTERRUPT HalpSpecialDismissTable[16] =
+{
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrq07,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrqGeneric,
+    HalpDismissIrq13,
+    HalpDismissIrqGeneric,
+    HalpDismissIrq15
+};
+
+/*
+ * These are the level IRQ dismissal functions that get copied in the table
+ * above if the given IRQ is actually level triggered.
+ */
+PHAL_DISMISS_INTERRUPT HalpSpecialDismissLevelTable[16] =
+{
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrq07Level,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrqLevel,
+    HalpDismissIrq13Level,
+    HalpDismissIrqLevel,
+    HalpDismissIrq15Level
+};
+
+/* This table contains the static x86 PIC mapping between IRQLs and IRQs */
+ULONG KiI8259MaskTable[32] =
+{
+#ifdef __GNUC__
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404
+    /*
+     * It Device IRQLs only start at 4 or higher, so these are just software
+     * IRQLs that don't really change anything on the hardware
+     */
+    0b00000000000000000000000000000000, /* IRQL 0 */
+    0b00000000000000000000000000000000, /* IRQL 1 */
+    0b00000000000000000000000000000000, /* IRQL 2 */
+    0b00000000000000000000000000000000, /* IRQL 3 */
+    
+    /*
+     * These next IRQLs are actually useless from the PIC perspective, because
+     * with only 2 PICs, the mask you can send them is only 8 bits each, for 16
+     * bits total, so these IRQLs are masking off a phantom PIC.
+     */
+    0b11111111100000000000000000000000, /* IRQL 4 */
+    0b11111111110000000000000000000000, /* IRQL 5 */
+    0b11111111111000000000000000000000, /* IRQL 6 */
+    0b11111111111100000000000000000000, /* IRQL 7 */
+    0b11111111111110000000000000000000, /* IRQL 8 */
+    0b11111111111111000000000000000000, /* IRQL 9 */
+    0b11111111111111100000000000000000, /* IRQL 10 */
+    0b11111111111111110000000000000000, /* IRQL 11 */
+    
+    /*
+     * Okay, now we're finally starting to mask off IRQs on the slave PIC, from
+     * IRQ15 to IRQ8. This means the higher-level IRQs get less priority in the
+     * IRQL sense.
+     */
+    0b11111111111111111000000000000000, /* IRQL 12 */
+    0b11111111111111111100000000000000, /* IRQL 13 */
+    0b11111111111111111110000000000000, /* IRQL 14 */
+    0b11111111111111111111000000000000, /* IRQL 15 */
+    0b11111111111111111111100000000000, /* IRQL 16 */
+    0b11111111111111111111110000000000, /* IRQL 17 */
+    0b11111111111111111111111000000000, /* IRQL 18 */
+    0b11111111111111111111111000000000, /* IRQL 19 */
+    
+    /*
+     * Now we mask off the IRQs on the master. Notice the 0 "droplet"? You might
+     * have also seen that IRQL 18 and 19 are essentially equal as far as the
+     * PIC is concerned. That bit is actually IRQ8, which happens to be the RTC.
+     * The RTC will keep firing as long as we don't reach PROFILE_LEVEL which
+     * actually kills it. The RTC clock (unlike the system clock) is used by the
+     * profiling APIs in the HAL, so that explains the logic.
+     */
+    0b11111111111111111111111010000000, /* IRQL 20 */
+    0b11111111111111111111111011000000, /* IRQL 21 */
+    0b11111111111111111111111011100000, /* IRQL 22 */
+    0b11111111111111111111111011110000, /* IRQL 23 */
+    0b11111111111111111111111011111000, /* IRQL 24 */
+    0b11111111111111111111111011111000, /* IRQL 25 */
+    0b11111111111111111111111011111010, /* IRQL 26 */
+    0b11111111111111111111111111111010, /* IRQL 27 */
+    
+    /*
+     * IRQL 24 and 25 are actually identical, so IRQL 28 is actually the last
+     * IRQL to modify a bit on the master PIC. It happens to modify the very
+     * last of the IRQs, IRQ0, which corresponds to the system clock interval
+     * timer that keeps track of time (the Windows heartbeat). We only want to
+     * turn this off at a high-enough IRQL, which is why IRQLs 24 and 25 are the
+     * same to give this guy a chance to come up higher. Note that IRQL 28 is
+     * called CLOCK2_LEVEL, which explains the usage we just explained.
+     */
+    0b11111111111111111111111111111011, /* IRQL 28 */
+    
+    /*
+     * We have finished off with the PIC so there's nothing left to mask at the
+     * level of these IRQLs, making them only logical IRQLs on x86 machines.
+     * Note that we have another 0 "droplet" you might've caught since IRQL 26.
+     * In this case, it's the 2nd bit that never gets turned off, which is IRQ2,
+     * the cascade IRQ that we use to bridge the slave PIC with the master PIC.
+     * We never want to turn it off, so no matter the IRQL, it will be set to 0.
+     */
+    0b11111111111111111111111111111011, /* IRQL 29 */
+    0b11111111111111111111111111111011, /* IRQL 30 */
+    0b11111111111111111111111111111011  /* IRQL 31 */
+#else
+    0,                             /* IRQL 0 */
+    0,                             /* IRQL 1 */
+    0,                             /* IRQL 2 */
+    0,                             /* IRQL 3 */
+    0xFF800000,                    /* IRQL 4 */
+    0xFFC00000,                    /* IRQL 5 */
+    0xFFE00000,                    /* IRQL 6 */
+    0xFFF00000,                    /* IRQL 7 */
+    0xFFF80000,                    /* IRQL 8 */
+    0xFFFC0000,                    /* IRQL 9 */
+    0xFFFE0000,                    /* IRQL 10 */
+    0xFFFF0000,                    /* IRQL 11 */
+    0xFFFF8000,                    /* IRQL 12 */
+    0xFFFFC000,                    /* IRQL 13 */
+    0xFFFFE000,                    /* IRQL 14 */
+    0xFFFFF000,                    /* IRQL 15 */
+    0xFFFFF800,                    /* IRQL 16 */
+    0xFFFFFC00,                    /* IRQL 17 */
+    0xFFFFFE00,                    /* IRQL 18 */
+    0xFFFFFE00,                    /* IRQL 19 */
+    0xFFFFFE80,                    /* IRQL 20 */
+    0xFFFFFEC0,                    /* IRQL 21 */
+    0xFFFFFEE0,                    /* IRQL 22 */
+    0xFFFFFEF0,                    /* IRQL 23 */
+    0xFFFFFEF8,                    /* IRQL 24 */
+    0xFFFFFEF8,                    /* IRQL 25 */
+    0xFFFFFEFA,                    /* IRQL 26 */
+    0xFFFFFFFA,                    /* IRQL 27 */
+    0xFFFFFFFB,                    /* IRQL 28 */
+    0xFFFFFFFB,                    /* IRQL 29 */
+    0xFFFFFFFB,                    /* IRQL 30 */
+    0xFFFFFFFB                     /* IRQL 31 */
+#endif
+#endif
+};
+
+/* This table indicates which IRQs, if pending, can preempt a given IRQL level */
+ULONG FindHigherIrqlMask[32] =
+{
+#ifdef __GNUC__
+#if __GNUC__ * 100 + __GNUC_MINOR__ >= 404
+    /*
+     * Software IRQLs, at these levels all hardware interrupts can preempt.
+     * Each higher IRQL simply enables which software IRQL can preempt the
+     * current level.
+     */
+    0b11111111111111111111111111111110, /* IRQL 0 */
+    0b11111111111111111111111111111100, /* IRQL 1 */
+    0b11111111111111111111111111111000, /* IRQL 2 */
+    
+    /*
+     * IRQL3 means only hardware IRQLs can now preempt. These last 4 zeros will
+     * then continue throughout the rest of the list, trickling down.
+     */
+    0b11111111111111111111111111110000, /* IRQL 3 */
+    
+    /*
+     * Just like in the previous list, these masks don't really mean anything
+     * since we've only got two PICs with 16 possible IRQs total
+     */
+    0b00000111111111111111111111110000, /* IRQL 4 */
+    0b00000011111111111111111111110000, /* IRQL 5 */
+    0b00000001111111111111111111110000, /* IRQL 6 */
+    0b00000000111111111111111111110000, /* IRQL 7 */
+    0b00000000011111111111111111110000, /* IRQL 8 */
+    0b00000000001111111111111111110000, /* IRQL 9 */
+    0b00000000000111111111111111110000, /* IRQL 10 */
+    
+    /*
+     * Now we start progressivly limiting which slave PIC interrupts have the
+     * right to preempt us at each level.
+     */
+    0b00000000000011111111111111110000, /* IRQL 11 */
+    0b00000000000001111111111111110000, /* IRQL 12 */
+    0b00000000000000111111111111110000, /* IRQL 13 */
+    0b00000000000000011111111111110000, /* IRQL 14 */
+    0b00000000000000001111111111110000, /* IRQL 15 */
+    0b00000000000000000111111111110000, /* IRQL 16 */
+    0b00000000000000000011111111110000, /* IRQL 17 */
+    0b00000000000000000001111111110000, /* IRQL 18 */
+    0b00000000000000000001111111110000, /* IRQL 19 */
+    
+    /*
+     * Also recall from the earlier table that IRQL 18/19 are treated the same
+     * in order to spread the masks better thoughout the 32 IRQLs and to reflect
+     * the fact that some bits will always stay on until much higher IRQLs since
+     * they are system-critical. One such example is the 1 bit that you start to
+     * see trickling down here. This is IRQ8, the RTC timer used for profiling,
+     * so it will always preempt until we reach PROFILE_LEVEL.
+     */
+    0b00000000000000000001011111110000, /* IRQL 20 */
+    0b00000000000000000001001111110000, /* IRQL 20 */
+    0b00000000000000000001000111110000, /* IRQL 22 */
+    0b00000000000000000001000011110000, /* IRQL 23 */
+    0b00000000000000000001000001110000, /* IRQL 24 */
+    0b00000000000000000001000000110000, /* IRQL 25 */
+    0b00000000000000000001000000010000, /* IRQL 26 */
+    
+    /* At this point, only the clock (IRQ0) can still preempt... */
+    0b00000000000000000000000000010000, /* IRQL 27 */
+    
+    /* And any higher than that there's no relation with hardware PICs anymore */
+    0b00000000000000000000000000000000, /* IRQL 28 */
+    0b00000000000000000000000000000000, /* IRQL 29 */
+    0b00000000000000000000000000000000, /* IRQL 30 */
+    0b00000000000000000000000000000000, /* IRQL 31 */
+#else
+    0xFFFFFFFE,                   /* IRQL  0 */
+    0xFFFFFFFC,                   /* IRQL 1 */
+    0xFFFFFFF8,                   /* IRQL 2 */
+    0xFFFFFFF0,                   /* IRQL 3 */
+    0x7FFFFF0,                    /* IRQL 4 */
+    0x3FFFFF0,                    /* IRQL 5 */
+    0x1FFFFF0,                    /* IRQL 6 */
+    0x0FFFFF0,                    /* IRQL 7 */
+    0x7FFFF0,                     /* IRQL 8 */
+    0x3FFFF0,                     /* IRQL 9 */
+    0x1FFFF0,                     /* IRQL 10 */
+    0x0FFFF0,                     /* IRQL 11 */
+    0x7FFF0,                      /* IRQL 12 */
+    0x3FFF0,                      /* IRQL 13 */
+    0x1FFF0,                      /* IRQL 14 */
+    0x0FFF0,                      /* IRQL 15 */
+    0x7FF0,                       /* IRQL 16 */
+    0x3FF0,                       /* IRQL 17 */
+    0x1FF0,                       /* IRQL 18 */
+    0x1FF0,                       /* IRQL 19 */
+    0x17F0,                       /* IRQL 20 */
+    0x13F0,                       /* IRQL 21 */
+    0x11F0,                       /* IRQL 22 */
+    0x10F0,                       /* IRQL 23 */
+    0x1070,                       /* IRQL 24 */
+    0x1030,                       /* IRQL 25 */
+    0x1010,                       /* IRQL 26 */
+    0x10,                         /* IRQL 27 */
+    0,                            /* IRQL 28 */
+    0,                            /* IRQL 29 */
+    0,                            /* IRQL 30 */
+    0                             /* IRQL 31 */
+#endif
+#endif
+};
+
+/* Denotes minimum required IRQL before we can process pending SW interrupts */
+KIRQL SWInterruptLookUpTable[8] =
+{
+    PASSIVE_LEVEL,                 /* IRR 0 */
+    PASSIVE_LEVEL,                 /* IRR 1 */
+    APC_LEVEL,                     /* IRR 2 */
+    APC_LEVEL,                     /* IRR 3 */
+    DISPATCH_LEVEL,                /* IRR 4 */
+    DISPATCH_LEVEL,                /* IRR 5 */
+    DISPATCH_LEVEL,                /* IRR 6 */
+    DISPATCH_LEVEL                 /* IRR 7 */
+};
+
+#define HalpDelayedHardwareInterrupt(x)                             \
+    VOID HalpHardwareInterrupt##x(VOID);                            \
+    VOID                                                            \
+    HalpHardwareInterrupt##x(VOID)                                  \
+    {                                                               \
+        asm volatile ("int $%c0\n"::"i"(PRIMARY_VECTOR_BASE + x));  \
+    }
+
+/* Pending/delayed hardware interrupt handlers */
+HalpDelayedHardwareInterrupt(0);
+HalpDelayedHardwareInterrupt(1);
+HalpDelayedHardwareInterrupt(2);
+HalpDelayedHardwareInterrupt(3);
+HalpDelayedHardwareInterrupt(4);
+HalpDelayedHardwareInterrupt(5);
+HalpDelayedHardwareInterrupt(6);
+HalpDelayedHardwareInterrupt(7);
+HalpDelayedHardwareInterrupt(8);
+HalpDelayedHardwareInterrupt(9);
+HalpDelayedHardwareInterrupt(10);
+HalpDelayedHardwareInterrupt(11);
+HalpDelayedHardwareInterrupt(12);
+HalpDelayedHardwareInterrupt(13);
+HalpDelayedHardwareInterrupt(14);
+HalpDelayedHardwareInterrupt(15);
+
+/* Handlers for pending interrupts */
+PHAL_SW_INTERRUPT_HANDLER SWInterruptHandlerTable[20] =
+{
+    KiUnexpectedInterrupt,
+    HalpApcInterrupt,
+    HalpDispatchInterrupt2,
+    KiUnexpectedInterrupt,
+    HalpHardwareInterrupt0,
+    HalpHardwareInterrupt1,
+    HalpHardwareInterrupt2,
+    HalpHardwareInterrupt3,
+    HalpHardwareInterrupt4,
+    HalpHardwareInterrupt5,
+    HalpHardwareInterrupt6,
+    HalpHardwareInterrupt7,
+    HalpHardwareInterrupt8,
+    HalpHardwareInterrupt9,
+    HalpHardwareInterrupt10,
+    HalpHardwareInterrupt11,
+    HalpHardwareInterrupt12,
+    HalpHardwareInterrupt13,
+    HalpHardwareInterrupt14,
+    HalpHardwareInterrupt15
+};
+
+/* Handlers for pending software interrupts when we already have a trap frame*/
+PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY SWInterruptHandlerTable2[3] =
+{
+    (PHAL_SW_INTERRUPT_HANDLER_2ND_ENTRY)KiUnexpectedInterrupt,
+    HalpApcInterrupt2ndEntry,
+    HalpDispatchInterrupt2ndEntry
+};
+
+LONG HalpEisaELCR;
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+HalpInitializePICs(IN BOOLEAN EnableInterrupts)
+{
+    ULONG EFlags;
+    I8259_ICW1 Icw1;
+    I8259_ICW2 Icw2;
+    I8259_ICW3 Icw3;
+    I8259_ICW4 Icw4;
+    EISA_ELCR Elcr;
+    ULONG i, j;
+    
+    /* Save EFlags and disable interrupts */
+    EFlags = __readeflags();
+    _disable();
+    
+    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
+    Icw1.NeedIcw4 = TRUE;
+    Icw1.InterruptMode = EdgeTriggered;
+    Icw1.OperatingMode = Cascade;
+    Icw1.Interval = Interval8;
+    Icw1.Init = TRUE;
+    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
+    __outbyte(PIC1_CONTROL_PORT, Icw1.Bits);
+    
+    /* Set interrupt vector base */
+    Icw2.Bits = PRIMARY_VECTOR_BASE;
+    __outbyte(PIC1_DATA_PORT, Icw2.Bits);
+    
+    /* Connect slave to IRQ 2 */
+    Icw3.Bits = 0;
+    Icw3.SlaveIrq2 = TRUE;
+    __outbyte(PIC1_DATA_PORT, Icw3.Bits);
+    
+    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
+    Icw4.Reserved = 0;
+    Icw4.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    __outbyte(PIC1_DATA_PORT, Icw4.Bits);
+    
+    /* Mask all interrupts */
+    __outbyte(PIC1_DATA_PORT, 0xFF);
+    
+    /* Initialize ICW1 for master, interval 8, edge-triggered mode with ICW4 */
+    Icw1.NeedIcw4 = TRUE;
+    Icw1.InterruptMode = EdgeTriggered;
+    Icw1.OperatingMode = Cascade;
+    Icw1.Interval = Interval8;
+    Icw1.Init = TRUE;
+    Icw1.InterruptVectorAddress = 0; /* This is only used in MCS80/85 mode */
+    __outbyte(PIC2_CONTROL_PORT, Icw1.Bits);
+    
+    /* Set interrupt vector base */
+    Icw2.Bits = PRIMARY_VECTOR_BASE + 8;
+    __outbyte(PIC2_DATA_PORT, Icw2.Bits);
+    
+    /* Slave ID */
+    Icw3.Bits = 0;
+    Icw3.SlaveId = 2;
+    __outbyte(PIC2_DATA_PORT, Icw3.Bits);
+    
+    /* Enable 8086 mode, non-automatic EOI, non-buffered mode, non special fully nested mode */
+    Icw4.Reserved = 0;
+    Icw4.SystemMode = New8086Mode;
+    Icw4.EoiMode = NormalEoi;
+    Icw4.BufferedMode = NonBuffered;
+    Icw4.SpecialFullyNestedMode = FALSE;
+    __outbyte(PIC2_DATA_PORT, Icw4.Bits);
+    
+    /* Mask all interrupts */
+    __outbyte(PIC2_DATA_PORT, 0xFF);
+    
+    /* Read EISA Edge/Level Register for master and slave */
+    Elcr.Bits = (__inbyte(EISA_ELCR_SLAVE) << 8) | __inbyte(EISA_ELCR_MASTER);
+    
+    /* IRQs 0, 1, 2, 8, and 13 are system-reserved and must be edge */
+    if (!(Elcr.Master.Irq0Level) && !(Elcr.Master.Irq1Level) && !(Elcr.Master.Irq2Level) &&
+        !(Elcr.Slave.Irq8Level) && !(Elcr.Slave.Irq13Level))
+    {
+        /* ELCR is as it's supposed to be, save it */
+        HalpEisaELCR = Elcr.Bits;
+        
+        /* Scan for level interrupts */
+        for (i = 1, j = 0; j < 16; i <<= 1, j++)
+        {
+            if (HalpEisaELCR & i)
+            {
+                /* Switch handler to level */
+                SWInterruptHandlerTable[j + 4] = HalpHardwareInterruptLevel;
+
+                /* Switch dismiss to level */
+                HalpSpecialDismissTable[j] = HalpSpecialDismissLevelTable[j];
+            }
+        }
+    }
+    
+    /* Restore interrupt state */
+    if (EnableInterrupts) EFlags |= EFLAGS_INTERRUPT_MASK;
+    __writeeflags(EFlags);
+}
+
+/* IRQL MANAGEMENT ************************************************************/
+
+/*
+ * @implemented
+ */
+KIRQL
+NTAPI
+KeGetCurrentIrql(VOID)
+{
+    /* Return the IRQL */
+    return KeGetPcr()->Irql;
+}
+
+/*
+ * @implemented
+ */
+KIRQL
+NTAPI
+KeRaiseIrqlToDpcLevel(VOID)
+{
+    PKPCR Pcr = KeGetPcr();
+    KIRQL CurrentIrql;
+    
+    /* Save and update IRQL */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = DISPATCH_LEVEL;
+    
+#ifdef IRQL_DEBUG
+    /* Validate correct raise */
+    if (CurrentIrql > DISPATCH_LEVEL) KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
+#endif
+
+    /* Return the previous value */
+    return CurrentIrql;
+}
+
+/*
+ * @implemented
+ */
+KIRQL
+NTAPI
+KeRaiseIrqlToSynchLevel(VOID)
+{
+    PKPCR Pcr = KeGetPcr();
+    KIRQL CurrentIrql;
+    
+    /* Save and update IRQL */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = SYNCH_LEVEL;
+    
+#ifdef IRQL_DEBUG
+    /* Validate correct raise */
+    if (CurrentIrql > SYNCH_LEVEL)
+    {
+        /* Crash system */
+        KeBugCheckEx(IRQL_NOT_GREATER_OR_EQUAL,
+                     CurrentIrql,
+                     SYNCH_LEVEL,
+                     0,
+                     1);
+    }
+#endif
+
+    /* Return the previous value */
+    return CurrentIrql;
+}
+
+/*
+ * @implemented
+ */
+KIRQL
+FASTCALL
+KfRaiseIrql(IN KIRQL NewIrql)
+{
+    PKPCR Pcr = KeGetPcr();
+    KIRQL CurrentIrql;
+
+    /* Read current IRQL */
+    CurrentIrql = Pcr->Irql;
+    
+#ifdef IRQL_DEBUG
+    /* Validate correct raise */
+    if (CurrentIrql > NewIrql)
+    {
+        /* Crash system */
+        Pcr->Irql = PASSIVE_LEVEL;
+        KeBugCheck(IRQL_NOT_GREATER_OR_EQUAL);
+    }
+#endif
+
+    /* Set new IRQL */
+    Pcr->Irql = NewIrql;
+    
+    /* Return old IRQL */
+    return CurrentIrql;
+}
+
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+KfLowerIrql(IN KIRQL OldIrql)
+{
+    ULONG EFlags;
+    ULONG PendingIrql, PendingIrqlMask;
+    PKPCR Pcr = KeGetPcr();
+    PIC_MASK Mask;
+    
+#ifdef IRQL_DEBUG
+    /* Validate correct lower */
+    if (OldIrql > Pcr->Irql)
+    {
+        /* Crash system */
+        Pcr->Irql = HIGH_LEVEL;
+        KeBugCheck(IRQL_NOT_LESS_OR_EQUAL);
+    }
+#endif
+    
+    /* Save EFlags and disable interrupts */
+    EFlags = __readeflags();
+    _disable();
+
+    /* Set old IRQL */
+    Pcr->Irql = OldIrql;
+    
+    /* Check for pending software interrupts and compare with current IRQL */
+    PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
+    if (PendingIrqlMask)
+    {
+        /* Check if pending IRQL affects hardware state */
+        BitScanReverse(&PendingIrql, PendingIrqlMask);
+        if (PendingIrql > DISPATCH_LEVEL)
+        {
+            /* Set new PIC mask */
+            Mask.Both = Pcr->IDR;
+            __outbyte(PIC1_DATA_PORT, Mask.Master);
+            __outbyte(PIC2_DATA_PORT, Mask.Slave);
+            
+            /* Clear IRR bit */
+            Pcr->IRR ^= (1 << PendingIrql);
+        }
+    
+        /* Now handle pending interrupt */
+        SWInterruptHandlerTable[PendingIrql]();
+    }
+
+    /* Restore interrupt state */
+    __writeeflags(EFlags);
+}
+
+/* SOFTWARE INTERRUPTS ********************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+HalRequestSoftwareInterrupt(IN KIRQL Irql)
+{
+    ULONG EFlags;
+    PKPCR Pcr = KeGetPcr();
+    KIRQL PendingIrql;
+    
+    /* Save EFlags and disable interrupts */
+    EFlags = __readeflags();
+    _disable();
+    
+    /* Mask out the requested bit */
+    Pcr->IRR |= (1 << Irql);
+
+    /* Check for pending software interrupts and compare with current IRQL */
+    PendingIrql = SWInterruptLookUpTable[Pcr->IRR & 3];
+    if (PendingIrql > Pcr->Irql) SWInterruptHandlerTable[PendingIrql]();
+    
+    /* Restore interrupt state */
+    __writeeflags(EFlags);
+}
+
+/*
+ * @implemented
+ */
+VOID
+FASTCALL
+HalClearSoftwareInterrupt(IN KIRQL Irql)
+{
+    /* Mask out the requested bit */
+    KeGetPcr()->IRR &= ~(1 << Irql);
+}
+
+VOID
+NTAPI
+HalpEndSoftwareInterrupt(IN KIRQL OldIrql,
+                         IN PKTRAP_FRAME TrapFrame)
+{
+    ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
+    PKPCR Pcr = KeGetPcr();
+    PIC_MASK Mask;
+
+    /* Set old IRQL */
+    Pcr->Irql = OldIrql;
+
+    /* Loop checking for pending interrupts */
+    while (TRUE)
+    {
+        /* Check for pending software interrupts and compare with current IRQL */
+        PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
+        if (!PendingIrqlMask) return;
+            
+        /* Check for in-service delayed interrupt */
+        if (Pcr->IrrActive & 0xFFFFFFF0) return;
+        
+        /* Check if pending IRQL affects hardware state */
+        BitScanReverse(&PendingIrql, PendingIrqlMask);
+        if (PendingIrql > DISPATCH_LEVEL)
+        {
+            /* Set new PIC mask */
+            Mask.Both = Pcr->IDR;
+            __outbyte(PIC1_DATA_PORT, Mask.Master);
+            __outbyte(PIC2_DATA_PORT, Mask.Slave);
+
+            /* Set active bit otherwise, and clear it from IRR */
+            PendingIrqMask = (1 << PendingIrql);
+            Pcr->IrrActive |= PendingIrqMask;
+            Pcr->IRR ^= PendingIrqMask;
+        
+            /* Handle delayed hardware interrupt */
+            SWInterruptHandlerTable[PendingIrql]();
+        
+            /* Handling complete */
+            Pcr->IrrActive ^= PendingIrqMask;
+        }
+        else
+        {
+            /* No need to loop checking for hardware interrupts */
+            SWInterruptHandlerTable2[PendingIrql](TrapFrame);
+        }
+    }
+}
+
+/* EDGE INTERRUPT DISMISSAL FUNCTIONS *****************************************/
+
+BOOLEAN
+FORCEINLINE
+_HalpDismissIrqGeneric(IN KIRQL Irql,
+                       IN ULONG Irq,
+                       OUT PKIRQL OldIrql)
+{
+    PIC_MASK Mask;
+    KIRQL CurrentIrql;
+    I8259_OCW2 Ocw2;
+    PKPCR Pcr = KeGetPcr();
+
+    /* First save current IRQL and compare it to the requested one */
+    CurrentIrql = Pcr->Irql;
+    
+    /* Check if this interrupt is really allowed to happen */
+    if (Irql > CurrentIrql)
+    {
+        /* Set the new IRQL and return the current one */
+        Pcr->Irql = Irql;
+        *OldIrql = CurrentIrql;
+    
+        /* Prepare OCW2 for EOI */
+        Ocw2.Bits = 0;
+        Ocw2.EoiMode = SpecificEoi;
+
+        /* Check which PIC needs the EOI */
+        if (Irq > 8)
+        {
+            /* Send the EOI for the IRQ */
+            __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | (Irq - 8));
+    
+            /* Send the EOI for IRQ2 on the master because this was cascaded */
+            __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
+        }
+        else
+        {
+            /* Send the EOI for the IRQ */
+            __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | Irq);
+        }
+    
+        /* Enable interrupts and return success */
+        _enable();
+        return TRUE;
+    }
+    
+    /* Update the IRR so that we deliver this interrupt when the IRQL is proper */
+    Pcr->IRR |= (1 << (Irq + 4));
+    
+    /* Set new PIC mask to real IRQL level, since the optimization is lost now */
+    Mask.Both = KiI8259MaskTable[CurrentIrql] | Pcr->IDR;
+    __outbyte(PIC1_DATA_PORT, Mask.Master);
+    __outbyte(PIC2_DATA_PORT, Mask.Slave);
+    
+    /* Now lie and say this was spurious */
+    return FALSE;
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrqGeneric(IN KIRQL Irql,
+                      IN ULONG Irq,
+                      OUT PKIRQL OldIrql)
+{
+    /* Run the inline code */
+    return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq15(IN KIRQL Irql,
+                 IN ULONG Irq,
+                 OUT PKIRQL OldIrql)
+{
+    I8259_OCW3 Ocw3;
+    I8259_OCW2 Ocw2;
+    I8259_ISR Isr;
+        
+    /* Request the ISR */
+    Ocw3.Bits = 0;
+    Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
+    Ocw3.ReadRequest = ReadIsr;
+    __outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
+    
+    /* Read the ISR */
+    Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
+    
+    /* Is IRQ15 really active (this is IR7) */
+    if (Isr.Irq7 == FALSE)
+    {
+        /* It isn't, so we have to EOI IRQ2 because this was cascaded */
+        Ocw2.Bits = 0;
+        Ocw2.EoiMode = SpecificEoi;
+        __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
+        
+        /* And now fail since this was spurious */
+        return FALSE;
+    }
+
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
+}
+
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq13(IN KIRQL Irql,
+                 IN ULONG Irq,
+                 OUT PKIRQL OldIrql)
+{
+    /* Clear the FPU busy latch */
+    __outbyte(0xF0, 0);
+    
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq07(IN KIRQL Irql,
+                 IN ULONG Irq,
+                 OUT PKIRQL OldIrql)
+{
+    I8259_OCW3 Ocw3;
+    I8259_ISR Isr;
+        
+    /* Request the ISR */
+    Ocw3.Bits = 0;
+    Ocw3.Sbo = 1;
+    Ocw3.ReadRequest = ReadIsr;
+    __outbyte(PIC1_CONTROL_PORT, Ocw3.Bits);
+    
+    /* Read the ISR */
+    Isr.Bits = __inbyte(PIC1_CONTROL_PORT);
+    
+    /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
+    if (Isr.Irq7 == FALSE) return FALSE;
+    
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqGeneric(Irql, Irq, OldIrql);
+}
+
+/* LEVEL INTERRUPT DISMISSAL FUNCTIONS ****************************************/
+
+BOOLEAN
+FORCEINLINE
+_HalpDismissIrqLevel(IN KIRQL Irql,
+                     IN ULONG Irq,
+                     OUT PKIRQL OldIrql)
+{
+    PIC_MASK Mask;
+    KIRQL CurrentIrql;
+    I8259_OCW2 Ocw2;
+    PKPCR Pcr = KeGetPcr();
+
+    /* Update the PIC */
+    Mask.Both = KiI8259MaskTable[Irql] | Pcr->IDR;
+    __outbyte(PIC1_DATA_PORT, Mask.Master);
+    __outbyte(PIC2_DATA_PORT, Mask.Slave);
+    
+    /* Update the IRR so that we clear this interrupt when the IRQL is proper */
+    Pcr->IRR |= (1 << (Irq + 4));
+    
+    /* Save current IRQL */
+    CurrentIrql = Pcr->Irql;
+       
+    /* Prepare OCW2 for EOI */
+    Ocw2.Bits = 0;
+    Ocw2.EoiMode = SpecificEoi;
+
+    /* Check which PIC needs the EOI */
+    if (Irq > 8)
+    {
+        /* Send the EOI for the IRQ */
+        __outbyte(PIC2_CONTROL_PORT, Ocw2.Bits | (Irq - 8));
+
+        /* Send the EOI for IRQ2 on the master because this was cascaded */
+        __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
+    }
+    else
+    {
+        /* Send the EOI for the IRQ */
+        __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | Irq);
+    }
+
+    /* Check if this interrupt should be allowed to happen */
+    if (Irql > CurrentIrql)
+    {
+        /* Set the new IRQL and return the current one */
+        Pcr->Irql = Irql;
+        *OldIrql = CurrentIrql;
+    
+        /* Enable interrupts and return success */
+        _enable();
+        return TRUE;
+    }
+    
+    /* Now lie and say this was spurious */
+    return FALSE;
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrqLevel(IN KIRQL Irql,
+                    IN ULONG Irq,
+                    OUT PKIRQL OldIrql)
+{
+    /* Run the inline code */
+    return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq15Level(IN KIRQL Irql,
+                      IN ULONG Irq,
+                      OUT PKIRQL OldIrql)
+{
+    I8259_OCW3 Ocw3;
+    I8259_OCW2 Ocw2;
+    I8259_ISR Isr;
+        
+    /* Request the ISR */
+    Ocw3.Bits = 0;
+    Ocw3.Sbo = 1; /* This encodes an OCW3 vs. an OCW2 */
+    Ocw3.ReadRequest = ReadIsr;
+    __outbyte(PIC2_CONTROL_PORT, Ocw3.Bits);
+    
+    /* Read the ISR */
+    Isr.Bits = __inbyte(PIC2_CONTROL_PORT);
+    
+    /* Is IRQ15 really active (this is IR7) */
+    if (Isr.Irq7 == FALSE)
+    {
+        /* It isn't, so we have to EOI IRQ2 because this was cascaded */
+        Ocw2.Bits = 0;
+        Ocw2.EoiMode = SpecificEoi;
+        __outbyte(PIC1_CONTROL_PORT, Ocw2.Bits | 2);
+        
+        /* And now fail since this was spurious */
+        return FALSE;
+    }
+
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq13Level(IN KIRQL Irql,
+                      IN ULONG Irq,
+                      OUT PKIRQL OldIrql)
+{
+    /* Clear the FPU busy latch */
+    __outbyte(0xF0, 0);
+    
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
+}
+
+BOOLEAN
+__attribute__((regparm(3)))
+HalpDismissIrq07Level(IN KIRQL Irql,
+                      IN ULONG Irq,
+                      OUT PKIRQL OldIrql)
+{
+    I8259_OCW3 Ocw3;
+    I8259_ISR Isr;
+        
+    /* Request the ISR */
+    Ocw3.Bits = 0;
+    Ocw3.Sbo = 1;
+    Ocw3.ReadRequest = ReadIsr;
+    __outbyte(PIC1_CONTROL_PORT, Ocw3.Bits);
+    
+    /* Read the ISR */
+    Isr.Bits = __inbyte(PIC1_CONTROL_PORT);
+    
+    /* Is IRQ 7 really active? If it isn't, this is spurious so fail */
+    if (Isr.Irq7 == FALSE) return FALSE;
+    
+    /* Do normal interrupt dismiss */
+    return _HalpDismissIrqLevel(Irql, Irq, OldIrql);
+}
+
+VOID
+HalpHardwareInterruptLevel(VOID)
+{
+    PKPCR Pcr = KeGetPcr();
+    ULONG PendingIrqlMask, PendingIrql;
+    
+    /* Check for pending software interrupts and compare with current IRQL */
+    PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
+    if (PendingIrqlMask)
+    {
+        /* Check for in-service delayed interrupt */
+        if (Pcr->IrrActive & 0xFFFFFFF0) return;
+          
+        /* Check if pending IRQL affects hardware state */
+        BitScanReverse(&PendingIrql, PendingIrqlMask);
+        
+        /* Clear IRR bit */
+        Pcr->IRR ^= (1 << PendingIrql);
+
+        /* Now handle pending interrupt */
+        SWInterruptHandlerTable[PendingIrql]();
+    }
+}
+
+/* SYSTEM INTERRUPTS **********************************************************/
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalEnableSystemInterrupt(IN UCHAR Vector,
+                         IN KIRQL Irql,
+                         IN KINTERRUPT_MODE InterruptMode)
+{
+    ULONG Irq;
+    PKPCR Pcr = KeGetPcr();
+    PIC_MASK PicMask;
+    
+    /* Validate the IRQ */
+    Irq = Vector - PRIMARY_VECTOR_BASE;
+    if (Irq >= CLOCK2_LEVEL) return FALSE;
+  
+    /* Check for level interrupt */
+    if (InterruptMode == LevelSensitive)
+    {
+        /* Switch handler to level */
+        SWInterruptHandlerTable[Irq + 4] = HalpHardwareInterruptLevel;
+            
+        /* Switch dismiss to level */
+        HalpSpecialDismissTable[Irq] = HalpSpecialDismissLevelTable[Irq];
+    }
+    
+    /* Disable interrupts */
+    _disable();
+    
+    /* Update software IDR */
+    Pcr->IDR &= ~(1 << Irq);
+
+    /* Set new PIC mask */
+    PicMask.Both = KiI8259MaskTable[Pcr->Irql] | Pcr->IDR;
+    __outbyte(PIC1_DATA_PORT, PicMask.Master);
+    __outbyte(PIC2_DATA_PORT, PicMask.Slave);
+    
+    /* Enable interrupts and exit */
+    _enable();
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalDisableSystemInterrupt(IN UCHAR Vector,
+                          IN KIRQL Irql)
+{
+    ULONG IrqMask;
+    PIC_MASK PicMask;
+
+    /* Compute new combined IRQ mask */
+    IrqMask = 1 << (Vector - PRIMARY_VECTOR_BASE);
+    
+    /* Disable interrupts */
+    _disable();
+    
+    /* Update software IDR */
+    KeGetPcr()->IDR |= IrqMask;
+    
+    /* Read current interrupt mask */
+    PicMask.Master = __inbyte(PIC1_DATA_PORT);
+    PicMask.Slave = __inbyte(PIC2_DATA_PORT);
+    
+    /* Add the new disabled interrupt */
+    PicMask.Both |= IrqMask;
+    
+    /* Write new interrupt mask */
+    __outbyte(PIC1_DATA_PORT, PicMask.Master);
+    __outbyte(PIC2_DATA_PORT, PicMask.Slave);
+    
+    /* Bring interrupts back */
+    _enable();
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalBeginSystemInterrupt(IN KIRQL Irql,
+                        IN UCHAR Vector,
+                        OUT PKIRQL OldIrql)
+{
+    ULONG Irq;
+    
+    /* Get the IRQ and call the proper routine to handle it */
+    Irq = Vector - PRIMARY_VECTOR_BASE;
+    return HalpSpecialDismissTable[Irq](Irql, Irq, OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalEndSystemInterrupt(IN KIRQL OldIrql,
+                      IN PKTRAP_FRAME TrapFrame)
+{
+    ULONG PendingIrql, PendingIrqlMask, PendingIrqMask;
+    PKPCR Pcr = KeGetPcr();
+    PIC_MASK Mask;
+
+    /* Set old IRQL */
+    Pcr->Irql = OldIrql;
+
+    /* Check for pending software interrupts and compare with current IRQL */
+    PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
+    if (PendingIrqlMask)
+    {
+        /* Check for in-service delayed interrupt */
+        if (Pcr->IrrActive & 0xFFFFFFF0) return;
+        
+        /* Loop checking for pending interrupts */
+        while (TRUE)
+        {
+            /* Check if pending IRQL affects hardware state */
+            BitScanReverse(&PendingIrql, PendingIrqlMask);
+            if (PendingIrql > DISPATCH_LEVEL)
+            {
+                /* Set new PIC mask */
+                Mask.Both = Pcr->IDR;
+                __outbyte(PIC1_DATA_PORT, Mask.Master);
+                __outbyte(PIC2_DATA_PORT, Mask.Slave);
+            
+                /* Now check if this specific interrupt is already in-service */
+                PendingIrqMask = (1 << PendingIrql);
+                if (Pcr->IrrActive & PendingIrqMask) return;
+                    
+                /* Set active bit otherwise, and clear it from IRR */
+                Pcr->IrrActive |= PendingIrqMask;
+                Pcr->IRR ^= PendingIrqMask;
+            
+                /* Handle delayed hardware interrupt */
+                SWInterruptHandlerTable[PendingIrql]();
+            
+                /* Handling complete */
+                Pcr->IrrActive ^= PendingIrqMask;
+            
+                /* Check if there's still interrupts pending */
+                PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[Pcr->Irql];
+                if (!PendingIrqlMask) break;
+            }
+            else
+            {
+                /* Now handle pending software interrupt */
+                SWInterruptHandlerTable2[PendingIrql](TrapFrame);
+            }
+        }
+    }
+}
+
+/* SOFTWARE INTERRUPT TRAPS ***************************************************/
+
+VOID
+FORCEINLINE
+DECLSPEC_NORETURN
+_HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+    KIRQL CurrentIrql;
+    PKPCR Pcr = KeGetPcr();
+    
+    /* Save the current IRQL and update it */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = APC_LEVEL;
+
+    /* Remove DPC from IRR */
+    Pcr->IRR &= ~(1 << APC_LEVEL);
+
+    /* Enable interrupts and call the kernel's APC interrupt handler */
+    _enable();
+    KiDeliverApc(((KiUserTrap(TrapFrame)) || (TrapFrame->EFlags & EFLAGS_V86_MASK)) ?
+                UserMode : KernelMode,
+                NULL,
+                TrapFrame);
+
+    /* Disable interrupts and end the interrupt */
+    _disable();
+    HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
+
+    /* Exit the interrupt */
+    KiEoiHelper(TrapFrame); 
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpApcInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Do the work */
+    _HalpApcInterruptHandler(TrapFrame);
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpApcInterruptHandler(IN PKTRAP_FRAME TrapFrame)
+{
+    /* Set up a fake INT Stack */
+    TrapFrame->EFlags = __readeflags();
+    TrapFrame->SegCs = KGDT_R0_CODE;
+    TrapFrame->Eip = TrapFrame->Eax;
+    
+    /* Build the trap frame */
+    KiEnterInterruptTrap(TrapFrame);
+    
+    /* Do the work */
+    _HalpApcInterruptHandler(TrapFrame);
+}
+
+KIRQL
+FORCEINLINE
+_HalpDispatchInterruptHandler(VOID)
+{
+    KIRQL CurrentIrql;
+    PKPCR Pcr = KeGetPcr();
+    
+    /* Save the current IRQL and update it */
+    CurrentIrql = Pcr->Irql;
+    Pcr->Irql = DISPATCH_LEVEL;
+    
+    /* Remove DPC from IRR */
+    Pcr->IRR &= ~(1 << DISPATCH_LEVEL);
+    
+    /* Enable interrupts and call the kernel's DPC interrupt handler */
+    _enable();
+    KiDispatchInterrupt();
+    _disable();
+    
+    /* Return IRQL */
+    return CurrentIrql;
+}
+
+VOID
+FASTCALL
+DECLSPEC_NORETURN
+HalpDispatchInterrupt2ndEntry(IN PKTRAP_FRAME TrapFrame)
+{
+    KIRQL CurrentIrql;
+    
+    /* Do the work */
+    CurrentIrql = _HalpDispatchInterruptHandler();
+    
+    /* End the interrupt */
+    HalpEndSoftwareInterrupt(CurrentIrql, TrapFrame);
+    
+    /* Exit the interrupt */
+    KiEoiHelper(TrapFrame);
+}
+
+VOID
+HalpDispatchInterrupt2(VOID)
+{
+    ULONG PendingIrqlMask, PendingIrql;
+    KIRQL OldIrql;
+    PIC_MASK Mask;
+    PKPCR Pcr = KeGetPcr();
+
+    /* Do the work */
+    OldIrql = _HalpDispatchInterruptHandler();
+    
+    /* Restore IRQL */
+    Pcr->Irql = OldIrql;
+
+    /* Check for pending software interrupts and compare with current IRQL */
+    PendingIrqlMask = Pcr->IRR & FindHigherIrqlMask[OldIrql];
+    if (PendingIrqlMask)
+    {
+        /* Check if pending IRQL affects hardware state */
+        BitScanReverse(&PendingIrql, PendingIrqlMask);
+        if (PendingIrql > DISPATCH_LEVEL)
+        {
+            /* Set new PIC mask */
+            Mask.Both = Pcr->IDR;
+            __outbyte(PIC1_DATA_PORT, Mask.Master);
+            __outbyte(PIC2_DATA_PORT, Mask.Slave);
+            
+            /* Clear IRR bit */
+            Pcr->IRR ^= (1 << PendingIrql);
+        }
+    
+        /* Now handle pending interrupt */
+        SWInterruptHandlerTable[PendingIrql]();
+    }
+}
+
+#else
+
+KIRQL
+NTAPI
+KeGetCurrentIrql(VOID)
+{
+    return PASSIVE_LEVEL;
+}
+
+VOID
+FASTCALL
+KfLowerIrql(
+    IN KIRQL OldIrql)
+{
+}
+
+KIRQL
+FASTCALL
+KfRaiseIrql(
+    IN KIRQL NewIrql)
+{
+    return NewIrql;
+}
+
+#endif
diff --git a/hal/halx86/up/processor.c b/hal/halx86/up/processor.c
new file mode 100644 (file)
index 0000000..662514b
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * PROJECT:         ReactOS HAL
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            hal/halx86/up/processor.c
+ * PURPOSE:         HAL Processor Routines
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <hal.h>
+#define NDEBUG
+#include <debug.h>
+
+LONG HalpActiveProcessors;
+KAFFINITY HalpDefaultInterruptAffinity;
+
+/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+HaliHaltSystem(VOID)
+{
+    /* Disable interrupts and halt the CPU */
+    _disable();
+    __halt();
+}
+
+/* FUNCTIONS *****************************************************************/
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalInitializeProcessor(IN ULONG ProcessorNumber,
+                       IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+    /* Set default IDR and stall count */
+    KeGetPcr()->IDR = 0xFFFFFFFB;
+    KeGetPcr()->StallScaleFactor = INITIAL_STALL_COUNT;
+
+    /* Update the interrupt affinity and processor mask */
+    InterlockedBitTestAndSet(&HalpActiveProcessors, ProcessorNumber);
+    InterlockedBitTestAndSet((PLONG)&HalpDefaultInterruptAffinity,
+                             ProcessorNumber);
+
+    /* Register routines for KDCOM */
+    HalpRegisterKdSupportFunctions();
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalAllProcessorsStarted(VOID)
+{
+    /* Do nothing */
+    return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+NTAPI
+HalStartNextProcessor(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+                      IN PKPROCESSOR_STATE ProcessorState)
+{
+    /* Ready to start */
+    return FALSE;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalProcessorIdle(VOID)
+{
+    /* Enable interrupts and halt the processor */
+    _enable();
+    __halt();
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+HalRequestIpi(KAFFINITY TargetProcessors)
+{
+    /* Not implemented on UP */
+    __debugbreak();
+}
+
+/* EOF */
diff --git a/include/dxsdk/bdatif.idl b/include/dxsdk/bdatif.idl
new file mode 100644 (file)
index 0000000..6c8887e
--- /dev/null
@@ -0,0 +1,270 @@
+#ifndef DO_NO_IMPORTS
+import "unknwn.idl";
+import "strmif.idl";
+import "tuner.idl";
+import "bdaiface.idl";
+#endif
+
+interface IMPEG2_TIF_CONTROL;
+interface IATSCChannelInfo;
+interface IMPEG2PIDMap;
+
+[
+    object,
+    uuid(DFEF4A68-EE61-415f-9CCB-CD95F2F98A3A),
+    pointer_default(unique)
+]
+interface IBDA_TIF_REGISTRATION : IUnknown
+{
+    HRESULT
+    RegisterTIFEx(
+        [in]  IPin * pTIFInputPin,
+        [in, out] ULONG * ppvRegistrationContext,
+        [in, out] IUnknown ** ppMpeg2DataControl);
+
+    HRESULT
+    UnregisterTIF(
+        [in] ULONG pvRegistrationContext);
+}
+
+[
+    object,
+    uuid(F9BAC2F9-4149-4916-B2EF-FAA202326862),
+    pointer_default(unique)
+]
+interface IMPEG2_TIF_CONTROL : IUnknown
+{
+    HRESULT
+    RegisterTIF(
+        [in]  IUnknown * pUnkTIF,
+        [in, out] ULONG * ppvRegistrationContext);
+
+    HRESULT
+    UnregisterTIF(
+        [in] ULONG pvRegistrationContext);
+
+    HRESULT
+    AddPIDs(
+        [in] ULONG ulcPIDs,
+        [in] ULONG * pulPIDs);
+
+    HRESULT
+    DeletePIDs(
+        [in] ULONG ulcPIDs,
+        [in] ULONG * pulPIDs);
+
+    HRESULT
+    GetPIDCount(
+        [out] ULONG * pulcPIDs);
+
+    HRESULT
+    GetPIDs(
+        [out] ULONG * pulcPIDs,
+        [out] ULONG * pulPIDs);
+}
+
+[
+    object,
+    uuid(A3B152DF-7A90-4218-AC54-9830BEE8C0B6),
+    pointer_default(unique)
+]
+interface ITuneRequestInfo : IUnknown
+{
+    HRESULT
+    GetLocatorData(
+        [in]  ITuneRequest *Request);
+
+    HRESULT
+    GetComponentData(
+        [in]  ITuneRequest *CurrentRequest);
+
+    HRESULT
+    CreateComponentList(
+        [in]  ITuneRequest *CurrentRequest);
+
+    HRESULT
+    GetNextProgram (
+        [in]  ITuneRequest *CurrentRequest,
+        [out, retval] ITuneRequest **TuneRequest);
+
+    HRESULT
+    GetPreviousProgram(
+        [in]  ITuneRequest *CurrentRequest,
+        [out, retval] ITuneRequest **TuneRequest);
+
+    HRESULT
+    GetNextLocator(
+        [in]  ITuneRequest *CurrentRequest,
+        [out, retval] ITuneRequest **TuneRequest);
+
+    HRESULT
+    GetPreviousLocator(
+        [in]  ITuneRequest *CurrentRequest,
+        [out, retval] ITuneRequest **TuneRequest);
+}
+
+[
+    object,
+    uuid(EFDA0C80-F395-42c3-9B3C-56B37DEC7BB7),
+    pointer_default(unique)
+]
+interface IGuideDataEvent : IUnknown
+{
+    HRESULT
+    GuideDataAcquired();
+
+    HRESULT ProgramChanged(
+        [in] VARIANT varProgramDescriptionID);
+
+    HRESULT ServiceChanged(
+        [in] VARIANT varServiceDescriptionID);
+
+    HRESULT ScheduleEntryChanged(
+        [in] VARIANT varScheduleEntryDescriptionID);
+
+    HRESULT ProgramDeleted(
+        [in] VARIANT varProgramDescriptionID);
+
+    HRESULT ServiceDeleted(
+        [in] VARIANT varServiceDescriptionID);
+
+    HRESULT ScheduleDeleted(
+        [in] VARIANT varScheduleEntryDescriptionID);
+}
+
+[
+    object,
+    uuid(88EC5E58-BB73-41d6-99CE-66C524B8B591),
+    pointer_default(unique)
+]
+interface IGuideDataProperty : IUnknown
+{
+    HRESULT 
+    get_Name(
+        [out] BSTR *pbstrName);
+
+    HRESULT
+    get_Language(
+        [out] long *idLang);
+
+    HRESULT
+    get_Value(
+        [out] VARIANT *pvar);
+}
+
+[
+    object,
+    uuid(AE44423B-4571-475c-AD2C-F40A771D80EF),
+    pointer_default(unique)
+]
+interface IEnumGuideDataProperties : IUnknown
+{
+    HRESULT
+    Next(
+        [in] unsigned long celt, 
+        [out] IGuideDataProperty **ppprop,
+        [out] unsigned long *pcelt);
+
+    HRESULT
+    Skip(
+        [in] unsigned long celt);
+
+    HRESULT
+    Reset();
+
+    HRESULT
+    Clone(
+        [out] IEnumGuideDataProperties **ppenum);
+}
+
+[
+    object,
+    uuid(1993299C-CED6-4788-87A3-420067DCE0C7),
+    pointer_default(unique)
+]
+interface IEnumTuneRequests : IUnknown
+{
+    HRESULT
+    Next(
+        [in] unsigned long celt,
+        [out] ITuneRequest **ppprop,
+        [out] unsigned long *pcelt);
+
+    HRESULT
+    Skip(
+        [in] unsigned long celt);
+
+    HRESULT
+    Reset();
+
+    HRESULT
+    Clone(
+        [out] IEnumTuneRequests **ppenum);
+}
+
+[
+    object,
+    uuid(61571138-5B01-43cd-AEAF-60B784A0BF93),
+    pointer_default(unique)
+]
+interface IGuideData : IUnknown
+{
+    HRESULT
+    GetServices(
+        [out, retval] IEnumTuneRequests ** ppEnumTuneRequests);
+
+    HRESULT
+    GetServiceProperties(
+        [in] ITuneRequest * pTuneRequest,
+        [out, retval] IEnumGuideDataProperties ** ppEnumProperties);
+
+    HRESULT
+    GetGuideProgramIDs(
+        [out, retval] IEnumVARIANT ** pEnumPrograms);
+
+    HRESULT
+    GetProgramProperties(
+        [in] VARIANT varProgramDescriptionID,
+        [out, retval] IEnumGuideDataProperties ** ppEnumProperties);
+
+    HRESULT
+    GetScheduleEntryIDs(
+        [out, retval] IEnumVARIANT ** pEnumScheduleEntries);
+
+    HRESULT
+    GetScheduleEntryProperties(
+        [in] VARIANT varScheduleEntryDescriptionID,
+        [out, retval] IEnumGuideDataProperties ** ppEnumProperties);
+}
+
+[
+    object,
+    uuid(4764ff7c-fa95-4525-af4d-d32236db9e38),
+    pointer_default(unique)
+]
+interface IGuideDataLoader : IUnknown
+{
+    HRESULT Init([in] IGuideData *pGuideStore);
+    HRESULT Terminate();
+};
+
+[
+    uuid(8224A083-7F8C-432D-B83E-3C5E9BDE3528),
+    version(1.0),
+]
+library PSISLOADLib
+{
+    importlib("stdole32.tlb");
+    importlib("stdole2.tlb");
+
+    [
+        uuid(14EB8748-1753-4393-95AE-4F7E7A87AAD6),
+        helpstring("TIFLoad Class")
+    ]
+    coclass TIFLoad
+    {
+        interface IGuideDataLoader;
+        interface IGuideDataEvent;
+    };
+};
+
diff --git a/include/ndk/peb_teb.h b/include/ndk/peb_teb.h
new file mode 100644 (file)
index 0000000..38791b3
--- /dev/null
@@ -0,0 +1,389 @@
+
+#define PASTE2(x,y)       x##y
+#define PASTE(x,y)         PASTE2(x,y)
+
+#ifdef EXPLICIT_32BIT
+  #define STRUCT(x) PASTE(x,32)
+  #define PTR(x) ULONG
+#elif defined(EXPLICIT_64BIT)
+  #define STRUCT(x) PASTE(x,64)
+  #define PTR(x) ULONG64
+#else
+  #define STRUCT(x) x
+  #define PTR(x) x
+#endif
+
+#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
+  #define GDI_HANDLE_BUFFER_SIZE 60
+#else
+  #define GDI_HANDLE_BUFFER_SIZE 34
+#endif
+
+typedef struct STRUCT(_PEB)
+{
+    BOOLEAN InheritedAddressSpace;
+    BOOLEAN ReadImageFileExecOptions;
+    BOOLEAN BeingDebugged;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+    union
+    {
+        BOOLEAN BitField;
+        struct
+        {
+            BOOLEAN ImageUsesLargePages:1;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+            BOOLEAN IsProtectedProcess:1;
+            BOOLEAN IsLegacyProcess:1;
+            BOOLEAN IsImageDynamicallyRelocated:1;
+            BOOLEAN SkipPatchingUser32Forwarders:1;
+            BOOLEAN SpareBits:3;
+#else
+            BOOLEAN SpareBits:7;
+#endif
+        };
+    };
+#else
+    BOOLEAN SpareBool;
+#endif
+    PTR(HANDLE) Mutant;
+    PTR(PVOID) ImageBaseAddress;
+    PTR(PPEB_LDR_DATA) Ldr;
+    PTR(struct _RTL_USER_PROCESS_PARAMETERS*) ProcessParameters;
+    PTR(PVOID) SubSystemData;
+    PTR(PVOID) ProcessHeap;
+    PTR(struct _RTL_CRITICAL_SECTION*) FastPebLock;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(PVOID) AltThunkSListPtr;
+    PTR(PVOID) IFEOKey;
+    union
+    {
+        ULONG CrossProcessFlags;
+        struct
+        {
+            ULONG ProcessInJob:1;
+            ULONG ProcessInitializing:1;
+            ULONG ProcessUsingVEH:1;
+            ULONG ProcessUsingVCH:1;
+            ULONG ReservedBits0:28;
+        };
+    };
+    union
+    {
+        PTR(PVOID) KernelCallbackTable;
+        PTR(PVOID) UserSharedInfoPtr;
+    };
+#elif (NTDDI_VERSION >= NTDDI_WS03)
+    PTR(PVOID) AltThunkSListPtr;
+    PTR(PVOID) SparePtr2;
+    ULONG EnvironmentUpdateCount;
+    PTR(PVOID) KernelCallbackTable;
+#else
+    PTR(PPEBLOCKROUTINE) FastPebLockRoutine;
+    PTR(PPEBLOCKROUTINE) FastPebUnlockRoutine;
+    ULONG EnvironmentUpdateCount;
+    PTR(PVOID) KernelCallbackTable;
+#endif
+    ULONG SystemReserved[1];
+    ULONG SpareUlong; // AtlThunkSListPtr32
+    PTR(PPEB_FREE_BLOCK) FreeList;
+    ULONG TlsExpansionCounter;
+    PTR(PVOID) TlsBitmap;
+    ULONG TlsBitmapBits[2];
+    PTR(PVOID) ReadOnlySharedMemoryBase;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(PVOID) HotpatchInformation;
+#else
+    PTR(PVOID) ReadOnlySharedMemoryHeap;
+#endif
+    PTR(PVOID*) ReadOnlyStaticServerData;
+    PTR(PVOID) AnsiCodePageData;
+    PTR(PVOID) OemCodePageData;
+    PTR(PVOID) UnicodeCaseTableData;
+    ULONG NumberOfProcessors;
+    ULONG NtGlobalFlag;
+    LARGE_INTEGER CriticalSectionTimeout;
+    PTR(ULONG_PTR) HeapSegmentReserve;
+    PTR(ULONG_PTR) HeapSegmentCommit;
+    PTR(ULONG_PTR) HeapDeCommitTotalFreeThreshold;
+    PTR(ULONG_PTR) HeapDeCommitFreeBlockThreshold;
+    ULONG NumberOfHeaps;
+    ULONG MaximumNumberOfHeaps;
+    PTR(PVOID*) ProcessHeaps;
+    PTR(PVOID) GdiSharedHandleTable;
+    PTR(PVOID) ProcessStarterHelper;
+    ULONG GdiDCAttributeList;
+    PTR(struct _RTL_CRITICAL_SECTION*) LoaderLock;
+    ULONG OSMajorVersion;
+    ULONG OSMinorVersion;
+    USHORT OSBuildNumber;
+    USHORT OSCSDVersion;
+    ULONG OSPlatformId;
+    ULONG ImageSubsystem;
+    ULONG ImageSubsystemMajorVersion;
+    ULONG ImageSubsystemMinorVersion;
+    PTR(ULONG_PTR) ImageProcessAffinityMask;
+    ULONG GdiHandleBuffer[GDI_HANDLE_BUFFER_SIZE];
+    PTR(PPOST_PROCESS_INIT_ROUTINE) PostProcessInitRoutine;
+    PTR(PVOID) TlsExpansionBitmap;
+    ULONG TlsExpansionBitmapBits[32];
+    ULONG SessionId;
+#if (NTDDI_VERSION >= NTDDI_WINXP)
+    ULARGE_INTEGER AppCompatFlags;
+    ULARGE_INTEGER AppCompatFlagsUser;
+    PTR(PVOID) pShimData;
+    PTR(PVOID) AppCompatInfo;
+    STRUCT(UNICODE_STRING) CSDVersion;
+    PTR(struct _ACTIVATION_CONTEXT_DATA*) ActivationContextData;
+    PTR(struct _ASSEMBLY_STORAGE_MAP*) ProcessAssemblyStorageMap;
+    PTR(struct _ACTIVATION_CONTEXT_DATA*) SystemDefaultActivationContextData;
+    PTR(struct _ASSEMBLY_STORAGE_MAP*) SystemAssemblyStorageMap;
+    PTR(ULONG_PTR) MinimumStackCommit;
+#endif
+#if (NTDDI_VERSION >= NTDDI_WS03)
+    PTR(PVOID*) FlsCallback;
+    STRUCT(LIST_ENTRY) FlsListHead;
+    PTR(PVOID) FlsBitmap;
+    ULONG FlsBitmapBits[4];
+    ULONG FlsHighIndex;
+#endif
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(PVOID) WerRegistrationData;
+    PTR(PVOID) WerShipAssertPtr;
+#endif
+} STRUCT(PEB), *STRUCT(PPEB);
+
+
+#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), Mutant) == 0x08);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), Ldr) == 0x18);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), FastPebLock) == 0x038);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), TlsExpansionCounter) == 0x070);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), NtGlobalFlag) == 0x0BC);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), GdiSharedHandleTable) == 0x0F8);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), LoaderLock) == 0x110);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), ImageSubsystem) == 0x128);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), ImageProcessAffinityMask) == 0x138);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), PostProcessInitRoutine) == 0x230);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), SessionId) == 0x2C0);
+#if (NTDDI_VERSION >= NTDDI_WS03)
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), FlsHighIndex) == 0x350);
+#endif
+#else
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), Mutant) == 0x04);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), Ldr) == 0x0C);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), FastPebLock) == 0x01C);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), TlsExpansionCounter) == 0x03C);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), NtGlobalFlag) == 0x068);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), GdiSharedHandleTable) == 0x094);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), LoaderLock) == 0x0A0);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), ImageSubsystem) == 0x0B4);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), ImageProcessAffinityMask) == 0x0C0);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), PostProcessInitRoutine) == 0x14C);
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), SessionId) == 0x1D4);
+#if (NTDDI_VERSION >= NTDDI_WS03)
+C_ASSERT(FIELD_OFFSET(STRUCT(PEB), FlsHighIndex) == 0x22C);
+#endif
+#endif
+
+//
+// GDI Batch Descriptor
+//
+typedef struct STRUCT(_GDI_TEB_BATCH)
+{
+    ULONG Offset;
+    PTR(HANDLE) HDC;
+    ULONG Buffer[0x136];
+} STRUCT(GDI_TEB_BATCH), *STRUCT(PGDI_TEB_BATCH);
+
+//
+// Thread Environment Block (TEB)
+//
+typedef struct STRUCT(_TEB)
+{
+    STRUCT(NT_TIB)         NtTib;
+    PTR(PVOID)             EnvironmentPointer;
+    STRUCT(CLIENT_ID)      ClientId;
+    PTR(PVOID)             ActiveRpcHandle;
+    PTR(PVOID)             ThreadLocalStoragePointer;
+    PTR(STRUCT(PPEB))      ProcessEnvironmentBlock;
+    ULONG                  LastErrorValue;
+    ULONG                  CountOfOwnedCriticalSections;
+    PTR(PVOID)             CsrClientThread;
+    PTR(PVOID)             Win32ThreadInfo;
+    ULONG                  User32Reserved[26];
+    ULONG                  UserReserved[5];
+    PTR(PVOID)             WOW32Reserved;
+    LCID                   CurrentLocale;
+    ULONG                  FpSoftwareStatusRegister;
+    PTR(PVOID)             SystemReserved1[54];
+    LONG                   ExceptionCode;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(struct _ACTIVATION_CONTEXT_STACK*) ActivationContextStackPointer;
+    UCHAR                  SpareBytes1[0x30 - 3 * sizeof(PTR(PVOID))];
+    ULONG                  TxFsContext;
+#elif (NTDDI_VERSION >= NTDDI_WS03)
+    PTR(struct _ACTIVATION_CONTEXT_STACK*) ActivationContextStackPointer;
+    UCHAR                  SpareBytes1[0x34 - 3 * sizeof(PTR(PVOID))];
+#else
+    ACTIVATION_CONTEXT_STACK ActivationContextStack;
+    UCHAR                  SpareBytes1[24];
+#endif
+    STRUCT(GDI_TEB_BATCH)  GdiTebBatch;
+    STRUCT(CLIENT_ID)      RealClientId;
+    PTR(PVOID)             GdiCachedProcessHandle;
+    ULONG                  GdiClientPID;
+    ULONG                  GdiClientTID;
+    PTR(PVOID)             GdiThreadLocalInfo;
+    PTR(SIZE_T)            Win32ClientInfo[62];
+    PTR(PVOID)             glDispatchTable[233];
+    PTR(SIZE_T)            glReserved1[29];
+    PTR(PVOID)             glReserved2;
+    PTR(PVOID)             glSectionInfo;
+    PTR(PVOID)             glSection;
+    PTR(PVOID)             glTable;
+    PTR(PVOID)             glCurrentRC;
+    PTR(PVOID)             glContext;
+    NTSTATUS               LastStatusValue;
+    STRUCT(UNICODE_STRING) StaticUnicodeString;
+    WCHAR                  StaticUnicodeBuffer[261];
+    PTR(PVOID)             DeallocationStack;
+    PTR(PVOID)             TlsSlots[64];
+    STRUCT(LIST_ENTRY)     TlsLinks;
+    PTR(PVOID)             Vdm;
+    PTR(PVOID)             ReservedForNtRpc;
+    PTR(PVOID)             DbgSsReserved[2];
+#if (NTDDI_VERSION >= NTDDI_WS03)
+    ULONG                  HardErrorMode;
+#else
+    ULONG                  HardErrorsAreDisabled;
+#endif
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(PVOID)             Instrumentation[13 - sizeof(GUID)/sizeof(PTR(PVOID))];
+    GUID                   ActivityId;
+    PTR(PVOID)             SubProcessTag;
+    PTR(PVOID)             EtwLocalData;
+    PTR(PVOID)             EtwTraceData;
+#elif (NTDDI_VERSION >= NTDDI_WS03)
+    PTR(PVOID)             Instrumentation[14];
+    PTR(PVOID)             SubProcessTag;
+    PTR(PVOID)             EtwLocalData;
+#else
+    PTR(PVOID)             Instrumentation[16];
+#endif
+    PTR(PVOID)             WinSockData;
+    ULONG                  GdiBatchCount;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    BOOLEAN                SpareBool0;
+    BOOLEAN                SpareBool1;
+    BOOLEAN                SpareBool2;
+#else
+    BOOLEAN                InDbgPrint;
+    BOOLEAN                FreeStackOnTermination;
+    BOOLEAN                HasFiberData;
+#endif
+    UCHAR                  IdealProcessor;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+    ULONG                  GuaranteedStackBytes;
+#else
+    ULONG                  Spare3;
+#endif
+    PTR(PVOID)             ReservedForPerf;
+    PTR(PVOID)             ReservedForOle;
+    ULONG                  WaitingOnLoaderLock;
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PTR(PVOID)             SavedPriorityState;
+    PTR(ULONG_PTR)         SoftPatchPtr1;
+    PTR(ULONG_PTR)         ThreadPoolData;
+#elif (NTDDI_VERSION >= NTDDI_WS03)
+    PTR(ULONG_PTR)         SparePointer1;
+    PTR(ULONG_PTR)         SoftPatchPtr1;
+    PTR(ULONG_PTR)         SoftPatchPtr2;
+#else
+    Wx86ThreadState        Wx86Thread;
+#endif
+    PTR(PVOID*)            TlsExpansionSlots;
+#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
+    PTR(PVOID)             DeallocationBStore;                                                  
+    PTR(PVOID)             BStoreLimit;                                                         
+#endif
+    ULONG                  ImpersonationLocale;
+    ULONG                  IsImpersonating;
+    PTR(PVOID)             NlsCache;
+    PTR(PVOID)             pShimData;
+    ULONG                  HeapVirtualAffinity;
+    PTR(HANDLE)            CurrentTransactionHandle;
+    PTR(PTEB_ACTIVE_FRAME) ActiveFrame;
+#if (NTDDI_VERSION >= NTDDI_WS03)
+    PVOID FlsData;
+#endif
+#if (NTDDI_VERSION >= NTDDI_LONGHORN)
+    PVOID PreferredLangauges;
+    PVOID UserPrefLanguages;
+    PVOID MergedPrefLanguages;
+    ULONG MuiImpersonation;
+    union
+    {
+        struct
+        {
+            USHORT SpareCrossTebFlags:16;
+        };
+        USHORT CrossTebFlags;
+    };
+    union
+    {
+        struct
+        {
+            USHORT DbgSafeThunkCall:1;
+            USHORT DbgInDebugPrint:1;
+            USHORT DbgHasFiberData:1;
+            USHORT DbgSkipThreadAttach:1;
+            USHORT DbgWerInShipAssertCode:1;
+            USHORT DbgIssuedInitialBp:1;
+            USHORT DbgClonedThread:1;
+            USHORT SpareSameTebBits:9;
+        };
+        USHORT SameTebFlags;
+    };
+    PTR(PVOID) TxnScopeEntercallback;
+    PTR(PVOID) TxnScopeExitCAllback;
+    PTR(PVOID) TxnScopeContext;
+    ULONG LockCount;
+    ULONG ProcessRundown;
+    ULONG64 LastSwitchTime;
+    ULONG64 TotalSwitchOutTime;
+    LARGE_INTEGER WaitReasonBitMap;
+#else
+    BOOLEAN SafeThunkCall;
+    BOOLEAN BooleanSpare[3];
+#endif
+} STRUCT(TEB), *STRUCT(PTEB);
+
+#if defined(_WIN64) && !defined(EXPLICIT_32BIT)
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), EnvironmentPointer) == 0x038);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), ExceptionCode) == 0x2C0);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), GdiTebBatch) == 0x2F0);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), LastStatusValue) == 0x1250);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), Vdm) == 0x1690);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), HardErrorMode) == 0x16B0);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), GdiBatchCount) == 0x1740);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), IdealProcessor) == 0x1747);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), WaitingOnLoaderLock) == 0x1760);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), TlsExpansionSlots) == 0x1780);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), WaitingOnLoaderLock) == 0x1760);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), ActiveFrame) == 0x17C0);
+#else
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), EnvironmentPointer) == 0x01C);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), ExceptionCode) == 0x1A4);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), GdiTebBatch) == 0x1D4);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), LastStatusValue) == 0xBF4);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), Vdm) == 0xF18);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), GdiBatchCount) == 0xF70);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), TlsExpansionSlots) == 0xF94);
+C_ASSERT(FIELD_OFFSET(STRUCT(TEB), ActiveFrame) == 0xFB0);
+#endif
+
+#undef PTR
+#undef STRUCT
+#undef PASTE
+#undef PASTE2
+#undef GDI_HANDLE_BUFFER_SIZE
index 7b7e0a9..ecc9037 100644 (file)
Binary files a/media/inf/machine.inf and b/media/inf/machine.inf differ
index 9cd6347..cd0859b 100644 (file)
@@ -2180,9 +2180,19 @@ IopEnumerateDetectedDevices(
    const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
    UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
    static ULONG DeviceIndexMouse = 0;
    const UNICODE_STRING IdentifierMouse = RTL_CONSTANT_STRING(L"PointerController");
    UNICODE_STRING HardwareIdMouse = RTL_CONSTANT_STRING(L"*PNP0F13\0");
    static ULONG DeviceIndexMouse = 0;
+   const UNICODE_STRING IdentifierParallel = RTL_CONSTANT_STRING(L"PARALLEL");
+   UNICODE_STRING HardwareIdParallel = RTL_CONSTANT_STRING(L"*PNP0400\0");
+   static ULONG DeviceIndexParallel = 0;
+   const UNICODE_STRING IdentifierFloppy = RTL_CONSTANT_STRING(L"FLOPPY");
+   UNICODE_STRING HardwareIdFloppy = RTL_CONSTANT_STRING(L"*PNP0700\0");
+   static ULONG DeviceIndexFloppy = 0;
+   const UNICODE_STRING IdentifierIsa = RTL_CONSTANT_STRING(L"ISA");
+   UNICODE_STRING HardwareIdIsa = RTL_CONSTANT_STRING(L"*PNP0A00\0");
+   static ULONG DeviceIndexIsa = 0;
    UNICODE_STRING HardwareIdKey;
    PUNICODE_STRING pHardwareId;
    ULONG DeviceIndex = 0;
    UNICODE_STRING HardwareIdKey;
    PUNICODE_STRING pHardwareId;
    ULONG DeviceIndex = 0;
+   BOOLEAN IsDeviceDesc;
 
     if (RelativePath)
     {
 
     if (RelativePath)
     {
@@ -2409,16 +2419,19 @@ IopEnumerateDetectedDevices(
       {
          pHardwareId = &HardwareIdSerial;
          DeviceIndex = DeviceIndexSerial++;
       {
          pHardwareId = &HardwareIdSerial;
          DeviceIndex = DeviceIndexSerial++;
+         IsDeviceDesc = TRUE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
       {
          pHardwareId = &HardwareIdKeyboard;
          DeviceIndex = DeviceIndexKeyboard++;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierKeyboard, FALSE) == 0)
       {
          pHardwareId = &HardwareIdKeyboard;
          DeviceIndex = DeviceIndexKeyboard++;
+         IsDeviceDesc = FALSE;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
       {
          pHardwareId = &HardwareIdMouse;
          DeviceIndex = DeviceIndexMouse++;
       }
       else if (RelativePath && RtlCompareUnicodeString(RelativePath, &IdentifierMouse, FALSE) == 0)
       {
          pHardwareId = &HardwareIdMouse;
          DeviceIndex = DeviceIndexMouse++;
+         IsDeviceDesc = FALSE;
       }
       else if (NT_SUCCESS(Status))
       {
       }
       else if (NT_SUCCESS(Status))
       {
@@ -2427,19 +2440,51 @@ IopEnumerateDetectedDevices(
          {
             pHardwareId = &HardwareIdPci;
             DeviceIndex = DeviceIndexPci++;
          {
             pHardwareId = &HardwareIdPci;
             DeviceIndex = DeviceIndexPci++;
+            IsDeviceDesc = FALSE;
+         }
+         else if (RtlCompareUnicodeString(&ValueName, &IdentifierIsa, FALSE) == 0)
+         {
+            pHardwareId = &HardwareIdIsa;
+            DeviceIndex = DeviceIndexIsa++;
+            IsDeviceDesc = FALSE;
          }
 #ifdef ENABLE_ACPI
          else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0)
          {
             pHardwareId = &HardwareIdAcpi;
             DeviceIndex = DeviceIndexAcpi++;
          }
 #ifdef ENABLE_ACPI
          else if (RtlCompareUnicodeString(&ValueName, &IdentifierAcpi, FALSE) == 0)
          {
             pHardwareId = &HardwareIdAcpi;
             DeviceIndex = DeviceIndexAcpi++;
+            IsDeviceDesc = FALSE;
          }
 #endif
          }
 #endif
-         else
+         else /* Now let's detect devices with a device number at the end */
          {
          {
-            /* Unknown device */
-            DPRINT("Unknown device '%wZ'\n", &ValueName);
-            goto nextdevice;
+            /* First, we remove the number */
+            ValueName.Length -= sizeof(WCHAR);
+
+            /* Let's see if it is a floppy device */
+            if (RtlCompareUnicodeString(&ValueName, &IdentifierFloppy, FALSE) == 0)
+            {
+                pHardwareId = &HardwareIdFloppy;
+                DeviceIndex = DeviceIndexFloppy++;
+                IsDeviceDesc = FALSE;
+            }
+            /* Nope, is it a parallel port? */
+            else if (RtlCompareUnicodeString(&ValueName, &IdentifierParallel, FALSE) == 0)
+            {
+                pHardwareId = &HardwareIdParallel;
+                DeviceIndex = DeviceIndexParallel++;
+                IsDeviceDesc = FALSE;
+            }
+            /* Nope, out of ideas so let's skip this one */
+            else
+            {
+                ValueName.Length += sizeof(WCHAR);
+                DPRINT("Unknown device '%wZ'\n", &ValueName);
+                goto nextdevice;
+            }
+
+            /* Add the number back */
+            ValueName.Length += sizeof(WCHAR);
          }
       }
       else
          }
       }
       else
@@ -2486,12 +2531,15 @@ IopEnumerateDetectedDevices(
          goto nextdevice;
       }
       DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
          goto nextdevice;
       }
       DPRINT("Found %wZ #%lu (%wZ)\n", &ValueName, DeviceIndex, &HardwareIdKey);
-      Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength);
-      if (!NT_SUCCESS(Status))
+      if (IsDeviceDesc)
       {
       {
-         DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
-         ZwDeleteKey(hLevel2Key);
-         goto nextdevice;
+         Status = ZwSetValueKey(hLevel2Key, &DeviceDescU, 0, REG_SZ, ValueName.Buffer, ValueName.MaximumLength);
+         if (!NT_SUCCESS(Status))
+         {
+            DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
+            ZwDeleteKey(hLevel2Key);
+            goto nextdevice;
+         }
       }
       Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
       if (!NT_SUCCESS(Status))
       }
       Status = ZwSetValueKey(hLevel2Key, &HardwareIDU, 0, REG_MULTI_SZ, pHardwareId->Buffer, pHardwareId->MaximumLength);
       if (!NT_SUCCESS(Status))