mirror of
https://github.com/reactos/reactos.git
synced 2025-04-30 11:08:51 +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)
|
static VOID NTAPI EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
ULONG i;
|
||||||
UNIMPLEMENTED;
|
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)
|
static BOOLEAN NTAPI EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
|
||||||
{
|
{
|
||||||
// TODO: NOT IMPLEMENTED
|
ULONG i;
|
||||||
UNIMPLEMENTED;
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -209,6 +209,7 @@ MemInstallFastMemoryHook(PVOID Address,
|
||||||
ULONG i;
|
ULONG i;
|
||||||
ULONG FirstPage = (ULONG_PTR)Address >> 12;
|
ULONG FirstPage = (ULONG_PTR)Address >> 12;
|
||||||
ULONG LastPage = ((ULONG_PTR)Address + Size - 1) >> 12;
|
ULONG LastPage = ((ULONG_PTR)Address + Size - 1) >> 12;
|
||||||
|
PLIST_ENTRY Pointer;
|
||||||
|
|
||||||
/* Make sure none of these pages are already allocated */
|
/* Make sure none of these pages are already allocated */
|
||||||
for (i = FirstPage; i <= LastPage; i++)
|
for (i = FirstPage; i <= LastPage; i++)
|
||||||
|
@ -216,20 +217,39 @@ MemInstallFastMemoryHook(PVOID Address,
|
||||||
if (PageTable[i] != NULL) return FALSE;
|
if (PageTable[i] != NULL) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and initialize a new hook entry */
|
for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
|
||||||
Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
|
{
|
||||||
if (Hook == NULL) return FALSE;
|
Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
|
||||||
|
|
||||||
Hook->hVdd = NULL;
|
if (Hook->hVdd == NULL
|
||||||
Hook->Count = LastPage - FirstPage + 1;
|
&& Hook->FastReadHandler == ReadHandler
|
||||||
Hook->FastReadHandler = ReadHandler;
|
&& Hook->FastWriteHandler == WriteHandler)
|
||||||
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;
|
for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
|
||||||
|
|
||||||
/* ... and to the list of hooks */
|
|
||||||
InsertTailList(&HookList, &Hook->Entry);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +359,7 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
||||||
ULONG LastPage = ((ULONG_PTR)pStart + dwCount - 1) >> 12;
|
ULONG LastPage = ((ULONG_PTR)pStart + dwCount - 1) >> 12;
|
||||||
PVOID Address = (PVOID)(FirstPage * PAGE_SIZE);
|
PVOID Address = (PVOID)(FirstPage * PAGE_SIZE);
|
||||||
SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE;
|
SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE;
|
||||||
|
PLIST_ENTRY Pointer;
|
||||||
|
|
||||||
/* Check validity of the VDD handle */
|
/* Check validity of the VDD handle */
|
||||||
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return FALSE;
|
if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE) return FALSE;
|
||||||
|
@ -350,27 +371,45 @@ VDDInstallMemoryHook(IN HANDLE hVdd,
|
||||||
if (PageTable[i] != NULL) return FALSE;
|
if (PageTable[i] != NULL) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create and initialize a new hook entry */
|
for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
|
||||||
Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
|
{
|
||||||
if (Hook == NULL) return FALSE;
|
Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
|
||||||
|
if (Hook->hVdd == hVdd && Hook->VddHandler == MemoryHandler) break;
|
||||||
|
}
|
||||||
|
|
||||||
Hook->hVdd = hVdd;
|
if (Pointer == &HookList)
|
||||||
Hook->Count = LastPage - FirstPage + 1;
|
{
|
||||||
Hook->VddHandler = MemoryHandler;
|
/* 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 */
|
/* Decommit the pages */
|
||||||
Status = NtFreeVirtualMemory(NtCurrentProcess(), &Address, &Size, MEM_DECOMMIT);
|
Status = NtFreeVirtualMemory(NtCurrentProcess(), &Address, &Size, MEM_DECOMMIT);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, Hook);
|
if (Pointer == &HookList)
|
||||||
|
{
|
||||||
|
RemoveEntryList(&Hook->Entry);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, Hook);
|
||||||
|
}
|
||||||
|
|
||||||
return FALSE;
|
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;
|
for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
|
||||||
|
|
||||||
/* ... and to the list of hooks */
|
|
||||||
InsertTailList(&HookList, &Hook->Entry);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue