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

📄 videoprt.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
   if (Length == 0)
   {
      if (RomImageBuffer != NULL)
      {
         ExFreePool(RomImageBuffer);
         RomImageBuffer = NULL;
      }
      return NULL;
   }
   else
   {
      /*
       * The DDK says we shouldn't use the legacy C0000 method but get the
       * rom base address from the corresponding pci or acpi register but
       * lets ignore that and use C0000 anyway. We have already mapped the
       * bios area into memory so we'll copy from there.
       */

      /* Copy the bios. */
      Length = min(Length, 0x10000);
      if (RomImageBuffer != NULL)
      {
         ExFreePool(RomImageBuffer);
      }

      RomImageBuffer = ExAllocatePool(PagedPool, Length);
      if (RomImageBuffer == NULL)
      {
         return NULL;
      }

      IntAttachToCSRSS(&CallingProcess, &ApcState);
      RtlCopyMemory(RomImageBuffer, (PUCHAR)0xC0000, Length);
      IntDetachFromCSRSS(&CallingProcess, &ApcState);

      return RomImageBuffer;
   }
}

/*
 * @implemented
 */

BOOLEAN NTAPI
VideoPortScanRom(
   IN PVOID HwDeviceExtension,
   IN PUCHAR RomBase,
   IN ULONG RomLength,
   IN PUCHAR String)
{
   ULONG StringLength;
   BOOLEAN Found;
   PUCHAR SearchLocation;

   DPRINT("VideoPortScanRom RomBase %p RomLength 0x%x String %s\n", RomBase, RomLength, String);

   StringLength = strlen((PCHAR)String);
   Found = FALSE;
   SearchLocation = RomBase;
   for (SearchLocation = RomBase;
        !Found && SearchLocation < RomBase + RomLength - StringLength;
        SearchLocation++)
   {
      Found = (RtlCompareMemory(SearchLocation, String, StringLength) == StringLength);
      if (Found)
      {
         DPRINT("Match found at %p\n", SearchLocation);
      }
   }

   return Found;
}

/*
 * @implemented
 */

BOOLEAN NTAPI
VideoPortSynchronizeExecution(
   IN PVOID HwDeviceExtension,
   IN VIDEO_SYNCHRONIZE_PRIORITY Priority,
   IN PMINIPORT_SYNCHRONIZE_ROUTINE SynchronizeRoutine,
   OUT PVOID Context)
{
   BOOLEAN Ret;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   KIRQL OldIrql;

   switch (Priority)
   {
      case VpLowPriority:
         Ret = (*SynchronizeRoutine)(Context);
         break;

      case VpMediumPriority:
         DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
         if (DeviceExtension->InterruptObject == NULL)
            Ret = (*SynchronizeRoutine)(Context);
         else
            Ret = KeSynchronizeExecution(
               DeviceExtension->InterruptObject,
               SynchronizeRoutine,
               Context);
         break;

      case VpHighPriority:
         OldIrql = KeGetCurrentIrql();
         if (OldIrql < SYNCH_LEVEL)
            OldIrql = KfRaiseIrql(SYNCH_LEVEL);

         Ret = (*SynchronizeRoutine)(Context);

         if (OldIrql < SYNCH_LEVEL)
            KfLowerIrql(OldIrql);
         break;

      default:
         Ret = FALSE;
   }

   return Ret;
}

/*
 * @implemented
 */

VP_STATUS NTAPI
VideoPortEnumerateChildren(
   IN PVOID HwDeviceExtension,
   IN PVOID Reserved)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   ULONG Status;
   VIDEO_CHILD_ENUM_INFO ChildEnumInfo;
   VIDEO_CHILD_TYPE ChildType;
   BOOLEAN bHaveLastMonitorID = FALSE;
   UCHAR LastMonitorID[10];
   UCHAR ChildDescriptor[256];
   ULONG ChildId;
   ULONG Unused;
   INT i;

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   if (DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor == NULL)
   {
      DPRINT("Miniport's HwGetVideoChildDescriptor is NULL!\n");
      return NO_ERROR;
   }

   /* Setup the ChildEnumInfo */
   ChildEnumInfo.Size = sizeof (ChildEnumInfo);
   ChildEnumInfo.ChildDescriptorSize = sizeof (ChildDescriptor);
   ChildEnumInfo.ACPIHwId = 0;
   ChildEnumInfo.ChildHwDeviceExtension = NULL; /* FIXME: must be set to
                                                   ChildHwDeviceExtension... */

   /* Enumerate the children */
   for (i = 1; ; i++)
   {
      ChildEnumInfo.ChildIndex = i;
      RtlZeroMemory(ChildDescriptor, sizeof(ChildDescriptor));
      Status = DeviceExtension->DriverExtension->InitializationData.HwGetVideoChildDescriptor(
                  HwDeviceExtension,
                  &ChildEnumInfo,
                  &ChildType,
                  ChildDescriptor,
                  &ChildId,
                  &Unused);
      if (Status == VIDEO_ENUM_MORE_DEVICES)
      {
         if (ChildType == Monitor)
         {
            // Check if the EDID is valid
            if (ChildDescriptor[0] == 0x00 &&
                ChildDescriptor[1] == 0xFF &&
                ChildDescriptor[2] == 0xFF &&
                ChildDescriptor[3] == 0xFF &&
                ChildDescriptor[4] == 0xFF &&
                ChildDescriptor[5] == 0xFF &&
                ChildDescriptor[6] == 0xFF &&
                ChildDescriptor[7] == 0x00)
            {
               if (bHaveLastMonitorID)
               {
                  // Compare the previous monitor ID with the current one, break the loop if they are identical
                  if (RtlCompareMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID)) == sizeof(LastMonitorID))
                  {
                     DPRINT("Found identical Monitor ID two times, stopping enumeration\n");
                     break;
                  }
               }

               // Copy 10 bytes from the EDID, which can be used to uniquely identify the monitor
               RtlCopyMemory(LastMonitorID, &ChildDescriptor[8], sizeof(LastMonitorID));
               bHaveLastMonitorID = TRUE;
            }
         }
      }
      else if (Status == VIDEO_ENUM_INVALID_DEVICE)
      {
         DPRINT("Child device %d is invalid!\n", ChildEnumInfo.ChildIndex);
         continue;
      }
      else if (Status == VIDEO_ENUM_NO_MORE_DEVICES)
      {
         DPRINT("End of child enumeration! (%d children enumerated)\n", i - 1);
         break;
      }
      else
      {
         DPRINT("HwGetVideoChildDescriptor returned unknown status code 0x%x!\n", Status);
         break;
      }

#ifndef NDEBUG
      if (ChildType == Monitor)
      {
         INT j;
         PUCHAR p = ChildDescriptor;
         DPRINT("Monitor device enumerated! (ChildId = 0x%x)\n", ChildId);
         for (j = 0; j < sizeof (ChildDescriptor); j += 8)
         {
            DPRINT("%02x %02x %02x %02x %02x %02x %02x %02x\n",
                   p[j+0], p[j+1], p[j+2], p[j+3],
                   p[j+4], p[j+5], p[j+6], p[j+7]);
         }
      }
      else if (ChildType == Other)
      {
         DPRINT("\"Other\" device enumerated: DeviceId = %S\n", (PWSTR)ChildDescriptor);
      }
      else
      {
         DPRINT("HwGetVideoChildDescriptor returned unsupported type: %d\n", ChildType);
      }
#endif /* NDEBUG */

   }

   return NO_ERROR;
}

/*
 * @unimplemented
 */

VP_STATUS NTAPI
VideoPortCreateSecondaryDisplay(
   IN PVOID HwDeviceExtension,
   IN OUT PVOID *SecondaryDeviceExtension,
   IN ULONG Flag)
{
   DPRINT1("VideoPortCreateSecondaryDisplay: Unimplemented.\n");
   return NO_ERROR;
}

/*
 * @implemented
 */

BOOLEAN NTAPI
VideoPortQueueDpc(
   IN PVOID HwDeviceExtension,
   IN PMINIPORT_DPC_ROUTINE CallbackRoutine,
   IN PVOID Context)
{
   return KeInsertQueueDpc(
      &VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension)->DpcObject,
      (PVOID)CallbackRoutine,
      (PVOID)Context);
}

/*
 * @implemented
 */

PVOID NTAPI
VideoPortGetAssociatedDeviceExtension(IN PVOID DeviceObject)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;

   DPRINT("VideoPortGetAssociatedDeviceExtension\n");
   DeviceExtension = ((PDEVICE_OBJECT)DeviceObject)->DeviceExtension;
   if (!DeviceExtension)
      return NULL;
   return DeviceExtension->MiniPortDeviceExtension;
}

/*
 * @implemented
 */

VP_STATUS NTAPI
VideoPortGetVersion(
   IN PVOID HwDeviceExtension,
   IN OUT PVPOSVERSIONINFO VpOsVersionInfo)
{
   RTL_OSVERSIONINFOEXW Version;

   Version.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
   if (VpOsVersionInfo->Size >= sizeof(VPOSVERSIONINFO))
   {
#if 1
      if (NT_SUCCESS(RtlGetVersion((PRTL_OSVERSIONINFOW)&Version)))
      {
         VpOsVersionInfo->MajorVersion = Version.dwMajorVersion;
         VpOsVersionInfo->MinorVersion = Version.dwMinorVersion;
         VpOsVersionInfo->BuildNumber = Version.dwBuildNumber;
         VpOsVersionInfo->ServicePackMajor = Version.wServicePackMajor;
         VpOsVersionInfo->ServicePackMinor = Version.wServicePackMinor;
         return NO_ERROR;
      }
      return ERROR_INVALID_PARAMETER;
#else
      VpOsVersionInfo->MajorVersion = 5;
      VpOsVersionInfo->MinorVersion = 0;
      VpOsVersionInfo->BuildNumber = 2195;
      VpOsVersionInfo->ServicePackMajor = 4;
      VpOsVersionInfo->ServicePackMinor = 0;
      return NO_ERROR;
#endif
   }

   return ERROR_INVALID_PARAMETER;
}

/*
 * @implemented
 */

BOOLEAN NTAPI
VideoPortCheckForDeviceExistence(
   IN PVOID HwDeviceExtension,
   IN USHORT VendorId,
   IN USHORT DeviceId,
   IN UCHAR RevisionId,
   IN USHORT SubVendorId,
   IN USHORT SubSystemId,
   IN ULONG Flags)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PCI_DEVICE_PRESENT_INTERFACE PciDevicePresentInterface;
   IO_STATUS_BLOCK IoStatusBlock;
   IO_STACK_LOCATION IoStack;
   ULONG PciFlags = 0;
   NTSTATUS Status;
   BOOL DevicePresent;

   DPRINT("VideoPortCheckForDeviceExistence\n");

   if (Flags & ~(CDE_USE_REVISION | CDE_USE_SUBSYSTEM_IDS))
   {
       DPRINT1("VideoPortCheckForDeviceExistence: Unknown flags 0x%lx\n", Flags & ~(CDE_USE_REVISION | CDE_USE_SUBSYSTEM_IDS));
       return FALSE;
   }

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);

   PciDevicePresentInterface.Size = sizeof(PCI_DEVICE_PRESENT_INTERFACE);
   PciDevicePresentInterface.Version = 1;
   IoStack.Parameters.QueryInterface.Size = PciDevicePresentInterface.Size;
      IoStack.Parameters.QueryInterface.Version = PciDevicePresentInterface.Version;
      IoStack.Parameters.QueryInterface.Interface = (PINTERFACE)&PciDevicePresentInterface;
      IoStack.Parameters.QueryInterface.InterfaceType =
      &GUID_PCI_DEVICE_PRESENT_INTERFACE;
   Status = IopInitiatePnpIrp(DeviceExtension->NextDeviceObject,
      &IoStatusBlock, IRP_MN_QUERY_INTERFACE, &IoStack);
   if (!NT_SUCCESS(Status))
   {
      DPRINT("IopInitiatePnpIrp() failed! (Status 0x%lx)\n", Status);
      return FALSE;
   }

   if (Flags & CDE_USE_REVISION)
      PciFlags |= PCI_USE_REVISION;
   if (Flags & CDE_USE_SUBSYSTEM_IDS)
      PciFlags |= PCI_USE_SUBSYSTEM_IDS;

   DevicePresent = PciDevicePresentInterface.IsDevicePresent(
      VendorId, DeviceId, RevisionId,
      SubVendorId, SubSystemId, PciFlags);

   PciDevicePresentInterface.InterfaceDereference(PciDevicePresentInterface.Context);

   return DevicePresent;
}

/*
 * @unimplemented
 */

VP_STATUS NTAPI
VideoPortRegisterBugcheckCallback(
   IN PVOID HwDeviceExtension,
   IN ULONG BugcheckCode,
   IN PVOID Callback,
   IN ULONG BugcheckDataSize)
{
   DPRINT1("VideoPortRegisterBugcheckCallback(): Unimplemented.\n");
   return NO_ERROR;
}

/*
 * @implemented
 */

LONGLONG NTAPI
VideoPortQueryPerformanceCounter(
   IN PVOID HwDeviceExtension,
   OUT PLONGLONG PerformanceFrequency OPTIONAL)
{
   LARGE_INTEGER Result;

   DPRINT("VideoPortQueryPerformanceCounter\n");
   Result = KeQueryPerformanceCounter((PLARGE_INTEGER)PerformanceFrequency);
   return Result.QuadPart;
}

/*
 * @implemented
 */

VOID NTAPI
VideoPortAcquireDeviceLock(
   IN PVOID  HwDeviceExtension)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   NTSTATUS Status;
   (void)Status;

   DPRINT("VideoPortAcquireDeviceLock\n");
   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   Status = KeWaitForMutexObject(&DeviceExtension->DeviceLock, Executive,
                                 KernelMode, FALSE, NULL);
   // ASSERT(Status == STATUS_SUCCESS);
}

/*
 * @implemented
 */

VOID NTAPI
VideoPortReleaseDeviceLock(
   IN PVOID  HwDeviceExtension)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   LONG Status;
   (void)Status;

   DPRINT("VideoPortReleaseDeviceLock\n");
   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   Status = KeReleaseMutex(&DeviceExtension->DeviceLock, FALSE);
   //ASSERT(Status == 0);
}

/*
 * @unimplemented
 */

VOID NTAPI
VpNotifyEaData(
   IN PDEVICE_OBJECT DeviceObject,
   IN PVOID Data)
{
     DPRINT1("unimplemented VpNotifyEaData\n");
}

/*
 * @implemented
 */
PVOID NTAPI
VideoPortAllocateContiguousMemory(
   IN PVOID HwDeviceExtension,
   IN ULONG NumberOfBytes,
   IN PHYSICAL_ADDRESS HighestAcceptableAddress
    )
{

    return MmAllocateContiguousMemory(NumberOfBytes, HighestAcceptableAddress);
}

⌨️ 快捷键说明

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