Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

743 lines
22 KiB

  1. /*
  2. * demdasd.c - module for direct disk access related support functions
  3. *
  4. * Williamh 09-Dec-1992 Created
  5. * Revision 24-Mar-1993 added fdisk support
  6. */
  7. #include "io.h"
  8. #include "dem.h"
  9. #include "stdio.h"
  10. #include "windows.h"
  11. #include "demdasd.h"
  12. #include "softpc.h"
  13. PBDS demBDS;
  14. BYTE NumberOfFloppy;
  15. BYTE NumberOfFdisk;
  16. extern WORD int13h_vector_off, int13h_vector_seg;
  17. extern WORD int13h_caller_off, int13h_caller_seg;
  18. BPB StdBpb[MAX_FLOPPY_TYPE] = {
  19. {512, 2, 1, 2, 112, 2*9*40, 0xFD, 2, 9, 2, 0, 0}, // 360KB
  20. {512, 1, 1, 2, 224, 2*15*80, 0xF9, 7, 15, 2, 0, 0}, // 1.2MB
  21. {512, 2, 1, 2, 112, 2*9*80, 0xF9, 3, 9, 2, 0, 0}, // 720KB
  22. {512, 1, 1, 2, 224, 2*18*80, 0xF0, 9, 18, 2, 0, 0}, // 1.44MB
  23. {512, 2, 1, 2, 240, 2*36*80, 0xF0, 9, 36, 2, 0, 0} // 2.88MB
  24. };
  25. BYTE FormFactorTable[MAX_FLOPPY_TYPE] = {
  26. FF_360,
  27. FF_120,
  28. FF_720,
  29. FF_144,
  30. FF_288
  31. };
  32. /* demDasdInit - dem diskette system Initialiazation
  33. *
  34. * Entry
  35. * none
  36. *
  37. *
  38. * Exit
  39. * None
  40. */
  41. VOID demDasdInit(VOID)
  42. {
  43. demBDS = NULL;
  44. NumberOfFloppy = NumberOfFdisk = 0;
  45. demFloppyInit();
  46. demFdiskInit();
  47. }
  48. /* demAbsRead - int 25, absolute read
  49. *
  50. * Entry
  51. * Client (AL) = drive number (0 based)
  52. * (DS:BX) = pointer to the buffer to receive the read data
  53. * or pointer to the DISKIO structure
  54. * (CX) = number of sectors to read
  55. * if (0FFFFh) then DS:DX points to DISKIO
  56. * DX contents are discarded
  57. * (DX) = starting sector number
  58. *
  59. *
  60. * Exit
  61. * Client (CY) = 0 if operation succeed
  62. * (AX) = 0
  63. *
  64. * (CY) = 1 if operation failed
  65. * (AX) = error code
  66. */
  67. VOID demAbsRead (VOID)
  68. {
  69. #if DBG
  70. if (fShowSVCMsg & DEM_ABSDRD)
  71. OutputDebugStringOem("DEM: INT 25 Called \n");
  72. #endif
  73. demAbsReadWrite(FALSE);
  74. }
  75. /* demAbsWrite - int 26, absolute read
  76. *
  77. *
  78. * Entry
  79. * Client (AL) = drive number (0 based)
  80. * (DS:BX) = pointer to the buffer to receive the read data
  81. * or pointer to the DISKIO structure
  82. * (CX) = number of sectors to read
  83. * if (0FFFFh) then DS:DX points to DISKIO
  84. * DX contents are discarded
  85. * (DX) = starting sector number
  86. *
  87. *
  88. * Exit
  89. * Client (CY) = 0 if operation succeed
  90. * (AX) = 0
  91. *
  92. * (CY) = 1 if operation failed
  93. * (AX) = error code
  94. */
  95. VOID demAbsWrite(VOID)
  96. {
  97. #if DBG
  98. if (fShowSVCMsg & DEM_ABSWRT)
  99. OutputDebugStringOem("DEM: INT 26 Called \n");
  100. #endif
  101. demAbsReadWrite(TRUE);
  102. }
  103. extern BOOL (*DosWowDoDirectHDPopup)(VOID); // defined in demlfn.c
  104. VOID demAbsReadWrite(BOOL IsWrite)
  105. {
  106. BYTE Drive;
  107. DWORD LastError;
  108. DWORD Sectors;
  109. DWORD StartSector;
  110. PDISKIO DiskIo;
  111. DWORD SectorsReturned;
  112. PBDS pBDS;
  113. WORD BufferOff, BufferSeg;
  114. Drive = getAL();
  115. if ((Sectors = getCX()) == 0xFFFF) {
  116. DiskIo = (PDISKIO) GetVDMAddr(getDS(), getBX());
  117. Sectors = DiskIo->Sectors;
  118. StartSector = DiskIo->StartSector;
  119. BufferOff = DiskIo->BufferOff;
  120. BufferSeg = DiskIo->BufferSeg;
  121. }
  122. else {
  123. StartSector = getDX();
  124. BufferOff = getBX();
  125. BufferSeg = getDS();
  126. }
  127. if ((pBDS = demGetBDS(Drive)) == NULL) {
  128. if (!demIsDriveFloppy(Drive) && Drive < 26) {
  129. if (NULL == DosWowDoDirectHDPopup || (*DosWowDoDirectHDPopup)()) {
  130. host_direct_access_error(NOSUPPORT_HARDDISK);
  131. }
  132. }
  133. setAX(DOS_DRIVE_NOT_READY);
  134. setCF(1);
  135. return;
  136. }
  137. #if DBG
  138. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  139. sprintf(demDebugBuffer, "Drive Number: %d\n", Drive);
  140. OutputDebugStringOem(demDebugBuffer);
  141. sprintf(demDebugBuffer, "StartSector: %d\n", StartSector);
  142. OutputDebugStringOem(demDebugBuffer);
  143. sprintf(demDebugBuffer, "Total Sectors: %d\n", Sectors);
  144. OutputDebugStringOem(demDebugBuffer);
  145. sprintf(demDebugBuffer, "Buffer: %x:%x\n", BufferSeg, BufferOff);
  146. }
  147. #endif
  148. if (IsWrite)
  149. SectorsReturned = demDasdWrite(pBDS,
  150. StartSector,
  151. Sectors,
  152. BufferOff,
  153. BufferSeg
  154. );
  155. else
  156. SectorsReturned = demDasdRead(pBDS,
  157. StartSector,
  158. Sectors,
  159. BufferOff,
  160. BufferSeg
  161. );
  162. if (SectorsReturned != Sectors) {
  163. LastError = GetLastError();
  164. #if DBG
  165. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  166. sprintf(demDebugBuffer, "dem: AbsRDWR Failed, error=%lx\n", LastError);
  167. OutputDebugStringOem(demDebugBuffer);
  168. }
  169. #endif
  170. setAX(demWinErrorToDosError(LastError));
  171. setCF(1);
  172. return;
  173. }
  174. setCF(0);
  175. return;
  176. }
  177. DWORD demDasdRead(
  178. PBDS pbds,
  179. DWORD StartSector,
  180. DWORD Sectors,
  181. WORD BufferOff,
  182. WORD BufferSeg
  183. )
  184. {
  185. ULONG SizeReturned;
  186. LARGE_INTEGER LargeInteger;
  187. DWORD Size;
  188. DWORD SectorSize;
  189. WORD CurBiosDiskIoOff, CurBiosDiskIoSeg;
  190. PBYTE Buffer;
  191. // if this is the first time we access the BDS or
  192. // the media has been changed, build the bds -- floppy
  193. if (!(pbds->Flags & NON_REMOVABLE) &&
  194. ((pbds->Flags & UNFORMATTED_MEDIA) ||
  195. !nt_floppy_media_check(pbds->DrivePhys))) {
  196. if (!demGetBPB(pbds))
  197. return 0;
  198. }
  199. if (StartSector >= pbds->TotalSectors ||
  200. StartSector + Sectors > pbds->TotalSectors) {
  201. SetLastError(ERROR_SECTOR_NOT_FOUND);
  202. return 0 ;
  203. }
  204. SectorSize = pbds->bpb.SectorSize;
  205. LargeInteger.QuadPart = Int32x32To64(Sectors, SectorSize);
  206. // size must fit in ulong
  207. if (LargeInteger.HighPart != 0) {
  208. SetLastError(ERROR_SECTOR_NOT_FOUND);
  209. return 0;
  210. }
  211. Size = LargeInteger.LowPart;
  212. Buffer = (PBYTE) GetVDMAddr(BufferSeg, BufferOff);
  213. if (pbds->Flags & NON_REMOVABLE) {
  214. LargeInteger.QuadPart = Int32x32To64(StartSector, SectorSize);
  215. SizeReturned = nt_fdisk_read(
  216. pbds->DrivePhys,
  217. &LargeInteger,
  218. Size,
  219. Buffer
  220. );
  221. }
  222. else {
  223. // floppy need special care beacuse application may hook
  224. // bios disk interrupt. We dont' do this for hard disks because
  225. // we don't allow int13 to them
  226. sas_loadw(0x13*4, &CurBiosDiskIoOff);
  227. sas_loadw(0x13* 4 + 2, &CurBiosDiskIoSeg);
  228. if (int13h_vector_off == CurBiosDiskIoOff &&
  229. int13h_vector_seg == CurBiosDiskIoSeg)
  230. SizeReturned = nt_floppy_read(
  231. pbds->DrivePhys,
  232. StartSector * SectorSize,
  233. Size,
  234. Buffer
  235. );
  236. else
  237. return (demBiosDiskIoRW(pbds,
  238. StartSector,
  239. Sectors,
  240. BufferOff,
  241. BufferSeg,
  242. FALSE
  243. ));
  244. }
  245. if (SizeReturned == Size)
  246. return Sectors;
  247. else
  248. return SizeReturned / SectorSize;
  249. }
  250. DWORD demDasdWrite(
  251. PBDS pbds,
  252. DWORD StartSector,
  253. DWORD Sectors,
  254. WORD BufferOff,
  255. WORD BufferSeg
  256. )
  257. {
  258. ULONG SizeReturned;
  259. LARGE_INTEGER LargeInteger;
  260. DWORD Size;
  261. DWORD SectorSize;
  262. WORD CurBiosDiskIoOff, CurBiosDiskIoSeg;
  263. PBYTE Buffer;
  264. // if this is the first time we access the BDS or
  265. // the media has been changed, build the bds
  266. if (!(pbds->Flags & NON_REMOVABLE) &&
  267. ((pbds->Flags & UNFORMATTED_MEDIA) ||
  268. !nt_floppy_media_check(pbds->DrivePhys))) {
  269. if (!demGetBPB(pbds))
  270. return 0;
  271. }
  272. if (StartSector >= pbds->TotalSectors ||
  273. StartSector + Sectors > pbds->TotalSectors) {
  274. SetLastError(ERROR_SECTOR_NOT_FOUND);
  275. return 0 ;
  276. }
  277. SectorSize = pbds->bpb.SectorSize;
  278. LargeInteger.QuadPart = Int32x32To64(Sectors, SectorSize);
  279. // size must fit in ulong
  280. if (LargeInteger.HighPart != 0) {
  281. SetLastError(ERROR_SECTOR_NOT_FOUND);
  282. return 0;
  283. }
  284. Size = LargeInteger.LowPart;
  285. Buffer = (PBYTE) GetVDMAddr(BufferSeg, BufferOff);
  286. if (pbds->Flags & NON_REMOVABLE) {
  287. LargeInteger.QuadPart = Int32x32To64(StartSector, SectorSize);
  288. SizeReturned = nt_fdisk_write(
  289. pbds->DrivePhys,
  290. &LargeInteger,
  291. Size,
  292. Buffer
  293. );
  294. }
  295. else {
  296. // floppy need special care beacuse application may hook
  297. // bios disk interrupt. We dont' do this for hard disks because
  298. // we don't allow int13 to them
  299. sas_loadw(0x13*4, &CurBiosDiskIoOff);
  300. sas_loadw(0x13* 4 + 2, &CurBiosDiskIoSeg);
  301. if (int13h_vector_off == CurBiosDiskIoOff &&
  302. int13h_vector_seg == CurBiosDiskIoSeg)
  303. SizeReturned = nt_floppy_write(
  304. pbds->DrivePhys,
  305. StartSector * SectorSize,
  306. Size,
  307. Buffer
  308. );
  309. else
  310. return(demBiosDiskIoRW(pbds,
  311. StartSector,
  312. Sectors,
  313. BufferOff,
  314. BufferSeg,
  315. TRUE
  316. ));
  317. }
  318. if (Size == SizeReturned)
  319. return Sectors;
  320. else
  321. return SizeReturned / SectorSize;
  322. }
  323. BOOL demDasdFormat(PBDS pbds, DWORD Head, DWORD Cylinder, MEDIA_TYPE * Media)
  324. {
  325. BOOL Result;
  326. if (pbds->Flags & NON_REMOVABLE)
  327. Result = demDasdVerify(pbds, Head, Cylinder);
  328. else {
  329. if (*Media == Unknown) {
  330. *Media = nt_floppy_get_media_type(pbds->DrivePhys,
  331. pbds->Cylinders,
  332. pbds->bpb.TrackSize,
  333. pbds->bpb.Heads
  334. );
  335. return TRUE;
  336. }
  337. else {
  338. Result = nt_floppy_format(pbds->DrivePhys,
  339. (WORD)Cylinder,
  340. (WORD)Head,
  341. *Media
  342. );
  343. }
  344. }
  345. return (Result);
  346. }
  347. BOOL demDasdVerify(PBDS pbds, DWORD Head, DWORD Cylinder)
  348. {
  349. DWORD Size, StartSector;
  350. LARGE_INTEGER LargeInteger;
  351. // if floppy, make sure we have up-to-date BPB and a valid media is in
  352. if (!(pbds->Flags & NON_REMOVABLE)) {
  353. if (!demGetBPB(pbds))
  354. return FALSE;
  355. Size = pbds->bpb.TrackSize * pbds->bpb.SectorSize;
  356. StartSector = pbds->bpb.TrackSize * (Cylinder * pbds->bpb.Heads + Head) + 1;
  357. return (nt_floppy_verify(pbds->DrivePhys,
  358. StartSector * pbds->bpb.SectorSize,
  359. Size));
  360. }
  361. // hard disk needs special care because of their size
  362. Size = pbds->bpb.TrackSize * pbds->bpb.SectorSize;
  363. StartSector = pbds->bpb.TrackSize * (Cylinder * pbds->bpb.Heads + Head) + 1;
  364. LargeInteger.QuadPart = Int32x32To64(StartSector, pbds->bpb.SectorSize);
  365. return (nt_fdisk_verify(pbds->DrivePhys,
  366. &LargeInteger,
  367. Size
  368. ));
  369. }
  370. PBDS demGetBDS(BYTE DriveLog)
  371. {
  372. PBDS pbds;
  373. pbds = demBDS;
  374. while (pbds != NULL && pbds->DriveLog != DriveLog)
  375. pbds = pbds->Next;
  376. return pbds;
  377. }
  378. BOOL demGetBPB(PBDS pbds)
  379. {
  380. PBOOTSECTOR pbs;
  381. BYTE SectorBuffer[BYTES_PER_SECTOR];
  382. // when RETURN_FAKE_BPB is set(set by Set Device Parameter IOCTL,
  383. // the appplication has set a new BPB, we simply return it
  384. if (!(pbds->Flags & RETURN_FAKE_BPB) &&
  385. !(pbds->Flags & NON_REMOVABLE) &&
  386. ((pbds->Flags & UNFORMATTED_MEDIA) || !nt_floppy_media_check(pbds->DrivePhys))
  387. ) {
  388. pbds->Flags &= ~(UNFORMATTED_MEDIA);
  389. nt_floppy_close(pbds->DrivePhys);
  390. if (nt_floppy_read(pbds->DrivePhys,
  391. 0,
  392. BYTES_PER_SECTOR,
  393. SectorBuffer
  394. ) != BYTES_PER_SECTOR)
  395. return FALSE;
  396. pbs = (PBOOTSECTOR)SectorBuffer;
  397. if ((pbs->Jump == 0x69 || pbs->Jump == 0xE9 ||
  398. (pbs->Jump == 0xEB && pbs->Target[1] == 0x90)) &&
  399. (pbs->bpb.MediaID & 0xF0) == 0xF0) {
  400. pbds->bpb = pbs->bpb;
  401. pbds->TotalSectors = (pbs->bpb.Sectors) ? pbs->bpb.Sectors :
  402. pbs->bpb.BigSectors;
  403. return TRUE;
  404. }
  405. // an unknown media found
  406. else {
  407. pbds->Flags |= UNFORMATTED_MEDIA;
  408. // What should we do here? The diskette has strange boot sector
  409. // should we guess it or what?
  410. //
  411. #if DEVL
  412. if (fShowSVCMsg & (DEM_ABSDRD | DEM_ABSWRT)) {
  413. sprintf(demDebugBuffer, "Invalid Boot Sector Found\n");
  414. OutputDebugStringOem(demDebugBuffer);
  415. }
  416. #endif
  417. host_direct_access_error(NOSUPPORT_FLOPPY);
  418. return FALSE;
  419. }
  420. }
  421. return TRUE;
  422. }
  423. DWORD demBiosDiskIoRW(
  424. PBDS pbds,
  425. DWORD StartSector,
  426. DWORD Sectors,
  427. WORD BufferOff,
  428. WORD BufferSeg,
  429. BOOL IsWrite
  430. )
  431. {
  432. BYTE CurHead, CurSector, BiosErrorCode;
  433. WORD CurTrack, TrackSize, Heads, SectorTrack;
  434. WORD AX, BX, CX, DX, ES, CS, IP;
  435. BYTE SectorsRead, SectorsToRead;
  436. WORD wRetry = 3;
  437. AX = getAX();
  438. BX = getBX();
  439. CX = getCX();
  440. DX = getDX();
  441. ES = getES();
  442. CS = getCS();
  443. IP = getIP();
  444. TrackSize = pbds->bpb.TrackSize;
  445. Heads = pbds->bpb.Heads;
  446. SectorsRead = 0;
  447. CurSector = (BYTE) ((StartSector % TrackSize) + 1);
  448. CurTrack = (WORD) (StartSector / TrackSize);
  449. CurHead = CurTrack % Heads;
  450. CurTrack /= Heads;
  451. SectorsToRead = TrackSize - CurSector + 1;
  452. while (Sectors != 0) {
  453. if (Sectors < SectorsToRead)
  454. SectorsToRead = (BYTE) Sectors;
  455. // low byte: bit 6 and 7 are high bits of track,
  456. // bit 0 - 5 are sector number
  457. // high byte: bit 0 - bit 7 ->track lower 8 bits
  458. SectorTrack = ((CurTrack & 0x300) >> 2) | (CurSector & 0x3f) |
  459. ((CurTrack &0xFF) << 8);
  460. wRetry = 3;
  461. BiosRetry:
  462. setAH((BYTE) ((IsWrite) ? DISKIO_WRITE : DISKIO_READ));
  463. setAL(SectorsToRead);
  464. setBX(BufferOff);
  465. setES(BufferSeg);
  466. setDH(CurHead);
  467. setDL(pbds->DrivePhys);
  468. setCX(SectorTrack);
  469. setCS(int13h_caller_seg);
  470. setIP(int13h_caller_off);
  471. host_simulate();
  472. if (getCF() == 0) {
  473. SectorsRead += SectorsToRead;
  474. if ((Sectors -= SectorsToRead) == 0)
  475. break;
  476. CurSector = 1;
  477. if (++CurHead == Heads) {
  478. CurHead = 0;
  479. CurTrack++;
  480. }
  481. SectorsToRead = (BYTE) TrackSize;
  482. }
  483. else {
  484. BiosErrorCode = getAH();
  485. // reset the disk
  486. setAH(DISKIO_RESET);
  487. setDL(pbds->DrivePhys);
  488. setCS(int13h_caller_seg);
  489. setIP(int13h_caller_off);
  490. host_simulate();
  491. // NOTE that we dont' handle DMA boundary here
  492. // because it shouldn't happen. -- the NT disk DD
  493. // will take care of that.
  494. if (BiosErrorCode & BIOS_TIME_OUT) {
  495. SetLastError(ERROR_NO_MEDIA_IN_DRIVE);
  496. break;
  497. }
  498. if (wRetry--)
  499. goto BiosRetry;
  500. SetLastError(BiosErrorToNTError(BiosErrorCode));
  501. break;
  502. }
  503. }
  504. setAX(AX);
  505. setBX(BX);
  506. setCX(CX);
  507. setDX(DX);
  508. setES(ES);
  509. setCS(CS);
  510. setIP(IP);
  511. return SectorsRead;
  512. }
  513. DWORD BiosErrorToNTError(BYTE BiosErrorCode)
  514. {
  515. DWORD NtErrorCode;
  516. switch (BiosErrorCode) {
  517. case BIOS_INVALID_FUNCTION:
  518. NtErrorCode = ERROR_BAD_COMMAND;
  519. break;
  520. case BIOS_BAD_ADDRESS_MARK:
  521. NtErrorCode = ERROR_FLOPPY_ID_MARK_NOT_FOUND;
  522. break;
  523. case BIOS_WRITE_PROTECTED:
  524. NtErrorCode = ERROR_WRITE_PROTECT;
  525. break;
  526. case BIOS_BAD_SECTOR:
  527. case BIOS_CRC_ERROR:
  528. NtErrorCode = ERROR_SECTOR_NOT_FOUND;
  529. break;
  530. case BIOS_DISK_CHANGED:
  531. NtErrorCode = ERROR_DISK_CHANGE;
  532. break;
  533. case BIOS_NO_MEDIA:
  534. NtErrorCode = ERROR_NO_MEDIA_IN_DRIVE;
  535. break;
  536. case BIOS_SEEK_ERROR:
  537. NtErrorCode = ERROR_SEEK;
  538. break;
  539. default:
  540. NtErrorCode = ERROR_FLOPPY_UNKNOWN_ERROR;
  541. }
  542. return NtErrorCode;
  543. }
  544. WORD demWinErrorToDosError(DWORD LastError)
  545. {
  546. WORD DosError;
  547. switch(LastError) {
  548. case ERROR_SEEK:
  549. DosError = DOS_SEEK_ERROR;
  550. break;
  551. case ERROR_BAD_UNIT:
  552. DosError = DOS_UNKNOWN_UNIT;
  553. break;
  554. case ERROR_NO_MEDIA_IN_DRIVE:
  555. case ERROR_NOT_READY:
  556. DosError = DOS_DRIVE_NOT_READY;
  557. break;
  558. case ERROR_NOT_DOS_DISK:
  559. DosError = DOS_UNKNOWN_MEDIA;
  560. break;
  561. case ERROR_SECTOR_NOT_FOUND:
  562. case ERROR_FLOPPY_WRONG_CYLINDER:
  563. DosError = DOS_SECTOR_NOT_FOUND;
  564. break;
  565. case ERROR_READ_FAULT:
  566. DosError = DOS_READ_FAULT;
  567. break;
  568. case ERROR_WRITE_FAULT:
  569. DosError = DOS_WRITE_FAULT;
  570. break;
  571. case ERROR_WRONG_DISK:
  572. case ERROR_DISK_CHANGE:
  573. case ERROR_MEDIA_CHANGED:
  574. DosError = DOS_INVALID_MEDIA_CHANGE;
  575. break;
  576. case ERROR_WRITE_PROTECT:
  577. DosError = DOS_WRITE_PROTECTION;
  578. break;
  579. default:
  580. DosError = DOS_GEN_FAILURE;
  581. }
  582. return (DosError);
  583. }
  584. VOID demFdiskInit(VOID)
  585. {
  586. PBDS pbds;
  587. UCHAR Drive;
  588. DISK_GEOMETRY DiskGeometry;
  589. BPB bpb;
  590. Drive = 0;
  591. do {
  592. // first, the drive must be valid
  593. // second, the drive must be a hard disk(fixed)
  594. // third, the drive must be a FAT
  595. if (demGetPhysicalDriveType(Drive) == DRIVE_FIXED &&
  596. nt_fdisk_init(Drive, &bpb, &DiskGeometry)) {
  597. pbds = (PBDS) malloc(sizeof(BDS));
  598. if (pbds != NULL) {
  599. pbds->bpb = bpb;
  600. pbds->rbpb = bpb;
  601. pbds->DrivePhys = NumberOfFdisk++;
  602. pbds->DriveLog = Drive;
  603. pbds->DriveType = DRIVETYPE_FDISK;
  604. pbds->FormFactor = FF_FDISK;
  605. pbds->TotalSectors = (bpb.Sectors) ?
  606. bpb.Sectors :
  607. bpb.BigSectors;
  608. pbds->Cylinders = (WORD) DiskGeometry.Cylinders.LowPart;
  609. pbds->Next = demBDS;
  610. pbds->Flags = NON_REMOVABLE | PHYS_OWNER;
  611. demBDS = pbds;
  612. }
  613. }
  614. } while (++Drive < 26);
  615. }
  616. VOID demFloppyInit(VOID)
  617. {
  618. WORD AX, BX, CX, DX, DI, ES;
  619. BYTE i, MyNumberOfFloppy;
  620. PBDS pbds;
  621. BYTE DriveType;
  622. AX = getAX();
  623. BX = getBX();
  624. CX = getCX();
  625. DX = getDX();
  626. DI = getDI();
  627. ES = getES();
  628. // reset the floppy system
  629. setDL(0);
  630. setAH(DISKIO_RESET);
  631. diskette_io();
  632. setDL(0);
  633. setAH(DISKIO_GETPARAMS);
  634. diskette_io();
  635. if (getCF() == 0 && (MyNumberOfFloppy = getDL()) != 0) {
  636. for(i = 0; i < MyNumberOfFloppy; i++) {
  637. setDL(i);
  638. setAH(DISKIO_GETPARAMS);
  639. diskette_io();
  640. if (getCF() == 0) {
  641. pbds = (PBDS) malloc(sizeof(BDS));
  642. if (pbds == NULL) {
  643. OutputDebugStringOem("dem: not enough memory for BDS\n");
  644. break;
  645. }
  646. pbds->DrivePhys = pbds->DriveLog = i;
  647. pbds->DriveType = DriveType = getBL() & 0x0F;
  648. pbds->fd = NULL;
  649. pbds->Cylinders = getCH() + 1;
  650. pbds->Sectors = getCL();
  651. pbds->rbpb = StdBpb[DriveType - 1];
  652. pbds->TotalSectors = 0;
  653. pbds->Next = demBDS;
  654. pbds->FormFactor = FormFactorTable[DriveType - 1];
  655. demBDS = pbds;
  656. pbds->Flags = UNFORMATTED_MEDIA | PHYS_OWNER;
  657. setAH(DISKIO_DRIVETYPE);
  658. setDL(i);
  659. diskette_io();
  660. if (getAH() == 2 )
  661. pbds->Flags |= HAS_CHANGELINE;
  662. }
  663. }
  664. }
  665. setAX(AX);
  666. setBX(BX);
  667. setCX(CX);
  668. setDX(DX);
  669. setDI(DI);
  670. setES(ES);
  671. }