ReactOS  0.4.14-dev-52-g6116262
emsdrv.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/emsdrv.c
5  * PURPOSE: DOS EMS Driver
6  * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
7  *
8  * DOCUMENTATION: Official specification:
9  * LIM EMS v4.0: http://www.phatcode.net/res/218/files/limems40.txt
10  */
11 
12 /* INCLUDES *******************************************************************/
13 
14 #include "ntvdm.h"
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 #include "emulator.h"
20 #include "../../memory.h"
21 #include "bios/umamgr.h"
22 
23 #include "dos.h"
24 #include "dos/dem.h"
25 #include "device.h"
26 
27 #include "emsdrv.h"
28 
29 #define EMS_DEVICE_NAME "EMMXXXX0"
30 
31 #define EMS_SEGMENT_SIZE ((EMS_PHYSICAL_PAGES * EMS_PAGE_SIZE) >> 4)
32 #define EMS_SYSTEM_HANDLE 0
33 
34 /* PRIVATE VARIABLES **********************************************************/
35 
43 static ULONG EmsTotalPages = 0;
44 static PVOID EmsMemory = NULL;
46 
47 /* PRIVATE FUNCTIONS **********************************************************/
48 
50 {
51  USHORT i;
52 
53  for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
54  {
59  }
60 }
61 
63 {
64  PEMS_HANDLE HandleEntry;
65  USHORT i;
66 
67  /* Handle 0 is reserved (system handle) */
68  for (i = 1; i < ARRAYSIZE(EmsHandleTable); i++)
69  {
70  HandleEntry = &EmsHandleTable[i];
71  if (!HandleEntry->Allocated)
72  {
73  *Handle = i;
74  HandleEntry->Allocated = TRUE;
75  return HandleEntry;
76  }
77  }
78 
79  return NULL;
80 }
81 
82 static VOID FreeHandle(PEMS_HANDLE HandleEntry)
83 {
84  HandleEntry->Allocated = FALSE;
85  HandleEntry->PageCount = 0;
86  RtlZeroMemory(HandleEntry->Name, sizeof(HandleEntry->Name));
87  // InitializeListHead(&HandleEntry->PageList);
88 }
89 
91 {
92  if (Handle >= ARRAYSIZE(EmsHandleTable)) return NULL;
93  return &EmsHandleTable[Handle];
94 }
95 
96 static inline BOOLEAN ValidateHandle(PEMS_HANDLE HandleEntry)
97 {
98  return (HandleEntry != NULL && HandleEntry->Allocated);
99 }
100 
102 {
104  PEMS_HANDLE HandleEntry = GetEmsHandleRecord(Handle);
105 
106  if (!ValidateHandle(HandleEntry))
108 
109  for (Entry = HandleEntry->PageList.Flink;
110  Entry != &HandleEntry->PageList;
111  Entry = Entry->Flink)
112  {
114  ULONG PageNumber = ARRAY_INDEX(PageEntry, EmsPageTable);
115 
116  /* Free the page */
117  RtlClearBits(&AllocBitmap, PageNumber, 1);
118  }
119 
120  InitializeListHead(&HandleEntry->PageList);
121 
122  if (Handle != EMS_SYSTEM_HANDLE)
123  FreeHandle(HandleEntry);
124 
125  return EMS_STATUS_SUCCESS;
126 }
127 
128 static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
129 {
130  ULONG i, CurrentIndex = 0;
131  PEMS_HANDLE HandleEntry;
132 
133  if (NumPages == 0) return EMS_STATUS_ZERO_PAGES;
134 
135  HandleEntry = CreateHandle(Handle);
136  if (!HandleEntry) return EMS_STATUS_NO_MORE_HANDLES;
137 
138  while (HandleEntry->PageCount < NumPages)
139  {
140  ULONG RunStart;
141  ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
142 
143  if (RunSize == 0)
144  {
145  /* Free what's been allocated already and report failure */
146  EmsFree(*Handle);
148  }
149  else if ((HandleEntry->PageCount + RunSize) > NumPages)
150  {
151  /* We don't need the entire run */
152  RunSize = NumPages - HandleEntry->PageCount;
153  }
154 
155  CurrentIndex = RunStart + RunSize;
156  HandleEntry->PageCount += RunSize;
157  RtlSetBits(&AllocBitmap, RunStart, RunSize);
158 
159  for (i = 0; i < RunSize; i++)
160  {
161  EmsPageTable[RunStart + i].Handle = *Handle;
162  InsertTailList(&HandleEntry->PageList, &EmsPageTable[RunStart + i].Entry);
163  }
164  }
165 
166  return EMS_STATUS_SUCCESS;
167 }
168 
169 static UCHAR InitSystemHandle(USHORT NumPages)
170 {
171  //
172  // FIXME: This is an adapted copy of EmsAlloc!!
173  //
174 
175  ULONG i, CurrentIndex = 0;
177 
178  /* The system handle must never have been initialized before */
179  ASSERT(!HandleEntry->Allocated);
180 
181  /* Now allocate it */
182  HandleEntry->Allocated = TRUE;
183 
184  while (HandleEntry->PageCount < NumPages)
185  {
186  ULONG RunStart;
187  ULONG RunSize = RtlFindNextForwardRunClear(&AllocBitmap, CurrentIndex, &RunStart);
188 
189  if (RunSize == 0)
190  {
191  /* Free what's been allocated already and report failure */
193  // FIXME: For this function (and EmsAlloc as well),
194  // use instead an internal function that just uses
195  // PEMS_HANDLE pointers instead. It's only in the
196  // EMS interrupt handler that we should do the
197  // unfolding.
199  }
200  else if ((HandleEntry->PageCount + RunSize) > NumPages)
201  {
202  /* We don't need the entire run */
203  RunSize = NumPages - HandleEntry->PageCount;
204  }
205 
206  CurrentIndex = RunStart + RunSize;
207  HandleEntry->PageCount += RunSize;
208  RtlSetBits(&AllocBitmap, RunStart, RunSize);
209 
210  for (i = 0; i < RunSize; i++)
211  {
212  EmsPageTable[RunStart + i].Handle = EMS_SYSTEM_HANDLE;
213  InsertTailList(&HandleEntry->PageList, &EmsPageTable[RunStart + i].Entry);
214  }
215  }
216 
217  return EMS_STATUS_SUCCESS;
218 }
219 
220 static PEMS_PAGE GetLogicalPage(PEMS_HANDLE HandleEntry, USHORT LogicalPage)
221 {
222  PLIST_ENTRY Entry = HandleEntry->PageList.Flink;
223 
224  while (LogicalPage)
225  {
226  if (Entry == &HandleEntry->PageList) return NULL;
227  LogicalPage--;
228  Entry = Entry->Flink;
229  }
230 
232 }
233 
234 static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
235 {
236  PEMS_PAGE PageEntry;
237  PEMS_HANDLE HandleEntry = GetEmsHandleRecord(Handle);
238 
239  if (!ValidateHandle(HandleEntry))
241 
242  if (PhysicalPage >= EMS_PHYSICAL_PAGES)
244 
245  if (LogicalPage == 0xFFFF)
246  {
247  /* Unmap */
248  Mapping[PhysicalPage] = NULL;
249  return EMS_STATUS_SUCCESS;
250  }
251 
252  PageEntry = GetLogicalPage(HandleEntry, LogicalPage);
253  if (!PageEntry) return EMS_STATUS_INV_LOGICAL_PAGE;
254 
255  Mapping[PhysicalPage] = (PVOID)((ULONG_PTR)EmsMemory
256  + ARRAY_INDEX(PageEntry, EmsPageTable) * EMS_PAGE_SIZE);
257  return EMS_STATUS_SUCCESS;
258 }
259 
261 {
262  switch (getAH())
263  {
264  /* Get Manager Status */
265  case 0x40:
266  {
268  break;
269  }
270 
271  /* Get Page Frame Segment */
272  case 0x41:
273  {
275  setBX(EmsSegment);
276  break;
277  }
278 
279  /* Get Number of Unallocated Pages */
280  case 0x42:
281  {
285  break;
286  }
287 
288  /* Get Handle and Allocate Memory */
289  case 0x43:
290  {
291  USHORT Handle;
293 
294  if (Status == EMS_STATUS_SUCCESS)
295  setDX(Handle);
296 
297  setAH(Status);
298  break;
299  }
300 
301  /* Map Memory */
302  case 0x44:
303  {
304  setAH(EmsMap(getDX(), getAL(), getBX()));
305  break;
306  }
307 
308  /* Release Handle and Memory */
309  case 0x45:
310  {
311  setAH(EmsFree(getDX()));
312  break;
313  }
314 
315  /* Get EMM Version */
316  case 0x46:
317  {
320  break;
321  }
322 
323  /* Save Page Map */
324  case 0x47:
325  {
326  // FIXME: This depends on an EMS handle given in DX
329  break;
330  }
331 
332  /* Restore Page Map */
333  case 0x48:
334  {
335  // FIXME: This depends on an EMS handle given in DX
338  break;
339  }
340 
341  /* Get Number of Opened Handles */
342  case 0x4B:
343  {
344  USHORT NumOpenHandles = 0;
345  USHORT i;
346 
347  for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
348  {
350  ++NumOpenHandles;
351  }
352 
354  setBX(NumOpenHandles);
355  break;
356  }
357 
358  /* Get Handle Number of Pages */
359  case 0x4C:
360  {
361  PEMS_HANDLE HandleEntry = GetEmsHandleRecord(getDX());
362 
363  if (!ValidateHandle(HandleEntry))
364  {
366  break;
367  }
368 
370  setBX(HandleEntry->PageCount);
371  break;
372  }
373 
374  /* Get All Handles Number of Pages */
375  case 0x4D:
376  {
378  USHORT NumOpenHandles = 0;
379  USHORT i;
380 
381  for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
382  {
384  {
385  HandlePageInfo->Handle = i;
386  HandlePageInfo->PageCount = EmsHandleTable[i].PageCount;
387  ++HandlePageInfo;
388  ++NumOpenHandles;
389  }
390  }
391 
393  setBX(NumOpenHandles);
394  break;
395  }
396 
397  /* Get or Set Page Map */
398  case 0x4E:
399  {
400  switch (getAL())
401  {
402  /* Get Mapping Registers */
403  // case 0x00: // TODO: NOT IMPLEMENTED
404 
405  /* Set Mapping Registers */
406  // case 0x01: // TODO: NOT IMPLEMENTED
407 
408  /* Get and Set Mapping Registers At Once */
409  // case 0x02: // TODO: NOT IMPLEMENTED
410 
411  /* Get Size of Page-Mapping Array */
412  case 0x03:
413  {
415  setAL(sizeof(Mapping));
416  break;
417  }
418 
419  default:
420  {
421  DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL());
423  break;
424  }
425  }
426 
427  break;
428  }
429 
430  /* Get/Set Handle Name */
431  case 0x53:
432  {
433  PEMS_HANDLE HandleEntry = GetEmsHandleRecord(getDX());
434 
435  if (!ValidateHandle(HandleEntry))
436  {
438  break;
439  }
440 
441  if (getAL() == 0x00)
442  {
443  /* Retrieve the name */
445  HandleEntry->Name,
446  sizeof(HandleEntry->Name));
448  }
449  else if (getAL() == 0x01)
450  {
451  /* Store the name */
452  RtlCopyMemory(HandleEntry->Name,
453  SEG_OFF_TO_PTR(getDS(), getSI()),
454  sizeof(HandleEntry->Name));
456  }
457  else
458  {
459  DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
461  }
462 
463  break;
464  }
465 
466  /* Handle Directory functions */
467  case 0x54:
468  {
469  if (getAL() == 0x00)
470  {
471  /* Get Handle Directory */
472 
474  USHORT NumOpenHandles = 0;
475  USHORT i;
476 
477  for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
478  {
480  {
481  HandleDir->Handle = i;
482  RtlCopyMemory(HandleDir->Name,
484  sizeof(HandleDir->Name));
485  ++HandleDir;
486  ++NumOpenHandles;
487  }
488  }
489 
491  setAL((UCHAR)NumOpenHandles);
492  }
493  else if (getAL() == 0x01)
494  {
495  /* Search for Named Handle */
496 
497  PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
498  PEMS_HANDLE HandleFound = NULL;
499  USHORT i;
500 
501  for (i = 0; i < ARRAYSIZE(EmsHandleTable); i++)
502  {
503  if (EmsHandleTable[i].Allocated &&
504  RtlCompareMemory(HandleName,
506  sizeof(EmsHandleTable[i].Name)) == sizeof(EmsHandleTable[i].Name))
507  {
508  HandleFound = &EmsHandleTable[i];
509  break;
510  }
511  }
512 
513  /* Bail out if no handle was found */
514  if (i >= ARRAYSIZE(EmsHandleTable)) // HandleFound == NULL
515  {
517  break;
518  }
519 
520  /* Return the handle number */
521  setDX(i);
522 
523  /* Sanity check: Check whether the handle was unnamed */
524  i = 0;
525  while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0'))
526  ++i;
527 
528  if (i >= sizeof(HandleFound->Name))
529  {
531  }
532  else
533  {
535  }
536  }
537  else if (getAL() == 0x02)
538  {
539  /*
540  * Get Total Number of Handles
541  *
542  * This function retrieves the maximum number of handles
543  * (allocated or not) the memory manager supports, which
544  * a program may request.
545  */
548  }
549  else
550  {
551  DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL());
553  }
554 
555  break;
556  }
557 
558  /* Move/Exchange Memory */
559  case 0x57:
560  {
561  PUCHAR SourcePtr, DestPtr;
562  PEMS_HANDLE HandleEntry;
563  PEMS_PAGE PageEntry;
564  BOOLEAN Exchange = getAL();
566 
567  if (Data->SourceType)
568  {
569  /* Expanded memory */
570  HandleEntry = GetEmsHandleRecord(Data->SourceHandle);
571  if (!ValidateHandle(HandleEntry))
572  {
574  break;
575  }
576 
577  PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
578  if (!PageEntry)
579  {
581  break;
582  }
583 
584  SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory
585  + ARRAY_INDEX(PageEntry, EmsPageTable) * EMS_PAGE_SIZE
586  + Data->SourceOffset);
587  }
588  else
589  {
590  /* Conventional memory */
591  SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
592  }
593 
594  if (Data->DestType)
595  {
596  /* Expanded memory */
597  HandleEntry = GetEmsHandleRecord(Data->DestHandle);
598  if (!ValidateHandle(HandleEntry))
599  {
601  break;
602  }
603 
604  PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
605  if (!PageEntry)
606  {
608  break;
609  }
610 
611  DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory
612  + ARRAY_INDEX(PageEntry, EmsPageTable) * EMS_PAGE_SIZE
613  + Data->DestOffset);
614  }
615  else
616  {
617  /* Conventional memory */
618  DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
619  }
620 
621  if (Exchange)
622  {
623  ULONG i;
624 
625  /* Exchange */
626  for (i = 0; i < Data->RegionLength; i++)
627  {
628  UCHAR Temp = DestPtr[i];
629  DestPtr[i] = SourcePtr[i];
630  SourcePtr[i] = Temp;
631  }
632  }
633  else
634  {
635  /* Move */
636  RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
637  }
638 
640  break;
641  }
642 
643  /* Get Mappable Physical Address Array */
644  case 0x58:
645  {
646  if (getAL() == 0x00)
647  {
649  ULONG i;
650 
651  for (i = 0; i < EMS_PHYSICAL_PAGES; i++)
652  {
653  PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4);
654  PageArray->PageNumber = i;
655  ++PageArray;
656  }
657 
660  }
661  else if (getAL() == 0x01)
662  {
665  }
666  else
667  {
668  DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL());
670  }
671 
672  break;
673  }
674 
675  /* Get Expanded Memory Hardware Information */
676  case 0x59:
677  {
678  if (getAL() == 0x00)
679  {
681 
682  /* Return the hardware information */
683  HardwareInfo->RawPageSize = EMS_PAGE_SIZE >> 4;
684  HardwareInfo->AlternateRegSets = 0;
685  HardwareInfo->ContextAreaSize = sizeof(Mapping);
686  HardwareInfo->DmaRegisterSets = 0;
687  HardwareInfo->DmaChannelOperation = 0;
688 
690  }
691  else if (getAL() == 0x01)
692  {
693  /* Same as function AH = 42h */
697  }
698  else
699  {
700  DPRINT1("Invalid subfunction %02X for EMS function AH = 59h\n", getAL());
702  }
703 
704  break;
705  }
706 
707  default:
708  {
709  DPRINT1("EMS function AH = %02X NOT IMPLEMENTED\n", getAH());
711  break;
712  }
713  }
714 }
715 
717 {
718  ULONG i;
719  ULONG RelativeAddress = Address - TO_LINEAR(EmsSegment, 0);
720  ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
721  ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
723 
724  for (i = FirstPage; i <= LastPage; i++)
725  {
726  Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
727  Length = ((i == LastPage)
728  ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
729  : EMS_PAGE_SIZE) - Offset;
730 
733  }
734 }
735 
737 {
738  ULONG i;
739  ULONG RelativeAddress = Address - TO_LINEAR(EmsSegment, 0);
740  ULONG FirstPage = RelativeAddress / EMS_PAGE_SIZE;
741  ULONG LastPage = (RelativeAddress + Size - 1) / EMS_PAGE_SIZE;
743 
744  for (i = FirstPage; i <= LastPage; i++)
745  {
746  Offset = (i == FirstPage) ? RelativeAddress & (EMS_PAGE_SIZE - 1) : 0;
747  Length = ((i == LastPage)
748  ? (RelativeAddress + Size - (LastPage << EMS_PAGE_BITS))
749  : EMS_PAGE_SIZE) - Offset;
750 
753  }
754 
755  return TRUE;
756 }
757 
759 {
760  // TODO: NOT IMPLEMENTED
762  return DOS_DEVSTAT_DONE;
763 }
764 
765 /* PUBLIC FUNCTIONS ***********************************************************/
766 
768 {
769  USHORT Size;
770 
771  /* Try to allocate our page table in UMA at the given segment */
772  EmsSegment = (Segment != 0 ? Segment : EMS_SEGMENT);
773  Size = EMS_SEGMENT_SIZE; // Size in paragraphs
774  if (!UmaDescReserve(&EmsSegment, &Size)) return FALSE;
775 
776  EmsTotalPages = TotalPages;
777  EmsBitmapBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
779  ((TotalPages + 31) / 32) * sizeof(ULONG));
780  if (EmsBitmapBuffer == NULL)
781  {
783  return FALSE;
784  }
785 
787 
788  EmsPageTable = (PEMS_PAGE)RtlAllocateHeap(RtlGetProcessHeap(),
790  TotalPages * sizeof(EMS_PAGE));
791  if (EmsPageTable == NULL)
792  {
793  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
795 
797  return FALSE;
798  }
799 
800  EmsMemory = (PVOID)RtlAllocateHeap(RtlGetProcessHeap(), 0, TotalPages * EMS_PAGE_SIZE);
801  if (EmsMemory == NULL)
802  {
803  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
804  EmsPageTable = NULL;
805  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
807 
809  return FALSE;
810  }
811 
813  /*
814  * FIXME: We should ensure that the system handle is associated
815  * with mapped pages from conventional memory. DosEmu seems to do
816  * it correctly. 384kB of memory mapped.
817  */
818  if (InitSystemHandle(384/16) != EMS_STATUS_SUCCESS)
819  {
820  DPRINT1("Impossible to allocate pages for the system handle!\n");
821 
822  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
823  EmsMemory = NULL;
824  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
825  EmsPageTable = NULL;
826  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
828 
830  return FALSE;
831  }
832 
837 
838  /* Create the device */
842  Node->IoctlReadRoutine = EmsDrvDispatchIoctlRead;
843 
846 
847  return TRUE;
848 }
849 
851 {
852  /* Delete the device */
854 
857 
858  if (EmsMemory)
859  {
860  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsMemory);
861  EmsMemory = NULL;
862  }
863 
864  if (EmsPageTable)
865  {
866  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsPageTable);
867  EmsPageTable = NULL;
868  }
869 
870  if (EmsBitmapBuffer)
871  {
872  RtlFreeHeap(RtlGetProcessHeap(), 0, EmsBitmapBuffer);
874  }
875 
877 }
struct _EMS_MAPPABLE_PHYS_PAGE * PEMS_MAPPABLE_PHYS_PAGE
#define EMS_SYSTEM_HANDLE
Definition: emsdrv.c:32
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
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
LIST_ENTRY PageList
Definition: emsdrv.h:44
USHORT Handle
Definition: emsdrv.h:64
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
_In_ PIRP _In_ PDEVICE_OBJECT Device
Definition: fatprocs.h:2020
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
struct _Entry Entry
Definition: kefuncs.h:640
static ULONG EmsTotalPages
Definition: emsdrv.c:43
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
static USHORT EmsSegment
Definition: emsdrv.c:45
static PVOID Mapping[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:41
unsigned char * PUCHAR
Definition: retypes.h:3
static RTL_BITMAP AllocBitmap
Definition: emsdrv.c:37
#define EMS_STATUS_ZERO_PAGES
Definition: emsdrv.h:32
#define DOS_DEVATTR_IOCTL
Definition: device.h:28
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOL MemRemoveFastMemoryHook(PVOID Address, ULONG Size)
Definition: memory.c:350
#define EMS_PHYSICAL_PAGES
Definition: emsdrv.h:21
UCHAR Name[8]
Definition: emsdrv.h:45
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
#define EMS_SEGMENT
Definition: emsdrv.h:16
UCHAR WINAPI getAH(VOID)
Definition: registers.c:128
WORD RawPageSize
Definition: emsdrv.h:89
UCHAR WINAPI getAL(VOID)
Definition: registers.c:142
#define InsertTailList(ListHead, Entry)
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
#define FASTCALL
Definition: nt_native.h:50
#define EMS_STATUS_INSUFFICIENT_PAGES
Definition: emsdrv.h:31
WORD DmaRegisterSets
Definition: emsdrv.h:92
#define EMS_DEVICE_NAME
Definition: emsdrv.c:29
static PEMS_PAGE EmsPageTable
Definition: emsdrv.c:39
WORD ContextAreaSize
Definition: emsdrv.h:91
static UCHAR InitSystemHandle(USHORT NumPages)
Definition: emsdrv.c:169
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
static EMS_HANDLE EmsHandleTable[EMS_MAX_HANDLES]
Definition: emsdrv.c:40
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _EMS_PAGE * PEMS_PAGE
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define EMS_INTERRUPT_NUM
Definition: emsdrv.h:15
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
WORD DmaChannelOperation
Definition: emsdrv.h:93
static VOID FASTCALL EmsReadMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: emsdrv.c:716
static BOOLEAN FASTCALL EmsWriteMemory(ULONG Address, PVOID Buffer, ULONG Size)
Definition: emsdrv.c:736
#define EMS_STATUS_SUCCESS
Definition: emsdrv.h:26
static BOOLEAN ValidateHandle(PEMS_HANDLE HandleEntry)
Definition: emsdrv.c:96
#define EMS_STATUS_INV_LOGICAL_PAGE
Definition: emsdrv.h:33
USHORT Handle
Definition: emsdrv.h:51
VOID EmsDrvCleanup(VOID)
Definition: emsdrv.c:850
Definition: emsdrv.h:62
ULONG RegisterInt32(IN ULONG FarPtr, IN BYTE IntNumber, IN EMULATOR_INT32_PROC IntHandler, OUT PSIZE_T CodeSize OPTIONAL)
Definition: int32.c:118
VOID DosDeleteDevice(PDOS_DEVICE_NODE DeviceNode)
Definition: device.c:419
BOOLEAN Allocated
Definition: emsdrv.h:42
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
unsigned char BOOLEAN
IN PFCB IN VBO OUT PLBO OUT PULONG OUT PBOOLEAN Allocated
Definition: fatprocs.h:297
#define EMS_SEGMENT_SIZE
Definition: emsdrv.c:31
smooth NULL
Definition: ftsmooth.c:416
static WCHAR Address[46]
Definition: ping.c:68
static PEMS_HANDLE CreateHandle(PUSHORT Handle)
Definition: emsdrv.c:62
NTSYSAPI ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP)
#define Int16To32StubSize
Definition: int32.h:38
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define UlongToPtr(u)
Definition: config.h:106
_Inout_ PVOID Segment
Definition: exfuncs.h:893
LIST_ENTRY Entry
Definition: emsdrv.h:50
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
WORD * PWORD
Definition: pedump.c:67
static WORD NTAPI EmsDrvDispatchIoctlRead(PDOS_DEVICE_NODE Device, DWORD Buffer, PWORD Length)
Definition: emsdrv.c:758
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
BOOLEAN EmsDrvInitialize(USHORT Segment, ULONG TotalPages)
Definition: emsdrv.c:767
static VOID FreeHandle(PEMS_HANDLE HandleEntry)
Definition: emsdrv.c:82
#define DEVICE_PRIVATE_AREA(Driver)
Definition: device.h:16
PDOS_DEVICE_NODE DosCreateDeviceEx(WORD Attributes, PCHAR DeviceName, WORD PrivateDataSize)
Definition: device.c:361
static PEMS_HANDLE GetEmsHandleRecord(USHORT Handle)
Definition: emsdrv.c:90
USHORT WINAPI getES(VOID)
Definition: registers.c:522
BOOL MemInstallFastMemoryHook(PVOID Address, ULONG Size, PMEMORY_READ_HANDLER ReadHandler, PMEMORY_WRITE_HANDLER WriteHandler)
Definition: memory.c:296
#define WINAPI
Definition: msvc.h:8
struct _EMS_HANDLE_DIR_ENTRY * PEMS_HANDLE_DIR_ENTRY
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
BOOLEAN UmaDescRelease(IN USHORT Segment)
Definition: umamgr.c:207
static PULONG EmsBitmapBuffer
Definition: emsdrv.c:38
VOID WINAPI setDX(USHORT)
Definition: registers.c:293
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
#define EMS_MAX_HANDLES
Definition: emsdrv.h:18
#define EMS_STATUS_UNKNOWN_FUNCTION
Definition: emsdrv.h:29
unsigned char UCHAR
Definition: xmlstorage.h:181
static UCHAR EmsAlloc(USHORT NumPages, PUSHORT Handle)
Definition: emsdrv.c:128
#define EMS_STATUS_NO_MORE_HANDLES
Definition: emsdrv.h:30
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
#define EMS_STATUS_UNNAMED_HANDLE
Definition: emsdrv.h:37
#define EMS_STATUS_INVALID_HANDLE
Definition: emsdrv.h:28
#define EMS_PAGE_SIZE
Definition: emsdrv.h:20
Definition: typedefs.h:117
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
struct _EMS_HANDLE_PAGE_INFO * PEMS_HANDLE_PAGE_INFO
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
#define DOS_DEVSTAT_DONE
Definition: device.h:49
#define EMS_STATUS_HANDLE_NOT_FOUND
Definition: emsdrv.h:36
struct _EMS_COPY_DATA * PEMS_COPY_DATA
#define EMS_STATUS_INVALID_SUBFUNCTION
Definition: emsdrv.h:35
Status
Definition: gdiplustypes.h:24
uint16_t * LPWORD
Definition: typedefs.h:54
#define DOS_DEVATTR_CHARACTER
Definition: device.h:29
unsigned short USHORT
Definition: pedump.c:61
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
VOID WINAPI setCX(USHORT)
Definition: registers.c:235
#define DPRINT1
Definition: precomp.h:8
static PDOS_DEVICE_NODE Node
Definition: emsdrv.c:36
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
#define ARRAY_INDEX(ptr, array)
Definition: emulator.h:36
unsigned int ULONG
Definition: retypes.h:1
#define EMS_VERSION_NUM
Definition: emsdrv.h:14
#define UNIMPLEMENTED
Definition: debug.h:114
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
WORD AlternateRegSets
Definition: emsdrv.h:90
NTSYSAPI void WINAPI RtlSetBits(PRTL_BITMAP, ULONG, ULONG)
struct _EMS_HARDWARE_INFO * PEMS_HARDWARE_INFO
#define EMS_PAGE_BITS
Definition: emsdrv.h:19
USHORT PageCount
Definition: emsdrv.h:43
static PVOID EmsMemory
Definition: emsdrv.c:44
static PVOID MappingBackup[EMS_PHYSICAL_PAGES]
Definition: emsdrv.c:42
static UCHAR EmsMap(USHORT Handle, UCHAR PhysicalPage, USHORT LogicalPage)
Definition: emsdrv.c:234
unsigned short * PUSHORT
Definition: retypes.h:2
base of all file and directory entries
Definition: entries.h:82
static VOID WINAPI EmsIntHandler(LPWORD Stack)
Definition: emsdrv.c:260
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
static PEMS_PAGE GetLogicalPage(PEMS_HANDLE HandleEntry, USHORT LogicalPage)
Definition: emsdrv.c:220
static UCHAR EmsFree(USHORT Handle)
Definition: emsdrv.c:101
UCHAR Name[8]
Definition: emsdrv.h:65
Definition: dlist.c:348
#define EMS_STATUS_INV_PHYSICAL_PAGE
Definition: emsdrv.h:34
static VOID InitHandlesTable(VOID)
Definition: emsdrv.c:49
struct _EMS_PAGE EMS_PAGE