Esempio n. 1
0
static int OpenPhysMem() {
    NTSTATUS status;
    UNICODE_STRING name;
    OBJECT_ATTRIBUTES attr;

    RtlInitUnicodeString(&name,L"\\device\\physicalmemory");
    InitializeObjectAttributes(&attr,&name,OBJ_CASE_INSENSITIVE,NULL,NULL);
    status = ZwOpenSection(&mem_fd,SECTION_MAP_READ,&attr);

    if (!NT_SUCCESS(status))
        return 1;

    return 0;
}
Esempio n. 2
0
/*
 * @implemented
 */
HANDLE
NTAPI
OpenFileMappingW(DWORD dwDesiredAccess,
                 BOOL bInheritHandle,
                 LPCWSTR lpName)
{
    NTSTATUS Status;
    HANDLE SectionHandle;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING UnicodeName;

    /* We need a name */
    if (!lpName)
    {
        /* Otherwise, fail */
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }

    /* Convert attributes */
    RtlInitUnicodeString(&UnicodeName, lpName);
    InitializeObjectAttributes(&ObjectAttributes,
                               &UnicodeName,
                               (bInheritHandle ? OBJ_INHERIT : 0),
                               hBaseDir,
                               NULL);

    /* Convert COPY to READ */
    if (dwDesiredAccess == FILE_MAP_COPY) dwDesiredAccess = FILE_MAP_READ;

    /* Open the section */
    Status = ZwOpenSection(&SectionHandle,
                           dwDesiredAccess,
                           &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        /* We failed */
        BaseSetLastNTError(Status);
        return NULL;
    }

    SetLastError(ERROR_SUCCESS);
    /* Otherwise, return the handle */
    return SectionHandle;
}
Esempio n. 3
0
NTSTATUS
NTAPI
IntInitializeVideoAddressSpace(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
    NTSTATUS Status;
    HANDLE PhysMemHandle;
    PVOID BaseAddress;
    LARGE_INTEGER Offset;
    SIZE_T ViewSize;
    CHAR IVTAndBda[1024+256];

    /* Free the 1MB pre-reserved region. In reality, ReactOS should simply support us mapping the view into the reserved area, but it doesn't. */
    BaseAddress = 0;
    ViewSize = 1024 * 1024;
    Status = ZwFreeVirtualMemory(NtCurrentProcess(),
                                 &BaseAddress,
                                 &ViewSize,
                                 MEM_RELEASE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't unmap reserved memory (%x)\n", Status);
        return 0;
    }

    /* Open the physical memory section */
    InitializeObjectAttributes(&ObjectAttributes,
                               &PhysMemName,
                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenSection(&PhysMemHandle,
                           SECTION_ALL_ACCESS,
                           &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
        return Status;
    }

    /* Map the BIOS and device registers into the address space */
    Offset.QuadPart = 0xa0000;
    ViewSize = 0x100000 - 0xa0000;
    BaseAddress = (PVOID)0xa0000;
    Status = ZwMapViewOfSection(PhysMemHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                ViewSize,
                                &Offset,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't map physical memory (%x)\n", Status);
        ZwClose(PhysMemHandle);
        return Status;
    }

    /* Close physical memory section handle */
    ZwClose(PhysMemHandle);

    if (BaseAddress != (PVOID)0xa0000)
    {
        DPRINT1("Couldn't map physical memory at the right address (was %x)\n",
                BaseAddress);
        return STATUS_UNSUCCESSFUL;
    }

    /* Allocate some low memory to use for the non-BIOS
     * parts of the v86 mode address space
     */
    BaseAddress = (PVOID)0x1;
    ViewSize = 0xa0000 - 0x1000;
    Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
                                     &BaseAddress,
                                     0,
                                     &ViewSize,
                                     MEM_RESERVE | MEM_COMMIT,
                                     PAGE_EXECUTE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Failed to allocate virtual memory (Status %x)\n", Status);
        return Status;
    }
    if (BaseAddress != (PVOID)0x0)
    {
        DPRINT1("Failed to allocate virtual memory at right address (was %x)\n",
                BaseAddress);
        return 0;
    }

    /* Get the real mode IVT and BDA from the kernel */
    Status = NtVdmControl(VdmInitialize, IVTAndBda);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("NtVdmControl failed (status %x)\n", Status);
        return Status;
    }

    /* Return success */
    return STATUS_SUCCESS;
}
Esempio n. 4
0
NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,
                                        ULONG PhysMemSizeInBytes,
                                        PVOID *ppPhysMemLin,
                                        HANDLE *pPhysicalMemoryHandle)
{
  UNICODE_STRING     PhysicalMemoryUnicodeString;
  PVOID              PhysicalMemorySection = NULL;
  OBJECT_ATTRIBUTES  ObjectAttributes;
  PHYSICAL_ADDRESS   ViewBase;
  NTSTATUS           ntStatus;
  PHYSICAL_ADDRESS   pStartPhysAddress;
  PHYSICAL_ADDRESS   pEndPhysAddress;
  PHYSICAL_ADDRESS   MappingLength;
  BOOLEAN            Result1, Result2;
  ULONG              IsIOSpace;
  unsigned char     *pbPhysMemLin = NULL;

  OutputDebugString ("Entering MapPhysicalMemoryToLinearSpace");

  RtlInitUnicodeString (&PhysicalMemoryUnicodeString,
                        L"\\Device\\PhysicalMemory");

  InitializeObjectAttributes (&ObjectAttributes,
                              &PhysicalMemoryUnicodeString,
                              OBJ_CASE_INSENSITIVE,
                              (HANDLE) NULL,
                              (PSECURITY_DESCRIPTOR) NULL);

  *pPhysicalMemoryHandle = NULL;

  ntStatus = ZwOpenSection (pPhysicalMemoryHandle,
                            SECTION_ALL_ACCESS,
                            &ObjectAttributes);

  if (NT_SUCCESS(ntStatus))
  {

    ntStatus = ObReferenceObjectByHandle (*pPhysicalMemoryHandle,
                                          SECTION_ALL_ACCESS,
                                          (POBJECT_TYPE) NULL,
                                          KernelMode,
                                          &PhysicalMemorySection,
                                          (POBJECT_HANDLE_INFORMATION) NULL);

    if (NT_SUCCESS(ntStatus))
    {

      pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress;

      pEndPhysAddress = RtlLargeIntegerAdd (pStartPhysAddress,
                                            RtlConvertUlongToLargeInteger(PhysMemSizeInBytes));

      IsIOSpace = 0;

      Result1 = HalTranslateBusAddress (1, 0, pStartPhysAddress, &IsIOSpace, &pStartPhysAddress);

      IsIOSpace = 0;

      Result2 = HalTranslateBusAddress (1, 0, pEndPhysAddress, &IsIOSpace, &pEndPhysAddress);

      if (Result1 && Result2)
      {

        MappingLength = RtlLargeIntegerSubtract (pEndPhysAddress, pStartPhysAddress);

        if (MappingLength.LowPart)
        {
        
          // Let ZwMapViewOfSection pick a linear address

          PhysMemSizeInBytes = MappingLength.LowPart;

          ViewBase = pStartPhysAddress;

          ntStatus = ZwMapViewOfSection (*pPhysicalMemoryHandle,
                                         (HANDLE) -1,
                                         &pbPhysMemLin,
                                         0L,
                                         PhysMemSizeInBytes,
                                         &ViewBase,
                                         &PhysMemSizeInBytes,
                                         ViewShare,
                                         0,
                                         PAGE_READWRITE | PAGE_NOCACHE);

          if (!NT_SUCCESS(ntStatus))
            OutputDebugString ("ERROR: ZwMapViewOfSection failed");
          else
          {
            pbPhysMemLin += (ULONG)pStartPhysAddress.LowPart - (ULONG)ViewBase.LowPart;
            *ppPhysMemLin = pbPhysMemLin;
          }  
        }
        else
          OutputDebugString ("ERROR: RtlLargeIntegerSubtract failed");
      }
      else
        OutputDebugString ("ERROR: MappingLength = 0");
    }
    else
      OutputDebugString ("ERROR: ObReferenceObjectByHandle failed");
  }
  else
    OutputDebugString ("ERROR: ZwOpenSection failed");
    
  if (!NT_SUCCESS(ntStatus))
    ZwClose(*pPhysicalMemoryHandle);
  
  OutputDebugString ("Leaving MapPhysicalMemoryToLinearSpace");

  return ntStatus;
}
Esempio n. 5
0
static
VOID
TestPhysicalMemorySection(VOID)
{
    NTSTATUS Status;
    UNICODE_STRING SectionName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE SectionHandle;
    PVOID SectionObject;
    PUCHAR MyPage;
    PHYSICAL_ADDRESS MyPagePhysical;
    PUCHAR ZeroPageContents;
    PHYSICAL_ADDRESS ZeroPagePhysical;
    PVOID Mapping;
    PUCHAR MappingBytes;
    SIZE_T ViewSize;
    SIZE_T EqualBytes;

    MyPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPmK');
    if (skip(MyPage != NULL, "Out of memory\n"))
        return;
    MyPagePhysical = MmGetPhysicalAddress(MyPage);
    RtlFillMemory(MyPage + 0 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x23);
    RtlFillMemory(MyPage + 1 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x67);
    RtlFillMemory(MyPage + 2 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xab);
    RtlFillMemory(MyPage + 3 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xef);

    ZeroPageContents = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'ZPmK');
    if (skip(ZeroPageContents != NULL, "Out of memory\n"))
    {
        ExFreePoolWithTag(MyPage, 'MPmK');
        return;
    }
    ZeroPagePhysical.QuadPart = 0;

    Mapping = MmMapIoSpace(ZeroPagePhysical, PAGE_SIZE, MmCached);
    if (skip(Mapping != NULL, "Failed to map zero page\n"))
    {
        ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
        ExFreePoolWithTag(MyPage, 'MPmK');
        return;
    }

    RtlCopyMemory(ZeroPageContents, Mapping, PAGE_SIZE);
    MmUnmapIoSpace(Mapping, PAGE_SIZE);

    InitializeObjectAttributes(&ObjectAttributes,
                               &SectionName,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
    ok_eq_hex(Status, STATUS_SUCCESS);
    if (!skip(NT_SUCCESS(Status), "No section\n"))
    {
        /* Map zero page and compare */
        Mapping = NULL;
        ViewSize = PAGE_SIZE;
        Status = ZwMapViewOfSection(SectionHandle,
                                    ZwCurrentProcess(),
                                    &Mapping,
                                    0,
                                    0,
                                    &ZeroPagePhysical,
                                    &ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (!skip(NT_SUCCESS(Status), "No view\n"))
        {
            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
            EqualBytes = RtlCompareMemory(Mapping,
                                          ZeroPageContents,
                                          PAGE_SIZE);
            ok_eq_size(EqualBytes, PAGE_SIZE);
            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
            ok_eq_hex(Status, STATUS_SUCCESS);
        }

        /* Map the zero page non-cached */
        Mapping = NULL;
        ViewSize = PAGE_SIZE;
        Status = ZwMapViewOfSection(SectionHandle,
                                    ZwCurrentProcess(),
                                    &Mapping,
                                    0,
                                    0,
                                    &ZeroPagePhysical,
                                    &ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE | PAGE_NOCACHE);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (!skip(NT_SUCCESS(Status), "No view\n"))
        {
            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
            EqualBytes = RtlCompareMemory(Mapping,
                                          ZeroPageContents,
                                          PAGE_SIZE);
            ok_eq_size(EqualBytes, PAGE_SIZE);
            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
            ok_eq_hex(Status, STATUS_SUCCESS);
        }

        /* Map our NP page, compare, and check that modifications are reflected */
        Mapping = NULL;
        ViewSize = PAGE_SIZE;
        Status = ZwMapViewOfSection(SectionHandle,
                                    ZwCurrentProcess(),
                                    &Mapping,
                                    0,
                                    0,
                                    &MyPagePhysical,
                                    &ViewSize,
                                    ViewUnmap,
                                    0,
                                    PAGE_READWRITE);
        ok_eq_hex(Status, STATUS_SUCCESS);
        if (!skip(NT_SUCCESS(Status), "No view\n"))
        {
            ok((LONG_PTR)Mapping > 0, "Mapping = %p\n", Mapping);
            EqualBytes = RtlCompareMemory(Mapping,
                                          MyPage,
                                          PAGE_SIZE);
            ok_eq_size(EqualBytes, PAGE_SIZE);

            MappingBytes = Mapping;
            ok(MappingBytes[5] == 0x23, "Mapping[5] = 0x%x\n", MappingBytes[5]);
            ok(MyPage[5] == 0x23, "MyPage[5] = 0x%x\n", MyPage[5]);

            MyPage[5] = 0x44;
            ok(MappingBytes[5] == 0x44, "Mapping[5] = 0x%x\n", MappingBytes[5]);
            ok(MyPage[5] == 0x44, "MyPage[5] = 0x%x\n", MyPage[5]);

            MappingBytes[5] = 0x88;
            ok(MappingBytes[5] == 0x88, "Mapping[5] = 0x%x\n", MappingBytes[5]);
            ok(MyPage[5] == 0x88, "MyPage[5] = 0x%x\n", MyPage[5]);

            Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
            ok_eq_hex(Status, STATUS_SUCCESS);
        }

        Status = ZwClose(SectionHandle);
        ok_eq_hex(Status, STATUS_SUCCESS);
    }

    /* Try flag 0x80000000, which ROS calls SEC_PHYSICALMEMORY */
    InitializeObjectAttributes(&ObjectAttributes,
                               NULL,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = ZwCreateSection(&SectionHandle,
                             SECTION_ALL_ACCESS,
                             &ObjectAttributes,
                             NULL,
                             PAGE_READWRITE,
                             0x80000000,
                             NULL);
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
    if (NT_SUCCESS(Status))
        ZwClose(SectionHandle);

    /* Assertion failure: AllocationAttributes & SEC_IMAGE | SEC_RESERVE | SEC_COMMIT */
    if (!KmtIsCheckedBuild)
    {
        InitializeObjectAttributes(&ObjectAttributes,
                                   NULL,
                                   OBJ_KERNEL_HANDLE,
                                   NULL,
                                   NULL);
        Status = MmCreateSection(&SectionObject,
                                 SECTION_ALL_ACCESS,
                                 &ObjectAttributes,
                                 NULL,
                                 PAGE_READWRITE,
                                 0x80000000,
                                 NULL,
                                 NULL);
        ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
        if (NT_SUCCESS(Status))
            ObDereferenceObject(SectionObject);
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               NULL,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);
    Status = MmCreateSection(&SectionObject,
                             SECTION_ALL_ACCESS,
                             &ObjectAttributes,
                             NULL,
                             PAGE_READWRITE,
                             SEC_RESERVE | 0x80000000,
                             NULL,
                             NULL);
    ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
    if (NT_SUCCESS(Status))
        ObDereferenceObject(SectionObject);

    ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
    ExFreePoolWithTag(MyPage, 'MPmK');
}
Esempio n. 6
0
{
   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))
   {
      WARN_(VIDEOPRT, "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,
Esempio n. 7
0
NTSTATUS
NTAPI
INIT_FUNCTION
VdmpInitialize(PVOID ControlData)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING PhysMemName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
    NTSTATUS Status;
    HANDLE PhysMemHandle;
    PVOID BaseAddress;
    volatile PVOID NullAddress = NULL;
    LARGE_INTEGER Offset;
    ULONG ViewSize;

    /* Open the physical memory section */
    InitializeObjectAttributes(&ObjectAttributes,
                               &PhysMemName,
                               0,
                               NULL,
                               NULL);
    Status = ZwOpenSection(&PhysMemHandle,
                           SECTION_ALL_ACCESS,
                           &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't open \\Device\\PhysicalMemory\n");
        return Status;
    }

    /* Map the BIOS and device registers into the address space */
    Offset.QuadPart = 0;
    ViewSize = PAGE_SIZE;
    BaseAddress = 0;
    Status = ZwMapViewOfSection(PhysMemHandle,
                                NtCurrentProcess(),
                                &BaseAddress,
                                0,
                                ViewSize,
                                &Offset,
                                &ViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't map physical memory (%x)\n", Status);
        ZwClose(PhysMemHandle);
        return Status;
    }

    /* Enter SEH */
    _SEH2_TRY
    {
        /* Copy the first physical page into the first virtual page */
        RtlMoveMemory(NullAddress, BaseAddress, ViewSize);
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        /* Fail */
        DPRINT1("Couldn't copy first page (%x)\n", Status);
        ZwClose(PhysMemHandle);
        ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
        _SEH2_YIELD(return _SEH2_GetExceptionCode());
    }
    _SEH2_END;

    /* Close physical memory section handle */
    ZwClose(PhysMemHandle);

    /* Unmap the section */
    Status = ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);

    if (!NT_SUCCESS(Status))
    {
        DPRINT1("Couldn't unmap the section (%x)\n", Status);
        return Status;
    }

    return STATUS_SUCCESS;
}
Esempio n. 8
0
NTSTATUS
VdmpInitialize(
    PVDMICAUSERDATA pIcaUserData
    )

/*++

Routine Description:

    Initialize the address space of a VDM.

Arguments:

    None,

Return Value:

    NTSTATUS.

--*/

{
    NTSTATUS Status, StatusCopy;
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING SectionName;
    UNICODE_STRING WorkString;
    ULONG ViewSize;
    LARGE_INTEGER ViewBase;
    PVOID BaseAddress;
    PVOID destination;
    HANDLE SectionHandle, RegistryHandle;
    PEPROCESS Process;
    ULONG ResultLength;
    ULONG Index;
    PCM_FULL_RESOURCE_DESCRIPTOR ResourceDescriptor;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialResourceDescriptor;
    PKEY_VALUE_FULL_INFORMATION KeyValueBuffer;
    PCM_ROM_BLOCK BiosBlock;
    ULONG LastMappedAddress;
    PVDM_PROCESS_OBJECTS pVdmObjects = NULL;
    USHORT PagedQuotaCharged = 0;
    USHORT NonPagedQuotaCharged = 0;
    HANDLE hThread;
    PVDM_TIB VdmTib;


    PAGED_CODE();

    Status = VdmpGetVdmTib(&VdmTib, VDMTIB_PROBE); // take from user mode and probe

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    if ((KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) == 0) {

        //
        // This is PC/AT (and FMR in Japan) VDM.
        //

        RtlInitUnicodeString(
            &SectionName,
            L"\\Device\\PhysicalMemory"
            );

        InitializeObjectAttributes(
            &ObjectAttributes,
            &SectionName,
            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
            (HANDLE) NULL,
            (PSECURITY_DESCRIPTOR) NULL
            );

        Status = ZwOpenSection(
            &SectionHandle,
            SECTION_ALL_ACCESS,
            &ObjectAttributes
            );

        if (!NT_SUCCESS(Status)) {

            return Status;

        }

        //
        // Copy the first page of memory into the VDM's address space
        //

        BaseAddress = 0;
        destination = 0;
        ViewSize = 0x1000;
        ViewBase.LowPart = 0;
        ViewBase.HighPart = 0;

        Status = ZwMapViewOfSection(
            SectionHandle,
            NtCurrentProcess(),
            &BaseAddress,
            0,
            ViewSize,
            &ViewBase,
            &ViewSize,
            ViewUnmap,
            0,
            PAGE_READWRITE
            );

        if (!NT_SUCCESS(Status)) {
           ZwClose(SectionHandle);
           return Status;
        }

        // problem with this statement below --
        // it could be a non-vdm process and copying memory to address 0
        // should be guarded against

        StatusCopy = STATUS_SUCCESS;
        try {
            RtlMoveMemory(
               destination,
               BaseAddress,
               ViewSize
               );
        }
        except(ExSystemExceptionFilter()) {
           StatusCopy = GetExceptionCode();
        }


        Status = ZwUnmapViewOfSection(
            NtCurrentProcess(),
            BaseAddress
            );

        if (!NT_SUCCESS(Status) || !NT_SUCCESS(StatusCopy)) {
           ZwClose(SectionHandle);
           return (NT_SUCCESS(Status) ? StatusCopy : Status);
        }

        //
        // Map Rom into address space
        //

        BaseAddress = (PVOID) 0x000C0000;
        ViewSize = 0x40000;
        ViewBase.LowPart = 0x000C0000;
        ViewBase.HighPart = 0;


        //
        // First unmap the reserved memory.  This must be done here to prevent
        // the virtual memory in question from being consumed by some other
        // alloc vm call.
        //

        Status = ZwFreeVirtualMemory(
            NtCurrentProcess(),
            &BaseAddress,
            &ViewSize,
            MEM_RELEASE
            );

        // N.B.  This should probably take into account the fact that there are
        // a handfull of error conditions that are ok.  (such as no memory to
        // release.)

        if (!NT_SUCCESS(Status)) {
            ZwClose(SectionHandle);
            return Status;

        }

        //
        // Set up and open KeyPath
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDescriptionSystemName,
            OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
            (HANDLE)NULL,
            NULL
            );

        Status = ZwOpenKey(
            &RegistryHandle,
            KEY_READ,
            &ObjectAttributes
            );

        if (!NT_SUCCESS(Status)) {
            ZwClose(SectionHandle);
            return Status;
        }

        //
        // Allocate space for the data
        //

        KeyValueBuffer = ExAllocatePoolWithTag(
            PagedPool,
            KEY_VALUE_BUFFER_SIZE,
            ' MDV'
            );

        if (KeyValueBuffer == NULL) {
            ZwClose(RegistryHandle);
            ZwClose(SectionHandle);
            return STATUS_NO_MEMORY;
        }

        //
        // Get the data for the rom information
        //

        RtlInitUnicodeString(
            &WorkString,
            L"Configuration Data"
            );

        Status = ZwQueryValueKey(
            RegistryHandle,
            &WorkString,
            KeyValueFullInformation,
            KeyValueBuffer,
            KEY_VALUE_BUFFER_SIZE,
            &ResultLength
            );

        if (!NT_SUCCESS(Status)) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            return Status;
        }

        ResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)
            ((PUCHAR) KeyValueBuffer + KeyValueBuffer->DataOffset);

        if ((KeyValueBuffer->DataLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR)) ||
            (ResourceDescriptor->PartialResourceList.Count < 2)
        ) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            // No rom blocks.
            return STATUS_SUCCESS;
        }

        PartialResourceDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)
            ((PUCHAR)ResourceDescriptor +
            sizeof(CM_FULL_RESOURCE_DESCRIPTOR) +
            ResourceDescriptor->PartialResourceList.PartialDescriptors[0]
                .u.DeviceSpecificData.DataSize);


        if (KeyValueBuffer->DataLength < ((PUCHAR)PartialResourceDescriptor -
            (PUCHAR)ResourceDescriptor + sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)
            + sizeof(CM_ROM_BLOCK))
        ) {
            ZwClose(RegistryHandle);
            ExFreePool(KeyValueBuffer);
            ZwClose(SectionHandle);
            return STATUS_ILL_FORMED_SERVICE_ENTRY;
        }


        BiosBlock = (PCM_ROM_BLOCK)((PUCHAR)PartialResourceDescriptor +
            sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR));

        Index = PartialResourceDescriptor->u.DeviceSpecificData.DataSize /
            sizeof(CM_ROM_BLOCK);

        //
        // N.B.  Rom blocks begin on 2K (not necessarily page) boundaries
        //       They end on 512 byte boundaries.  This means that we have
        //       to keep track of the last page mapped, and round the next
        //       Rom block up to the next page boundary if necessary.
        //

        LastMappedAddress = 0xC0000;

        while (Index) {
    #if 0
            DbgPrint(
                "Bios Block, PhysAddr = %lx, size = %lx\n",
                BiosBlock->Address,
                BiosBlock->Size
                );
    #endif
            if ((Index > 1) &&
                ((BiosBlock->Address + BiosBlock->Size) == BiosBlock[1].Address)
            ) {
                //
                // Coalesce adjacent blocks
                //
                BiosBlock[1].Address = BiosBlock[0].Address;
                BiosBlock[1].Size += BiosBlock[0].Size;
                Index--;
                BiosBlock++;
                continue;
            }

            BaseAddress = (PVOID)(BiosBlock->Address);
            ViewSize = BiosBlock->Size;

            if ((ULONG)BaseAddress < LastMappedAddress) {
                if (ViewSize > (LastMappedAddress - (ULONG)BaseAddress)) {
                    ViewSize = ViewSize - (LastMappedAddress - (ULONG)BaseAddress);
                    BaseAddress = (PVOID)LastMappedAddress;
                } else {
                    ViewSize = 0;
                }
            }

            ViewBase.LowPart = (ULONG)BaseAddress;

            if (ViewSize > 0) {

                Status = ZwMapViewOfSection(
                    SectionHandle,
                    NtCurrentProcess(),
                    &BaseAddress,
                    0,
                    ViewSize,
                    &ViewBase,
                    &ViewSize,
                    ViewUnmap,
                    MEM_DOS_LIM,
                    PAGE_READWRITE
                    );

                if (!NT_SUCCESS(Status)) {
                    break;
                }

                LastMappedAddress = (ULONG)BaseAddress + ViewSize;
            }

            Index--;
            BiosBlock++;
        }

        //
        // Free up the handles
        //

        ZwClose(SectionHandle);
        ZwClose(RegistryHandle);
        ExFreePool(KeyValueBuffer);

    } else {