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.…
==============================================================================
--- 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/memo…
==============================================================================
--- 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;
}