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

📄 agp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:

      Status = ZwFreeVirtualMemory(VirtualMapping->ProcessHandle,
                                   &BaseAddress,
                                   &Size, MEM_RELEASE);
      if (!NT_SUCCESS(Status))
      {
         DPRINT1("Warning: ZwFreeVirtualMemory() failed: Status = 0x%x\n", Status);
         return NULL;
      }
      ASSERT(Size == Pages * PAGE_SIZE);
      ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                               OffsetInBytes));
      
      /* Map the physical memory into the released virtual memory area */
      Status = IntVideoPortMapPhysicalMemory(VirtualMapping->ProcessHandle,
                                             PhysicalAddress,
                                             Size,
                                             PAGE_READWRITE,
                                             &BaseAddress);
      if (!NT_SUCCESS(Status))
      {
         DPRINT1("Warning: IntVideoPortMapPhysicalMemory() failed: Status = 0x%x\n", Status);
         /* Reserve the released virtual memory area again */
         Status = ZwAllocateVirtualMemory(VirtualMapping->ProcessHandle,
                                          &BaseAddress, 0, &Size, MEM_RESERVE,
                                          PAGE_NOACCESS);
         if (!NT_SUCCESS(Status))
         {
            DPRINT1("Warning: ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
            /* FIXME: What to do now?? */
            ASSERT(0);
            return NULL;
         }
         ASSERT(Size == Pages * PAGE_SIZE);
         ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                               OffsetInBytes));
         return NULL;
      }
      ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                               OffsetInBytes));
   }

   return BaseAddress;
}

VOID NTAPI
IntAgpFreeVirtual(
   IN PVOID HwDeviceExtension,
   IN PVOID VirtualContext,
   IN ULONG Pages,
   IN ULONG Offset)
{
   PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
   PVOID BaseAddress = NULL;
   NTSTATUS Status;

   DPRINT("AgpFreeVirtual - VirtualContext: 0x%x Pages: %d, Offset: 0x%x\n",
          VirtualContext, Pages, Offset);

   VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;

   if (VirtualMapping->ProcessHandle == NULL)
   {
      /* FIXME: not implemented */
   }
   else /* ProcessHandle != NULL */
   {
      /* Unmap the section view */
      ULONG Size = Pages * PAGE_SIZE;
      ULONG OffsetInBytes = Offset * PAGE_SIZE;
      BaseAddress = (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                       OffsetInBytes);

      Status = ZwUnmapViewOfSection(VirtualMapping->ProcessHandle, BaseAddress);
      if (!NT_SUCCESS(Status))
      {
         DPRINT1("Warning: ZwUnmapViewOfSection() failed: Status = 0x%x\n", Status);
         /* FIXME: What to do now?? */
         ASSERT(0);
         return;
      }

      /* And reserve the virtual memory area again */
      Status = ZwAllocateVirtualMemory(VirtualMapping->ProcessHandle,
                                       &BaseAddress, 0, &Size, MEM_RESERVE,
                                       PAGE_NOACCESS);
      if (!NT_SUCCESS(Status))
      {
         DPRINT1("Warning: ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
         /* FIXME: What to do now?? */
         ASSERT(0);
         return;
      }
      ASSERT(Size == Pages * PAGE_SIZE);
      ASSERT(BaseAddress == (PVOID)((ULONG_PTR)VirtualMapping->MappedAddress +
                                               OffsetInBytes));
   }
}

VOID NTAPI
IntAgpReleaseVirtual(
   IN PVOID HwDeviceExtension,
   IN PVOID VirtualContext)
{
   PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
   NTSTATUS Status;

   DPRINT("AgpReleaseVirtual - VirtualContext: 0x%x\n", VirtualContext);

   VirtualMapping = (PVIDEO_PORT_AGP_VIRTUAL_MAPPING)VirtualContext;
   
   /* Release the virtual memory */
   if (VirtualMapping->ProcessHandle == NULL)
   {
      /* FIXME: not implemented */
   }
   else /* ProcessHandle != NULL */
   {
      /* Release the allocated virtual memory */
      ULONG Size = VirtualMapping->AgpMapping->NumberOfPages * PAGE_SIZE;
      Status = ZwFreeVirtualMemory(VirtualMapping->ProcessHandle,
                                   &VirtualMapping->MappedAddress,
                                   &Size, MEM_RELEASE);
      if (!NT_SUCCESS(Status))
      {
         DPRINT1("Warning: ZwFreeVirtualMemory() failed: Status = 0x%x\n", Status);
      }
   }
   
   /* Free resources */
   ExFreePool(VirtualMapping);
}

PVOID NTAPI
IntAgpReserveVirtual(
   IN  PVOID HwDeviceExtension,
   IN  HANDLE ProcessHandle,
   IN  PVOID PhysicalContext,
   OUT PVOID *VirtualContext)
{
   PVIDEO_PORT_AGP_MAPPING AgpMapping;
   PVIDEO_PORT_AGP_VIRTUAL_MAPPING VirtualMapping;
   PVOID MappedAddress;
   NTSTATUS Status;

   DPRINT("AgpReserveVirtual - ProcessHandle: 0x%x PhysicalContext: 0x%x\n",
          ProcessHandle, PhysicalContext);

   AgpMapping = (PVIDEO_PORT_AGP_MAPPING)PhysicalContext;

   /* Allocate an AGP virtual mapping structure */
   VirtualMapping = ExAllocatePoolWithTag(PagedPool,
                                          sizeof(VIDEO_PORT_AGP_VIRTUAL_MAPPING),
                                          TAG_VIDEO_PORT);
   if (VirtualMapping == NULL)
   {
      DPRINT1("Out of memory! Couldn't allocate AGP virtual mapping structure!\n");
      return NULL;
   }
   RtlZeroMemory(VirtualMapping, sizeof(VIDEO_PORT_AGP_VIRTUAL_MAPPING));

   /* Reserve a virtual memory area for the physical pages. */
   if (ProcessHandle == NULL)
   {
      /* FIXME: What to do in this case? */
      ExFreePool(VirtualMapping);
      return NULL;
   }
   else /* ProcessHandle != NULL */
   {
      /* Reserve memory for usermode */
      ULONG Size = AgpMapping->NumberOfPages * PAGE_SIZE;
      MappedAddress = NULL;
      Status = ZwAllocateVirtualMemory(ProcessHandle, &MappedAddress, 0, &Size,
                                       MEM_RESERVE, PAGE_NOACCESS);
      if (!NT_SUCCESS(Status))
      {
         ExFreePool(VirtualMapping);
         DPRINT("ZwAllocateVirtualMemory() failed: Status = 0x%x\n", Status);
         return NULL;
      }
   }

   /* Fill the AGP virtual mapping */
   VirtualMapping->AgpMapping = AgpMapping;
   VirtualMapping->ProcessHandle = ProcessHandle;
   VirtualMapping->MappedAddress = MappedAddress;

   *VirtualContext = (PVOID)VirtualMapping;
   return MappedAddress;
}


BOOLEAN NTAPI
IntAgpSetRate(
   IN PVOID HwDeviceExtension,
   IN ULONG Rate)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;

   DPRINT("AgpSetRate - Rate: %d\n", Rate);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;
   
   return NT_SUCCESS(AgpBusInterface->SetRate(AgpBusInterface->AgpContext, Rate));
}


NTSTATUS NTAPI
IntAgpGetInterface(
   IN PVOID HwDeviceExtension,
   IN OUT PINTERFACE Interface)
{
   IO_STATUS_BLOCK IoStatusBlock;
   IO_STACK_LOCATION IoStack;
   NTSTATUS Status;
   PVIDEO_PORT_AGP_INTERFACE_2 AgpInterface;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   PAGP_BUS_INTERFACE_STANDARD AgpBusInterface;

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   AgpBusInterface = &DeviceExtension->AgpInterface;
   AgpInterface = (PVIDEO_PORT_AGP_INTERFACE_2)Interface;

   ASSERT((Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_2 &&
           Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE_2)) ||
          (Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_1 &&
           Interface->Size >= sizeof(VIDEO_PORT_AGP_INTERFACE)));

   if (DeviceExtension->NextDeviceObject == NULL)
   {
      DPRINT("DeviceExtension->NextDeviceObject is NULL!\n");
      return STATUS_UNSUCCESSFUL;
   }

   /* Query the interface from the AGP bus driver */
   if (DeviceExtension->AgpInterface.Size == 0)
   {
      AgpBusInterface->Size = sizeof(AGP_BUS_INTERFACE_STANDARD);
      if (Interface->Version == VIDEO_PORT_AGP_INTERFACE_VERSION_1)
         AgpBusInterface->Version = AGP_BUS_INTERFACE_V1;
      else /* if (InterfaceVersion == VIDEO_PORT_AGP_INTERFACE_VERSION_2) */
         AgpBusInterface->Version = AGP_BUS_INTERFACE_V2;
      IoStack.Parameters.QueryInterface.Size = AgpBusInterface->Size;
      IoStack.Parameters.QueryInterface.Version = AgpBusInterface->Version;
      IoStack.Parameters.QueryInterface.Interface = (PINTERFACE)AgpBusInterface;
      IoStack.Parameters.QueryInterface.InterfaceType =
         &GUID_AGP_TARGET_BUS_INTERFACE_STANDARD;
      Status = IopInitiatePnpIrp(DeviceExtension->NextDeviceObject,
         &IoStatusBlock, IRP_MN_QUERY_INTERFACE, &IoStack);
      if (!NT_SUCCESS(Status))
      {
         DPRINT("IopInitiatePnpIrp() failed! (Status 0x%x)\n", Status);
         return Status;
      }
      DPRINT("Got AGP driver interface!\n");
   }

   /* FIXME: Not sure if we should wrap the reference/dereference functions */
   AgpInterface->Context = AgpBusInterface->AgpContext;
   AgpInterface->InterfaceReference = AgpBusInterface->InterfaceReference;
   AgpInterface->InterfaceDereference = AgpBusInterface->InterfaceDereference;
   AgpInterface->AgpReservePhysical = IntAgpReservePhysical;
   AgpInterface->AgpReleasePhysical = IntAgpReleasePhysical;
   AgpInterface->AgpCommitPhysical = IntAgpCommitPhysical;
   AgpInterface->AgpFreePhysical = IntAgpFreePhysical;
   AgpInterface->AgpReserveVirtual = IntAgpReserveVirtual;
   AgpInterface->AgpReleaseVirtual = IntAgpReleaseVirtual;
   AgpInterface->AgpCommitVirtual = IntAgpCommitVirtual;
   AgpInterface->AgpFreeVirtual = IntAgpFreeVirtual;
   AgpInterface->AgpAllocationLimit = 0x1000000; /* FIXME: using 16 MB for now */

   if (AgpInterface->Version >= VIDEO_PORT_AGP_INTERFACE_VERSION_2)
   {
      AgpInterface->AgpSetRate = IntAgpSetRate;
   }

   return STATUS_SUCCESS;
}

⌨️ 快捷键说明

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