ReactOS  0.4.13-dev-1165-gd2976ca
himem.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include "cpu/bop.h"
#include "../../memory.h"
#include "bios/umamgr.h"
#include "device.h"
#include "himem.h"
Include dependency graph for himem.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define XMS_DEVICE_NAME   "XMSXXXX0"
 
#define BOP_XMS   0x52
 

Functions

static VOID XmsLocalEnableA20 (VOID)
 
static VOID XmsLocalDisableA20 (VOID)
 
static PXMS_HANDLE GetXmsHandleRecord (WORD Handle)
 
static BOOLEAN ValidateXmsHandle (PXMS_HANDLE HandleEntry)
 
static WORD XmsGetLargestFreeBlock (VOID)
 
static UCHAR XmsAlloc (WORD Size, PWORD Handle)
 
static UCHAR XmsRealloc (WORD Handle, WORD NewSize)
 
static UCHAR XmsFree (WORD Handle)
 
static UCHAR XmsLock (WORD Handle, PDWORD Address)
 
static UCHAR XmsUnlock (WORD Handle)
 
static VOID WINAPI XmsBopProcedure (LPWORD Stack)
 
BOOLEAN XmsGetDriverEntry (PDWORD Pointer)
 
VOID XmsInitialize (VOID)
 
VOID XmsCleanup (VOID)
 

Variables

static const BYTE EntryProcedure []
 
static PDOS_DEVICE_NODE Node = NULL
 
static XMS_HANDLE HandleTable [XMS_MAX_HANDLES]
 
static WORD FreeBlocks = XMS_BLOCKS
 
static RTL_BITMAP AllocBitmap
 
static ULONG BitmapBuffer [(XMS_BLOCKS+31)/32]
 
static WORD HmaMinSize = 0
 
static BOOLEAN IsHmaReserved = FALSE
 
static BOOLEAN IsA20Enabled = FALSE
 
static BOOLEAN CanChangeA20 = TRUE
 
static LONG A20EnableCount = 0
 

Macro Definition Documentation

◆ BOP_XMS

#define BOP_XMS   0x52

Definition at line 65 of file himem.c.

◆ NDEBUG

#define NDEBUG

Definition at line 51 of file himem.c.

◆ XMS_DEVICE_NAME

#define XMS_DEVICE_NAME   "XMSXXXX0"

Definition at line 62 of file himem.c.

Function Documentation

◆ GetXmsHandleRecord()

static PXMS_HANDLE GetXmsHandleRecord ( WORD  Handle)
inlinestatic

Definition at line 172 of file himem.c.

173 {
175  if (Handle == 0 || Handle >= XMS_MAX_HANDLES) return NULL;
176 
177  Entry = &HandleTable[Handle - 1];
178  return Entry->Size ? Entry : NULL;
179 }
struct _Entry Entry
Definition: kefuncs.h:640
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
smooth NULL
Definition: ftsmooth.c:416
_In_ HANDLE Handle
Definition: extypes.h:390
base of all file and directory entries
Definition: entries.h:82
#define XMS_MAX_HANDLES
Definition: himem.h:18

Referenced by XmsBopProcedure(), XmsFree(), XmsLock(), XmsRealloc(), and XmsUnlock().

◆ ValidateXmsHandle()

static BOOLEAN ValidateXmsHandle ( PXMS_HANDLE  HandleEntry)
inlinestatic

Definition at line 181 of file himem.c.

182 {
183  return (HandleEntry != NULL && HandleEntry->Handle != 0);
184 }
smooth NULL
Definition: ftsmooth.c:416
BYTE Handle
Definition: himem.h:45

Referenced by XmsBopProcedure(), XmsFree(), XmsLock(), XmsRealloc(), and XmsUnlock().

◆ XmsAlloc()

static UCHAR XmsAlloc ( WORD  Size,
PWORD  Handle 
)
static

Definition at line 208 of file himem.c.

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 }
#define XMS_BLOCK_SIZE
Definition: himem.h:16
static WORD FreeBlocks
Definition: himem.c:84
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define XMS_ADDRESS
Definition: himem.h:15
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
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
BYTE LockCount
Definition: himem.h:46
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
_In_ HANDLE Handle
Definition: extypes.h:390
NTSYSAPI ULONG WINAPI RtlFindLastBackwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
WORD Size
Definition: himem.h:47
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
unsigned long DWORD
Definition: ntddk_ex.h:95
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
unsigned char BYTE
Definition: mem.h:68
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
DWORD Address
Definition: himem.h:48
#define XMS_BLOCKS
Definition: himem.h:17
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
#define XMS_MAX_HANDLES
Definition: himem.h:18
BYTE Handle
Definition: himem.h:45
#define XMS_STATUS_OUT_OF_HANDLES
Definition: himem.h:29

Referenced by XmsBopProcedure().

◆ XmsBopProcedure()

static VOID WINAPI XmsBopProcedure ( LPWORD  Stack)
static

Definition at line 413 of file himem.c.

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 }
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
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
#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
static BOOLEAN IsHmaReserved
Definition: himem.c:103
#define XMS_BLOCK_SIZE
Definition: himem.h:16
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
DWORD SourceOffset
Definition: himem.h:56
static WORD FreeBlocks
Definition: himem.c:84
#define XMS_STATUS_NOT_IMPLEMENTED
Definition: himem.h:21
DWORD DestOffset
Definition: himem.h:58
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 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
BYTE LockCount
Definition: himem.h:46
#define XMS_STATUS_BAD_SRC_HANDLE
Definition: himem.h:31
WORD DestHandle
Definition: himem.h:57
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
unsigned char BOOLEAN
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
_In_ HANDLE Handle
Definition: extypes.h:390
struct _XMS_COPY_DATA * PXMS_COPY_DATA
WORD Size
Definition: himem.h:47
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
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
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
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
DWORD Address
Definition: himem.h:48
static UCHAR XmsRealloc(WORD Handle, WORD NewSize)
Definition: himem.c:277
unsigned short USHORT
Definition: pedump.c:61
UCHAR WINAPI getBL(VOID)
Definition: registers.c:198
unsigned int UINT
Definition: ndis.h:50
DWORD Count
Definition: himem.h:54
#define DPRINT1
Definition: precomp.h:8
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
#define HIWORD(l)
Definition: typedefs.h:246
#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:1090
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

Referenced by XmsInitialize().

◆ XmsCleanup()

VOID XmsCleanup ( VOID  )

Definition at line 814 of file himem.c.

815 {
818 }
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define BOP_XMS
Definition: himem.c:65
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
smooth NULL
Definition: ftsmooth.c:416
Definition: dlist.c:348

◆ XmsFree()

static UCHAR XmsFree ( WORD  Handle)
static

Definition at line 360 of file himem.c.

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 }
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define XMS_BLOCK_SIZE
Definition: himem.h:16
static WORD FreeBlocks
Definition: himem.c:84
#define XMS_ADDRESS
Definition: himem.h:15
BYTE LockCount
Definition: himem.h:46
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
_In_ HANDLE Handle
Definition: extypes.h:390
WORD Size
Definition: himem.h:47
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
unsigned long DWORD
Definition: ntddk_ex.h:95
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
DWORD Address
Definition: himem.h:48
#define XMS_STATUS_LOCKED
Definition: himem.h:36
BYTE Handle
Definition: himem.h:45

Referenced by XmsBopProcedure().

◆ XmsGetDriverEntry()

BOOLEAN XmsGetDriverEntry ( PDWORD  Pointer)

Definition at line 789 of file himem.c.

790 {
791  if (Node == NULL) return FALSE;
792  *Pointer = DEVICE_PRIVATE_AREA(Node->Driver);
793  return TRUE;
794 }
#define TRUE
Definition: types.h:120
smooth NULL
Definition: ftsmooth.c:416
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
Definition: dlist.c:348

Referenced by DosInt2Fh().

◆ XmsGetLargestFreeBlock()

static WORD XmsGetLargestFreeBlock ( VOID  )
static

Definition at line 186 of file himem.c.

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 }
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
_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 RTL_BITMAP AllocBitmap
Definition: himem.c:85
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
#define XMS_BLOCKS
Definition: himem.h:17
unsigned int ULONG
Definition: retypes.h:1

Referenced by XmsBopProcedure().

◆ XmsInitialize()

VOID XmsInitialize ( VOID  )

Definition at line 796 of file himem.c.

797 {
801 
804  sizeof(EntryProcedure));
805 
807 
808  /* Copy the entry routine to the device private area */
811  sizeof(EntryProcedure));
812 }
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
#define BOP_XMS
Definition: himem.c:65
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define FAR_POINTER(x)
Definition: emulator.h:31
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
#define XMS_DEVICE_NAME
Definition: himem.c:62
static ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
Definition: himem.c:86
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
#define XMS_BLOCKS
Definition: himem.h:17
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
Definition: himem.c:413
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
static const BYTE EntryProcedure[]
Definition: himem.c:69
Definition: dlist.c:348

Referenced by DosKRNLInitialize().

◆ XmsLocalDisableA20()

static VOID XmsLocalDisableA20 ( VOID  )
static

Definition at line 141 of file himem.c.

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 }
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
#define XMS_STATUS_A20_STILL_ENABLED
Definition: himem.h:27
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
_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
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:272
#define XMS_STATUS_A20_ERROR
Definition: himem.h:22
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
unsigned char UCHAR
Definition: xmlstorage.h:181
static BOOLEAN CanChangeA20
Definition: himem.c:116
Definition: hiveinit.c:368
static LONG A20EnableCount
Definition: himem.c:121

Referenced by XmsBopProcedure().

◆ XmsLocalEnableA20()

static VOID XmsLocalEnableA20 ( VOID  )
static

Definition at line 125 of file himem.c.

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 }
#define TRUE
Definition: types.h:120
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID EmulatorSetA20(BOOLEAN Enabled)
Definition: memory.c:272
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
static BOOLEAN CanChangeA20
Definition: himem.c:116
static LONG A20EnableCount
Definition: himem.c:121

Referenced by XmsBopProcedure().

◆ XmsLock()

static UCHAR XmsLock ( WORD  Handle,
PDWORD  Address 
)
static

Definition at line 380 of file himem.c.

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 }
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
#define XMS_STATUS_LOCK_OVERFLOW
Definition: himem.h:37
BYTE LockCount
Definition: himem.h:46
static WCHAR Address[46]
Definition: ping.c:68
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
_In_ HANDLE Handle
Definition: extypes.h:390
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
DWORD Address
Definition: himem.h:48

Referenced by XmsBopProcedure().

◆ XmsRealloc()

static UCHAR XmsRealloc ( WORD  Handle,
WORD  NewSize 
)
static

Definition at line 277 of file himem.c.

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 }
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
NTSYSAPI void WINAPI RtlClearBits(PRTL_BITMAP, ULONG, ULONG)
#define XMS_BLOCK_SIZE
Definition: himem.h:16
NTSYSAPI BOOLEAN WINAPI RtlAreBitsClear(PCRTL_BITMAP, ULONG, ULONG)
static WORD FreeBlocks
Definition: himem.c:84
#define XMS_ADDRESS
Definition: himem.h:15
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
BYTE LockCount
Definition: himem.h:46
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
#define XMS_STATUS_OUT_OF_MEMORY
Definition: himem.h:28
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
_In_ HANDLE Handle
Definition: extypes.h:390
WORD Size
Definition: himem.h:47
static RTL_BITMAP AllocBitmap
Definition: himem.c:85
unsigned long DWORD
Definition: ntddk_ex.h:95
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30
_Must_inspect_result_ _In_ USHORT NewSize
Definition: fltkernel.h:975
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
DWORD Address
Definition: himem.h:48
#define XMS_BLOCKS
Definition: himem.h:17
#define XMS_STATUS_LOCKED
Definition: himem.h:36
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)

Referenced by XmsBopProcedure().

◆ XmsUnlock()

static UCHAR XmsUnlock ( WORD  Handle)
static

Definition at line 397 of file himem.c.

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 }
#define XMS_STATUS_NOT_LOCKED
Definition: himem.h:35
static PXMS_HANDLE GetXmsHandleRecord(WORD Handle)
Definition: himem.c:172
BYTE LockCount
Definition: himem.h:46
static BOOLEAN ValidateXmsHandle(PXMS_HANDLE HandleEntry)
Definition: himem.c:181
_In_ HANDLE Handle
Definition: extypes.h:390
#define XMS_STATUS_SUCCESS
Definition: himem.h:20
#define XMS_STATUS_INVALID_HANDLE
Definition: himem.h:30

Referenced by XmsBopProcedure().

Variable Documentation

◆ A20EnableCount

LONG A20EnableCount = 0
static

Definition at line 121 of file himem.c.

Referenced by XmsLocalDisableA20(), and XmsLocalEnableA20().

◆ AllocBitmap

RTL_BITMAP AllocBitmap
static

Definition at line 85 of file himem.c.

Referenced by XmsAlloc(), XmsFree(), XmsGetLargestFreeBlock(), XmsInitialize(), and XmsRealloc().

◆ BitmapBuffer

ULONG BitmapBuffer[(XMS_BLOCKS+31)/32]
static

◆ CanChangeA20

BOOLEAN CanChangeA20 = TRUE
static

Definition at line 116 of file himem.c.

Referenced by XmsLocalDisableA20(), and XmsLocalEnableA20().

◆ EntryProcedure

const BYTE EntryProcedure[]
static
Initial value:
=
{
0xEB,
0x03,
0x90,
0x90,
0x90,
0xCB
}
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_XMS
Definition: himem.c:65
#define EMULATOR_BOP
Definition: bop.h:16

Definition at line 69 of file himem.c.

Referenced by XmsInitialize().

◆ FreeBlocks

WORD FreeBlocks = XMS_BLOCKS
static

Definition at line 84 of file himem.c.

Referenced by XmsAlloc(), XmsBopProcedure(), XmsFree(), and XmsRealloc().

◆ HandleTable

◆ HmaMinSize

WORD HmaMinSize = 0
static

Definition at line 98 of file himem.c.

Referenced by XmsBopProcedure().

◆ IsA20Enabled

BOOLEAN IsA20Enabled = FALSE
static

Definition at line 109 of file himem.c.

Referenced by XmsBopProcedure().

◆ IsHmaReserved

BOOLEAN IsHmaReserved = FALSE
static

Definition at line 103 of file himem.c.

Referenced by XmsBopProcedure().

◆ Node

Definition at line 82 of file himem.c.