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; }
/* * @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; }
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; }
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; }
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'); }
{ 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,
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; }
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 {