⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pnproot.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
    Device->DeviceDescription.Buffer = NULL;
  }

  DPRINT("Got device description: %S\n", DeviceDesc->Buffer);

  /* 2. Read informations in instance key, LogConf subkey */
  RtlZeroMemory(QueryTable, sizeof(QueryTable));
  wcscat(KeyName, L"\\LogConf");
  
  Status = PnpRootReadRegistryBinary(
    KeyName,
    L"BasicConfigVector",
    (PVOID*)&Device->ResourceRequirementsList,
    NULL);

  DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status);

  if (!NT_SUCCESS(Status))
  {
    /* FIXME: */
  }

  Status = PnpRootReadRegistryBinary(
    KeyName,
    L"BootConfig",
    (PVOID*)&Device->BootResourceList,
    &Device->BootResourceListSize);

  DPRINT("PnpRootReadRegistryBinary() returned status 0x%08lx\n", Status);

  if (!NT_SUCCESS(Status))
  {
    /* FIXME: */
  }

  return STATUS_SUCCESS;
}


NTSTATUS
PnpRootFdoEnumerateDevices(
  PDEVICE_OBJECT DeviceObject)
{
  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
  OBJECT_ATTRIBUTES ObjectAttributes, SubKeyAttributes;
  PKEY_BASIC_INFORMATION KeyInfo, SubKeyInfo;
  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\" ENUM_NAME_ROOT);
  UNICODE_STRING SubKeyName;
  PPNPROOT_DEVICE Device;
  WCHAR Buffer[MAX_PATH];
  HANDLE KeyHandle, SubKeyHandle;
  ULONG BufferSize;
  ULONG ResultSize;
  NTSTATUS Status;
  ULONG Index1, Index2;

  DPRINT("Called\n");

  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  BufferSize = sizeof(KEY_BASIC_INFORMATION) + (MAX_PATH+1) * sizeof(WCHAR);
  KeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
  if (!KeyInfo)
  {
    return STATUS_INSUFFICIENT_RESOURCES;
  }
  SubKeyInfo = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_PNP_ROOT);
  if (!SubKeyInfo)
  {
    ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  InitializeObjectAttributes(
    &ObjectAttributes,
		&KeyName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL);

  Status = ZwOpenKey(&KeyHandle, KEY_ENUMERATE_SUB_KEYS, &ObjectAttributes);
  if (!NT_SUCCESS(Status))
  {
    DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
    ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
    ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);
    return Status;
  }

  /* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
            there are more entries in the list than found in the registry as some
            drivers are passed on the command line */
//  DeviceExtension->DeviceListCount = 0;

  /* Devices are sub-sub-keys of 'KeyName'. KeyName is already opened as
   * KeyHandle. We'll first do a first enumeration to have first level keys,
   * and an inner one to have the real devices list.
   */
  Index1 = 0;
  
  while (TRUE)
  {
    Status = ZwEnumerateKey(
      KeyHandle,
      Index1,
      KeyBasicInformation,
      KeyInfo,
      BufferSize,
      &ResultSize);
    if (!NT_SUCCESS(Status))
    {
      DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
      break;
    }

    /* Terminate the string */
    KeyInfo->Name[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
    
    /* Open the key */
    RtlInitUnicodeString(&SubKeyName, KeyInfo->Name);
    InitializeObjectAttributes(
      &SubKeyAttributes,
      &SubKeyName,
      0, /* Attributes */
      KeyHandle,
      NULL); /* Security descriptor */
    Status = ZwOpenKey(&SubKeyHandle, KEY_ENUMERATE_SUB_KEYS, &SubKeyAttributes);
    if (!NT_SUCCESS(Status))
    {
      DPRINT("ZwOpenKey() failed (Status 0x%08lx)\n", Status);
      break;
    }
    
    /* Enumerate the sub-keys */
    Index2 = 0;
    while (TRUE)
    {
      Status = ZwEnumerateKey(
        SubKeyHandle,
        Index2,
        KeyBasicInformation,
        SubKeyInfo,
        BufferSize,
        &ResultSize);
      if (!NT_SUCCESS(Status))
      {
        DPRINT("ZwEnumerateKey() (Status 0x%08lx)\n", Status);
        break;
      }
      
      /* Terminate the string */
      SubKeyInfo->Name[SubKeyInfo->NameLength / sizeof(WCHAR)] = 0;
      
      Device = (PPNPROOT_DEVICE)ExAllocatePoolWithTag(PagedPool, sizeof(PNPROOT_DEVICE), TAG_PNP_ROOT);
      if (!Device)
      {
        /* FIXME: */
        DPRINT("ExAllocatePoolWithTag() failed\n");
        break;
      }

      RtlZeroMemory(Device, sizeof(PNPROOT_DEVICE));

      if (!RtlCreateUnicodeString(&Device->ServiceName, KeyInfo->Name))
      {
        /* FIXME: */
        DPRINT("RtlCreateUnicodeString() failed\n");
      }

      wcscpy(Buffer, ENUM_NAME_ROOT);
      wcscat(Buffer, L"\\");
      wcscat(Buffer, KeyInfo->Name);

      if (!RtlCreateUnicodeString(&Device->DeviceID, Buffer))
      {
        /* FIXME: */
        DPRINT("RtlCreateUnicodeString() failed\n");
      }

      DPRINT("Got entry: %S\n", Device->DeviceID.Buffer);

      if (!RtlCreateUnicodeString(
        &Device->InstanceID,
        SubKeyInfo->Name))
      {
        /* FIXME: */
        DPRINT("RtlCreateUnicodeString() failed\n");
      }

      Status = PnpRootFdoReadDeviceInfo(Device);
      if (!NT_SUCCESS(Status))
      {
        /* FIXME */
        DPRINT("PnpRootFdoReadDeviceInfo() failed with status 0x%08lx\n", Status);
      }

      ExInterlockedInsertTailList(
        &DeviceExtension->DeviceListHead,
        &Device->ListEntry,
        &DeviceExtension->DeviceListLock);

      DeviceExtension->DeviceListCount++;
      
      Index2++;
    }
    
    ZwClose(SubKeyHandle);
    Index1++;
  }

  ZwClose(KeyHandle);

  ExFreePoolWithTag(KeyInfo, TAG_PNP_ROOT);
  ExFreePoolWithTag(SubKeyInfo, TAG_PNP_ROOT);

  return STATUS_SUCCESS;
}


NTSTATUS
PnpRootQueryBusRelations(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp,
  IN PIO_STACK_LOCATION IrpSp)
{
  PPNPROOT_PDO_DEVICE_EXTENSION PdoDeviceExtension;
  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
  PDEVICE_RELATIONS Relations;
  PPNPROOT_DEVICE Device;
  NTSTATUS Status;
  ULONG Size;
  ULONG i;

  DPRINT("Called\n");

  Status = PnpRootFdoEnumerateDevices(DeviceObject);
  if (!NT_SUCCESS(Status))
    return Status;

  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  if (Irp->IoStatus.Information)
  {
    /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
              structure so we must merge this structure with our own */
  }

  Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
    (DeviceExtension->DeviceListCount - 1);

  Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
  if (!Relations)
    return STATUS_INSUFFICIENT_RESOURCES;

  Relations->Count = DeviceExtension->DeviceListCount;

  i = 0;
  LIST_FOR_EACH(Device,&DeviceExtension->DeviceListHead,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,
        sizeof(PNPROOT_PDO_DEVICE_EXTENSION),
        NULL,
        FILE_DEVICE_CONTROLLER,
        FILE_AUTOGENERATED_DEVICE_NAME,
        FALSE,
        &Device->Pdo);
      if (!NT_SUCCESS(Status))
      {
        DPRINT("IoCreateDevice() failed with status 0x%X\n", Status);
        ExFreePool(Relations);
        return Status;
      }

      DPRINT("Created PDO 0x%p\n", Device->Pdo);

      Device->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE;

      Device->Pdo->Flags &= ~DO_DEVICE_INITIALIZING;

      //Device->Pdo->Flags |= DO_POWER_PAGABLE;

      PdoDeviceExtension = (PPNPROOT_PDO_DEVICE_EXTENSION)Device->Pdo->DeviceExtension;

      RtlZeroMemory(PdoDeviceExtension, sizeof(PNPROOT_PDO_DEVICE_EXTENSION));

      PdoDeviceExtension->Common.IsFDO = FALSE;

      PdoDeviceExtension->Common.DeviceObject = Device->Pdo;

      PdoDeviceExtension->Common.DevicePowerState = PowerDeviceD0;

      PdoDeviceExtension->Device = Device;

      DPRINT("DeviceID: %wZ  PDO %p\n",
        &PdoDeviceExtension->Device->DeviceID,
        Device->Pdo);

      DPRINT("InstanceID: %wZ  PDO %p\n",
        &PdoDeviceExtension->Device->InstanceID,
        Device->Pdo);

      DPRINT("ResourceRequirementsList: %p  PDO %p\n",
        PdoDeviceExtension->Device->ResourceRequirementsList,
        Device->Pdo);
    }

    /* 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++;
  }

  if (NT_SUCCESS(Status))
  {
    Irp->IoStatus.Information = (ULONG_PTR)Relations;
  }
  else
  {
    Irp->IoStatus.Information = 0;
  }

  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;
}


/*
 * FUNCTION: Handle Plug and Play IRPs for the root bus device object
 * ARGUMENTS:
 *     DeviceObject = Pointer to functional device object of the root bus driver
 *     Irp          = Pointer to IRP that should be handled
 * RETURNS:
 *     Status
 */
NTSTATUS
STDCALL
PnpRootFdoPnpControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp)
{
  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
  PIO_STACK_LOCATION IrpSp;
  NTSTATUS Status;

  DPRINT("Called\n");

  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  Status = Irp->IoStatus.Status;

  IrpSp = IoGetCurrentIrpStackLocation(Irp);

  switch (IrpSp->MinorFunction) {
  case IRP_MN_QUERY_DEVICE_RELATIONS:
    Status = PnpRootQueryDeviceRelations(DeviceObject, Irp, IrpSp);
    break;

  case IRP_MN_START_DEVICE:
    DeviceExtension->State = dsStarted;
    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;
}


/*
 * FUNCTION: Handle power management IRPs for the root bus device object
 * ARGUMENTS:
 *     DeviceObject = Pointer to functional device object of the root bus driver
 *     Irp          = Pointer to IRP that should be handled
 * RETURNS:
 *     Status
 */
NTSTATUS
STDCALL
PnpRootFdoPowerControl(
  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;
}


/*
 * FUNCTION: Handle Plug and Play IRPs
 * ARGUMENTS:
 *     DeviceObject = Pointer to PDO or FDO
 *     Irp          = Pointer to IRP that should be handled
 * RETURNS:
 *     Status
 */
NTSTATUS
STDCALL
PnpRootPnpControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp)
{
  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
  NTSTATUS Status;

  DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  DPRINT("DeviceObject 0x%p  DeviceExtension 0x%p  IsFDO %d\n",
    DeviceObject,
    DeviceExtension,
    DeviceExtension->IsFDO);

  if (DeviceExtension->IsFDO) {
    Status = PnpRootFdoPnpControl(DeviceObject, Irp);
  } else {
    Status = PnpRootPdoPnpControl(DeviceObject, Irp);
  }

  return Status;
}


/*
 * FUNCTION: Handle power management IRPs
 * ARGUMENTS:
 *     DeviceObject = Pointer to PDO or FDO
 *     Irp          = Pointer to IRP that should be handled
 * RETURNS:
 *     Status
 */
NTSTATUS
STDCALL
PnpRootPowerControl(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp)
{
  PPNPROOT_COMMON_DEVICE_EXTENSION DeviceExtension;
  NTSTATUS Status;

  DeviceExtension = (PPNPROOT_COMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

  if (DeviceExtension->IsFDO) {
    Status = PnpRootFdoPowerControl(DeviceObject, Irp);
  } else {
    Status = PnpRootPdoPowerControl(DeviceObject, Irp);
  }

  return Status;
}


NTSTATUS
STDCALL
PnpRootAddDevice(
  IN PDRIVER_OBJECT DriverObject,
  IN PDEVICE_OBJECT PhysicalDeviceObject)
{
  PPNPROOT_FDO_DEVICE_EXTENSION DeviceExtension;
  NTSTATUS Status;

  DPRINT("Called\n");

  Status = IoCreateDevice(
    DriverObject,
    sizeof(PNPROOT_FDO_DEVICE_EXTENSION),
    NULL,
    FILE_DEVICE_BUS_EXTENDER,
    FILE_DEVICE_SECURE_OPEN,
    TRUE,
    &PnpRootDeviceObject);
  if (!NT_SUCCESS(Status)) {
    KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
  }

  DeviceExtension = (PPNPROOT_FDO_DEVICE_EXTENSION)PnpRootDeviceObject->DeviceExtension;

  RtlZeroMemory(DeviceExtension, sizeof(PNPROOT_FDO_DEVICE_EXTENSION));

  DeviceExtension->Common.IsFDO = TRUE;

  DeviceExtension->State = dsStopped;

  DeviceExtension->Ldo = IoAttachDeviceToDeviceStack(
    PnpRootDeviceObject,
    PhysicalDeviceObject);

  if (!PnpRootDeviceObject) {
    CPRINT("PnpRootDeviceObject 0x%p\n", PnpRootDeviceObject);
    KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
  }

  if (!PhysicalDeviceObject) {
    CPRINT("PhysicalDeviceObject 0x%p\n", PhysicalDeviceObject);
    KEBUGCHECKEX(PHASE1_INITIALIZATION_FAILED, Status, 0, 0, 0);
  }

  InitializeListHead(&DeviceExtension->DeviceListHead);

  DeviceExtension->DeviceListCount = 0;

  KeInitializeSpinLock(&DeviceExtension->DeviceListLock);

  PnpRootDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

  //PnpRootDeviceObject->Flags |= DO_POWER_PAGABLE;

  DPRINT("Done AddDevice()\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 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -