ReactOS  0.4.13-dev-982-g9853eab
disk.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: GPL - See COPYING in the top level directory
3  * PROJECT: ReactOS Virtual DOS Machine
4  * FILE: subsystems/mvdm/ntvdm/hardware/disk.c
5  * PURPOSE: Generic Disk Controller (Floppy, Hard Disk, ...)
6  * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  *
8  * NOTE 1: This file is meant to be splitted into FDC and HDC
9  * when its code will grow out of control!
10  *
11  * NOTE 2: This is poor-man implementation, i.e. at the moment this file
12  * contains an API for manipulating the disks for the rest of NTVDM,
13  * but does not implement real hardware emulation (IO ports, etc...).
14  * One will have to progressively transform it into a real HW emulation
15  * and, in case the disk APIs are needed, move them elsewhere.
16  *
17  * FIXME: The big endian support (which is hardcoded here for machines
18  * in little endian) *MUST* be fixed!
19  */
20 
21 /* INCLUDES *******************************************************************/
22 
23 #include "ntvdm.h"
24 
25 #define NDEBUG
26 #include <debug.h>
27 
28 #include "emulator.h"
29 #include "disk.h"
30 
31 // #include "io.h"
32 #include "memory.h"
33 
34 #include "utils.h"
35 
36 
37 /**************** HARD DRIVES -- VHD FIXED DISK FORMAT SUPPORT ****************/
38 
39 // http://citrixblogger.org/2008/12/01/dynamic-vhd-walkthrough/
40 // http://www.microsoft.com/en-us/download/details.aspx?id=23850
41 // https://projects.honeynet.org/svn/sebek/virtualization/qebek/trunk/block/vpc.c
42 // https://git.virtualopensystems.com/trescca/qemu/raw/40645c7bfd7c4d45381927e1e80081fa827c368a/block/vpc.c
43 // https://gitweb.gentoo.org/proj/qemu-kvm.git/tree/block/vpc.c?h=qemu-kvm-0.12.4-gentoo&id=827dccd6740639c64732418539bf17e6e4c99d77
44 
45 #pragma pack(push, 1)
46 
48 {
49  VHD_FIXED = 2,
52 };
53 
54 // Seconds since Jan 1, 2000 0:00:00 (UTC)
55 #define VHD_TIMESTAMP_BASE 946684800
56 
57 // Always in BIG-endian format!
58 typedef struct _VHD_FOOTER
59 {
60  CHAR creator[8]; // "conectix"
63 
64  // Offset of next header structure, 0xFFFFFFFF if none
66 
67  // Seconds since Jan 1, 2000 0:00:00 (UTC)
69 
70  CHAR creator_app[4]; // "vpc "; "win"
73  CHAR creator_os[4]; // "Wi2k"
74 
77 
81 
82  ULONG type; // VHD_TYPE
83 
84  // Checksum of the Hard Disk Footer ("one's complement of the sum of all
85  // the bytes in the footer without the checksum field")
87 
88  // UUID used to identify a parent hard disk (backing file)
89  BYTE uuid[16];
90 
92 
93  BYTE Padding[0x200-0x55];
94 
96 C_ASSERT(sizeof(VHD_FOOTER) == 0x200);
97 
98 #pragma pack(pop)
99 
100 #if 0
101 /*
102  * Calculates the number of cylinders, heads and sectors per cylinder
103  * based on a given number of sectors. This is the algorithm described
104  * in the VHD specification.
105  *
106  * Note that the geometry doesn't always exactly match total_sectors but
107  * may round it down.
108  *
109  * Returns TRUE on success, FALSE if the size is larger than 127 GB
110  */
111 static BOOLEAN
112 calculate_geometry(ULONG64 total_sectors, PUSHORT cyls,
113  PBYTE heads, PBYTE secs_per_cyl)
114 {
115  ULONG cyls_times_heads;
116 
117  if (total_sectors > 65535 * 16 * 255)
118  return FALSE;
119 
120  if (total_sectors > 65535 * 16 * 63)
121  {
122  *secs_per_cyl = 255;
123  *heads = 16;
124  cyls_times_heads = total_sectors / *secs_per_cyl;
125  }
126  else
127  {
128  *secs_per_cyl = 17;
129  cyls_times_heads = total_sectors / *secs_per_cyl;
130  *heads = (cyls_times_heads + 1023) / 1024;
131 
132  if (*heads < 4)
133  *heads = 4;
134 
135  if (cyls_times_heads >= (*heads * 1024) || *heads > 16)
136  {
137  *secs_per_cyl = 31;
138  *heads = 16;
139  cyls_times_heads = total_sectors / *secs_per_cyl;
140  }
141 
142  if (cyls_times_heads >= (*heads * 1024))
143  {
144  *secs_per_cyl = 63;
145  *heads = 16;
146  cyls_times_heads = total_sectors / *secs_per_cyl;
147  }
148  }
149 
150  *cyls = cyls_times_heads / *heads;
151 
152  return TRUE;
153 }
154 #endif
155 
156 
157 
158 /*************************** FLOPPY DISK CONTROLLER ***************************/
159 
160 // A Floppy Controller can support up to 4 floppy drives.
162 
163 // Taken from DOSBox
164 typedef struct _DISK_GEO
165 {
166  DWORD ksize; /* Size in kilobytes */
167  WORD secttrack; /* Sectors per track */
168  WORD headscyl; /* Heads per cylinder */
169  WORD cylcount; /* Cylinders per side */
170  WORD biosval; /* Type to return from BIOS & CMOS */
171 } DISK_GEO, *PDISK_GEO;
172 
173 // FIXME: At the moment, all of our diskettes have 512 bytes per sector...
174 static WORD HackSectorSize = 512;
176 {
177  { 160, 8, 1, 40, 0},
178  { 180, 9, 1, 40, 0},
179  { 200, 10, 1, 40, 0},
180  { 320, 8, 2, 40, 1},
181  { 360, 9, 2, 40, 1},
182  { 400, 10, 2, 40, 1},
183  { 720, 9, 2, 80, 3},
184  {1200, 15, 2, 80, 2},
185  {1440, 18, 2, 80, 4},
186  {2880, 36, 2, 80, 6},
187 };
188 
189 BOOLEAN
191  IN HANDLE hFile)
192 {
193  ULONG FileSize;
194  USHORT i;
195 
196  /*
197  * Retrieve the size of the file. In NTVDM we will handle files
198  * of maximum 1Mb so we can largely use GetFileSize only.
199  */
202  {
203  /* We failed, bail out */
204  DisplayMessage(L"MountFDI: Error when retrieving file size, or size too large (%d).", FileSize);
205  return FALSE;
206  }
207 
208  /* Convert the size in kB */
209  FileSize /= 1024;
210 
211  /* Find the floppy format in the list, and mount it if found */
212  for (i = 0; i < ARRAYSIZE(DiskGeometryList); ++i)
213  {
214  if (DiskGeometryList[i].ksize == FileSize ||
215  DiskGeometryList[i].ksize + 1 == FileSize)
216  {
217  /* Found, mount it */
218  DiskImage->DiskType = DiskGeometryList[i].biosval;
219  DiskImage->DiskInfo.Cylinders = DiskGeometryList[i].cylcount;
220  DiskImage->DiskInfo.Heads = DiskGeometryList[i].headscyl;
221  DiskImage->DiskInfo.Sectors = DiskGeometryList[i].secttrack;
222  DiskImage->DiskInfo.SectorSize = HackSectorSize;
223 
224  /* Set the file pointer to the beginning */
226 
227  DiskImage->hDisk = hFile;
228  return TRUE;
229  }
230  }
231 
232  /* If we are here, we failed to find a suitable format. Bail out. */
233  DisplayMessage(L"MountFDI: Floppy image of invalid size %d.", FileSize);
234  return FALSE;
235 }
236 
237 
238 /************************** IDE HARD DISK CONTROLLER **************************/
239 
240 // An IDE Hard Disk Controller can support up to 4 drives:
241 // Primary Master Drive, Primary Slave Drive,
242 // Secondary Master Drive, Secondary Slave Drive.
244 
245 BOOLEAN
247  IN HANDLE hFile)
248 {
249  /**** Support for VHD fixed disks ****/
250  DWORD FilePointer, BytesToRead;
251  VHD_FOOTER vhd_footer;
252 
253  /* Go to the end of the file and retrieve the footer */
254  FilePointer = SetFilePointer(hFile, -(LONG)sizeof(VHD_FOOTER), NULL, FILE_END);
255  if (FilePointer == INVALID_SET_FILE_POINTER)
256  {
257  DPRINT1("MountHDD: Error when seeking HDD footer, last error = %d\n", GetLastError());
258  return FALSE;
259  }
260 
261  /* Read footer */
262  // FIXME: We may consider just mapping section to the file...
263  BytesToRead = sizeof(VHD_FOOTER);
264  if (!ReadFile(hFile, &vhd_footer, BytesToRead, &BytesToRead, NULL))
265  {
266  DPRINT1("MountHDD: Error when reading HDD footer, last error = %d\n", GetLastError());
267  return FALSE;
268  }
269 
270  /* Perform validity checks */
271  if (RtlCompareMemory(vhd_footer.creator, "conectix",
272  sizeof(vhd_footer.creator)) != sizeof(vhd_footer.creator))
273  {
274  DisplayMessage(L"MountHDD: Invalid HDD image (expected VHD).");
275  return FALSE;
276  }
277  if (vhd_footer.version != 0x00000100 &&
278  vhd_footer.version != 0x00000500) // FIXME: Big endian!
279  {
280  DisplayMessage(L"MountHDD: VHD HDD image of unexpected version %d.", vhd_footer.version);
281  return FALSE;
282  }
283  if (RtlUlongByteSwap(vhd_footer.type) != VHD_FIXED) // FIXME: Big endian!
284  {
285  DisplayMessage(L"MountHDD: Only VHD HDD fixed images are supported.");
286  return FALSE;
287  }
288  if (vhd_footer.data_offset != 0xFFFFFFFFFFFFFFFF)
289  {
290  DisplayMessage(L"MountHDD: Unexpected data offset for VHD HDD fixed image.");
291  return FALSE;
292  }
293  if (vhd_footer.orig_size != vhd_footer.size)
294  {
295  DisplayMessage(L"MountHDD: VHD HDD fixed image size should be the same as its original size.");
296  return FALSE;
297  }
298  // FIXME: Checksum!
299 
300  /* Found, mount it */
301  DiskImage->DiskType = 0;
302  DiskImage->DiskInfo.Cylinders = RtlUshortByteSwap(vhd_footer.cyls); // FIXME: Big endian!
303  DiskImage->DiskInfo.Heads = vhd_footer.heads;
304  DiskImage->DiskInfo.Sectors = vhd_footer.secs_per_cyl;
305  DiskImage->DiskInfo.SectorSize = RtlUlonglongByteSwap(vhd_footer.size) / // FIXME: Big endian!
306  DiskImage->DiskInfo.Cylinders /
307  DiskImage->DiskInfo.Heads / DiskImage->DiskInfo.Sectors;
308 
309  /* Set the file pointer to the beginning */
311 
312  DiskImage->hDisk = hFile;
313  return TRUE;
314 }
315 
316 
317 
318 /************************ GENERIC DISK CONTROLLER API *************************/
319 
320 BOOLEAN
322 {
323  ASSERT(DiskImage);
324  return (DiskImage->hDisk != INVALID_HANDLE_VALUE && DiskImage->hDisk != NULL);
325 }
326 
327 BYTE
329  IN WORD Cylinder,
330  IN BYTE Head,
331  IN BYTE Sector)
332 {
333  DWORD FilePointer;
334 
335  /* Check that the sector number is 1-based */
336  // FIXME: Or do it in the caller?
337  if (Sector == 0)
338  {
339  /* Return error */
340  return 0x01;
341  }
342 
343  /* Set position */
344  // Compute the offset
345  FilePointer = (DWORD)((DWORD)((DWORD)Cylinder * DiskImage->DiskInfo.Heads + Head)
346  * DiskImage->DiskInfo.Sectors + (Sector - 1))
347  * DiskImage->DiskInfo.SectorSize;
348  FilePointer = SetFilePointer(DiskImage->hDisk, FilePointer, NULL, FILE_BEGIN);
349  if (FilePointer == INVALID_SET_FILE_POINTER)
350  {
351  /* Return error */
352  return 0x40;
353  }
354 
355  return 0x00;
356 }
357 
358 BYTE
360  IN WORD Cylinder,
361  IN BYTE Head,
362  IN BYTE Sector,
363  IN BYTE NumSectors)
364 {
365  BYTE Result;
366  DWORD BytesToRead;
367 
368  PVOID LocalBuffer;
369  BYTE StaticBuffer[1024];
370 
371  /* Read the sectors */
372  Result = SeekDisk(DiskImage, Cylinder, Head, Sector);
373  if (Result != 0x00)
374  return Result;
375 
376  BytesToRead = (DWORD)NumSectors * DiskImage->DiskInfo.SectorSize;
377 
378  // FIXME: Consider just looping around filling each time the buffer...
379 
380  if (BytesToRead <= sizeof(StaticBuffer))
381  {
382  LocalBuffer = StaticBuffer;
383  }
384  else
385  {
386  LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BytesToRead);
387  ASSERT(LocalBuffer != NULL);
388  }
389 
390  if (ReadFile(DiskImage->hDisk, LocalBuffer, BytesToRead, &BytesToRead, NULL))
391  {
392  /* Write to the memory */
394  TO_LINEAR(getES(), getBX()),
395  LocalBuffer,
396  BytesToRead);
397 
398  Result = 0x00;
399  }
400  else
401  {
402  Result = 0x04;
403  }
404 
405  if (LocalBuffer != StaticBuffer)
406  RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
407 
408  /* Return success or error */
409  return Result;
410 }
411 
412 BYTE
414  IN WORD Cylinder,
415  IN BYTE Head,
416  IN BYTE Sector,
417  IN BYTE NumSectors)
418 {
419  BYTE Result;
420  DWORD BytesToWrite;
421 
422  PVOID LocalBuffer;
423  BYTE StaticBuffer[1024];
424 
425  /* Check for write protection */
426  if (DiskImage->ReadOnly)
427  {
428  /* Return error */
429  return 0x03;
430  }
431 
432  /* Write the sectors */
433  Result = SeekDisk(DiskImage, Cylinder, Head, Sector);
434  if (Result != 0x00)
435  return Result;
436 
437  BytesToWrite = (DWORD)NumSectors * DiskImage->DiskInfo.SectorSize;
438 
439  // FIXME: Consider just looping around filling each time the buffer...
440 
441  if (BytesToWrite <= sizeof(StaticBuffer))
442  {
443  LocalBuffer = StaticBuffer;
444  }
445  else
446  {
447  LocalBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BytesToWrite);
448  ASSERT(LocalBuffer != NULL);
449  }
450 
451  /* Read from the memory */
453  TO_LINEAR(getES(), getBX()),
454  LocalBuffer,
455  BytesToWrite);
456 
457  if (WriteFile(DiskImage->hDisk, LocalBuffer, BytesToWrite, &BytesToWrite, NULL))
458  Result = 0x00;
459  else
460  Result = 0x04;
461 
462  if (LocalBuffer != StaticBuffer)
463  RtlFreeHeap(RtlGetProcessHeap(), 0, LocalBuffer);
464 
465  /* Return success or error */
466  return Result;
467 }
468 
470 
471 typedef struct _DISK_MOUNT_INFO
472 {
477 
479 {
482 };
483 
486  IN ULONG DiskNumber)
487 {
488  ASSERT(DiskType < MAX_DISK_TYPE);
489 
490  if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
491  {
492  DisplayMessage(L"RetrieveDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
493  return NULL;
494  }
495 
496  return &DiskMountInfo[DiskType].DiskArray[DiskNumber];
497 }
498 
499 BOOLEAN
501  IN ULONG DiskNumber,
504 {
506  PDISK_IMAGE DiskImage;
507  HANDLE hFile;
508 
510 
511  ASSERT(DiskType < MAX_DISK_TYPE);
512 
513  if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
514  {
515  DisplayMessage(L"MountDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
516  return FALSE;
517  }
518 
519  DiskImage = &DiskMountInfo[DiskType].DiskArray[DiskNumber];
520  if (IsDiskPresent(DiskImage))
521  {
522  DPRINT1("MountDisk: Disk %d:%d:0x%p already in use, recycling...\n", DiskType, DiskNumber, DiskImage);
523  UnmountDisk(DiskType, DiskNumber);
524  }
525 
526  /* Try to open the file */
527  SetLastError(0); // For debugging purposes
528  if (ReadOnly)
529  {
531  GENERIC_READ,
533  NULL,
536  NULL);
537  }
538  else
539  {
542  0, // No sharing access
543  NULL,
546  NULL);
547  }
548  DPRINT1("File '%S' opening %s ; GetLastError() = %u\n",
549  FileName, hFile != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
550 
551  /* If we failed, bail out */
553  {
554  DisplayMessage(L"MountDisk: Error when opening disk file '%s' (Error: %u).", FileName, GetLastError());
555  return FALSE;
556  }
557 
558  /* OK, we have a handle to the file */
559 
560  /*
561  * Check that it is really a file, and not a physical drive.
562  * For obvious security reasons, we do not want to be able to
563  * write directly to physical drives.
564  *
565  * Redundant checks
566  */
567  SetLastError(0);
570  {
571  /* Objects other than real files are not supported */
572  DisplayMessage(L"MountDisk: '%s' is not a valid disk file.", FileName);
573  goto Quit;
574  }
575  SetLastError(0);
578  {
579  /* Objects other than real files are not supported */
580  DisplayMessage(L"MountDisk: '%s' is not a valid disk file.", FileName);
581  goto Quit;
582  }
583 
584  /* Success, mount the image */
585  if (!DiskMountInfo[DiskType].MountDiskHelper(DiskImage, hFile))
586  {
587  DisplayMessage(L"MountDisk: Failed to mount disk file '%s' in 0x%p.", FileName, DiskImage);
588  goto Quit;
589  }
590 
591  /* Update its read/write state */
592  DiskImage->ReadOnly = ReadOnly;
593 
594  Success = TRUE;
595 
596 Quit:
597  if (!Success) FileClose(hFile);
598  return Success;
599 }
600 
601 BOOLEAN
603  IN ULONG DiskNumber)
604 {
605  PDISK_IMAGE DiskImage;
606 
607  ASSERT(DiskType < MAX_DISK_TYPE);
608 
609  if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
610  {
611  DisplayMessage(L"UnmountDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
612  return FALSE;
613  }
614 
615  DiskImage = &DiskMountInfo[DiskType].DiskArray[DiskNumber];
616  if (!IsDiskPresent(DiskImage))
617  {
618  DPRINT1("UnmountDisk: Disk %d:%d:0x%p is already unmounted\n", DiskType, DiskNumber, DiskImage);
619  return FALSE;
620  }
621 
622  /* Flush the image and unmount it */
623  FlushFileBuffers(DiskImage->hDisk);
624  FileClose(DiskImage->hDisk);
625  DiskImage->hDisk = NULL;
626  return TRUE;
627 }
628 
629 
630 /* PUBLIC FUNCTIONS ***********************************************************/
631 
633 {
634  return TRUE;
635 }
636 
638 {
639  ULONG DiskNumber;
640 
641  /* Unmount all the floppy disk drives */
642  for (DiskNumber = 0; DiskNumber < DiskMountInfo[FLOPPY_DISK].NumDisks; ++DiskNumber)
643  UnmountDisk(FLOPPY_DISK, DiskNumber);
644 
645  /* Unmount all the hard disk drives */
646  for (DiskNumber = 0; DiskNumber < DiskMountInfo[HARD_DISK].NumDisks; ++DiskNumber)
647  UnmountDisk(HARD_DISK, DiskNumber);
648 }
649 
650 /* EOF */
BYTE WriteDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:413
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define IN
Definition: typedefs.h:38
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
#define TRUE
Definition: types.h:120
#define INVALID_SET_FILE_POINTER
Definition: winbase.h:115
PDISK_IMAGE DiskArray
Definition: disk.c:473
#define ERROR_SUCCESS
Definition: deptool.c:10
__u16 heads
Definition: mkdosfs.c:370
#define RtlUlonglongByteSwap(_x)
Definition: rtlfuncs.h:3201
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3199
WORD headscyl
Definition: disk.c:168
Definition: arc.h:80
static DISK_GEO DiskGeometryList[]
Definition: disk.c:175
VHD_TYPE
Definition: disk.c:47
char CHAR
Definition: xmlstorage.h:175
#define _ARRAYSIZE(A)
Definition: ntbasedef.h:708
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
BOOLEAN MountHDD(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:246
DWORD ksize
Definition: disk.c:166
WORD secttrack
Definition: disk.c:167
static WORD HackSectorSize
Definition: disk.c:174
BOOLEAN IsDiskPresent(IN PDISK_IMAGE DiskImage)
Definition: disk.c:321
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:183
DWORD total_sectors
Definition: cdmake.c:201
BOOLEAN DiskCtrlInitialize(VOID)
Definition: disk.c:632
#define INVALID_FILE_SIZE
Definition: winbase.h:529
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
#define DWORD
Definition: nt_native.h:44
#define FILE_SHARE_READ
Definition: compat.h:125
static DISK_IMAGE XDCFloppyDrive[4]
Definition: disk.c:161
DWORD WINAPI DECLSPEC_HOTPATCH SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
Definition: fileinfo.c:204
BYTE ReadDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:359
WORD biosval
Definition: disk.c:170
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
long LONG
Definition: pedump.c:60
#define GENERIC_WRITE
Definition: nt_native.h:90
unsigned char BOOLEAN
MOUNT_DISK_HANDLER MountDiskHelper
Definition: disk.c:475
smooth NULL
Definition: ftsmooth.c:416
_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
BOOLEAN MountFDI(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:190
#define OPEN_EXISTING
Definition: compat.h:426
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
C_ASSERT(sizeof(VHD_FOOTER)==0x200)
struct _VHD_FOOTER * PVHD_FOOTER
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:175
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:608
#define FILE_END
Definition: winbase.h:114
if(!(yy_init))
Definition: macro.lex.yy.c:714
USHORT WINAPI getES(VOID)
Definition: registers.c:522
BOOLEAN ReadOnly
Definition: disk.h:37
enum _DISK_TYPE DISK_TYPE
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:481
#define SetLastError(x)
Definition: compat.h:409
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
unsigned __int64 ULONG64
Definition: imports.h:198
ULONG NumDisks
Definition: disk.c:474
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
unsigned char BYTE
Definition: mem.h:68
struct _VHD_FOOTER VHD_FOOTER
#define GENERIC_READ
Definition: compat.h:124
_In_ HANDLE hFile
Definition: mswsock.h:90
#define RtlUlongByteSwap(_x)
Definition: compat.h:465
struct _DISK_GEO * PDISK_GEO
BOOLEAN MountDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber, IN PCWSTR FileName, IN BOOLEAN ReadOnly)
Definition: disk.c:500
#define FILE_BEGIN
Definition: winbase.h:112
HANDLE hDisk
Definition: disk.h:36
unsigned short USHORT
Definition: pedump.c:61
Definition: disk.c:49
BOOLEAN UnmountDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber)
Definition: disk.c:602
PDISK_IMAGE RetrieveDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber)
Definition: disk.c:485
WORD cylcount
Definition: disk.c:169
BYTE SeekDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector)
Definition: disk.c:328
FAST486_STATE EmulatorContext
Definition: cpu.c:39
#define DPRINT1
Definition: precomp.h:8
#define CreateFileW
Definition: compat.h:400
struct _DISK_MOUNT_INFO * PDISK_MOUNT_INFO
#define BOOLEAN
Definition: pedump.c:73
Definition: msctf.idl:510
unsigned int ULONG
Definition: retypes.h:1
struct _DISK_MOUNT_INFO DISK_MOUNT_INFO
VOID DiskCtrlCleanup(VOID)
Definition: disk.c:637
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
BOOL WINAPI ReadFile(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead, OUT LPDWORD lpNumberOfBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:123
static DISK_MOUNT_INFO DiskMountInfo[MAX_DISK_TYPE]
Definition: disk.c:478
BYTE * PBYTE
Definition: pedump.c:66
static DISK_IMAGE XDCHardDrive[4]
Definition: disk.c:243
Definition: disk.h:45
unsigned short * PUSHORT
Definition: retypes.h:2
BOOLEAN(* MOUNT_DISK_HANDLER)(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:469
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:139
struct _DISK_GEO DISK_GEO