Filter:   InfoImg
download pnproot.c
Language: C
LOC: 205
Project Info
owp
Server: SourceForge
Type: cvs
...owp\owp\kernel\ntoskrnl\io\
   .cvsignore
   adapter.c
   buildirp.c
   cancel.c
   cleanup.c
   cntrller.c
   create.c
   device.c
   dir.c
   drvlck.c
   errlog.c
   error.c
   event.c
   file.c
   flush.c
   fs.c
   iocomp.c
   ioctrl.c
   iomgr.c
   irp.c
   lock.c
   mailslot.c
   mdl.c
   npipe.c
   page.c
   pnpmgr.c
   pnproot.c
   process.c
   queue.c
   resource.c
   rw.c
   share.c
   shutdown.c
   symlink.c
   timer.c
   vpb.c
   xhaldisp.c
   xhaldrv.c

/* $Id: pnproot.c,v 1.1.1.1 2001/12/18 23:40:53 brandon6684 Exp $
 *
 * COPYRIGHT:      See COPYING in the top level directory
 * PROJECT:        ReactOS kernel
 * FILE:           ntoskrnl/io/pnproot.c
 * PURPOSE:        PnP manager root device
 * PROGRAMMER:     Casper S. Hornstrup (chorns@users.sourceforge.net)
 * UPDATE HISTORY:
 *  16/04/2001 CSH Created
 */

/* INCLUDES ******************************************************************/

#include <ddk/ntddk.h>
#include <internal/io.h>

#define NDEBUG
#include <internal/debug.h>

/* GLOBALS *******************************************************************/

/* DATA **********************************************************************/

typedef struct _PNPROOT_DEVICE {
  LIST_ENTRY ListEntry;
  PDEVICE_OBJECT Pdo;
} PNPROOT_DEVICE, *PPNPROOT_DEVICE;

PDEVICE_OBJECT PnpRootDeviceObject;
LIST_ENTRY PnpRootDeviceListHead;
ULONG PnpRootDeviceListCount;
KSPIN_LOCK PnpRootDeviceListLock;

/* FUNCTIONS *****************************************************************/

NTSTATUS
PnpRootCreateDevice(
  PDEVICE_OBJECT *PhysicalDeviceObject)
{
  PPNPROOT_DEVICE Device;
  NTSTATUS Status;

  DPRINT("Called\n");

  Device = (PPNPROOT_DEVICE)ExAllocatePool(PagedPool, sizeof(PNPROOT_DEVICE));
  if (!Device)
    return STATUS_INSUFFICIENT_RESOURCES;

  Status = IoCreateDevice(PnpRootDeviceObject->DriverObject, 0,
    NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
  if (!NT_SUCCESS(Status))
    {
      DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
      ExFreePool(Device);
      return Status;
    }

  Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

  ObReferenceObject(Device->Pdo);

  ExInterlockedInsertTailList(&PnpRootDeviceListHead,
    &Device->ListEntry,
    &PnpRootDeviceListLock);

  *PhysicalDeviceObject = Device->Pdo;

  return STATUS_SUCCESS;
}


NTSTATUS
PnpRootQueryBusRelations(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp,
  IN PIO_STACK_LOCATION IrpSp)
{
  PDEVICE_RELATIONS Relations;
  PLIST_ENTRY CurrentEntry;
  PPNPROOT_DEVICE Device;
  NTSTATUS Status;
  ULONG Size;
  ULONG i;

  DPRINT("Called\n");

  Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
    (PnpRootDeviceListCount - 1);
  Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
  if (!Relations)
    return STATUS_INSUFFICIENT_RESOURCES;

  Relations->Count = PnpRootDeviceListCount;

  i = 0;
  CurrentEntry = PnpRootDeviceListHead.Flink;
  while (CurrentEntry != &PnpRootDeviceListHead)
    {
    Device = CONTAINING_RECORD(
      CurrentEntry, PNPROOT_DEVICE, ListEntry);

    if (!Device->Pdo) {
      /* Create a physical device object for the
         device as it does not already have one */
      Status = IoCreateDevice(DeviceObject->DriverObject, 0,
        NULL, FILE_DEVICE_CONTROLLER, 0, FALSE, &Device->Pdo);
      if (!NT_SUCCESS(Status)) {
        DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
        ExFreePool(Relations);
        return Status;
      }

      Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;
    }

    /* Reference the physical device object. The PnP manager
       will dereference it again when it is no longer needed */
    ObReferenceObject(Device->Pdo);

    Relations->Objects[i] = Device->Pdo;

    i++;

    CurrentEntry = CurrentEntry->Flink;
    }

  Irp->IoStatus.Information = (ULONG)Relations;

  return Status;
}

NTSTATUS
PnpRootQueryDeviceRelations(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp,
  IN PIO_STACK_LOCATION IrpSp)
{
  NTSTATUS Status;

  DPRINT("Called\n");

  switch (IrpSp->Parameters.QueryDeviceRelations.Type)
    {
  case BusRelations:
    Status = PnpRootQueryBusRelations(DeviceObject, Irp, IrpSp);
    break;

  default:
    Status = STATUS_NOT_IMPLEMENTED;
    }

  return Status;
}

NTSTATUS
STDCALL
PnpRootPnpControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp)
{
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status;

  DPRINT("Called\n");

  IrpSp = IoGetCurrentIrpStackLocation(Irp);
  switch (IrpSp->MinorFunction)
    {
  case IRP_MN_QUERY_DEVICE_RELATIONS:
    Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
    break;
  
  case IRP_MN_START_DEVICE:
    PnpRootDeviceListCount = 0;
    Status = STATUS_SUCCESS;
    break;

  case IRP_MN_STOP_DEVICE:
    /* Root device cannot be stopped */
    Status = STATUS_UNSUCCESSFUL;
    break;

  default:
    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
    Status = STATUS_NOT_IMPLEMENTED;
    break;
    }

  if (Status != STATUS_PENDING)
    {
      Irp->IoStatus.Status = Status;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

  DPRINT("Leaving. Status 0x%X\n", Status);

  return Status;
}

NTSTATUS
STDCALL
PnpRootPowerControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp)
{
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status;

  DPRINT("Called\n");

  IrpSp = IoGetCurrentIrpStackLocation(Irp);
  switch (IrpSp->MinorFunction)
  {
  default:
    DPRINT("Unknown IOCTL 0x%X\n", IrpSp->MinorFunction);
    Status = STATUS_NOT_IMPLEMENTED;
    break;
  }

  if (Status != STATUS_PENDING)
    {
      Irp->IoStatus.Status = Status;
      IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

  DPRINT("Leaving. Status 0x%X\n", Status);

  return Status;
}

NTSTATUS
PnpRootAddDevice(
  IN PDRIVER_OBJECT DriverObject,
  IN PDEVICE_OBJECT PhysicalDeviceObject)
{
  PDEVICE_OBJECT Ldo;
  NTSTATUS Status;

  DPRINT("Called\n");

  Status = IoCreateDevice(DriverObject, 0, NULL, FILE_DEVICE_BUS_EXTENDER,
    FILE_DEVICE_SECURE_OPEN, TRUE, &PnpRootDeviceObject);
  if (!NT_SUCCESS(Status))
    {
      DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
      KeBugCheck(0);
      return Status;
    }

  Ldo = IoAttachDeviceToDeviceStack(PnpRootDeviceObject, PhysicalDeviceObject);

  if (!PnpRootDeviceObject)
    {
      DbgPrint("PnpRootDeviceObject 0x%X\n", PnpRootDeviceObject);
      KeBugCheck(0);
    }

  if (!PhysicalDeviceObject)
    {
      DbgPrint("PhysicalDeviceObject 0x%X\n", PhysicalDeviceObject);
      KeBugCheck(0);
    }

  InitializeListHead(&PnpRootDeviceListHead);
  PnpRootDeviceListCount = 0;
  KeInitializeSpinLock(&PnpRootDeviceListLock);

  PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

  DPRINT("Done\n");

  return STATUS_SUCCESS;
}

NTSTATUS
STDCALL
PnpRootDriverEntry(
  IN PDRIVER_OBJECT DriverObject,
  IN PUNICODE_STRING RegistryPath)
{
  DPRINT("Called\n");

  DriverObject->MajorFunction[IRP_MJ_PNP] = PnpRootPnpControl;
  DriverObject->MajorFunction[IRP_MJ_POWER] = PnpRootPowerControl;
  DriverObject->DriverExtension->AddDevice = PnpRootAddDevice;

  return STATUS_SUCCESS;
}

/* EOF */