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

📄 dispatch.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * IntVideoPortWrite
 *
 * This is a bit of a hack. We want to take ownership of the display as late
 * as possible, just before the switch to graphics mode. Win32k knows when
 * this happens, we don't. So we need Win32k to inform us. This could be done
 * using an IOCTL, but there's no way of knowing which IOCTL codes are unused
 * in the communication between GDI driver and miniport driver. So we use
 * IRP_MJ_WRITE as the signal that win32k is ready to switch to graphics mode,
 * since we know for certain that there is no read/write activity going on
 * between GDI and miniport drivers.
 * We don't actually need the data that is passed, we just trigger on the fact
 * that an IRP_MJ_WRITE was sent.
 *
 * Run Level
 *    PASSIVE_LEVEL
 */

NTSTATUS NTAPI
IntVideoPortDispatchWrite(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
{
   PIO_STACK_LOCATION piosStack = IoGetCurrentIrpStackLocation(Irp);
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   NTSTATUS nErrCode;

   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

   /*
    * Storing the device extension pointer in a static variable is an
    * ugly hack. Unfortunately, we need it in IntVideoPortResetDisplayParameters
    * and InbvNotifyDisplayOwnershipLost doesn't allow us to pass a userdata
    * parameter. On the bright side, the DISPLAY device is opened
    * exclusively, so there can be only one device extension active at
    * any point in time.
    *
    * FIXME: We should process all opened display devices in
    * IntVideoPortResetDisplayParameters.
    */

   ResetDisplayParametersDeviceExtension = DeviceExtension;
   InbvNotifyDisplayOwnershipLost(IntVideoPortResetDisplayParameters);

   nErrCode = STATUS_SUCCESS;
   Irp->IoStatus.Information = piosStack->Parameters.Write.Length;
   Irp->IoStatus.Status = nErrCode;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);

   return nErrCode;
}


NTSTATUS NTAPI
IntVideoPortPnPStartDevice(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
{
   PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
   PDRIVER_OBJECT DriverObject;
   PVIDEO_PORT_DRIVER_EXTENSION DriverExtension;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PCM_RESOURCE_LIST AllocatedResources;

   /*
    * Get the initialization data we saved in VideoPortInitialize.
    */

   DriverObject = DeviceObject->DriverObject;
   DriverExtension = IoGetDriverObjectExtension(DriverObject, DriverObject);
   DeviceExtension = (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

   /*
    * Store some resources in the DeviceExtension.
    */

   AllocatedResources = Stack->Parameters.StartDevice.AllocatedResources;
   if (AllocatedResources != NULL)
   {
      CM_FULL_RESOURCE_DESCRIPTOR *FullList;
      CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
      ULONG ResourceCount;
      ULONG ResourceListSize;

      /* Save the resource list */
      ResourceCount = AllocatedResources->List[0].PartialResourceList.Count;
      ResourceListSize =
         FIELD_OFFSET(CM_RESOURCE_LIST, List[0].PartialResourceList.
                      PartialDescriptors[ResourceCount]);
      DeviceExtension->AllocatedResources = ExAllocatePool(PagedPool, ResourceListSize);
      if (DeviceExtension->AllocatedResources == NULL)
      {
         return STATUS_INSUFFICIENT_RESOURCES;
      }

      RtlCopyMemory(DeviceExtension->AllocatedResources,
                    AllocatedResources,
                    ResourceListSize);

      /* Get the interrupt level/vector - needed by HwFindAdapter sometimes */
      for (FullList = AllocatedResources->List;
           FullList < AllocatedResources->List + AllocatedResources->Count;
           FullList++)
      {
         /* FIXME: Is this ASSERT ok for resources from the PNP manager? */
         ASSERT(FullList->InterfaceType == PCIBus &&
                FullList->BusNumber == DeviceExtension->SystemIoBusNumber &&
                1 == FullList->PartialResourceList.Version &&
                1 == FullList->PartialResourceList.Revision);
	 for (Descriptor = FullList->PartialResourceList.PartialDescriptors;
              Descriptor < FullList->PartialResourceList.PartialDescriptors + FullList->PartialResourceList.Count;
              Descriptor++)
         {
            if (Descriptor->Type == CmResourceTypeInterrupt)
            {
               DeviceExtension->InterruptLevel = Descriptor->u.Interrupt.Level;
               DeviceExtension->InterruptVector = Descriptor->u.Interrupt.Vector;
               if (Descriptor->ShareDisposition == CmResourceShareShared)
                  DeviceExtension->InterruptShared = TRUE;
               else
                  DeviceExtension->InterruptShared = FALSE;
            }
         }
      }
   }
   DPRINT("Interrupt level: 0x%x Interrupt Vector: 0x%x\n",
          DeviceExtension->InterruptLevel,
          DeviceExtension->InterruptVector);

   /*
    * Create adapter device object.
    */

   return IntVideoPortFindAdapter(
      DriverObject,
      DriverExtension,
      DeviceObject);
}


NTSTATUS
NTAPI
IntVideoPortForwardIrpAndWaitCompletionRoutine(
    PDEVICE_OBJECT Fdo,
    PIRP Irp,
    PVOID Context)
{
  PKEVENT Event = Context;

  if (Irp->PendingReturned)
    KeSetEvent(Event, IO_NO_INCREMENT, FALSE);

  return STATUS_MORE_PROCESSING_REQUIRED;
}


NTSTATUS
NTAPI
IntVideoPortForwardIrpAndWait(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
   KEVENT Event;
   NTSTATUS Status;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension =
                   (PVIDEO_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

   KeInitializeEvent(&Event, NotificationEvent, FALSE);
   IoCopyCurrentIrpStackLocationToNext(Irp);
   IoSetCompletionRoutine(Irp, IntVideoPortForwardIrpAndWaitCompletionRoutine,
                          &Event, TRUE, TRUE, TRUE);
   Status = IoCallDriver(DeviceExtension->NextDeviceObject, Irp);
   if (Status == STATUS_PENDING)
   {
      KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
      Status = Irp->IoStatus.Status;
   }
   return Status;
}


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

   IrpSp = IoGetCurrentIrpStackLocation(Irp);

   switch (IrpSp->MinorFunction)
   {
      case IRP_MN_START_DEVICE:
         Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
         if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
            Status = IntVideoPortPnPStartDevice(DeviceObject, Irp);
         Irp->IoStatus.Status = Status;
         Irp->IoStatus.Information = 0;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         break;


      case IRP_MN_REMOVE_DEVICE:
      case IRP_MN_QUERY_REMOVE_DEVICE:
      case IRP_MN_CANCEL_REMOVE_DEVICE:
      case IRP_MN_SURPRISE_REMOVAL:

      case IRP_MN_STOP_DEVICE:
         Status = IntVideoPortForwardIrpAndWait(DeviceObject, Irp);
         if (NT_SUCCESS(Status) && NT_SUCCESS(Irp->IoStatus.Status))
            Status = STATUS_SUCCESS;
         Irp->IoStatus.Status = Status;
         Irp->IoStatus.Information = 0;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         break;

      case IRP_MN_QUERY_STOP_DEVICE:
      case IRP_MN_CANCEL_STOP_DEVICE:
         Status = STATUS_SUCCESS;
         Irp->IoStatus.Status = STATUS_SUCCESS;
         Irp->IoStatus.Information = 0;
         IoCompleteRequest(Irp, IO_NO_INCREMENT);
         break;

      default:
         return STATUS_NOT_IMPLEMENTED;
         break;
   }

   return Status;
}

NTSTATUS NTAPI
IntVideoPortDispatchCleanup(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;

   DeviceExtension = DeviceObject->DeviceExtension;
   RtlFreeUnicodeString(&DeviceExtension->RegistryPath);

   Irp->IoStatus.Status = STATUS_SUCCESS;
   Irp->IoStatus.Information = 0;
   IoCompleteRequest(Irp, IO_NO_INCREMENT);

   return STATUS_SUCCESS;
}

NTSTATUS NTAPI
IntVideoPortDispatchPower(
   IN PDEVICE_OBJECT DeviceObject,
   IN PIRP Irp)
{
   return STATUS_NOT_IMPLEMENTED;
}

VOID NTAPI
IntVideoPortUnload(PDRIVER_OBJECT DriverObject)
{
}

⌨️ 快捷键说明

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