ReactOS  0.4.13-dev-982-g9853eab
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 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;
280  PXMS_HANDLE HandleEntry = GetXmsHandleRecord(Handle);
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;
363  PXMS_HANDLE HandleEntry = GetXmsHandleRecord(Handle);
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 {
382  PXMS_HANDLE HandleEntry = GetXmsHandleRecord(Handle);
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 {
399  PXMS_HANDLE HandleEntry = GetXmsHandleRecord(Handle);
400 
401  if (!ValidateXmsHandle(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;
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 
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  {
656  DWORD 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 
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  {
725  BOOLEAN Result;
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  {
743  BOOLEAN Result;
744  USHORT Segment = getDX();
745 
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 
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 }
#define XMS_STATUS_NOT_LOCKED
Definition: himem.h:35
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
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
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
WORD SourceHandle
Definition: himem.h:55
#define XMS_ADDRESS
Definition: himem.h:15
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
#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
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 UCHAR XmsAlloc(WORD Size, PWORD Handle)
Definition: himem.c:208
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
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
_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
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
void * PVOID
Definition: retypes.h:9
_Inout_ PVOID Segment
Definition: exfuncs.h:893
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
WORD * PWORD
Definition: pedump.c:67
_In_ HANDLE Handle
Definition: extypes.h:390
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
#define WINAPI
Definition: msvc.h:8
#define XMS_STATUS_A20_ERROR
Definition: himem.h:22
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#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
unsigned char BYTE
Definition: mem.h:68
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
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
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
base of all file and directory entries
Definition: entries.h:82
#define XMS_MAX_HANDLES
Definition: himem.h:18
Definition: dlist.c:348
BYTE Handle
Definition: himem.h:45
#define XMS_STATUS_OUT_OF_HANDLES
Definition: himem.h:29