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

📄 resource.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * VideoPort driver
 *
 * Copyright (C) 2002 - 2005 ReactOS Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; see the file COPYING.LIB.
 * If not, write to the Free Software Foundation,
 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * $Id: resource.c 21844 2006-05-07 19:34:23Z ion $
 */

#include "videoprt.h"

/* PRIVATE FUNCTIONS **********************************************************/

NTSTATUS NTAPI
IntVideoPortMapPhysicalMemory(
   IN HANDLE Process,
   IN PHYSICAL_ADDRESS PhysicalAddress,
   IN ULONG SizeInBytes,
   IN ULONG Protect,
   IN OUT PVOID *VirtualAddress  OPTIONAL)
{
   OBJECT_ATTRIBUTES ObjAttribs;
   UNICODE_STRING UnicodeString;
   HANDLE hMemObj;
   NTSTATUS Status;
   SIZE_T Size;

   /* Initialize object attribs */
   RtlInitUnicodeString(&UnicodeString, L"\\Device\\PhysicalMemory");
   InitializeObjectAttributes(&ObjAttribs,
                              &UnicodeString,
                              OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                              NULL, NULL);

   /* Open physical memory section */
   Status = ZwOpenSection(&hMemObj, SECTION_ALL_ACCESS, &ObjAttribs);
   if (!NT_SUCCESS(Status))
   {
      DPRINT("ZwOpenSection() failed! (0x%x)\n", Status);
      return Status;
   }

   /* Map view of section */
   Size = SizeInBytes;
   Status = ZwMapViewOfSection(hMemObj,
                               Process,
                               VirtualAddress,
                               0,
                               Size,
                               (PLARGE_INTEGER)(&PhysicalAddress),
                               &Size,
                               ViewUnmap,
                               0,
                               Protect);
   ZwClose(hMemObj);
   if (!NT_SUCCESS(Status))
   {
      DPRINT("ZwMapViewOfSection() failed! (0x%x)\n", Status);
   }

   return Status;
}


PVOID NTAPI
IntVideoPortMapMemory(
   IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
   IN PHYSICAL_ADDRESS IoAddress,
   IN ULONG NumberOfUchars,
   IN UCHAR InIoSpace,
   IN HANDLE ProcessHandle,
   OUT VP_STATUS *Status)
{
   PHYSICAL_ADDRESS TranslatedAddress;
   PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
   ULONG AddressSpace;
   PVOID MappedAddress;
   PLIST_ENTRY Entry;

   DPRINT("- IoAddress: %lx\n", IoAddress.u.LowPart);
   DPRINT("- NumberOfUchars: %lx\n", NumberOfUchars);
   DPRINT("- InIoSpace: %x\n", InIoSpace);

   InIoSpace &= ~VIDEO_MEMORY_SPACE_DENSE;
   if ((InIoSpace & VIDEO_MEMORY_SPACE_P6CACHE) != 0)
   {
      DPRINT("VIDEO_MEMORY_SPACE_P6CACHE not supported, turning off\n");
      InIoSpace &= ~VIDEO_MEMORY_SPACE_P6CACHE;
   }

   if (ProcessHandle != NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
   {
      DPRINT("ProcessHandle is not NULL (0x%x) but InIoSpace does not have "
             "VIDEO_MEMORY_SPACE_USER_MODE set! Setting "
             "VIDEO_MEMORY_SPACE_USER_MODE.\n",
             ProcessHandle);
      InIoSpace |= VIDEO_MEMORY_SPACE_USER_MODE;
   }
   else if (ProcessHandle == NULL && (InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
   {
      DPRINT("ProcessHandle is NULL (0x%x) but InIoSpace does have "
             "VIDEO_MEMORY_SPACE_USER_MODE set! Setting ProcessHandle "
             "to NtCurrentProcess()\n",
             ProcessHandle);
      ProcessHandle = NtCurrentProcess();
   }

   if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0 &&
       !IsListEmpty(&DeviceExtension->AddressMappingListHead))
   {
      Entry = DeviceExtension->AddressMappingListHead.Flink;
      while (Entry != &DeviceExtension->AddressMappingListHead)
      {
         AddressMapping = CONTAINING_RECORD(
            Entry,
            VIDEO_PORT_ADDRESS_MAPPING,
            List);
         if (IoAddress.QuadPart == AddressMapping->IoAddress.QuadPart &&
             NumberOfUchars <= AddressMapping->NumberOfUchars)
         {
            {
               AddressMapping->MappingCount++;
               if (Status)
                  *Status = NO_ERROR;
               return AddressMapping->MappedAddress;
            }
         }
         Entry = Entry->Flink;
      }
   }

   AddressSpace = (ULONG)InIoSpace;
   AddressSpace &= ~VIDEO_MEMORY_SPACE_USER_MODE;
   if (HalTranslateBusAddress(
          DeviceExtension->AdapterInterfaceType,
          DeviceExtension->SystemIoBusNumber,
          IoAddress,
          &AddressSpace,
          &TranslatedAddress) == FALSE)
   {
      if (Status)
         *Status = ERROR_NOT_ENOUGH_MEMORY;

      return NULL;
   }

   /* I/O space */
   if (AddressSpace != 0)
   {
      ASSERT(0 == TranslatedAddress.u.HighPart);
      if (Status)
         *Status = NO_ERROR;

      return (PVOID)TranslatedAddress.u.LowPart;
   }

   /* user space */
   if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) != 0)
   {
      NTSTATUS NtStatus;
      MappedAddress = NULL;
      NtStatus = IntVideoPortMapPhysicalMemory(ProcessHandle,
                                               TranslatedAddress,
                                               NumberOfUchars,
                                               PAGE_READWRITE/* | PAGE_WRITECOMBINE*/,
                                               &MappedAddress);
      if (!NT_SUCCESS(NtStatus))
      {
         DPRINT("IntVideoPortMapPhysicalMemory() failed! (0x%x)\n", NtStatus);
         if (Status)
            *Status = NO_ERROR;
         return NULL;
      }
      DPRINT("Mapped user address = 0x%08x\n", MappedAddress);
   }
   else /* kernel space */
   {
      MappedAddress = MmMapIoSpace(
         TranslatedAddress,
         NumberOfUchars,
         MmNonCached);
   }

   if (MappedAddress != NULL)
   {
      if (Status)
      {
         *Status = NO_ERROR;
      }
      if ((InIoSpace & VIDEO_MEMORY_SPACE_USER_MODE) == 0)
      {
         AddressMapping = ExAllocatePoolWithTag(
            PagedPool,
            sizeof(VIDEO_PORT_ADDRESS_MAPPING),
            TAG_VIDEO_PORT);

         if (AddressMapping == NULL)
            return MappedAddress;

         RtlZeroMemory(AddressMapping, sizeof(VIDEO_PORT_ADDRESS_MAPPING));
         AddressMapping->NumberOfUchars = NumberOfUchars;
         AddressMapping->IoAddress = IoAddress;
         AddressMapping->SystemIoBusNumber = DeviceExtension->SystemIoBusNumber;
         AddressMapping->MappedAddress = MappedAddress;
         AddressMapping->MappingCount = 1;
         InsertHeadList(
            &DeviceExtension->AddressMappingListHead,
            &AddressMapping->List);
      }

      return MappedAddress;
   }

   if (Status)
      *Status = NO_ERROR;

   return NULL;
}

VOID NTAPI
IntVideoPortUnmapMemory(
   IN PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension,
   IN PVOID MappedAddress)
{
   PVIDEO_PORT_ADDRESS_MAPPING AddressMapping;
   PLIST_ENTRY Entry;
   NTSTATUS Status;

   Entry = DeviceExtension->AddressMappingListHead.Flink;
   while (Entry != &DeviceExtension->AddressMappingListHead)
   {
      AddressMapping = CONTAINING_RECORD(
         Entry,
         VIDEO_PORT_ADDRESS_MAPPING,
         List);
      if (AddressMapping->MappedAddress == MappedAddress)
      {
         ASSERT(AddressMapping->MappingCount > 0);
         AddressMapping->MappingCount--;
         if (AddressMapping->MappingCount == 0)
         {
            MmUnmapIoSpace(
               AddressMapping->MappedAddress,
               AddressMapping->NumberOfUchars);
            RemoveEntryList(Entry);
            ExFreePool(AddressMapping);
         }
         return;
      }

      Entry = Entry->Flink;
   }

   /* If there was no kernelmode mapping for the given address found we assume
    * that the given address is a usermode mapping and try to unmap it.
    *
    * FIXME: Is it ok to use NtCurrentProcess?
    */
   Status = ZwUnmapViewOfSection(NtCurrentProcess(), MappedAddress);
   if (!NT_SUCCESS(Status))
   {
      DPRINT1("Warning: Mapping for address 0x%x not found!\n", (ULONG)MappedAddress);
   }
}

/* PUBLIC FUNCTIONS ***********************************************************/

/*
 * @implemented
 */

PVOID NTAPI
VideoPortGetDeviceBase(
   IN PVOID HwDeviceExtension,
   IN PHYSICAL_ADDRESS IoAddress,
   IN ULONG NumberOfUchars,
   IN UCHAR InIoSpace)
{
   DPRINT("VideoPortGetDeviceBase\n");
   return IntVideoPortMapMemory(
      VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
      IoAddress,
      NumberOfUchars,
      InIoSpace,
      NULL,
      NULL);
}

/*
 * @implemented
 */

VOID NTAPI
VideoPortFreeDeviceBase(
   IN PVOID HwDeviceExtension,
   IN PVOID MappedAddress)
{
   DPRINT("VideoPortFreeDeviceBase\n");
   IntVideoPortUnmapMemory(
      VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
      MappedAddress);
}

/*
 * @unimplemented
 */

VP_STATUS NTAPI
VideoPortMapBankedMemory(
   IN PVOID HwDeviceExtension,
   IN PHYSICAL_ADDRESS PhysicalAddress,
   IN PULONG Length,
   IN PULONG InIoSpace,
   OUT PVOID *VirtualAddress,
   IN ULONG BankLength,
   IN UCHAR ReadWriteBank,
   IN PBANKED_SECTION_ROUTINE BankRoutine,
   IN PVOID Context)
{
   DPRINT("VideoPortMapBankedMemory\n");
   UNIMPLEMENTED;
   return ERROR_CALL_NOT_IMPLEMENTED;
}


/*
 * @implemented
 */

VP_STATUS NTAPI
VideoPortMapMemory(
   IN PVOID HwDeviceExtension,
   IN PHYSICAL_ADDRESS PhysicalAddress,
   IN PULONG Length,
   IN PULONG InIoSpace,
   OUT PVOID *VirtualAddress)
{
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   NTSTATUS Status;

   DPRINT("VideoPortMapMemory\n");
   DPRINT("- *VirtualAddress: 0x%x\n", *VirtualAddress);

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);
   *VirtualAddress = IntVideoPortMapMemory(
      DeviceExtension,
      PhysicalAddress,
      *Length,
      *InIoSpace,
      (HANDLE)*VirtualAddress,
      &Status);

   return Status;
}

/*
 * @implemented
 */

VP_STATUS NTAPI
VideoPortUnmapMemory(
   IN PVOID HwDeviceExtension,
   IN PVOID VirtualAddress,
   IN HANDLE ProcessHandle)
{
   DPRINT("VideoPortFreeDeviceBase\n");

   IntVideoPortUnmapMemory(
      VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension),
      VirtualAddress);

   return NO_ERROR;
}

/*
 * @implemented
 */

VP_STATUS NTAPI
VideoPortGetAccessRanges(
   IN PVOID HwDeviceExtension,
   IN ULONG NumRequestedResources,
   IN PIO_RESOURCE_DESCRIPTOR RequestedResources OPTIONAL,
   IN ULONG NumAccessRanges,
   IN PVIDEO_ACCESS_RANGE AccessRanges,
   IN PVOID VendorId,
   IN PVOID DeviceId,
   IN PULONG Slot)
{
   PCI_SLOT_NUMBER PciSlotNumber;
   ULONG FunctionNumber;
   PCI_COMMON_CONFIG Config;
   PCM_RESOURCE_LIST AllocatedResources;
   NTSTATUS Status;
   UINT AssignedCount;
   CM_FULL_RESOURCE_DESCRIPTOR *FullList;
   CM_PARTIAL_RESOURCE_DESCRIPTOR *Descriptor;
   PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension;
   USHORT VendorIdToFind;
   USHORT DeviceIdToFind;
   ULONG SlotIdToFind;
   ULONG ReturnedLength;

   DPRINT("VideoPortGetAccessRanges\n");

   DeviceExtension = VIDEO_PORT_GET_DEVICE_EXTENSION(HwDeviceExtension);

⌨️ 快捷键说明

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