ReactOS 0.4.16-dev-297-gc569aee
memory.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define TOTAL_PAGES   (MAX_ADDRESS / PAGE_SIZE)
 

Typedefs

typedef VOID(FASTCALLPMEMORY_READ_HANDLER) (ULONG Address, PVOID Buffer, ULONG Size)
 
typedef BOOLEAN(FASTCALLPMEMORY_WRITE_HANDLER) (ULONG Address, PVOID Buffer, ULONG Size)
 

Functions

BOOLEAN MemInitialize (VOID)
 
VOID MemCleanup (VOID)
 
VOID MemExceptionHandler (ULONG FaultAddress, BOOLEAN Writing)
 
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)
 
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)
 

Macro Definition Documentation

◆ TOTAL_PAGES

#define TOTAL_PAGES   (MAX_ADDRESS / PAGE_SIZE)

Definition at line 14 of file memory.h.

Typedef Documentation

◆ PMEMORY_READ_HANDLER

typedef VOID(FASTCALL * PMEMORY_READ_HANDLER) (ULONG Address, PVOID Buffer, ULONG Size)

Definition at line 16 of file memory.h.

◆ PMEMORY_WRITE_HANDLER

typedef BOOLEAN(FASTCALL * PMEMORY_WRITE_HANDLER) (ULONG Address, PVOID Buffer, ULONG Size)

Definition at line 24 of file memory.h.

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:590
#define NULL
Definition: types.h:112
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2686
#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
uint32_t ULONG
Definition: typedefs.h:59
_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:599
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:325
_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
void * PVOID
Definition: typedefs.h:50
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:179

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:608
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#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:5230
#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:73
PVDD_MEMORY_HANDLER VddHandler
Definition: memory.c:32
HANDLE hVdd
Definition: testvdd.c:87

Referenced by CpuExceptionFilter().

◆ 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:4492
#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:1306
#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().