ReactOS 0.4.15-dev-7924-g5949c20
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{
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!
58typedef 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)
90
92
93 BYTE Padding[0x200-0x55];
94
96C_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 */
111static BOOLEAN
112calculate_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
164typedef 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 */
172
173// FIXME: At the moment, all of our diskettes have 512 bytes per sector...
174static 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
189static BOOLEAN
192{
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
245static BOOLEAN
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
322{
323 ASSERT(DiskImage);
324 return (DiskImage->hDisk != INVALID_HANDLE_VALUE && DiskImage->hDisk != NULL);
325}
326
327BYTE
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
358BYTE
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
412BYTE
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
471typedef 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
501 IN ULONG DiskNumber,
504{
506 PDISK_IMAGE DiskImage;
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
531 NULL,
534 NULL);
535 DPRINT1("File '%S' opening %s ; GetLastError() = %u\n",
536 FileName, hFile != INVALID_HANDLE_VALUE ? "succeeded" : "failed", GetLastError());
537
538 /* If we failed, bail out */
540 {
541 DisplayMessage(L"MountDisk: Error when opening disk file '%s' (Error: %u).", FileName, GetLastError());
542 return FALSE;
543 }
544
545 /* OK, we have a handle to the file */
546
547 /*
548 * Check that it is really a file, and not a physical drive.
549 * For obvious security reasons, we do not want to be able to
550 * write directly to physical drives.
551 *
552 * Redundant checks
553 */
554 SetLastError(0);
557 {
558 /* Objects other than real files are not supported */
559 DisplayMessage(L"MountDisk: '%s' is not a valid disk file.", FileName);
560 goto Quit;
561 }
562 SetLastError(0);
565 {
566 /* Objects other than real files are not supported */
567 DisplayMessage(L"MountDisk: '%s' is not a valid disk file.", FileName);
568 goto Quit;
569 }
570
571 /* Success, mount the image */
572 if (!DiskMountInfo[DiskType].MountDiskHelper(DiskImage, hFile))
573 {
574 DisplayMessage(L"MountDisk: Failed to mount disk file '%s' in 0x%p.", FileName, DiskImage);
575 goto Quit;
576 }
577
578 /* Update its read/write state */
579 DiskImage->ReadOnly = ReadOnly;
580
581 Success = TRUE;
582
583Quit:
584 if (!Success) FileClose(hFile);
585 return Success;
586}
587
590 IN ULONG DiskNumber)
591{
592 PDISK_IMAGE DiskImage;
593
594 ASSERT(DiskType < MAX_DISK_TYPE);
595
596 if (DiskNumber >= DiskMountInfo[DiskType].NumDisks)
597 {
598 DisplayMessage(L"UnmountDisk: Disk number %d:%d invalid.", DiskType, DiskNumber);
599 return FALSE;
600 }
601
602 DiskImage = &DiskMountInfo[DiskType].DiskArray[DiskNumber];
603 if (!IsDiskPresent(DiskImage))
604 {
605 DPRINT1("UnmountDisk: Disk %d:%d:0x%p is already unmounted\n", DiskType, DiskNumber, DiskImage);
606 return FALSE;
607 }
608
609 /* Flush the image and unmount it */
610 FlushFileBuffers(DiskImage->hDisk);
611 FileClose(DiskImage->hDisk);
612 DiskImage->hDisk = NULL;
613 return TRUE;
614}
615
616
617/* PUBLIC FUNCTIONS ***********************************************************/
618
620{
621 return TRUE;
622}
623
625{
626 ULONG DiskNumber;
627
628 /* Unmount all the present floppy disk drives */
629 for (DiskNumber = 0; DiskNumber < DiskMountInfo[FLOPPY_DISK].NumDisks; ++DiskNumber)
630 {
631 if (IsDiskPresent(&DiskMountInfo[FLOPPY_DISK].DiskArray[DiskNumber]))
632 UnmountDisk(FLOPPY_DISK, DiskNumber);
633 }
634
635 /* Unmount all the present hard disk drives */
636 for (DiskNumber = 0; DiskNumber < DiskMountInfo[HARD_DISK].NumDisks; ++DiskNumber)
637 {
638 if (IsDiskPresent(&DiskMountInfo[HARD_DISK].DiskArray[DiskNumber]))
639 UnmountDisk(HARD_DISK, DiskNumber);
640 }
641}
642
643/* EOF */
unsigned char BOOLEAN
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define ERROR_INVALID_FUNCTION
Definition: dderror.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define FILE_BEGIN
Definition: compat.h:761
#define RtlUlongByteSwap(_x)
Definition: compat.h:815
#define INVALID_SET_FILE_POINTER
Definition: compat.h:732
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
Definition: fileinfo.c:458
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:25
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
#define TO_LINEAR(seg, off)
Definition: emulator.h:26
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
@ Success
Definition: eventcreate.c:712
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
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
Definition: msctf.idl:550
#define C_ASSERT(e)
Definition: intsafe.h:73
if(dx< 0)
Definition: linetemp.h:194
__u16 heads
Definition: mkdosfs.c:12
#define ASSERT(a)
Definition: mode.c:44
unsigned __int64 ULONG64
Definition: imports.h:198
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
_In_ HANDLE hFile
Definition: mswsock.h:90
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define _ARRAYSIZE(A)
Definition: ntbasedef.h:701
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
@ ReadOnly
Definition: arc.h:80
DWORD ksize
Definition: disk.c:166
WORD secttrack
Definition: disk.c:167
WORD headscyl
Definition: disk.c:168
WORD cylcount
Definition: disk.c:169
WORD biosval
Definition: disk.c:170
HANDLE hDisk
Definition: disk.h:36
BOOLEAN ReadOnly
Definition: disk.h:37
PDISK_IMAGE DiskArray
Definition: disk.c:473
MOUNT_DISK_HANDLER MountDiskHelper
Definition: disk.c:475
ULONG NumDisks
Definition: disk.c:474
FAST486_STATE EmulatorContext
Definition: cpu.c:39
static DISK_MOUNT_INFO DiskMountInfo[MAX_DISK_TYPE]
Definition: disk.c:478
BOOLEAN DiskCtrlInitialize(VOID)
Definition: disk.c:619
struct _VHD_FOOTER VHD_FOOTER
static DISK_GEO DiskGeometryList[]
Definition: disk.c:175
static DISK_IMAGE XDCHardDrive[4]
Definition: disk.c:243
BYTE ReadDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:359
static BOOLEAN MountFDI(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:190
BOOLEAN UnmountDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber)
Definition: disk.c:589
struct _DISK_GEO * PDISK_GEO
VOID DiskCtrlCleanup(VOID)
Definition: disk.c:624
BOOLEAN IsDiskPresent(IN PDISK_IMAGE DiskImage)
Definition: disk.c:321
BYTE WriteDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector, IN BYTE NumSectors)
Definition: disk.c:413
struct _VHD_FOOTER * PVHD_FOOTER
VHD_TYPE
Definition: disk.c:48
@ VHD_DIFFERENCING
Definition: disk.c:51
@ VHD_FIXED
Definition: disk.c:49
@ VHD_DYNAMIC
Definition: disk.c:50
static DISK_IMAGE XDCFloppyDrive[4]
Definition: disk.c:161
static BOOLEAN MountHDD(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:246
BYTE SeekDisk(IN PDISK_IMAGE DiskImage, IN WORD Cylinder, IN BYTE Head, IN BYTE Sector)
Definition: disk.c:328
static WORD HackSectorSize
Definition: disk.c:174
struct _DISK_GEO DISK_GEO
struct _DISK_MOUNT_INFO DISK_MOUNT_INFO
BOOLEAN MountDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber, IN PCWSTR FileName, IN BOOLEAN ReadOnly)
Definition: disk.c:500
BOOLEAN(* MOUNT_DISK_HANDLER)(IN PDISK_IMAGE DiskImage, IN HANDLE hFile)
Definition: disk.c:469
PDISK_IMAGE RetrieveDisk(IN DISK_TYPE DiskType, IN ULONG DiskNumber)
Definition: disk.c:485
struct _DISK_MOUNT_INFO * PDISK_MOUNT_INFO
@ HARD_DISK
Definition: disk.h:45
@ MAX_DISK_TYPE
Definition: disk.h:46
@ FLOPPY_DISK
Definition: disk.h:44
enum _DISK_TYPE DISK_TYPE
VOID FASTCALL EmulatorReadMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:142
VOID FASTCALL EmulatorWriteMemory(PFAST486_STATE State, ULONG Address, PVOID Buffer, ULONG Size)
Definition: memory.c:186
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
const uint16_t * PCWSTR
Definition: typedefs.h:57
uint16_t * PUSHORT
Definition: typedefs.h:56
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
USHORT WINAPI getES(VOID)
Definition: registers.c:522
#define FILE_END
Definition: winbase.h:114
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define INVALID_FILE_SIZE
Definition: winbase.h:548
_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:409
#define RtlUlonglongByteSwap(_x)
Definition: rtlfuncs.h:3199
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3197
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193