ReactOS 0.4.15-dev-5666-gc548b97
memory.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "memory.h"
#include <ndk/mmfuncs.h>
Include dependency graph for memory.c:

Go to the source code of this file.

Classes

struct  _MEM_HOOK
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _MEM_HOOK MEM_HOOK
 
typedef struct _MEM_HOOKPMEM_HOOK
 

Functions

static VOID MemFastMoveMemory (OUT VOID UNALIGNED *Destination, IN const VOID UNALIGNED *Source, IN SIZE_T Length)
 
static VOID ReadPage (PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
 
static VOID WritePage (PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
 
VOID FASTCALL EmulatorReadMemory (PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
 
VOID FASTCALL EmulatorWriteMemory (PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
 
VOID FASTCALL EmulatorCopyMemory (PFAST486_STATE State, ULONG DestAddress, ULONG SrcAddress, ULONG Size)
 
VOID EmulatorSetA20 (BOOLEAN Enabled)
 
BOOLEAN EmulatorGetA20 (VOID)
 
VOID MemExceptionHandler (ULONG FaultAddress, BOOLEAN Writing)
 
BOOL MemInstallFastMemoryHook (PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
 
BOOL MemRemoveFastMemoryHook (PVOID Address, ULONG Size)
 
BOOLEAN MemQueryMemoryZone (ULONG StartAddress, PULONG Length, PBOOLEAN Hooked)
 
PBYTE WINAPI Sim32pGetVDMPointer (IN ULONG Address, IN BOOLEAN ProtectedMode)
 
PBYTE WINAPI MGetVdmPointer (IN ULONG Address, IN ULONG Size, IN BOOLEAN ProtectedMode)
 
PVOID WINAPI VdmMapFlat (IN USHORT Segment, IN ULONG Offset, IN VDM_MODE Mode)
 
BOOL WINAPI VdmFlushCache (IN USHORT Segment, IN ULONG Offset, IN ULONG Size, IN VDM_MODE Mode)
 
BOOL WINAPI VdmUnmapFlat (IN USHORT Segment, IN ULONG Offset, IN PVOID Buffer, IN VDM_MODE Mode)
 
BOOL WINAPI VDDInstallMemoryHook (IN HANDLE hVdd, IN PVOID pStart, IN DWORD dwCount, IN PVDD_MEMORY_HANDLER MemoryHandler)
 
BOOL WINAPI VDDDeInstallMemoryHook (IN HANDLE hVdd, IN PVOID pStart, IN DWORD dwCount)
 
BOOL WINAPI VDDAllocMem (IN HANDLE hVdd, IN PVOID Address, IN ULONG Size)
 
BOOL WINAPI VDDFreeMem (IN HANDLE hVdd, IN PVOID Address, IN ULONG Size)
 
BOOL WINAPI VDDIncludeMem (IN HANDLE hVdd, IN PVOID Address, IN ULONG Size)
 
BOOL WINAPI VDDExcludeMem (IN HANDLE hVdd, IN PVOID Address, IN ULONG Size)
 
BOOLEAN MemInitialize (VOID)
 
VOID MemCleanup (VOID)
 

Variables

static LIST_ENTRY HookList
 
static PMEM_HOOK PageTable [TOTAL_PAGES] = { NULL }
 
static BOOLEAN A20Line = FALSE
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file memory.c.

Typedef Documentation

◆ MEM_HOOK

◆ PMEM_HOOK

Function Documentation

◆ EmulatorCopyMemory()

VOID FASTCALL EmulatorCopyMemory ( PFAST486_STATE  State,
ULONG  DestAddress,
ULONG  SrcAddress,
ULONG  Size 
)

Definition at line 219 of file memory.c.

220{
221 /*
222 * Guest-to-guest memory copy
223 */
224
225 // FIXME: This is a temporary implementation of a more useful functionality
226 // which should be a merge of EmulatorReadMemory & EmulatorWriteMemory without
227 // any local external buffer.
228 // NOTE: Process heap is by default serialized (unless one specifies it shouldn't).
229 static BYTE StaticBuffer[8192]; // Smallest static buffer we can use.
230 static PVOID HeapBuffer = NULL; // Always-growing heap buffer. Use it in case StaticBuffer is too small.
231 static ULONG HeapBufferSize = 0;
232 PVOID LocalBuffer; // Points to either StaticBuffer or HeapBuffer
233
234 if (Size <= sizeof(StaticBuffer))
235 {
236 /* Use the static buffer */
237 LocalBuffer = StaticBuffer;
238 }
239 else if (/* sizeof(StaticBuffer) <= Size && */ Size <= HeapBufferSize)
240 {
241 /* Use the heap buffer */
242 ASSERT(HeapBufferSize > 0 && HeapBuffer != NULL);
243 LocalBuffer = HeapBuffer;
244 }
245 else // if (Size > HeapBufferSize)
246 {
247 /* Enlarge the heap buffer and use it */
248
249 if (HeapBuffer == NULL)
250 {
251 /* First allocation */
252 LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
253 }
254 else
255 {
256 /* Reallocation */
257 LocalBuffer = RtlReAllocateHeap(RtlGetProcessHeap(), 0 /* HEAP_GENERATE_EXCEPTIONS */, HeapBuffer, Size);
258 }
259 ASSERT(LocalBuffer != NULL); // We must succeed! TODO: Handle it more properly.
260 HeapBuffer = LocalBuffer; // HeapBuffer is now reallocated.
261 HeapBufferSize = Size;
262 }
263
264 /* Perform memory copy */
265 EmulatorReadMemory( State, SrcAddress , LocalBuffer, Size);
266 EmulatorWriteMemory(State, DestAddress, LocalBuffer, Size);
267
268 // if (LocalBuffer != StaticBuffer)
269 // RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
270
271 // Note that we don't free HeapBuffer since it's an always-growing buffer.
272 // It is freed when NTVDM termiantes.
273}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
#define NULL
Definition: types.h:112
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
unsigned int ULONG
Definition: retypes.h:1
#define ASSERT(a)
Definition: mode.c:44
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:142
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:186
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
unsigned char BYTE
Definition: xxhash.c:193

Referenced by VidBiosScrollWindow().

◆ EmulatorGetA20()

BOOLEAN EmulatorGetA20 ( VOID  )

Definition at line 280 of file memory.c.

281{
282 return A20Line;
283}
static BOOLEAN A20Line
Definition: memory.c:44

Referenced by PS2WriteControl(), and XmsBopProcedure().

◆ EmulatorReadMemory()

VOID FASTCALL EmulatorReadMemory ( PFAST486_STATE  State,
ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)

Definition at line 142 of file memory.c.

143{
145 ULONG FirstPage, LastPage;
146
148
149 /* Mirror 0x000FFFF0 at 0xFFFFFFF0 */
150 if (Address >= 0xFFFFFFF0) Address -= 0xFFF00000;
151
152 /* If the A20 line is disabled, mask bit 20 */
153 if (!A20Line) Address &= ~(1 << 20);
154
155 if ((Address + Size - 1) >= MAX_ADDRESS)
156 {
157 ULONG ExtraStart = (Address < MAX_ADDRESS) ? MAX_ADDRESS - Address : 0;
158
159 /* Fill the memory that was above the limit with 0xFF */
160 RtlFillMemory((PVOID)((ULONG_PTR)Buffer + ExtraStart), Size - ExtraStart, 0xFF);
161
163 else return;
164 }
165
166 FirstPage = Address >> 12;
167 LastPage = (Address + Size - 1) >> 12;
168
169 if (FirstPage == LastPage)
170 {
171 ReadPage(PageTable[FirstPage], Address, Buffer, Size);
172 }
173 else
174 {
175 for (i = FirstPage; i <= LastPage; i++)
176 {
177 Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
178 Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
179
180 ReadPage(PageTable[i], (i << 12) + Offset, Buffer, Length);
182 }
183 }
184}
#define MAX_ADDRESS
Definition: bufpool.h:45
#define PAGE_SIZE
Definition: env_spec_w32.h:49
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
void * PVOID
Definition: retypes.h:9
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static WCHAR Address[46]
Definition: ping.c:68
static PMEM_HOOK PageTable[TOTAL_PAGES]
Definition: memory.c:43
static VOID ReadPage(PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:118
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by CpuInitialize(), DmaRequest(), DosWriteFile(), EmulatorCopyMemory(), PaintMouseCursor(), VidBiosDrawGlyph(), VidBiosVideoService(), and WriteDisk().

◆ EmulatorSetA20()

VOID EmulatorSetA20 ( BOOLEAN  Enabled)

Definition at line 275 of file memory.c.

276{
278}
@ Enabled
Definition: mountmgr.h:159

Referenced by PS2WriteData(), XmsLocalDisableA20(), and XmsLocalEnableA20().

◆ EmulatorWriteMemory()

VOID FASTCALL EmulatorWriteMemory ( PFAST486_STATE  State,
ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)

Definition at line 186 of file memory.c.

187{
189 ULONG FirstPage, LastPage;
190
192
193 /* If the A20 line is disabled, mask bit 20 */
194 if (!A20Line) Address &= ~(1 << 20);
195
196 if (Address >= MAX_ADDRESS) return;
198
199 FirstPage = Address >> 12;
200 LastPage = (Address + Size - 1) >> 12;
201
202 if (FirstPage == LastPage)
203 {
204 WritePage(PageTable[FirstPage], Address, Buffer, Size);
205 }
206 else
207 {
208 for (i = FirstPage; i <= LastPage; i++)
209 {
210 Offset = (i == FirstPage) ? (Address & (PAGE_SIZE - 1)) : 0;
211 Length = ((i == LastPage) ? (Address + Size - (LastPage << 12)) : PAGE_SIZE) - Offset;
212
213 WritePage(PageTable[i], (i << 12) + Offset, Buffer, Length);
215 }
216 }
217}
#define min(a, b)
Definition: monoChain.cc:55
static VOID WritePage(PMEM_HOOK Hook, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:129

Referenced by CpuInitialize(), DmaRequest(), DosReadFile(), EmulatorCopyMemory(), EraseMouseCursor(), PaintMouseCursor(), ReadDisk(), VidBiosClearScreen(), VidBiosDrawGlyph(), and VidBiosScrollWindow().

◆ MemCleanup()

VOID MemCleanup ( VOID  )

Definition at line 783 of file memory.c.

784{
787 PLIST_ENTRY Pointer;
788
789 while (!IsListEmpty(&HookList))
790 {
791 Pointer = RemoveHeadList(&HookList);
792 RtlFreeHeap(RtlGetProcessHeap(), 0, CONTAINING_RECORD(Pointer, MEM_HOOK, Entry));
793 }
794
795 /* Decommit the VDM memory */
798 &MemorySize,
799#ifndef STANDALONE
801#else
803#endif
804 );
805 if (!NT_SUCCESS(Status))
806 {
807 DPRINT1("NTVDM: Failed to decommit VDM memory, Status 0x%08lx\n", Status);
808 }
809}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
Status
Definition: gdiplustypes.h:25
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define MEM_DECOMMIT
Definition: nt_native.h:1315
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define MEM_RELEASE
Definition: nt_native.h:1316
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5224
#define STANDALONE
Definition: testlist.c:1
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
static LIST_ENTRY HookList
Definition: memory.c:42
static CONST DWORD MemorySize[]
Definition: svga.c:32
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by EmulatorCleanup().

◆ MemExceptionHandler()

VOID MemExceptionHandler ( ULONG  FaultAddress,
BOOLEAN  Writing 
)

Definition at line 286 of file memory.c.

287{
288 PMEM_HOOK Hook = PageTable[FaultAddress >> 12];
289 DPRINT("The memory at 0x%08X could not be %s.\n", FaultAddress, Writing ? "written" : "read");
290
291 /* Exceptions are only supposed to happen when using VDD-style memory hooks */
292 ASSERT(FaultAddress < MAX_ADDRESS && Hook != NULL && Hook->hVdd != NULL);
293
294 /* Call the VDD handler */
295 Hook->VddHandler(REAL_TO_PHYS(FaultAddress), (ULONG)Writing);
296}
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:37
#define DPRINT
Definition: sndvol32.h:71
PVDD_MEMORY_HANDLER VddHandler
Definition: memory.c:32
HANDLE hVdd
Definition: testvdd.c:87

Referenced by CpuExceptionFilter().

◆ MemFastMoveMemory()

static VOID MemFastMoveMemory ( OUT VOID UNALIGNED Destination,
IN const VOID UNALIGNED Source,
IN SIZE_T  Length 
)
inlinestatic

Definition at line 49 of file memory.c.

52{
53#if 1
54 /*
55 * We use a switch here to detect small moves of memory, as these
56 * constitute the bulk of our moves.
57 * Using RtlMoveMemory for all these small moves would be slow otherwise.
58 */
59 switch (Length)
60 {
61 case 0:
62 return;
63
64 case sizeof(UCHAR):
66 return;
67
68 case sizeof(USHORT):
70 return;
71
72 case sizeof(ULONG):
74 return;
75
76 case sizeof(ULONGLONG):
78 return;
79
80 default:
81#if defined(__GNUC__)
82 __builtin_memmove(Destination, Source, Length);
83#else
85#endif
86 }
87
88#else // defined(_MSC_VER)
89
91 PUCHAR Src = (PUCHAR)Source;
92
94
95 /* Move dword */
96 Count = NewSize >> 2; // NewSize / sizeof(ULONG);
97 NewSize = NewSize & 3; // NewSize % sizeof(ULONG);
98 __movsd(Dest, Src, Count);
99 Dest += Count << 2; // Count * sizeof(ULONG);
100 Src += Count << 2;
101
102 /* Move word */
103 Count = NewSize >> 1; // NewSize / sizeof(USHORT);
104 NewSize = NewSize & 1; // NewSize % sizeof(USHORT);
105 __movsw(Dest, Src, Count);
106 Dest += Count << 1; // Count * sizeof(USHORT);
107 Src += Count << 1;
108
109 /* Move byte */
110 Count = NewSize; // NewSize / sizeof(UCHAR);
111 // NewSize = NewSize; // NewSize % sizeof(UCHAR);
112 __movsb(Dest, Src, Count);
113
114#endif
115}
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
PPC_QUAL void __movsd(unsigned long *Destination, const unsigned long *Source, unsigned long Count)
Definition: intrin_ppc.h:333
PPC_QUAL void __movsw(unsigned short *Destination, const unsigned short *Source, unsigned long Count)
Definition: intrin_ppc.h:328
PPC_QUAL void __movsb(unsigned char *Destination, const unsigned char *Source, unsigned long Count)
Definition: intrin_ppc.h:323
unsigned int * PULONG
Definition: retypes.h:1
unsigned short * PUSHORT
Definition: retypes.h:2
unsigned char * PUCHAR
Definition: retypes.h:3
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2992
int Count
Definition: noreturn.cpp:7
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
unsigned short USHORT
Definition: pedump.c:61
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint64_t ULONGLONG
Definition: typedefs.h:67
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ReadPage(), and WritePage().

◆ MemInitialize()

BOOLEAN MemInitialize ( VOID  )

Definition at line 723 of file memory.c.

724{
726 SIZE_T MemorySize = MAX_ADDRESS; // See: kernel32/client/vdm.c!BaseGetVdmConfigInfo
727
729
730#ifndef STANDALONE
731
732 /*
733 * The reserved region starts from the very first page.
734 * We need to commit the reserved first 16 MB virtual address.
735 *
736 * NOTE: NULL has another signification for NtAllocateVirtualMemory.
737 */
738 BaseAddress = (PVOID)1;
739
740 /*
741 * Since to get NULL, we allocated from 0x1, account for this.
742 * See also: kernel32/client/proc.c!CreateProcessInternalW
743 */
744 MemorySize -= 1;
745
746#else
747
748 /* Allocate it anywhere */
750
751#endif
752
755 0,
756 &MemorySize,
757#ifndef STANDALONE
759#else
761#endif
763 if (!NT_SUCCESS(Status))
764 {
765 wprintf(L"FATAL: Failed to commit VDM memory, Status 0x%08lx\n", Status);
766 return FALSE;
767 }
768
769#ifndef STANDALONE
771#endif
772
773 /*
774 * For diagnostics purposes, we fill the memory with INT 0x03 codes
775 * so that if a program wants to execute random code in memory, we can
776 * retrieve the exact CS:IP where the problem happens.
777 */
779 return TRUE;
780}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define MEM_RESERVE
Definition: nt_native.h:1314
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1308
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4486
#define L(x)
Definition: ntvdm.h:50
#define wprintf(...)
Definition: whoami.c:18

Referenced by EmulatorInitialize().

◆ MemInstallFastMemoryHook()

BOOL MemInstallFastMemoryHook ( PVOID  Address,
ULONG  Size,
PMEMORY_READ_HANDLER  ReadHandler,
PMEMORY_WRITE_HANDLER  WriteHandler 
)

Definition at line 299 of file memory.c.

303{
304 PMEM_HOOK Hook;
305 ULONG i;
306 ULONG FirstPage = (ULONG_PTR)Address >> 12;
307 ULONG LastPage = ((ULONG_PTR)Address + Size - 1) >> 12;
308 PLIST_ENTRY Pointer;
309
310 /* Make sure none of these pages are already allocated */
311 for (i = FirstPage; i <= LastPage; i++)
312 {
313 if (PageTable[i] != NULL) return FALSE;
314 }
315
316 for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
317 {
318 Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
319
320 if (Hook->hVdd == NULL
321 && Hook->FastReadHandler == ReadHandler
322 && Hook->FastWriteHandler == WriteHandler)
323 {
324 break;
325 }
326 }
327
328 if (Pointer == &HookList)
329 {
330 /* Create and initialize a new hook entry... */
331 Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
332 if (Hook == NULL) return FALSE;
333
334 Hook->hVdd = NULL;
335 Hook->Count = 0;
336 Hook->FastReadHandler = ReadHandler;
337 Hook->FastWriteHandler = WriteHandler;
338
339 /* ... and add it to the list of hooks */
340 InsertTailList(&HookList, &Hook->Entry);
341 }
342
343 /* Increase the number of pages this hook has */
344 Hook->Count += LastPage - FirstPage + 1;
345
346 /* Add the hook entry to the page table */
347 for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
348
349 return TRUE;
350}
#define ULONG_PTR
Definition: config.h:101
#define InsertTailList(ListHead, Entry)
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PMEMORY_READ_HANDLER FastReadHandler
Definition: memory.c:36
PMEMORY_WRITE_HANDLER FastWriteHandler
Definition: memory.c:37
ULONG Count
Definition: memory.c:28
HANDLE hVdd
Definition: memory.c:27
LIST_ENTRY Entry
Definition: memory.c:26

Referenced by EmsDrvInitialize(), VgaWriteGc(), VgaWritePort(), and WriteProtectRom().

◆ MemQueryMemoryZone()

BOOLEAN MemQueryMemoryZone ( ULONG  StartAddress,
PULONG  Length,
PBOOLEAN  Hooked 
)

Definition at line 381 of file memory.c.

382{
383 ULONG Page = StartAddress >> 12;
384 if (Page >= TOTAL_PAGES) return FALSE;
385
386 *Length = 0;
387 *Hooked = PageTable[Page] != NULL;
388
389 while (Page < TOTAL_PAGES && (PageTable[Page] != NULL) == *Hooked)
390 {
391 *Length += PAGE_SIZE;
392 Page++;
393 }
394
395 return TRUE;
396}
_In_ PVOID _Out_opt_ BOOLEAN _Out_opt_ PPFN_NUMBER Page
Definition: mm.h:1298
#define TOTAL_PAGES
Definition: memory.h:14

Referenced by BiosMiscService().

◆ MemRemoveFastMemoryHook()

BOOL MemRemoveFastMemoryHook ( PVOID  Address,
ULONG  Size 
)

Definition at line 353 of file memory.c.

354{
355 PMEM_HOOK Hook;
356 ULONG i;
357 ULONG FirstPage = (ULONG_PTR)Address >> 12;
358 ULONG LastPage = ((ULONG_PTR)Address + Size - 1) >> 12;
359
360 if (Size == 0) return FALSE;
361
362 for (i = FirstPage; i <= LastPage; i++)
363 {
364 Hook = PageTable[i];
365 if (Hook == NULL || Hook->hVdd != NULL) continue;
366
367 if (--Hook->Count == 0)
368 {
369 /* This hook has no more pages */
370 RemoveEntryList(&Hook->Entry);
371 RtlFreeHeap(RtlGetProcessHeap(), 0, Hook);
372 }
373
374 PageTable[i] = NULL;
375 }
376
377 return TRUE;
378}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986

Referenced by EmsDrvCleanup(), VgaCleanup(), VgaWriteGc(), VgaWritePort(), and WriteUnProtectRom().

◆ MGetVdmPointer()

PBYTE WINAPI MGetVdmPointer ( IN ULONG  Address,
IN ULONG  Size,
IN BOOLEAN  ProtectedMode 
)

Definition at line 416 of file memory.c.

419{
421 return Sim32pGetVDMPointer(Address, ProtectedMode);
422}
PBYTE WINAPI Sim32pGetVDMPointer(IN ULONG Address, IN BOOLEAN ProtectedMode)
Definition: memory.c:400

◆ ReadPage()

static VOID ReadPage ( PMEM_HOOK  Hook,
ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)
inlinestatic

Definition at line 118 of file memory.c.

119{
120 if (Hook && !Hook->hVdd && Hook->FastReadHandler)
121 {
123 }
124
126}
static VOID MemFastMoveMemory(OUT VOID UNALIGNED *Destination, IN const VOID UNALIGNED *Source, IN SIZE_T Length)
Definition: memory.c:49

Referenced by EmulatorReadMemory().

◆ Sim32pGetVDMPointer()

PBYTE WINAPI Sim32pGetVDMPointer ( IN ULONG  Address,
IN BOOLEAN  ProtectedMode 
)

Definition at line 400 of file memory.c.

402{
403 // FIXME
404 UNREFERENCED_PARAMETER(ProtectedMode);
405
406 /*
407 * HIWORD(Address) == Segment (if ProtectedMode == FALSE)
408 * or Selector (if ProtectedMode == TRUE )
409 * LOWORD(Address) == Offset
410 */
411 return (PBYTE)FAR_POINTER(Address);
412}
#define FAR_POINTER(x)
Definition: emulator.h:35
BYTE * PBYTE
Definition: pedump.c:66

Referenced by MGetVdmPointer().

◆ VDDAllocMem()

BOOL WINAPI VDDAllocMem ( IN HANDLE  hVdd,
IN PVOID  Address,
IN ULONG  Size 
)

Definition at line 606 of file memory.c.

609{
611 PMEM_HOOK Hook;
612 ULONG i;
613 ULONG FirstPage = (ULONG_PTR)PHYS_TO_REAL(Address) >> 12;
614 ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(Address) + Size - 1) >> 12;
615 SIZE_T RealSize = (LastPage - FirstPage + 1) * PAGE_SIZE;
616
617 /* Check validity of the VDD handle */
618 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
619 {
621 return FALSE;
622 }
623
624 if (Size == 0) return FALSE;
625
626 /* Fixup the address */
627 Address = (PVOID)REAL_TO_PHYS(FirstPage * PAGE_SIZE);
628
629 /* Be sure that all the region is held by the VDD */
630 for (i = FirstPage; i <= LastPage; i++)
631 {
632 Hook = PageTable[i];
633 if (Hook == NULL) return FALSE;
634
635 if (Hook->hVdd != hVdd)
636 {
637 DPRINT1("VDDAllocMem: Page %u owned by someone else.\n", i);
638 return FALSE;
639 }
640 }
641
642 /* OK, all the range is held by the VDD. Commit the pages. */
644 &Address,
645 0,
646 &RealSize,
649 return NT_SUCCESS(Status);
650}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define PHYS_TO_REAL(ptr)
Definition: emulator.h:38
#define PAGE_READWRITE
Definition: nt_native.h:1304

◆ VDDDeInstallMemoryHook()

BOOL WINAPI VDDDeInstallMemoryHook ( IN HANDLE  hVdd,
IN PVOID  pStart,
IN DWORD  dwCount 
)

Definition at line 550 of file memory.c.

553{
555 PMEM_HOOK Hook;
556 ULONG i;
557 ULONG FirstPage = (ULONG_PTR)PHYS_TO_REAL(pStart) >> 12;
558 ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(pStart) + dwCount - 1) >> 12;
559 PVOID Address = (PVOID)REAL_TO_PHYS(FirstPage * PAGE_SIZE);
560 SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE;
561
562 /* Check validity of the VDD handle */
563 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
564 {
566 return FALSE;
567 }
568
569 if (dwCount == 0) return FALSE;
570
571 /* Commit the pages */
573 &Address,
574 0,
575 &Size,
578 if (!NT_SUCCESS(Status)) return FALSE;
579
580 for (i = FirstPage; i <= LastPage; i++)
581 {
582 Hook = PageTable[i];
583 if (Hook == NULL) continue;
584
585 if (Hook->hVdd != hVdd)
586 {
587 DPRINT1("VDDDeInstallMemoryHook: Page %u owned by someone else.\n", i);
588 continue;
589 }
590
591 if (--Hook->Count == 0)
592 {
593 /* This hook has no more pages */
594 RemoveEntryList(&Hook->Entry);
595 RtlFreeHeap(RtlGetProcessHeap(), 0, Hook);
596 }
597
598 PageTable[i] = NULL;
599 }
600
601 return TRUE;
602}

◆ VDDExcludeMem()

BOOL WINAPI VDDExcludeMem ( IN HANDLE  hVdd,
IN PVOID  Address,
IN ULONG  Size 
)

Definition at line 711 of file memory.c.

714{
715 // FIXME
717 return FALSE;
718}
#define UNIMPLEMENTED
Definition: debug.h:115

◆ VDDFreeMem()

BOOL WINAPI VDDFreeMem ( IN HANDLE  hVdd,
IN PVOID  Address,
IN ULONG  Size 
)

Definition at line 654 of file memory.c.

657{
659 PMEM_HOOK Hook;
660 ULONG i;
661 ULONG FirstPage = (ULONG_PTR)PHYS_TO_REAL(Address) >> 12;
662 ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(Address) + Size - 1) >> 12;
663 SIZE_T RealSize = (LastPage - FirstPage + 1) * PAGE_SIZE;
664
665 /* Check validity of the VDD handle */
666 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
667 {
669 return FALSE;
670 }
671
672 if (Size == 0) return FALSE;
673
674 /* Fixup the address */
675 Address = (PVOID)REAL_TO_PHYS(FirstPage * PAGE_SIZE);
676
677 /* Be sure that all the region is held by the VDD */
678 for (i = FirstPage; i <= LastPage; i++)
679 {
680 Hook = PageTable[i];
681 if (Hook == NULL) return FALSE;
682
683 if (Hook->hVdd != hVdd)
684 {
685 DPRINT1("VDDFreeMem: Page %u owned by someone else.\n", i);
686 return FALSE;
687 }
688 }
689
690 /* OK, all the range is held by the VDD. Decommit the pages. */
692 &Address,
693 &RealSize,
695 return NT_SUCCESS(Status);
696}

◆ VDDIncludeMem()

BOOL WINAPI VDDIncludeMem ( IN HANDLE  hVdd,
IN PVOID  Address,
IN ULONG  Size 
)

Definition at line 700 of file memory.c.

703{
704 // FIXME
706 return FALSE;
707}

◆ VDDInstallMemoryHook()

BOOL WINAPI VDDInstallMemoryHook ( IN HANDLE  hVdd,
IN PVOID  pStart,
IN DWORD  dwCount,
IN PVDD_MEMORY_HANDLER  MemoryHandler 
)

Definition at line 470 of file memory.c.

474{
476 PMEM_HOOK Hook;
477 ULONG i;
478 ULONG FirstPage = (ULONG_PTR)PHYS_TO_REAL(pStart) >> 12;
479 ULONG LastPage = ((ULONG_PTR)PHYS_TO_REAL(pStart) + dwCount - 1) >> 12;
480 PVOID Address = (PVOID)REAL_TO_PHYS(FirstPage * PAGE_SIZE);
481 SIZE_T Size = (LastPage - FirstPage + 1) * PAGE_SIZE;
482 PLIST_ENTRY Pointer;
483
484 /* Check validity of the VDD handle */
485 if (hVdd == NULL || hVdd == INVALID_HANDLE_VALUE)
486 {
488 return FALSE;
489 }
490
491 if (dwCount == 0) return FALSE;
492
493 /* Make sure none of these pages are already allocated */
494 for (i = FirstPage; i <= LastPage; i++)
495 {
496 if (PageTable[i] != NULL) return FALSE;
497 }
498
499 for (Pointer = HookList.Flink; Pointer != &HookList; Pointer = Pointer->Flink)
500 {
501 Hook = CONTAINING_RECORD(Pointer, MEM_HOOK, Entry);
502 if (Hook->hVdd == hVdd && Hook->VddHandler == MemoryHandler) break;
503 }
504
505 if (Pointer == &HookList)
506 {
507 /* Create and initialize a new hook entry... */
508 Hook = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(*Hook));
509 if (Hook == NULL)
510 {
512 return FALSE;
513 }
514
515 Hook->hVdd = hVdd;
516 Hook->Count = 0;
518
519 /* ... and add it to the list of hooks */
520 InsertTailList(&HookList, &Hook->Entry);
521 }
522
523 /* Decommit the pages */
525 &Address,
526 &Size,
528 if (!NT_SUCCESS(Status))
529 {
530 if (Pointer == &HookList)
531 {
532 RemoveEntryList(&Hook->Entry);
533 RtlFreeHeap(RtlGetProcessHeap(), 0, Hook);
534 }
535
536 return FALSE;
537 }
538
539 /* Increase the number of pages this hook has */
540 Hook->Count += LastPage - FirstPage + 1;
541
542 /* Add the hook entry to the page table */
543 for (i = FirstPage; i <= LastPage; i++) PageTable[i] = Hook;
544
545 return TRUE;
546}
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
VOID WINAPI MemoryHandler(IN PVOID FaultAddress, IN ULONG RWMode)
Definition: testvdd.c:217

◆ VdmFlushCache()

BOOL WINAPI VdmFlushCache ( IN USHORT  Segment,
IN ULONG  Offset,
IN ULONG  Size,
IN VDM_MODE  Mode 
)

Definition at line 440 of file memory.c.

444{
445 // FIXME
447 return TRUE;
448}

◆ VdmMapFlat()

PVOID WINAPI VdmMapFlat ( IN USHORT  Segment,
IN ULONG  Offset,
IN VDM_MODE  Mode 
)

Definition at line 426 of file memory.c.

429{
430 // FIXME
432
434}
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
_In_ ULONG Mode
Definition: hubbusif.h:303
_Inout_ PVOID Segment
Definition: exfuncs.h:1101

◆ VdmUnmapFlat()

BOOL WINAPI VdmUnmapFlat ( IN USHORT  Segment,
IN ULONG  Offset,
IN PVOID  Buffer,
IN VDM_MODE  Mode 
)

Definition at line 456 of file memory.c.

460{
461 // FIXME
463 return TRUE;
464}

◆ WritePage()

static VOID WritePage ( PMEM_HOOK  Hook,
ULONG  Address,
PVOID  Buffer,
ULONG  Size 
)
inlinestatic

Definition at line 129 of file memory.c.

130{
131 if (!Hook
132 || Hook->hVdd
133 || !Hook->FastWriteHandler
135 {
137 }
138}

Referenced by EmulatorWriteMemory(), and MmFinalizeSectionPageOut().

Variable Documentation

◆ A20Line

BOOLEAN A20Line = FALSE
static

Definition at line 44 of file memory.c.

Referenced by EmulatorGetA20(), EmulatorReadMemory(), EmulatorSetA20(), and EmulatorWriteMemory().

◆ HookList

LIST_ENTRY HookList
static

Definition at line 42 of file memory.c.

Referenced by MemCleanup(), MemInitialize(), MemInstallFastMemoryHook(), and VDDInstallMemoryHook().

◆ PageTable