mirror of
https://github.com/reactos/reactos.git
synced 2025-04-30 02:58:48 +00:00
[NTVDM]
Implement the EMS memory handlers. Make memory hooks expandable. svn path=/trunk/; revision=66673
This commit is contained in:
parent
a0ee24eb0b
commit
d2d2431614
2 changed files with 92 additions and 24 deletions
|
@ -297,14 +297,43 @@ static VOID WINAPI EmsIntHandler(LPWORD Stack)
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,6 +209,7 @@ MemInstallFastMemoryHook(PVOID Address,
|
|||
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 @@ MemInstallFastMemoryHook(PVOID Address,
|
|||
if (PageTable[i] != NULL) return FALSE;
|
||||
}
|
||||
|
||||
/* Create and initialize a new hook entry */
|
||||
Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
|
||||
if (Hook == NULL) return FALSE;
|
||||
for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
|
||||
{
|
||||
Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
|
||||
|
||||
Hook->hVdd = NULL;
|
||||
Hook->Count = LastPage - FirstPage + 1;
|
||||
Hook->FastReadHandler = ReadHandler;
|
||||
Hook->FastWriteHandler = WriteHandler;
|
||||
if (Hook->hVdd == NULL
|
||||
&& Hook->FastReadHandler == ReadHandler
|
||||
&& Hook->FastWriteHandler == WriteHandler)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the hook entry to the page table... */
|
||||
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 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
|||
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 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
|||
if (PageTable[i] != NULL) return FALSE;
|
||||
}
|
||||
|
||||
/* Create and initialize a new hook entry */
|
||||
Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
|
||||
if (Hook == NULL) return FALSE;
|
||||
for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
|
||||
{
|
||||
Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
|
||||
if (Hook->hVdd == hVdd && Hook->VddHandler == MemoryHandler) break;
|
||||
}
|
||||
|
||||
Hook->hVdd = hVdd;
|
||||
Hook->Count = LastPage - FirstPage + 1;
|
||||
Hook->VddHandler = MemoryHandler;
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue