ReactOS  r76032
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 
69 static 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 
86 static 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  */
98 static 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  */
121 static LONG A20EnableCount = 0;
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 
133  ++A20EnableCount;
134 
135 Quit:
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 
151  --A20EnableCount;
152 
153  /* The count is zero so disable A20 */
154  if (A20EnableCount == 0)
155  EmulatorSetA20(FALSE); // Result = XMS_STATUS_SUCCESS;
156  else
158 
159 Quit:
160  setAX(0x0001); /* Line successfully disabled */
161  setBL(Result);
162  return;
163 
164 Fail:
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 
181 static inline BOOLEAN ValidateHandle(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 
216  if (Size > FreeBlocks) return XMS_STATUS_OUT_OF_MEMORY;
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 
228  if (i == XMS_MAX_HANDLES) return XMS_STATUS_OUT_OF_HANDLES;
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;
280  PXMS_HANDLE HandleEntry = GetHandleRecord(Handle);
281  DWORD CurrentIndex = 0;
282  ULONG RunStart;
283  ULONG RunSize;
284 
285  if (!ValidateHandle(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 */
304  if (RtlAreBitsClear(&AllocBitmap,
305  BlockNumber + HandleEntry->Size,
306  NewSize - HandleEntry->Size))
307  {
308  /* Just increase the size of this block */
309  RtlSetBits(&AllocBitmap,
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;
363  PXMS_HANDLE HandleEntry = GetHandleRecord(Handle);
364 
365  if (!ValidateHandle(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 {
382  PXMS_HANDLE HandleEntry = GetHandleRecord(Handle);
383 
384  if (!ValidateHandle(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 {
399  PXMS_HANDLE HandleEntry = GetHandleRecord(Handle);
400 
401  if (!ValidateHandle(HandleEntry))
403 
404  if (!HandleEntry->LockCount)
405  return XMS_STATUS_NOT_LOCKED;
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 implicitely 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 
490  IsA20Enabled = TRUE;
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  {
550  setDX(FreeBlocks);
551 
552  if (FreeBlocks > 0)
554  else
556 
557  break;
558  }
559 
560  /* Allocate Extended Memory Block */
561  case 0x09:
562  {
563  WORD Handle;
564  UCHAR Result = XmsAlloc(getDX(), &Handle);
565 
566  if (Result == XMS_STATUS_SUCCESS)
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  {
583  UCHAR Result = XmsFree(getDX());
584 
585  setAX(Result == XMS_STATUS_SUCCESS);
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 = GetHandleRecord(CopyData->SourceHandle);
600  if (!ValidateHandle(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 */
618  SourceAddress = FAR_POINTER(CopyData->SourceOffset);
619  }
620 
621  if (CopyData->DestHandle)
622  {
623  HandleEntry = GetHandleRecord(CopyData->DestHandle);
624  if (!ValidateHandle(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  {
656  DWORD Address;
657  UCHAR Result = XmsLock(getDX(), &Address);
658 
659  if (Result == XMS_STATUS_SUCCESS)
660  {
661  setAX(1);
662 
663  /* Store the LINEAR address in DX:BX */
664  setDX(HIWORD(Address));
665  setBX(LOWORD(Address));
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 
681  setAX(Result == XMS_STATUS_SUCCESS);
682  setBL(Result);
683  break;
684  }
685 
686  /* Get Handle Information */
687  case 0x0E:
688  {
689  PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
690  UINT i;
691  UCHAR Handles = 0;
692 
693  if (!ValidateHandle(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 
717  setAX(Result == XMS_STATUS_SUCCESS);
718  setBL(Result);
719  break;
720  }
721 
722  /* Request UMB */
723  case 0x10:
724  {
725  BOOLEAN Result;
726  USHORT Segment = 0x0000; /* No preferred segment */
727  USHORT Size = getDX(); /* Size is in paragraphs */
728 
729  Result = UmaDescReserve(&Segment, &Size);
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  {
743  BOOLEAN Result;
744  USHORT Segment = getDX();
745 
746  Result = UmaDescRelease(Segment);
747  if (!Result)
749 
750  setAX(Result);
751  break;
752  }
753 
754  /* Reallocate UMB */
755  case 0x12:
756  {
757  BOOLEAN Result;
758  USHORT Segment = getDX();
759  USHORT Size = getBX(); /* Size is in paragraphs */
760 
761  Result = UmaDescReallocate(Segment, &Size);
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 {
798  RtlZeroMemory(HandleTable, sizeof(HandleTable));
801 
804  sizeof(EntryProcedure));
805 
807 
808  /* Copy the entry routine to the device private area */
811  sizeof(EntryProcedure));
812 }
813 
815 {
817  DosDeleteDevice(Node);
818 }
DWORD *typedef PVOID
Definition: winlogon.h:52
#define XMS_STATUS_NOT_LOCKED
Definition: himem.h:35
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
unsigned short WORD
Definition: ntddk_ex.h:93
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
BOOLEAN UmaDescReserve(IN OUT PUSHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:84
#define TRUE
Definition: types.h:120
#define XMS_STATUS_HMA_MIN_SIZE
Definition: himem.h:25
PVOID ULONG Address
Definition: oprghdlr.h:14
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
BOOLEAN EmulatorGetA20(VOID)
Definition: memory.c:277
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define XMS_STATUS_BAD_DEST_OFFSET
Definition: himem.h:34
#define XMS_STATUS_INVALID_UMB
Definition: himem.h:41
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
struct _Entry Entry
Definition: kefuncs.h:640
#define LOBYTE(W)
Definition: jmemdos.c:487
static BOOLEAN IsHmaReserved
Definition: himem.c:103
#define XMS_STATUS_A20_STILL_ENABLED
Definition: himem.h:27
#define XMS_BLOCK_SIZE
Definition: himem.h:16
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
NTSYSAPI BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP, ULONG, ULONG)
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
DWORD SourceOffset
Definition: himem.h:56
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
static WORD FreeBlocks
Definition: himem.c:84
#define HIBYTE(W)
Definition: jmemdos.c:486
#define XMS_STATUS_NOT_IMPLEMENTED
Definition: himem.h:21
#define XMS_STATUS_LOCK_OVERFLOW
Definition: himem.h:37
DWORD DestOffset
Definition: himem.h:58
#define BOP_XMS
Definition: himem.c:65
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
_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:426
WORD SourceHandle
Definition: himem.h:55
#define XMS_ADDRESS
Definition: himem.h:15
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
DWORD DWORD
Definition: winlogon.h:75
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define XMS_STATUS_HMA_IN_USE
Definition: himem.h:24
static WORD HmaMinSize
Definition: himem.c:98
GLenum GLclampf GLint i
Definition: glfuncs.h:14
static UCHAR XmsAlloc(WORD Size, PWORD Handle)
Definition: himem.c:208
#define FALSE
Definition: types.h:117
static BOOLEAN IsA20Enabled
Definition: himem.c:109
long LONG
Definition: pedump.c:60
BOOLEAN XmsGetDriverEntry(PDWORD Pointer)
Definition: himem.c:789
BYTE LockCount
Definition: himem.h:46
#define XMS_STATUS_BAD_SRC_HANDLE
Definition: himem.h:31
WORD DestHandle
Definition: himem.h:57
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
smooth NULL
Definition: ftsmooth.c:557
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
static PXMS_HANDLE GetHandleRecord(WORD Handle)
Definition: himem.c:172
static VOID XmsLocalDisableA20(VOID)
Definition: himem.c:141
#define FAR_POINTER(x)
Definition: emulator.h:31
#define XMS_STATUS_SMALLER_UMB
Definition: himem.h:39
_Inout_ PVOID Segment
Definition: exfuncs.h:893
UINTN Size
Definition: acefiex.h:555
WORD * PWORD
Definition: pedump.c:67
_In_ HANDLE Handle
Definition: extypes.h:390
unsigned char BOOLEAN
struct _XMS_COPY_DATA * PXMS_COPY_DATA
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
WORD Size
Definition: himem.h:47
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:272
DWORD Driver
Definition: device.h:88
#define XMS_STATUS_A20_ERROR
Definition: himem.h:22
static BOOLEAN ValidateHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
#define XMS_STATUS_OUT_OF_UMBS
Definition: himem.h:40
#define XMS_DEVICE_NAME
Definition: himem.c:62
static UCHAR XmsLock(WORD Handle, PDWORD Address)
Definition: himem.c:380
BOOLEAN UmaDescRelease(IN USHORT Segment)
Definition: umamgr.c:207
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
static UCHAR XmsFree(WORD Handle)
Definition: himem.c:360
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
unsigned char UCHAR
Definition: xmlstorage.h:181
#define XMS_STATUS_HMA_NOT_ALLOCATED
Definition: himem.h:26
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
static UCHAR XmsUnlock(WORD Handle)
Definition: himem.c:397
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
static BOOLEAN CanChangeA20
Definition: himem.c:116
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
#define WINAPI
Definition: msvc.h:20
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
unsigned char BYTE
Definition: ntddk_ex.h:96
uint16_t * LPWORD
Definition: typedefs.h:54
DWORD Address
Definition: himem.h:48
Definition: hiveinit.c:368
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
#define XMS_BLOCKS
Definition: himem.h:17
static UCHAR XmsRealloc(WORD Handle, WORD NewSize)
Definition: himem.c:277
unsigned short USHORT
Definition: pedump.c:61
#define EMULATOR_BOP
Definition: bop.h:16
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
#define XMS_STATUS_LOCKED
Definition: himem.h:36
unsigned int UINT
Definition: ndis.h:50
DWORD Count
Definition: himem.h:54
DWORD * PDWORD
Definition: pedump.c:68
static LONG A20EnableCount
Definition: himem.c:121
#define DPRINT1
Definition: precomp.h:8
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
VOID XmsCleanup(VOID)
Definition: himem.c:814
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
Definition: himem.c:413
#define HIWORD(l)
Definition: typedefs.h:246
unsigned int ULONG
Definition: retypes.h:1
VOID XmsInitialize(VOID)
Definition: himem.c:796
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
#define XMS_STATUS_BAD_SRC_OFFSET
Definition: himem.h:33
static VOID XmsLocalEnableA20(VOID)
Definition: himem.c:125
_Must_inspect_result_ typedef _In_ PHYSICAL_ADDRESS SourceAddress
Definition: iotypes.h:1089
static const BYTE EntryProcedure[]
Definition: himem.c:69
BOOLEAN UmaDescReallocate(IN USHORT Segment, IN OUT PUSHORT Size)
Definition: umamgr.c:260
#define LOWORD(l)
Definition: pedump.c:82
static WORD XmsGetLargestFreeBlock(VOID)
Definition: himem.c:186
#define XMS_STATUS_BAD_DEST_HANDLE
Definition: himem.h:32
#define XMS_MAX_HANDLES
Definition: himem.h:18
BYTE Handle
Definition: himem.h:45
#define XMS_STATUS_OUT_OF_HANDLES
Definition: himem.h:29