Author: aandrejevic Date: Sat Mar 14 01:54:35 2015 New Revision: 66673
URL: http://svn.reactos.org/svn/reactos?rev=66673&view=rev Log: [NTVDM] Implement the EMS memory handlers. Make memory hooks expandable.
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ems.c trunk/reactos/subsystems/mvdm/ntvdm/memory.c
Modified: trunk/reactos/subsystems/mvdm/ntvdm/ems.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/ems.c... ============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/ems.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/ems.c [iso-8859-1] Sat Mar 14 01:54:35 2015 @@ -297,14 +297,43 @@
static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; + ULONG i; + ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); + ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; + ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; + ULONG Offset, Length; + + for (i = FirstPage; i <= LastPage; i++) + { + Offset = (i == FirstPage) ? Address & (EMS_PAGE_SIZE - 1) : 0; + Length = ((i == LastPage) + ? (Address + Size - (LastPage << EMS_PAGE_BITS)) + : EMS_PAGE_SIZE) - Offset; + + if (Mapping[i]) RtlCopyMemory(Buffer, (PVOID)((ULONG_PTR)Mapping[i] + Offset), Length); + Buffer = (PVOID)((ULONG_PTR)Buffer + Length); + } }
static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size) { - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; + ULONG i; + ULONG RelativeAddress = Address - TO_LINEAR(EMS_SEGMENT, 0); + ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE; + ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE; + ULONG Offset, Length; + + for (i = FirstPage; i <= LastPage; i++) + { + Offset = (i == FirstPage) ? Address & (EMS_PAGE_SIZE - 1) : 0; + Length = ((i == LastPage) + ? (Address + Size - (LastPage << EMS_PAGE_BITS)) + : EMS_PAGE_SIZE) - Offset; + + if (Mapping[i]) RtlCopyMemory((PVOID)((ULONG_PTR)Mapping[i] + Offset), Buffer, Length); + Buffer = (PVOID)((ULONG_PTR)Buffer + Length); + } + return TRUE; }
Modified: trunk/reactos/subsystems/mvdm/ntvdm/memory.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/mvdm/ntvdm/memor... ============================================================================== --- trunk/reactos/subsystems/mvdm/ntvdm/memory.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/mvdm/ntvdm/memory.c [iso-8859-1] Sat Mar 14 01:54:35 2015 @@ -209,6 +209,7 @@ ULONG i; ULONG FirstPage = (ULONG_PTR)Address >> 12; ULONG LastPage = ((ULONG_PTR)Address + Size - 1) >> 12; + PLIST_ENTRY Pointer;
/* Make sure none of these pages are already allocated */ for (i = FirstPage; i <= LastPage; i++) @@ -216,20 +217,39 @@ if (PageTable[i] != NULL) return FALSE; }
- /* Create and initialize a new hook entry */ - Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook)); - if (Hook == NULL) return FALSE; - - Hook->hVdd = NULL; - Hook->Count = LastPage - FirstPage + 1; - Hook->FastReadHandler = ReadHandler; - Hook->FastWriteHandler = WriteHandler; - - /* Add the hook entry to the page table... */ + for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink) + { + Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry); + + if (Hook->hVdd == NULL + && Hook->FastReadHandler == ReadHandler + && Hook->FastWriteHandler == WriteHandler) + { + break; + } + } + + if (Pointer == &HookList) + { + /* Create and initialize a new hook entry... */ + Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook)); + if (Hook == NULL) return FALSE; + + Hook->hVdd = NULL; + Hook->Count = 0; + Hook->FastReadHandler = ReadHandler; + Hook->FastWriteHandler = WriteHandler; + + /* ... and add it to the list of hooks */ + InsertTailList(&HookList, &Hook->Entry); + } + + /* Increase the number of pages this hook has */ + Hook->Count += LastPage - FirstPage + 1; + + /* Add the hook entry to the page table */ for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
- /* ... and to the list of hooks */ - InsertTailList(&HookList, &Hook->Entry); return TRUE; }
@@ -339,6 +359,7 @@ ULONG LastPage = ((ULONG_PTR)pStart + dwCount - 1) >> 12; PVOID Address = (PVOID)(FirstPage * PAGE_SIZE); SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE; + PLIST_ENTRY Pointer;
/* Check validity of the VDD handle */ if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return FALSE; @@ -350,27 +371,45 @@ if (PageTable[i] != NULL) return FALSE; }
- /* Create and initialize a new hook entry */ - Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook)); - if (Hook == NULL) return FALSE; - - Hook->hVdd = hVdd; - Hook->Count = LastPage - FirstPage + 1; - Hook->VddHandler = MemoryHandler; + for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink) + { + Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry); + if (Hook->hVdd == hVdd && Hook->VddHandler == MemoryHandler) break; + } + + if (Pointer == &HookList) + { + /* Create and initialize a new hook entry... */ + Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook)); + if (Hook == NULL) return FALSE; + + Hook->hVdd = hVdd; + Hook->Count = 0; + Hook->VddHandler = MemoryHandler; + + /* ... and add it to the list of hooks */ + InsertTailList(&HookList, &Hook->Entry); + }
/* Decommit the pages */ Status = NtFreeVirtualMemory(NtCurrentProcess(), &Address, &Size, MEM_DECOMMIT); if (!NT_SUCCESS(Status)) { - RtlFreeHeap(RtlGetProcessHeap(), 0, Hook); + if (Pointer == &HookList) + { + RemoveEntryList(&Hook->Entry); + RtlFreeHeap(RtlGetProcessHeap(), 0, Hook); + } + return FALSE; }
- /* Add the hook entry to the page table... */ + /* Increase the number of pages this hook has */ + Hook->Count += LastPage - FirstPage + 1; + + /* Add the hook entry to the page table */ for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
- /* ... and to the list of hooks */ - InsertTailList(&HookList, &Hook->Entry); return TRUE; }