ReactOS 0.4.15-dev-7788-g1ad9096
himem.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPLv2+ - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
4 * FILE: subsystems/mvdm/ntvdm/dos/dos32krnl/himem.c
5 * PURPOSE: DOS XMS Driver and UMB Provider
6 * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8 *
9 * DOCUMENTATION: Official specifications:
10 * XMS v2.0: http://www.phatcode.net/res/219/files/xms20.txt
11 * XMS v3.0: http://www.phatcode.net/res/219/files/xms30.txt
12 *
13 * About the implementation of UMBs in DOS:
14 * ----------------------------------------
15 * DOS needs a UMB provider to be able to use chunks of RAM in the C000-EFF0
16 * memory region. A UMB provider detects regions of memory that do not contain
17 * any ROMs or other system mapped area such as video RAM.
18 *
19 * Where can UMB providers be found?
20 *
21 * The XMS specification (see himem.c) provides three APIs to create, free, and
22 * resize UMB blocks. As such, DOS performs calls into the XMS driver chain to
23 * request UMB blocks and include them into the DOS memory arena.
24 * However, is it only the HIMEM driver (implementing the XMS specification)
25 * which can provide UMBs? It appears that this is not necessarily the case:
26 * for example the MS HIMEM versions do not implement the UMB APIs; instead
27 * it is the EMS driver (EMM386) which provides them, by hooking into the XMS
28 * driver chain (see https://support.microsoft.com/en-us/kb/95555 : "MS-DOS 5.0
29 * and later EMM386.EXE can also be configured to provide UMBs according to the
30 * XMS. This causes EMM386.EXE to be a provider of the UMB portion of the XMS.").
31 *
32 * Some alternative replacements of HIMEM/EMM386 (for example in FreeDOS)
33 * implement everything inside only one driver (XMS+EMS+UMB provider).
34 * Finally there are some UMB providers that exist separately of XMS and EMS
35 * drivers (for example, UMBPCI): they use hardware-specific tricks to discover
36 * and provide UMBs.
37 *
38 * For more details, see:
39 * http://www.freedos.org/technotes/technote/txt/169.txt
40 * http://www.freedos.org/technotes/technote/txt/202.txt
41 * http://www.uncreativelabs.net/textfiles/system/UMB.TXT
42 *
43 * This DOS XMS Driver provides the UMB APIs that are implemented on top
44 * of the internal Upper Memory Area Manager, in umamgr.c
45 */
46
47/* INCLUDES *******************************************************************/
48
49#include "ntvdm.h"
50
51#define NDEBUG
52#include <debug.h>
53
54#include "emulator.h"
55#include "cpu/bop.h"
56#include "../../memory.h"
57#include "bios/umamgr.h"
58
59#include "device.h"
60#include "himem.h"
61
62#define XMS_DEVICE_NAME "XMSXXXX0"
63
64/* BOP Identifiers */
65#define BOP_XMS 0x52
66
67/* PRIVATE VARIABLES **********************************************************/
68
69static const BYTE EntryProcedure[] =
70{
71 0xEB, // jmp short +0x03
72 0x03,
73 0x90, // nop
74 0x90, // nop
75 0x90, // nop
78 BOP_XMS,
79 0xCB // retf
80};
81
86static ULONG BitmapBuffer[(XMS_BLOCKS + 31) / 32];
87
88/*
89 * This value is associated to HIMEM's "/HMAMIN=" switch. It indicates the
90 * minimum account of space in the HMA a program can use, and is used in
91 * conjunction with the "Request HMA" function.
92 *
93 * NOTE: The "/HMAMIN=" value is in kilo-bytes, whereas HmaMinSize is in bytes.
94 *
95 * Default value: 0. This causes the HMA to be allocated on a first come,
96 * first served basis.
97 */
98static WORD HmaMinSize = 0;
99/*
100 * Flag used by "Request/Release HMA" functions, which indicates
101 * whether the HMA was reserved or not.
102 */
104
105/*
106 * Flag used by "Global Enable/Disable A20" functions, so that they don't
107 * need to re-change the state of A20 if it was already enabled/disabled.
108 */
110/*
111 * This flag is set to TRUE or FALSE when A20 line was already disabled or
112 * enabled when XMS driver was loaded.
113 * In case A20 was disabled, we are allowed to modify it. In case A20 was
114 * already enabled, we are not allowed to touch it.
115 */
117/*
118 * Count for enabling or disabling the A20 line. The A20 line is enabled
119 * only if the enabling count is greater than or equal to 0.
120 */
122
123/* A20 LINE HELPERS ***********************************************************/
124
126{
127 /* Enable A20 only if we can do so, otherwise make the caller believe we enabled it */
128 if (!CanChangeA20) goto Quit;
129
130 /* The count is zero so enable A20 */
132
134
135Quit:
136 setAX(0x0001); /* Line successfully enabled */
138 return;
139}
140
142{
144
145 /* Disable A20 only if we can do so, otherwise make the caller believe we disabled it */
146 if (!CanChangeA20) goto Quit;
147
148 /* If the count is already zero, fail */
149 if (A20EnableCount == 0) goto Fail;
150
152
153 /* The count is zero so disable A20 */
154 if (A20EnableCount == 0)
155 EmulatorSetA20(FALSE); // Result = XMS_STATUS_SUCCESS;
156 else
158
159Quit:
160 setAX(0x0001); /* Line successfully disabled */
161 setBL(Result);
162 return;
163
164Fail:
165 setAX(0x0000); /* Line failed to be disabled */
167 return;
168}
169
170/* PRIVATE FUNCTIONS **********************************************************/
171
173{
175 if (Handle == 0 || Handle >= XMS_MAX_HANDLES) return NULL;
176
177 Entry = &HandleTable[Handle - 1];
178 return Entry->Size ? Entry : NULL;
179}
180
181static inline BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
182{
183 return (HandleEntry != NULL && HandleEntry->Handle != 0);
184}
185
187{
188 WORD Result = 0;
189 DWORD CurrentIndex = 0;
190 ULONG RunStart;
191 ULONG RunSize;
192
193 while (CurrentIndex < XMS_BLOCKS)
194 {
195 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
196 if (RunSize == 0) break;
197
198 /* Update the maximum */
199 if (RunSize > Result) Result = RunSize;
200
201 /* Go to the next run */
202 CurrentIndex = RunStart + RunSize;
203 }
204
205 return Result;
206}
207
209{
210 BYTE i;
211 PXMS_HANDLE HandleEntry;
212 DWORD CurrentIndex = 0;
213 ULONG RunStart;
214 ULONG RunSize;
215
217
218 for (i = 0; i < XMS_MAX_HANDLES; i++)
219 {
220 HandleEntry = &HandleTable[i];
221 if (HandleEntry->Handle == 0)
222 {
223 *Handle = i + 1;
224 break;
225 }
226 }
227
229
230 /* Optimize blocks */
231 for (i = 0; i < XMS_MAX_HANDLES; i++)
232 {
233 /* Skip free and locked blocks */
234 if (HandleEntry->Handle == 0 || HandleEntry->LockCount > 0) continue;
235
236 CurrentIndex = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
237
238 /* Check if there is any free space before this block */
239 RunSize = RtlFindLastBackwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
240 if (RunSize == 0) break;
241
242 /* Move this block back */
243 RtlMoveMemory((PVOID)REAL_TO_PHYS(HandleEntry->Address - RunSize * XMS_BLOCK_SIZE),
244 (PVOID)REAL_TO_PHYS(HandleEntry->Address),
245 RunSize * XMS_BLOCK_SIZE);
246
247 /* Update the address */
248 HandleEntry->Address -= RunSize * XMS_BLOCK_SIZE;
249 }
250
251 while (CurrentIndex < XMS_BLOCKS)
252 {
253 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
254 if (RunSize == 0) break;
255
256 if (RunSize >= HandleEntry->Size)
257 {
258 /* Allocate it here */
259 HandleEntry->Handle = i + 1;
260 HandleEntry->LockCount = 0;
261 HandleEntry->Size = Size;
262 HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE;
263
264 FreeBlocks -= Size;
265 RtlSetBits(&AllocBitmap, RunStart, HandleEntry->Size);
266
267 return XMS_STATUS_SUCCESS;
268 }
269
270 /* Keep searching */
271 CurrentIndex = RunStart + RunSize;
272 }
273
275}
276
278{
279 DWORD BlockNumber;
281 DWORD CurrentIndex = 0;
282 ULONG RunStart;
283 ULONG RunSize;
284
285 if (!ValidateXmsHandle(HandleEntry))
287
288 if (HandleEntry->LockCount)
289 return XMS_STATUS_LOCKED;
290
291 /* Get the block number */
292 BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
293
294 if (NewSize < HandleEntry->Size)
295 {
296 /* Just reduce the size of this block */
297 RtlClearBits(&AllocBitmap, BlockNumber + NewSize, HandleEntry->Size - NewSize);
298 FreeBlocks += HandleEntry->Size - NewSize;
299 HandleEntry->Size = NewSize;
300 }
301 else if (NewSize > HandleEntry->Size)
302 {
303 /* Check if we can expand in-place */
305 BlockNumber + HandleEntry->Size,
306 NewSize - HandleEntry->Size))
307 {
308 /* Just increase the size of this block */
310 BlockNumber + HandleEntry->Size,
311 NewSize - HandleEntry->Size);
312 FreeBlocks -= NewSize - HandleEntry->Size;
313 HandleEntry->Size = NewSize;
314
315 /* We're done */
316 return XMS_STATUS_SUCCESS;
317 }
318
319 /* Deallocate the current block range */
320 RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
321
322 /* Find a new place for this block */
323 while (CurrentIndex < XMS_BLOCKS)
324 {
325 RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
326 if (RunSize == 0) break;
327
328 if (RunSize >= NewSize)
329 {
330 /* Allocate the new range */
331 RtlSetBits(&AllocBitmap, RunStart, NewSize);
332
333 /* Move the data to the new location */
335 (PVOID)REAL_TO_PHYS(HandleEntry->Address),
336 HandleEntry->Size * XMS_BLOCK_SIZE);
337
338 /* Update the handle entry */
339 HandleEntry->Address = XMS_ADDRESS + RunStart * XMS_BLOCK_SIZE;
340 HandleEntry->Size = NewSize;
341
342 /* Update the free block counter */
343 FreeBlocks -= NewSize - HandleEntry->Size;
344
345 return XMS_STATUS_SUCCESS;
346 }
347
348 /* Keep searching */
349 CurrentIndex = RunStart + RunSize;
350 }
351
352 /* Restore the old block range */
353 RtlSetBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
355 }
356
357 return XMS_STATUS_SUCCESS;
358}
359
361{
362 DWORD BlockNumber;
364
365 if (!ValidateXmsHandle(HandleEntry))
367
368 if (HandleEntry->LockCount)
369 return XMS_STATUS_LOCKED;
370
371 BlockNumber = (HandleEntry->Address - XMS_ADDRESS) / XMS_BLOCK_SIZE;
372 RtlClearBits(&AllocBitmap, BlockNumber, HandleEntry->Size);
373
374 HandleEntry->Handle = 0;
375 FreeBlocks += HandleEntry->Size;
376
377 return XMS_STATUS_SUCCESS;
378}
379
381{
383
384 if (!ValidateXmsHandle(HandleEntry))
386
387 if (HandleEntry->LockCount == 0xFF)
389
390 /* Increment the lock count */
391 HandleEntry->LockCount++;
392 *Address = HandleEntry->Address;
393
394 return XMS_STATUS_SUCCESS;
395}
396
398{
400
401 if (!ValidateXmsHandle(HandleEntry))
403
404 if (!HandleEntry->LockCount)
406
407 /* Decrement the lock count */
408 HandleEntry->LockCount--;
409
410 return XMS_STATUS_SUCCESS;
411}
412
414{
415 switch (getAH())
416 {
417 /* Get XMS Version */
418 case 0x00:
419 {
420 setAX(0x0300); /* XMS version 3.00 */
421 setBX(0x0301); /* Driver version 3.01 */
422 setDX(0x0001); /* HMA present */
423 break;
424 }
425
426 /* Request HMA */
427 case 0x01:
428 {
429 /* Check whether HMA is already reserved */
430 if (IsHmaReserved)
431 {
432 /* It is, bail out */
433 setAX(0x0000);
435 break;
436 }
437
438 // NOTE: We implicitly suppose that we always have HMA.
439 // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST
440 // error code.
441
442 /* Check whether the requested size is above the minimal allowed one */
443 if (getDX() < HmaMinSize)
444 {
445 /* It is not, bail out */
446 setAX(0x0000);
448 break;
449 }
450
451 /* Reserve it */
453 setAX(0x0001);
455 break;
456 }
457
458 /* Release HMA */
459 case 0x02:
460 {
461 /* Check whether HMA was reserved */
462 if (!IsHmaReserved)
463 {
464 /* It was not, bail out */
465 setAX(0x0000);
467 break;
468 }
469
470 /* Release it */
472 setAX(0x0001);
474 break;
475 }
476
477 /* Global Enable A20 */
478 case 0x03:
479 {
480 /* Enable A20 if needed */
481 if (!IsA20Enabled)
482 {
484 if (getAX() != 0x0001)
485 {
486 /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */
487 break;
488 }
489
491 }
492
493 setAX(0x0001); /* Line successfully enabled */
495 break;
496 }
497
498 /* Global Disable A20 */
499 case 0x04:
500 {
502
503 /* Disable A20 if needed */
504 if (IsA20Enabled)
505 {
507 if (getAX() != 0x0001)
508 {
509 /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */
510 break;
511 }
512
514 Result = getBL();
515 }
516
517 setAX(0x0001); /* Line successfully disabled */
518 setBL(Result);
519 break;
520 }
521
522 /* Local Enable A20 */
523 case 0x05:
524 {
525 /* This call sets AX and BL to their correct values */
527 break;
528 }
529
530 /* Local Disable A20 */
531 case 0x06:
532 {
533 /* This call sets AX and BL to their correct values */
535 break;
536 }
537
538 /* Query A20 State */
539 case 0x07:
540 {
543 break;
544 }
545
546 /* Query Free Extended Memory */
547 case 0x08:
548 {
551
552 if (FreeBlocks > 0)
554 else
556
557 break;
558 }
559
560 /* Allocate Extended Memory Block */
561 case 0x09:
562 {
563 WORD Handle;
565
567 {
568 setAX(1);
569 setDX(Handle);
570 }
571 else
572 {
573 setAX(0);
574 setBL(Result);
575 }
576
577 break;
578 }
579
580 /* Free Extended Memory Block */
581 case 0x0A:
582 {
584
586 setBL(Result);
587 break;
588 }
589
590 /* Move Extended Memory Block */
591 case 0x0B:
592 {
593 PVOID SourceAddress, DestAddress;
595 PXMS_HANDLE HandleEntry;
596
597 if (CopyData->SourceHandle)
598 {
599 HandleEntry = GetXmsHandleRecord(CopyData->SourceHandle);
600 if (!ValidateXmsHandle(HandleEntry))
601 {
602 setAX(0);
604 break;
605 }
606
607 if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
608 {
609 setAX(0);
611 }
612
613 SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset);
614 }
615 else
616 {
617 /* The offset is actually a 16-bit segment:offset pointer */
619 }
620
621 if (CopyData->DestHandle)
622 {
623 HandleEntry = GetXmsHandleRecord(CopyData->DestHandle);
624 if (!ValidateXmsHandle(HandleEntry))
625 {
626 setAX(0);
628 break;
629 }
630
631 if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
632 {
633 setAX(0);
635 }
636
637 DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset);
638 }
639 else
640 {
641 /* The offset is actually a 16-bit segment:offset pointer */
642 DestAddress = FAR_POINTER(CopyData->DestOffset);
643 }
644
645 /* Perform the move */
646 RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count);
647
648 setAX(1);
650 break;
651 }
652
653 /* Lock Extended Memory Block */
654 case 0x0C:
655 {
658
660 {
661 setAX(1);
662
663 /* Store the LINEAR address in DX:BX */
666 }
667 else
668 {
669 setAX(0);
670 setBL(Result);
671 }
672
673 break;
674 }
675
676 /* Unlock Extended Memory Block */
677 case 0x0D:
678 {
680
682 setBL(Result);
683 break;
684 }
685
686 /* Get Handle Information */
687 case 0x0E:
688 {
689 PXMS_HANDLE HandleEntry = GetXmsHandleRecord(getDX());
690 UINT i;
691 UCHAR Handles = 0;
692
693 if (!ValidateXmsHandle(HandleEntry))
694 {
695 setAX(0);
697 break;
698 }
699
700 for (i = 0; i < XMS_MAX_HANDLES; i++)
701 {
702 if (HandleTable[i].Handle == 0) Handles++;
703 }
704
705 setAX(1);
706 setBH(HandleEntry->LockCount);
707 setBL(Handles);
708 setDX(HandleEntry->Size);
709 break;
710 }
711
712 /* Reallocate Extended Memory Block */
713 case 0x0F:
714 {
716
718 setBL(Result);
719 break;
720 }
721
722 /* Request UMB */
723 case 0x10:
724 {
726 USHORT Segment = 0x0000; /* No preferred segment */
727 USHORT Size = getDX(); /* Size is in paragraphs */
728
730 if (Result)
731 setBX(Segment);
732 else
734
735 setDX(Size);
736 setAX(Result);
737 break;
738 }
739
740 /* Release UMB */
741 case 0x11:
742 {
744 USHORT Segment = getDX();
745
747 if (!Result)
749
750 setAX(Result);
751 break;
752 }
753
754 /* Reallocate UMB */
755 case 0x12:
756 {
758 USHORT Segment = getDX();
759 USHORT Size = getBX(); /* Size is in paragraphs */
760
762 if (!Result)
763 {
764 if (Size > 0)
765 {
767 setDX(Size);
768 }
769 else
770 {
772 }
773 }
774
775 setAX(Result);
776 break;
777 }
778
779 default:
780 {
781 DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH());
783 }
784 }
785}
786
787/* PUBLIC FUNCTIONS ***********************************************************/
788
790{
791 if (Node == NULL) return FALSE;
792 *Pointer = DEVICE_PRIVATE_AREA(Node->Driver);
793 return TRUE;
794}
795
797{
801
804 sizeof(EntryProcedure));
805
807
808 /* Copy the entry routine to the device private area */
811 sizeof(EntryProcedure));
812}
813
815{
818}
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define EMULATOR_BOP
Definition: bop.h:16
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
int Fail
Definition: ehthrow.cxx:24
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:37
#define FAR_POINTER(x)
Definition: emulator.h:35
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:32
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
ULONG Handle
Definition: gdb_input.c:15
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
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
Definition: himem.c:413
static WORD XmsGetLargestFreeBlock(VOID)
Definition: himem.c:186
#define XMS_DEVICE_NAME
Definition: himem.c:62
static const BYTE EntryProcedure[]
Definition: himem.c:69
VOID XmsCleanup(VOID)
Definition: himem.c:814
static UCHAR XmsLock(WORD Handle, PDWORD Address)
Definition: himem.c:380
static UCHAR XmsFree(WORD Handle)
Definition: himem.c:360
BOOLEAN XmsGetDriverEntry(PDWORD Pointer)
Definition: himem.c:789
static UCHAR XmsRealloc(WORD Handle, WORD NewSize)
Definition: himem.c:277
static UCHAR XmsAlloc(WORD Size, PWORD Handle)
Definition: himem.c:208
static WORD FreeBlocks
Definition: himem.c:84
static BOOLEAN IsHmaReserved
Definition: himem.c:103
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
static BOOLEAN IsA20Enabled
Definition: himem.c:109
static LONG A20EnableCount
Definition: himem.c:121
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
#define BOP_XMS
Definition: himem.c:65
static VOID XmsLocalEnableA20(VOID)
Definition: himem.c:125
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
static UCHAR XmsUnlock(WORD Handle)
Definition: himem.c:397
static WORD HmaMinSize
Definition: himem.c:98
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
static BOOLEAN CanChangeA20
Definition: himem.c:116
static VOID XmsLocalDisableA20(VOID)
Definition: himem.c:141
VOID XmsInitialize(VOID)
Definition: himem.c:796
#define XMS_STATUS_LOCK_OVERFLOW
Definition: himem.h:37
#define XMS_STATUS_BAD_SRC_HANDLE
Definition: himem.h:31
#define XMS_ADDRESS
Definition: himem.h:15
#define XMS_STATUS_A20_STILL_ENABLED
Definition: himem.h:27
#define XMS_STATUS_BAD_SRC_OFFSET
Definition: himem.h:33
struct _XMS_COPY_DATA * PXMS_COPY_DATA
#define XMS_STATUS_SMALLER_UMB
Definition: himem.h:39
#define XMS_STATUS_BAD_DEST_HANDLE
Definition: himem.h:32
#define XMS_STATUS_HMA_IN_USE
Definition: himem.h:24
#define XMS_STATUS_A20_ERROR
Definition: himem.h:22
#define XMS_STATUS_INVALID_UMB
Definition: himem.h:41
#define XMS_BLOCKS
Definition: himem.h:17
#define XMS_STATUS_HMA_MIN_SIZE
Definition: himem.h:25
#define XMS_STATUS_OUT_OF_UMBS
Definition: himem.h:40
#define XMS_STATUS_HMA_NOT_ALLOCATED
Definition: himem.h:26
#define XMS_STATUS_BAD_DEST_OFFSET
Definition: himem.h:34
#define XMS_STATUS_NOT_IMPLEMENTED
Definition: himem.h:21
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
#define XMS_STATUS_NOT_LOCKED
Definition: himem.h:35
#define XMS_STATUS_LOCKED
Definition: himem.h:36
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
#define XMS_MAX_HANDLES
Definition: himem.h:18
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_BLOCK_SIZE
Definition: himem.h:16
#define XMS_STATUS_OUT_OF_HANDLES
Definition: himem.h:29
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
NTSYSAPI BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP, ULONG, ULONG)
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
unsigned int UINT
Definition: ndis.h:50
#define LOWORD(l)
Definition: pedump.c:82
WORD * PWORD
Definition: pedump.c:67
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
base of all file and directory entries
Definition: entries.h:83
DWORD SourceOffset
Definition: himem.h:56
DWORD DestOffset
Definition: himem.h:58
WORD SourceHandle
Definition: himem.h:55
WORD DestHandle
Definition: himem.h:57
DWORD Count
Definition: himem.h:54
BYTE Handle
Definition: himem.h:45
WORD Size
Definition: himem.h:47
DWORD Address
Definition: himem.h:48
BYTE LockCount
Definition: himem.h:46
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
BOOLEAN EmulatorGetA20(VOID)
Definition: memory.c:280
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:275
uint16_t * LPWORD
Definition: typedefs.h:56
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
BOOLEAN UmaDescReallocate(IN USHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:260
BOOLEAN UmaDescRelease(IN USHORT Segment)
Definition: umamgr.c:207
BOOLEAN UmaDescReserve(IN OUT PUSHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:84
Definition: dlist.c:348
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define WINAPI
Definition: msvc.h:6
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Inout_ PVOID Segment
Definition: exfuncs.h:1101
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1127
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned char BYTE
Definition: xxhash.c:193