ReactOS  0.4.13-dev-100-gc8611ae
floppy.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4 
5 Module Name:
6 
7  floppy.c
8 
9 Abstract:
10 
11  SCSI floppy class driver
12 
13 Author:
14 
15  Jeff Havens (jhavens)
16 
17 Environment:
18 
19  kernel mode only
20 
21 Notes:
22 
23 Revision History:
24 02/28/96 georgioc Merged this code with code developed by compaq in
25  parallel with microsoft, for 120MB floppy support.
26 
27 01/17/96 georgioc Made code PNP aware (uses the new \storage\classpnp/scsiport)
28 
29 --*/
30 
31 #ifdef _MSC_VER
32 #pragma warning(disable:4214) // nonstandard extension used : bit field types other than int
33 #pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
34 #endif
35 
36 #include <stddef.h>
37 #include <ntddk.h>
38 #ifndef __REACTOS__
39 #include <winerror.h>
40 #endif
41 #include <scsi.h>
42 #include <classpnp.h>
43 #include <initguid.h>
44 #include <ntddstor.h>
45 
46 #include <ntstrsafe.h>
47 #include <intsafe.h>
48 
49 #define MODE_DATA_SIZE 192
50 #define SCSI_FLOPPY_TIMEOUT 20
51 #define SFLOPPY_SRB_LIST_SIZE 4
52 //
53 // Define all possible drive/media combinations, given drives listed above
54 // and media types in ntdddisk.h.
55 //
56 // These values are used to index the DriveMediaConstants table.
57 //
58 
59 #define NUMBER_OF_DRIVE_TYPES 7
60 #define DRIVE_TYPE_120M 4 //120MB Floptical
61 #define DRIVE_TYPE_NONE NUMBER_OF_DRIVE_TYPES
62 
63 //
64 // This array describes all media types we support.
65 // It should be arranged in the increasing order of density
66 //
67 // For a given drive, we list all the mediatypes that will
68 // work with that drive. For instance, a 120MB drive will
69 // take 720KB media, 1.44MB media, and 120MB media.
70 //
71 // Note that, DriveMediaConstants given below is grouped
72 // as drive and media combination
73 //
74 typedef enum _DRIVE_MEDIA_TYPE {
75  Drive360Media160, // 5.25" 360k drive; 160k media
76  Drive360Media180, // 5.25" 360k drive; 180k media
77  Drive360Media320, // 5.25" 360k drive; 320k media
78  Drive360Media32X, // 5.25" 360k drive; 320k 1k secs
79  Drive360Media360, // 5.25" 360k drive; 360k media
80  Drive720Media720, // 3.5" 720k drive; 720k media
81  Drive120Media160, // 5.25" 1.2Mb drive; 160k media
82  Drive120Media180, // 5.25" 1.2Mb drive; 180k media
83  Drive120Media320, // 5.25" 1.2Mb drive; 320k media
84  Drive120Media32X, // 5.25" 1.2Mb drive; 320k 1k secs
85  Drive120Media360, // 5.25" 1.2Mb drive; 360k media
86  Drive120Media120, // 5.25" 1.2Mb drive; 1.2Mb media
87  Drive144Media720, // 3.5" 1.44Mb drive; 720k media
88  Drive144Media144, // 3.5" 1.44Mb drive; 1.44Mb media
89  Drive288Media720, // 3.5" 2.88Mb drive; 720k media
90  Drive288Media144, // 3.5" 2.88Mb drive; 1.44Mb media
91  Drive288Media288, // 3.5" 2.88Mb drive; 2.88Mb media
92  Drive2080Media720, // 3.5" 20.8Mb drive; 720k media
93  Drive2080Media144, // 3.5" 20.8Mb drive; 1.44Mb media
94  Drive2080Media2080, // 3.5" 20.8Mb drive; 20.8Mb media
95  Drive32MMedia32M, // 3.5" 32Mb drive; 32MB media
96  Drive120MMedia720, // 3.5" 120Mb drive; 720k media
97  Drive120MMedia144, // 3.5" 120Mb drive; 1.44Mb media
98  Drive120MMedia120M, // 3.5" 120Mb drive; 120Mb media
99  Drive240MMedia144M, // 3.5" 240Mb drive; 1.44Mb media
100  Drive240MMedia120M, // 3.5" 240Mb drive; 120Mb media
101  Drive240MMedia240M // 3.5" 240Mb drive; 240Mb media
103 
104 //
105 // When we want to determine the media type in a drive, we will first
106 // guess that the media with highest possible density is in the drive,
107 // and keep trying lower densities until we can successfully read from
108 // the drive.
109 //
110 // These values are used to select a DRIVE_MEDIA_TYPE value.
111 //
112 // The following table defines ranges that apply to the DRIVE_MEDIA_TYPE
113 // enumerated values when trying media types for a particular drive type.
114 // Note that for this to work, the DRIVE_MEDIA_TYPE values must be sorted
115 // by ascending densities within drive types. Also, for maximum track
116 // size to be determined properly, the drive types must be in ascending
117 // order.
118 //
119 
120 typedef struct _DRIVE_MEDIA_LIMITS {
124 
125 #if 0
127 
128  { Drive360Media360, Drive360Media160 }, // DRIVE_TYPE_0360
129  { Drive120Media120, Drive120Media160 }, // DRIVE_TYPE_1200
130  { Drive720Media720, Drive720Media720 }, // DRIVE_TYPE_0720
131  { Drive144Media144, Drive144Media720 }, // DRIVE_TYPE_1440
132  { Drive288Media288, Drive288Media720 }, // DRIVE_TYPE_2880
134 };
135 #else
137 
138  { Drive720Media720, Drive720Media720 }, // DRIVE_TYPE_0720
139  { Drive144Media144, Drive144Media720}, // DRIVE_TYPE_1440
140  { Drive288Media288, Drive288Media720}, // DRIVE_TYPE_2880
142  { Drive32MMedia32M, Drive32MMedia32M }, // DRIVE_TYPE_32M
143  { Drive120MMedia120M, Drive120MMedia720 }, // DRIVE_TYPE_120M
144  { Drive240MMedia240M, Drive240MMedia144M } // DRIVE_TYPE_240M
145 };
146 
147 #endif
148 //
149 // For each drive/media combination, define important constants.
150 //
151 
152 typedef struct _DRIVE_MEDIA_CONSTANTS {
159 
160 //
161 // Magic value to add to the SectorLengthCode to use it as a shift value
162 // to determine the sector size.
163 //
164 
165 #define SECTORLENGTHCODE_TO_BYTESHIFT 7
166 
167 //
168 // The following values were gleaned from many different sources, which
169 // often disagreed with each other. Where numbers were in conflict, I
170 // chose the more conservative or most-often-selected value.
171 //
172 
174  {
175 
176  { F5_160_512, 0x200, 0x08, 0x27, 0x1 },
177  { F5_180_512, 0x200, 0x09, 0x27, 0x1 },
178  { F5_320_1024, 0x400, 0x04, 0x27, 0x2 },
179  { F5_320_512, 0x200, 0x08, 0x27, 0x2 },
180  { F5_360_512, 0x200, 0x09, 0x27, 0x2 },
181 
182  { F3_720_512, 0x200, 0x09, 0x4f, 0x2 },
183 
184  { F5_160_512, 0x200, 0x08, 0x27, 0x1 },
185  { F5_180_512, 0x200, 0x09, 0x27, 0x1 },
186  { F5_320_1024, 0x400, 0x04, 0x27, 0x2 },
187  { F5_320_512, 0x200, 0x08, 0x27, 0x2 },
188  { F5_360_512, 0x200, 0x09, 0x27, 0x2 },
189  { F5_1Pt2_512, 0x200, 0x0f, 0x4f, 0x2 },
190 
191  { F3_720_512, 0x200, 0x09, 0x4f, 0x2 },
192  { F3_1Pt44_512, 0x200, 0x12, 0x4f, 0x2 },
193 
194  { F3_720_512, 0x200, 0x09, 0x4f, 0x2 },
195  { F3_1Pt44_512, 0x200, 0x12, 0x4f, 0x2 },
196  { F3_2Pt88_512, 0x200, 0x24, 0x4f, 0x2 },
197 
198  { F3_720_512, 0x200, 0x09, 0x4f, 0x2 },
199  { F3_1Pt44_512, 0x200, 0x12, 0x4f, 0x2 },
200  { F3_20Pt8_512, 0x200, 0x1b, 0xfa, 0x6 },
201 
202  { F3_32M_512, 0x200, 0x20, 0x3ff,0x2},
203 
204  { F3_720_512, 0x200, 0x09, 0x4f, 0x2 },
205  { F3_1Pt44_512, 0x200, 0x12, 0x4f, 0x2 },
206  { F3_120M_512, 0x200, 0x20, 0x3c2,0x8 },
207 
208  { F3_1Pt44_512, 0x200, 0x12, 0x4f, 0x2 },
209  { F3_120M_512, 0x200, 0x20, 0x3c2,0x8 },
210  { F3_240M_512, 0x200, 0x38, 0x105,0x20}
211 };
212 
213 
214 #define NUMBER_OF_DRIVE_MEDIA_COMBINATIONS sizeof(DriveMediaConstants)/sizeof(DRIVE_MEDIA_CONSTANTS)
215 
216 //
217 // floppy device data
218 //
219 
220 typedef struct _DISK_DATA {
223  // BOOLEAN EnableDMF;
226 
227 //
228 // The FloppyCapacities and FloppyGeometries arrays are used by the
229 // USBFlopGetMediaTypes() and USBFlopFormatTracks() routines.
230 
231 // The FloppyCapacities and FloppyGeometries arrays must be kept in 1:1 sync,
232 // i.e. each FloppyGeometries[i] must correspond to each FloppyCapacities[i].
233 
234 // Also, the arrays must be kept in sorted ascending order so that they
235 // are returned in sorted ascending order by IOCTL_DISK_GET_MEDIA_TYPES.
236 //
237 
238 typedef struct _FORMATTED_CAPACITY
239 {
241 
243 
244  BOOLEAN CanFormat; // return for IOCTL_DISK_GET_MEDIA_TYPES ?
245 
247 
248 
250 {
251  // Blocks BlockLen CanFormat H T B/S S/T
252  {0x000500, 0x0200, TRUE}, // 2 80 512 8 640 KB F5_640_512
253  {0x0005A0, 0x0200, TRUE}, // 2 80 512 9 720 KB F3_720_512
254  {0x000960, 0x0200, TRUE}, // 2 80 512 15 1.20 MB F3_1Pt2_512 (Toshiba)
255  {0x0004D0, 0x0400, TRUE}, // 2 77 1024 8 1.23 MB F3_1Pt23_1024 (NEC)
256  {0x000B40, 0x0200, TRUE}, // 2 80 512 18 1.44 MB F3_1Pt44_512
257  {0x000D20, 0x0200, FALSE}, // 2 80 512 21 1.70 MB DMF
258  {0x010000, 0x0200, TRUE}, // 2 1024 512 32 32 MB F3_32M_512
259  {0x03C300, 0x0200, TRUE}, // 8 963 512 32 120 MB F3_120M_512
260  {0x0600A4, 0x0200, TRUE}, // 13 890 512 34 200 MB F3_200Mb_512 (HiFD)
261  {0x072A00, 0x0200, TRUE} // 32 262 512 56 240 MB F3_240M_512
262 };
263 
265 {
266  // Cyl MediaType Trk/Cyl Sec/Trk Bytes/Sec
267 #ifndef __REACTOS__
268  {{80,0}, F3_640_512, 2, 8, 512},
269  {{80,0}, F3_720_512, 2, 9, 512},
270  {{80,0}, F3_1Pt2_512, 2, 15, 512},
271  {{77,0}, F3_1Pt23_1024, 2, 8, 1024},
272  {{80,0}, F3_1Pt44_512, 2, 18, 512},
273  {{80,0}, F3_1Pt44_512, 2, 21, 512}, // DMF -> F3_1Pt44_512
274  {{1024,0}, F3_32M_512, 2, 32, 512},
275  {{963,0}, F3_120M_512, 8, 32, 512},
276  {{890,0}, F3_200Mb_512, 13, 34, 512},
277  {{262,0}, F3_240M_512, 32, 56, 512}
278 #else
279  {{.LowPart = 80, .HighPart = 0}, F3_640_512, 2, 8, 512},
280  {{.LowPart = 80, .HighPart = 0}, F3_720_512, 2, 9, 512},
281  {{.LowPart = 80, .HighPart = 0}, F3_1Pt2_512, 2, 15, 512},
282  {{.LowPart = 77, .HighPart = 0}, F3_1Pt23_1024, 2, 8, 1024},
283  {{.LowPart = 80, .HighPart = 0}, F3_1Pt44_512, 2, 18, 512},
284  {{.LowPart = 80, .HighPart = 0}, F3_1Pt44_512, 2, 21, 512}, // DMF -> F3_1Pt44_512
285  {{.LowPart = 1024, .HighPart = 0}, F3_32M_512, 2, 32, 512},
286  {{.LowPart = 963, .HighPart = 0}, F3_120M_512, 8, 32, 512},
287  {{.LowPart = 890, .HighPart = 0}, F3_200Mb_512, 13, 34, 512},
288  {{.LowPart = 262, .HighPart = 0}, F3_240M_512, 32, 56, 512}
289 #endif
290 };
291 
292 #define FLOPPY_CAPACITIES (sizeof(FloppyCapacities)/sizeof(FloppyCapacities[0]))
293 
295 
296 //
297 // The following structures are used by USBFlopFormatTracks()
298 //
299 
300 #pragma pack (push, 1)
301 
302 typedef struct _CDB12FORMAT
303 {
317 
318 
319 typedef struct _DEFECT_LIST_HEADER
320 {
322  UCHAR Side : 1;
332 
333 typedef struct _FORMAT_UNIT_PARAMETER_LIST
334 {
338 
339 #pragma pack (pop)
340 
341 DRIVER_INITIALIZE DriverEntry;
342 
343 DRIVER_UNLOAD ScsiFlopUnload;
344 
345 DRIVER_ADD_DEVICE ScsiFlopAddDevice;
346 
347 NTSTATUS
348 #ifdef __REACTOS__
349 NTAPI
350 #endif
352  IN PDEVICE_OBJECT Fdo
353  );
354 
355 NTSTATUS
356 #ifdef __REACTOS__
357 NTAPI
358 #endif
360  IN PDEVICE_OBJECT Fdo
361  );
362 
363 NTSTATUS
364 #ifdef __REACTOS__
365 NTAPI
366 #endif
368  IN PDEVICE_OBJECT Fdo,
369  IN UCHAR Type
370  );
371 
372 NTSTATUS
373 #ifdef __REACTOS__
374 NTAPI
375 #endif
377  IN PDEVICE_OBJECT Fdo,
378  IN UCHAR Type
379  );
380 
381 BOOLEAN
386  IN PDEVICE_OBJECT PortDeviceObject,
388  );
389 
390 NTSTATUS
391 #ifdef __REACTOS__
392 NTAPI
393 #endif
396  IN PIRP Irp
397  );
398 
399 NTSTATUS
400 #ifdef __REACTOS__
401 NTAPI
402 #endif
405  IN PIRP Irp
406  );
407 
408 BOOLEAN
411  );
412 
413 NTSTATUS
416  IN PDEVICE_OBJECT PortDeviceObject,
418  );
419 
420 NTSTATUS
423  );
424 
425 ULONG
428  );
429 
430 BOOLEAN
433  IN PFORMAT_PARAMETERS FormatParameters
434  );
435 
436 NTSTATUS
439  MEDIA_TYPE MediaType
440  );
441 
442 NTSTATUS
446  );
447 
448 VOID
449 #ifdef __REACTOS__
450 NTAPI
451 #endif
455  NTSTATUS *Status,
456  BOOLEAN *Retry
457  );
458 
459 NTSTATUS
462  IN PIRP Irp
463  );
464 
465 NTSTATUS
468  IN PIRP Irp
469  );
470 
471 #ifdef ALLOC_PRAGMA
472 #pragma alloc_text(INIT, DriverEntry)
473 
474 #pragma alloc_text(PAGE, ScsiFlopUnload)
475 #pragma alloc_text(PAGE, ScsiFlopAddDevice)
476 #pragma alloc_text(PAGE, CreateFlopDeviceObject)
477 #pragma alloc_text(PAGE, ScsiFlopStartDevice)
478 #pragma alloc_text(PAGE, ScsiFlopRemoveDevice)
479 #pragma alloc_text(PAGE, IsFloppyDevice)
480 #pragma alloc_text(PAGE, DetermineMediaType)
481 #pragma alloc_text(PAGE, DetermineDriveType)
482 #pragma alloc_text(PAGE, FlCheckFormatParameters)
483 #pragma alloc_text(PAGE, FormatMedia)
484 #pragma alloc_text(PAGE, FlopticalFormatMedia)
485 #pragma alloc_text(PAGE, USBFlopGetMediaTypes)
486 #pragma alloc_text(PAGE, USBFlopFormatTracks)
487 
488 #endif
489 
490 
491 NTSTATUS
492 #ifdef __REACTOS__
493 NTAPI
494 #endif
498  )
499 /*++
500 
501 Routine Description:
502 
503  This is the system initialization routine for installable drivers.
504  It calls the SCSI class driver initialization routine.
505 
506 Arguments:
507 
508  DriverObject - Pointer to driver object created by system.
509 
510 Return Value:
511 
512  NTSTATUS
513 
514 --*/
515 
516 {
518 
519  //
520  // Zero InitData
521  //
522 
524 
525  //
526  // Set sizes
527  //
528 
529  InitializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);
530  InitializationData.FdoData.DeviceExtensionSize =
531  sizeof(FUNCTIONAL_DEVICE_EXTENSION) + sizeof(DISK_DATA);
532 
533  InitializationData.FdoData.DeviceType = FILE_DEVICE_DISK;
534  InitializationData.FdoData.DeviceCharacteristics = FILE_REMOVABLE_MEDIA | FILE_FLOPPY_DISKETTE;
535 
536  //
537  // Set entry points
538  //
539 
540  InitializationData.FdoData.ClassInitDevice = ScsiFlopInitDevice;
541  InitializationData.FdoData.ClassStartDevice = ScsiFlopStartDevice;
542  InitializationData.FdoData.ClassStopDevice = ScsiFlopStopDevice;
543  InitializationData.FdoData.ClassRemoveDevice = ScsiFlopRemoveDevice;
544 
545  InitializationData.FdoData.ClassReadWriteVerification = ScsiFlopReadWriteVerification;
546  InitializationData.FdoData.ClassDeviceControl = ScsiFlopDeviceControl;
547 
548  InitializationData.FdoData.ClassShutdownFlush = NULL;
549  InitializationData.FdoData.ClassCreateClose = NULL;
550  InitializationData.FdoData.ClassError = ScsiFlopProcessError;
551  InitializationData.ClassStartIo = NULL;
552 
553  InitializationData.ClassAddDevice = ScsiFlopAddDevice;
554  InitializationData.ClassUnload = ScsiFlopUnload;
555  //
556  // Call the class init routine
557  //
558 
560 
561 
562 } // end DriverEntry()
563 
564 VOID
565 #ifdef __REACTOS__
566 NTAPI
567 #endif
570  )
571 {
572  PAGED_CODE();
574  return;
575 }
576 
577 //
578 // AddDevice operation is performed in CreateFlopDeviceObject function which
579 // is called by ScsiFlopAddDevice (The AddDevice routine for sfloppy.sys).
580 // DO_DEVICE_INITIALIZING flag is cleard upon successfully processing AddDevice
581 // operation in CreateFlopDeviceObject. But PREFAST is currently unable to
582 // detect that DO_DEVICE_INITIALIZING is indeed cleard in CreateFlopDeviceObject
583 // and it raises Warning 28152 (The return from an AddDevice-like function
584 // unexpectedly did not clear DO_DEVICE_INITIALIZING). Suppress that warning
585 // using #pragma.
586 //
587 
588 #ifdef _MSC_VER
589 #pragma warning(push)
590 #pragma warning(disable:28152)
591 #endif
592 
593 NTSTATUS
594 #ifdef __REACTOS__
595 NTAPI
596 #endif
600  )
601 /*++
602 
603 Routine Description:
604 
605  This routine creates and initializes a new FDO for the corresponding
606  PDO. It may perform property queries on the FDO but cannot do any
607  media access operations.
608 
609 Arguments:
610 
611  DriverObject - Scsiscan class driver object.
612 
613  Pdo - the physical device object we are being added to
614 
615 Return Value:
616 
617  status
618 
619 --*/
620 {
623 
624  PAGED_CODE();
625 
626  //
627  // Get the number of disks already initialized.
628  //
629 
631 
632  if (NT_SUCCESS(status)) {
633 
634  //
635  // Increment system floppy device count.
636  //
637 
639  }
640 
641  return status;
642 }
643 
644 NTSTATUS
649  )
650 
651 /*++
652 
653 Routine Description:
654 
655  This routine creates an object for the device and then calls the
656  SCSI port driver for media capacity and sector size.
657 
658 Arguments:
659 
660  DriverObject - Pointer to driver object created by system.
661  PortDeviceObject - to connect to SCSI port driver.
662  DeviceCount - Number of previously installed Floppys.
663  AdapterDescriptor - Pointer to structure returned by SCSI port
664  driver describing adapter capabilites (and limitations).
665  DeviceDescriptor - Pointer to configuration information for this device.
666 
667 Return Value:
668 
669 --*/
670 {
672  PDEVICE_OBJECT deviceObject = NULL;
673  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
674  PDISK_DATA diskData;
675 
676  PAGED_CODE();
677 
678  DebugPrint((3,"CreateFlopDeviceObject: Enter routine\n"));
679 
680  //
681  // Try to claim the device.
682  //
683 
685 
686  if (!NT_SUCCESS(status)) {
687  return(status);
688  }
689 
690  DeviceCount--;
691 
692  do {
693  UCHAR name[256];
694 
695  //
696  // Create device object for this device.
697  //
698 
699  DeviceCount++;
700 
701  status = RtlStringCbPrintfA((PCCHAR) name,
702  sizeof(name)/sizeof(UCHAR),
703  "\\Device\\Floppy%u",
704  DeviceCount);
705  if (NT_SUCCESS(status)) {
706 
708  (PCCHAR) name,
709  Pdo,
710  TRUE,
711  &deviceObject);
712  }
713  } while ((status == STATUS_OBJECT_NAME_COLLISION) ||
715 
716  if (!NT_SUCCESS(status)) {
717  DebugPrint((1,"CreateFlopDeviceObjects: Can not create device\n"));
718  goto CreateFlopDeviceObjectExit;
719  }
720 
721  //
722  // Indicate that IRPs should include MDLs.
723  //
724 
725  deviceObject->Flags |= DO_DIRECT_IO;
726 
727  fdoExtension = deviceObject->DeviceExtension;
728 
729  //
730  // Back pointer to device object.
731  //
732 
733  fdoExtension->CommonExtension.DeviceObject = deviceObject;
734 
735  //
736  // This is the physical device.
737  //
738 
739  fdoExtension->CommonExtension.PartitionZeroExtension = fdoExtension;
740 
741  //
742  // Reset the drive type.
743  //
744 
745  diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
746  diskData->DriveType = DRIVE_TYPE_NONE;
747  diskData->IsDMF = FALSE;
748  // diskData->EnableDMF = TRUE;
749 
750  //
751  // Initialize lock count to zero. The lock count is used to
752  // disable the ejection mechanism when media is mounted.
753  //
754 
755  fdoExtension->LockCount = 0;
756 
757  //
758  // Save system floppy number
759  //
760 
761  fdoExtension->DeviceNumber = DeviceCount;
762 
763  //
764  // Set the alignment requirements for the device based on the
765  // host adapter requirements
766  //
767 
768  if (Pdo->AlignmentRequirement > deviceObject->AlignmentRequirement) {
770  }
771 
772  //
773  // Clear the SrbFlags and disable synchronous transfers
774  //
775 
777 
778  //
779  // Finally, attach to the PDO
780  //
781 
782  fdoExtension->LowerPdo = Pdo;
783 
784  fdoExtension->CommonExtension.LowerDeviceObject =
785  IoAttachDeviceToDeviceStack(deviceObject, Pdo);
786 
787  if(fdoExtension->CommonExtension.LowerDeviceObject == NULL) {
788 
790  goto CreateFlopDeviceObjectExit;
791  }
792 
793  deviceObject->StackSize++;
794 
795  //
796  // The device is initialized properly - mark it as such.
797  //
798 
799  deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
800 
801  return STATUS_SUCCESS;
802 
803 CreateFlopDeviceObjectExit:
804 
805  if (deviceObject != NULL) {
806  IoDeleteDevice(deviceObject);
807  }
808 
809  return status;
810 
811 } // end CreateFlopDeviceObject()
812 #ifdef _MSC_VER
813 #pragma warning(pop)
814 #endif
815 
816 NTSTATUS
817 #ifdef __REACTOS__
818 NTAPI
819 #endif
821  IN PDEVICE_OBJECT Fdo
822  )
823 {
824  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
825  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
826  PDISK_DATA diskData = commonExtension->DriverData;
827 
828  PVOID senseData = NULL;
829  ULONG timeOut;
830 
832 
833  //
834  // Allocate request sense buffer.
835  //
836 
837 #ifndef __REACTOS__
838  senseData = ExAllocatePool(NonPagedPoolNxCacheAligned, SENSE_BUFFER_SIZE);
839 #else
841 #endif
842 
843  if (senseData == NULL) {
844 
845  //
846  // The buffer cannot be allocated.
847  //
848 
850  return status;
851  }
852 
853  //
854  // Set the sense data pointer in the device extension.
855  //
856 
857  fdoExtension->SenseData = senseData;
858 
859  //
860  // Build the lookaside list for srb's for this device.
861  //
862 
865 
866  //
867  // Register for media change notification
868  //
870  (PUCHAR) "SFloppy");
871 
872  //
873  // Set timeout value in seconds.
874  //
875 
876  timeOut = ClassQueryTimeOutRegistryValue(Fdo);
877  if (timeOut) {
878  fdoExtension->TimeOutValue = timeOut;
879  } else {
880  fdoExtension->TimeOutValue = SCSI_FLOPPY_TIMEOUT;
881  }
882 
883  //
884  // Floppies are not partitionable so starting offset is 0.
885  //
886 
887  fdoExtension->CommonExtension.StartingOffset.QuadPart = (LONGLONG)0;
888 
889 #if 0
890  if (!IsFloppyDevice(Fdo) ||
891  !(Fdo->Characteristics & FILE_REMOVABLE_MEDIA) ||
892  (fdoExtension->DeviceDescriptor->DeviceType != DIRECT_ACCESS_DEVICE)) {
893 
894  ExFreePool(senseData);
896  return status;
897  }
898 #endif
899 
900  RtlZeroMemory(&(fdoExtension->DiskGeometry),
901  sizeof(DISK_GEOMETRY));
902 
903  //
904  // Determine the media type if possible. Set the current media type to
905  // Unknown so that determine media type will check the media.
906  //
907 
908  fdoExtension->DiskGeometry.MediaType = Unknown;
909 
910  //
911  // Register interfaces for this device.
912  //
913 
914  {
915  UNICODE_STRING interfaceName;
916 
917  RtlInitUnicodeString(&interfaceName, NULL);
918 
919  status = IoRegisterDeviceInterface(fdoExtension->LowerPdo,
920  (LPGUID) &GUID_DEVINTERFACE_FLOPPY,
921  NULL,
922  &interfaceName);
923 
924  if(NT_SUCCESS(status)) {
925  diskData->FloppyInterfaceString = interfaceName;
926  } else {
928  DebugPrint((1, "ScsiFlopStartDevice: Unable to register device "
929  "interface for fdo %p [%08lx]\n",
930  Fdo, status));
931  }
932  }
933 
934  return (STATUS_SUCCESS);
935 }
936 
937 #ifdef _MSC_VER
938 #pragma warning(suppress:6262) // This function uses 1096 bytes of stack which exceed default value of 1024 bytes used by Code Analysis for flagging as warning
939 #endif
940 #ifdef __REACTOS__
942 #else
944 #endif
945  IN PDEVICE_OBJECT Fdo
946  )
947 {
948  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
949  PCOMMON_DEVICE_EXTENSION commonExtension = Fdo->DeviceExtension;
950 
951  PIRP irp;
952  IO_STATUS_BLOCK ioStatus;
953 
954  SCSI_ADDRESS scsiAddress;
955 
956  WCHAR ntNameBuffer[256];
957  UNICODE_STRING ntUnicodeString;
958 
959  WCHAR arcNameBuffer[256];
960  UNICODE_STRING arcUnicodeString;
961 
962  KEVENT event;
963 
965 
966  PAGED_CODE();
967 
969 
970  DetermineMediaType(Fdo); // ignore unsuccessful here
971 
972  //
973  // Create device object for this device.
974  //
975 
976  RtlStringCbPrintfW(ntNameBuffer,
977  sizeof(ntNameBuffer)/sizeof(WCHAR),
978  L"\\Device\\Floppy%u",
979  fdoExtension->DeviceNumber);
980 
981  //
982  // Create local copy of unicode string
983  //
984  RtlInitUnicodeString(&ntUnicodeString,ntNameBuffer);
985 
986  //
987  // Create a symbolic link from the disk name to the corresponding
988  // ARC name, to be used if we're booting off the disk. This will
989  // fail if it's not system initialization time; that's fine. The
990  // ARC name looks something like \ArcName\scsi(0)Flop(0)fdisk(0).
991  // In order to get the address, we need to send a IOCTL_SCSI_GET_ADDRESS...
992  //
993 
995  Fdo,
996  NULL,
997  0,
998  &scsiAddress,
999  sizeof(scsiAddress),
1000  FALSE,
1001  &event,
1002  &ioStatus);
1003 
1004  if (irp == NULL) {
1006  }
1007 
1008  status = IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, irp);
1009 
1010  if (status == STATUS_PENDING) {
1012  status = ioStatus.Status;
1013  }
1014 
1015  //
1016  // IOCTL_SCSI_GET_ADDRESS might not be supported by the port driver and
1017  // hence may fail. But it is not a fatal error. Do not fail PnP start
1018  // if this IOCTL fails.
1019  //
1020  if (NT_SUCCESS(status)) {
1021 
1022  RtlStringCbPrintfW(arcNameBuffer,
1023  sizeof(arcNameBuffer)/sizeof(WCHAR),
1024  L"\\ArcName\\scsi(%u)disk(%u)fdisk(%u)",
1025  scsiAddress.PortNumber,
1026  scsiAddress.TargetId,
1027  scsiAddress.Lun);
1028 
1029  RtlInitUnicodeString(&arcUnicodeString, arcNameBuffer);
1030 
1031  IoAssignArcName(&arcUnicodeString, &ntUnicodeString);
1032  }
1033 
1035 
1036  //
1037  // Create the multi() arc name -- Create the "fake"
1038  // name of multi(0)disk(0)fdisk(#) to handle the case where the
1039  // SCSI floppy is the only floppy in the system. If this fails
1040  // it doesn't matter because the previous scsi() based ArcName
1041  // will work. This name is necessary for installation.
1042  //
1043 
1044  RtlStringCbPrintfW(arcNameBuffer,
1045  sizeof(arcNameBuffer)/sizeof(WCHAR),
1046  L"\\ArcName\\multi(%u)disk(%u)fdisk(%u)",
1047  0,
1048  0,
1049  fdoExtension->DeviceNumber);
1050 
1051  RtlInitUnicodeString(&arcUnicodeString, arcNameBuffer);
1052 
1053  IoAssignArcName(&arcUnicodeString, &ntUnicodeString);
1054 
1055  //
1056  // Set our interface state.
1057  //
1058 
1059  {
1060  PDISK_DATA diskData = commonExtension->DriverData;
1061 
1062  if(diskData->FloppyInterfaceString.Buffer != NULL) {
1063 
1065  &(diskData->FloppyInterfaceString),
1066  TRUE);
1067 
1068  if(!NT_SUCCESS(status)) {
1069  DebugPrint((1, "ScsiFlopStartDevice: Unable to set device "
1070  "interface state to TRUE for fdo %p "
1071  "[%08lx]\n",
1072  Fdo, status));
1073  }
1074  }
1075  }
1076 
1077  return STATUS_SUCCESS;
1078 }
1079 
1080 
1081 NTSTATUS
1082 #ifdef __REACTOS__
1083 NTAPI
1084 #endif
1087  IN PIRP Irp
1088  )
1089 
1090 /*++
1091 
1092 Routine Description:
1093 
1094 Arguments:
1095 
1096 Return Value:
1097 
1098  NT Status
1099 
1100 --*/
1101 
1102 {
1106 
1107  //
1108  // Make sure that the number of bytes to transfer is a multiple of the sector size
1109  //
1110  if ((irpSp->Parameters.Read.Length & (fdoExtension->DiskGeometry.BytesPerSector - 1)) != 0)
1111  {
1113  }
1114 
1115  Irp->IoStatus.Status = status;
1116 
1117  return status;
1118 }
1119 
1120 
1121 NTSTATUS
1122 #ifdef __REACTOS__
1123 NTAPI
1124 #endif
1127  PIRP Irp
1128  )
1129 
1130 /*++
1131 
1132 Routine Description:
1133 
1134 Arguments:
1135 
1136 Return Value:
1137 
1138  Status is returned.
1139 
1140 --*/
1141 
1142 {
1143  KIRQL currentIrql;
1146  PSCSI_REQUEST_BLOCK srb;
1147  PCDB cdb;
1148  NTSTATUS status;
1149  PDISK_GEOMETRY outputBuffer;
1150  ULONG outputBufferLength;
1151  ULONG i;
1152  DRIVE_MEDIA_TYPE lowestDriveMediaType;
1153  DRIVE_MEDIA_TYPE highestDriveMediaType;
1154  PFORMAT_PARAMETERS formatParameters;
1155  PMODE_PARAMETER_HEADER modeData;
1156  ULONG length;
1157 
1158  //
1159  // Initialize the information field
1160  //
1161  Irp->IoStatus.Information = 0;
1162 
1163 #ifndef __REACTOS__
1164  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
1165 #else
1167 #endif
1168 
1169  if (srb == NULL) {
1170 
1171  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1172  if (IoIsErrorUserInduced(Irp->IoStatus.Status)) {
1173 
1175  }
1176 
1177  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1180  KeLowerIrql(currentIrql);
1181 
1183  }
1184 
1185  //
1186  // Write zeros to Srb.
1187  //
1188 
1190 
1191  cdb = (PCDB)srb->Cdb;
1192 
1193  switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
1194 
1195 
1196  case IOCTL_DISK_VERIFY: {
1197 
1198  PVERIFY_INFORMATION verifyInfo = Irp->AssociatedIrp.SystemBuffer;
1199  LARGE_INTEGER byteOffset;
1200  ULONG sectorOffset;
1202 
1203  //
1204  // Validate buffer length.
1205  //
1206 
1207  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
1208  sizeof(VERIFY_INFORMATION)) {
1209 
1211  break;
1212  }
1213 
1214  //
1215  // Perform a bounds check on the sector range
1216  //
1217  if ((verifyInfo->StartingOffset.QuadPart > fdoExtension->CommonExtension.PartitionLength.QuadPart) ||
1218  (verifyInfo->StartingOffset.QuadPart < 0))
1219  {
1221  break;
1222  }
1223  else
1224  {
1225  ULONGLONG bytesRemaining = fdoExtension->CommonExtension.PartitionLength.QuadPart - verifyInfo->StartingOffset.QuadPart;
1226 
1227  if ((ULONGLONG)verifyInfo->Length > bytesRemaining)
1228  {
1230  break;
1231  }
1232  }
1233 
1234  //
1235  // Verify sectors
1236  //
1237 
1238  srb->CdbLength = 10;
1239 
1240  cdb->CDB10.OperationCode = SCSIOP_VERIFY;
1241 
1242  //
1243  // Add disk offset to starting sector.
1244  //
1245 
1246  byteOffset.QuadPart = fdoExtension->CommonExtension.StartingOffset.QuadPart +
1247  verifyInfo->StartingOffset.QuadPart;
1248 
1249  //
1250  // Convert byte offset to sector offset.
1251  //
1252 
1253  sectorOffset = (ULONG)(byteOffset.QuadPart >> fdoExtension->SectorShift);
1254 
1255  //
1256  // Convert ULONG byte count to USHORT sector count.
1257  //
1258 
1259  sectorCount = (USHORT)(verifyInfo->Length >> fdoExtension->SectorShift);
1260 
1261  //
1262  // Move little endian values into CDB in big endian format.
1263  //
1264 
1265  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&sectorOffset)->Byte3;
1266  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&sectorOffset)->Byte2;
1267  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&sectorOffset)->Byte1;
1268  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&sectorOffset)->Byte0;
1269 
1270  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&sectorCount)->Byte1;
1271  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&sectorCount)->Byte0;
1272 
1273  //
1274  // The verify command is used by the NT FORMAT utility and
1275  // requests are sent down for 5% of the volume size. The
1276  // request timeout value is calculated based on the number of
1277  // sectors verified.
1278  //
1279 
1280  srb->TimeOutValue = ((sectorCount + 0x7F) >> 7) *
1281  fdoExtension->TimeOutValue;
1282 
1284  srb,
1285  Irp,
1286  NULL,
1287  0,
1288  FALSE);
1289  return(status);
1290 
1291  }
1292 
1294 
1295  if (fdoExtension->AdapterDescriptor->BusType == BusTypeUsb) {
1296 
1298 
1299  // Don't need to propagate any error if one occurs
1300  //
1302 
1303  } else {
1304 
1306  }
1307 
1308  if (!NT_SUCCESS(status)) {
1309  // so will propogate error
1310  NOTHING;
1311  } else if (fdoExtension->DiskGeometry.MediaType == F3_120M_512) {
1312  //so that the format code will not try to partition it.
1314  } else {
1315  //
1316  // Free the Srb, since it is not needed.
1317  //
1318 
1319  ExFreePool(srb);
1320 
1321  //
1322  // Pass the request to the common device control routine.
1323  //
1324 
1326  }
1327  break;
1328  }
1329 
1331 
1332  DebugPrint((3,"ScsiDeviceIoControl: Get drive geometry\n"));
1333 
1334  if (fdoExtension->AdapterDescriptor->BusType == BusTypeUsb)
1335  {
1337  Irp);
1338  break;
1339  }
1340 
1341  //
1342  // If there's not enough room to write the
1343  // data, then fail the request.
1344  //
1345 
1346  if ( irpStack->Parameters.DeviceIoControl.OutputBufferLength <
1347  sizeof( DISK_GEOMETRY ) ) {
1348 
1350  break;
1351  }
1352 
1354 
1355  if (!NT_SUCCESS(status)) {
1356 
1357  Irp->IoStatus.Information = 0;
1358  Irp->IoStatus.Status = status;
1359 
1360  } else {
1361 
1362  //
1363  // Copy drive geometry information from device extension.
1364  //
1365 
1366  RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer,
1367  &(fdoExtension->DiskGeometry),
1368  sizeof(DISK_GEOMETRY));
1369 
1370  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
1372 
1373  }
1374 
1375  break;
1376  }
1377 
1379 
1380  if (fdoExtension->AdapterDescriptor->BusType == BusTypeUsb)
1381  {
1383  Irp);
1384  break;
1385  }
1386 
1388 
1389  if (i == DRIVE_TYPE_NONE) {
1391  break;
1392  }
1393 
1394  lowestDriveMediaType = DriveMediaLimits[i].LowestDriveMediaType;
1395  highestDriveMediaType = DriveMediaLimits[i].HighestDriveMediaType;
1396 
1397  outputBufferLength =
1398  irpStack->Parameters.DeviceIoControl.OutputBufferLength;
1399 
1400  //
1401  // Make sure that the input buffer has enough room to return
1402  // at least one descriptions of a supported media type.
1403  //
1404 
1405  if ( outputBufferLength < ( sizeof( DISK_GEOMETRY ) ) ) {
1406 
1408  break;
1409  }
1410 
1411  //
1412  // Assume success, although we might modify it to a buffer
1413  // overflow warning below (if the buffer isn't big enough
1414  // to hold ALL of the media descriptions).
1415  //
1416 
1418 
1419  if (outputBufferLength < ( sizeof( DISK_GEOMETRY ) *
1420  ( highestDriveMediaType - lowestDriveMediaType + 1 ) ) ) {
1421 
1422  //
1423  // The buffer is too small for all of the descriptions;
1424  // calculate what CAN fit in the buffer.
1425  //
1426 
1428 
1429  highestDriveMediaType = (DRIVE_MEDIA_TYPE)( ( lowestDriveMediaType - 1 ) +
1430  ( outputBufferLength /
1431  sizeof( DISK_GEOMETRY ) ) );
1432  }
1433 
1434  outputBuffer = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
1435 
1436  for (i = (UCHAR)lowestDriveMediaType;i <= (UCHAR)highestDriveMediaType;i++ ) {
1437 
1438  outputBuffer->MediaType = DriveMediaConstants[i].MediaType;
1439  outputBuffer->Cylinders.LowPart =
1441  outputBuffer->Cylinders.HighPart = 0;
1442  outputBuffer->TracksPerCylinder =
1444  outputBuffer->SectorsPerTrack =
1446  outputBuffer->BytesPerSector =
1448  outputBuffer++;
1449 
1450  Irp->IoStatus.Information += sizeof( DISK_GEOMETRY );
1451  }
1452 
1453  break;
1454  }
1455 
1456  case IOCTL_DISK_FORMAT_TRACKS: {
1457 
1458  if (fdoExtension->AdapterDescriptor->BusType == BusTypeUsb)
1459  {
1461  Irp);
1462  break;
1463  }
1464 
1465  //
1466  // Make sure that we got all the necessary format parameters.
1467  //
1468 
1469  if ( irpStack->Parameters.DeviceIoControl.InputBufferLength <sizeof( FORMAT_PARAMETERS ) ) {
1470 
1472  break;
1473  }
1474 
1475  formatParameters = (PFORMAT_PARAMETERS) Irp->AssociatedIrp.SystemBuffer;
1476 
1477  //
1478  // Make sure the parameters we got are reasonable.
1479  //
1480 
1481  if ( !FlCheckFormatParameters(DeviceObject, formatParameters)) {
1482 
1484  break;
1485  }
1486 
1487  //
1488  // If this request is for a 20.8 MB floppy then call a special
1489  // floppy format routine.
1490  //
1491 
1492  if (formatParameters->MediaType == F3_20Pt8_512) {
1494  formatParameters
1495  );
1496 
1497  break;
1498  }
1499 
1500  //
1501  // All the work is done in the pass. If this is not the first pass,
1502  // then complete the request and return;
1503  //
1504 
1505  if (formatParameters->StartCylinderNumber != 0 || formatParameters->StartHeadNumber != 0) {
1506 
1508  break;
1509  }
1510 
1511  status = FormatMedia( DeviceObject, formatParameters->MediaType);
1512  break;
1513  }
1514 
1515  case IOCTL_DISK_IS_WRITABLE: {
1516 
1517  if ((fdoExtension->DiskGeometry.MediaType) == F3_32M_512) {
1518 
1519  //
1520  // 32MB media is READ ONLY. Just return
1521  // STATUS_MEDIA_WRITE_PROTECTED
1522  //
1523 
1525 
1526  break;
1527  }
1528 
1529  //
1530  // Determine if the device is writable.
1531  //
1532 
1533 #ifndef __REACTOS__
1534  modeData = ExAllocatePool(NonPagedPoolNxCacheAligned, MODE_DATA_SIZE);
1535 #else
1537 #endif
1538 
1539  if (modeData == NULL) {
1541  break;
1542  }
1543 
1544  RtlZeroMemory(modeData, MODE_DATA_SIZE);
1545 
1547  (PCHAR) modeData,
1550 
1551  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1552 
1553  //
1554  // Retry the request in case of a check condition.
1555  //
1556 
1558  (PCHAR) modeData,
1561 
1562  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1564  ExFreePool(modeData);
1565  break;
1566  }
1567  }
1568 
1569  if (modeData->DeviceSpecificParameter & MODE_DSP_WRITE_PROTECT) {
1571  } else {
1573  }
1574 
1575  DebugPrint((2,"IOCTL_DISK_IS_WRITABLE returns %08X\n", status));
1576 
1577  ExFreePool(modeData);
1578  break;
1579  }
1580 
1581  default: {
1582 
1583  DebugPrint((3,"ScsiIoDeviceControl: Unsupported device IOCTL\n"));
1584 
1585  //
1586  // Free the Srb, since it is not needed.
1587  //
1588 
1589  ExFreePool(srb);
1590 
1591  //
1592  // Pass the request to the common device control routine.
1593  //
1594 
1596 
1597  break;
1598  }
1599 
1600  } // end switch( ...
1601 
1602  //
1603  // Check if SL_OVERRIDE_VERIFY_VOLUME flag is set in the IRP.
1604  // If so, do not return STATUS_VERIFY_REQUIRED
1605  //
1606  if ((status == STATUS_VERIFY_REQUIRED) &&
1607  (TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME))) {
1608 
1610 
1611  }
1612 
1613  Irp->IoStatus.Status = status;
1614 
1616 
1618  }
1619 
1620  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1623  KeLowerIrql(currentIrql);
1624 
1625  ExFreePool(srb);
1626 
1627  return status;
1628 
1629 } // end ScsiFlopDeviceControl()
1630 
1631 #if 0
1632 
1633 BOOLEAN
1636  )
1637 /*++
1638 
1639 Routine Description:
1640 
1641  The routine performs the necessary funcitons to deterime if the device is
1642  really a floppy rather than a harddisk. This is done by a mode sense
1643  command. First a check is made to see if the medimum type is set. Second
1644  a check is made for the flexible parameters mode page.
1645 
1646 Arguments:
1647 
1648  DeviceObject - Supplies the device object to be tested.
1649 
1650 Return Value:
1651 
1652  Return TRUE if the indicated device is a floppy.
1653 
1654 --*/
1655 {
1656 
1657  PVOID modeData;
1658  PUCHAR pageData;
1659  ULONG length;
1660 
1661  modeData = ExAllocatePool(NonPagedPoolNxCacheAligned, MODE_DATA_SIZE);
1662 
1663  if (modeData == NULL) {
1664  return(FALSE);
1665  }
1666 
1667  RtlZeroMemory(modeData, MODE_DATA_SIZE);
1668 
1670 
1671  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1672 
1673  //
1674  // Retry the request in case of a check condition.
1675  //
1676 
1678  modeData,
1681 
1682  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1683 
1684  ExFreePool(modeData);
1685  return(FALSE);
1686 
1687  }
1688  }
1689 
1690 #if 0
1691  //
1692  // Some drives incorrectly report this. In particular the SONY RMO-S350
1693  // when in disk mode.
1694  //
1695 
1696  if (((PMODE_PARAMETER_HEADER) modeData)->MediumType >= MODE_FD_SINGLE_SIDE
1697  && ((PMODE_PARAMETER_HEADER) modeData)->MediumType <= MODE_FD_MAXIMUM_TYPE) {
1698 
1699  DebugPrint((1, "ScsiFlop: MediumType value %2x, This is a floppy.\n", ((PMODE_PARAMETER_HEADER) modeData)->MediumType));
1700  ExFreePool(modeData);
1701  return(TRUE);
1702  }
1703 
1704 #endif
1705 
1706  //
1707  // If the length is greater than length indiated by the mode data reset
1708  // the data to the mode data.
1709  //
1710  if (length > (ULONG)((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
1711  length = (ULONG)((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
1712 
1713  }
1714 
1715  //
1716  // Look for the flexible disk mode page.
1717  //
1718 
1719  pageData = ClassFindModePage( modeData, length, MODE_PAGE_FLEXIBILE, TRUE);
1720 
1721  if (pageData != NULL) {
1722 
1723  DebugPrint((1, "ScsiFlop: Flexible disk page found, This is a floppy.\n"));
1724 
1725  //
1726  // As a special case for the floptical driver do a magic mode sense to
1727  // enable the drive.
1728  //
1729 
1730  ClassModeSense(DeviceObject, modeData, 0x2a, 0x2e);
1731 
1732  ExFreePool(modeData);
1733  return(TRUE);
1734 
1735  }
1736 
1737  ExFreePool(modeData);
1738  return(FALSE);
1739 
1740 }
1741 #endif
1742 
1743 
1744 NTSTATUS
1747  )
1748 /*++
1749 
1750 Routine Description:
1751 
1752  This routine determines the floppy media type based on the size of the
1753  device. The geometry information is set for the device object.
1754 
1755 Arguments:
1756 
1757  DeviceObject - Supplies the device object to be tested.
1758 
1759 Return Value:
1760 
1761  None
1762 
1763 --*/
1764 {
1766  PDISK_GEOMETRY geometry;
1767  LONG index;
1768  NTSTATUS status;
1769 
1770  PAGED_CODE();
1771 
1772  geometry = &(fdoExtension->DiskGeometry);
1773 
1774  //
1775  // Issue ReadCapacity to update device extension
1776  // with information for current media.
1777  //
1778 
1780 
1781  if (!NT_SUCCESS(status)) {
1782 
1783  //
1784  // Set the media type to unknow and zero the geometry information.
1785  //
1786 
1787  geometry->MediaType = Unknown;
1788 
1789  return status;
1790 
1791  }
1792 
1793  //
1794  // Look at the capcity of disk to determine its type.
1795  //
1796 
1797  for (index = NUMBER_OF_DRIVE_MEDIA_COMBINATIONS - 1; index >= 0; index--) {
1798 
1799  //
1800  // Walk the table backward untill the drive capacity holds all of the
1801  // data and the bytes per setor are equal
1802  //
1803 
1805  (DriveMediaConstants[index].MaximumTrack + 1) *
1807  DriveMediaConstants[index].BytesPerSector) <=
1808  fdoExtension->CommonExtension.PartitionLength.LowPart &&
1810  geometry->BytesPerSector) {
1811 
1816  break;
1817  }
1818  }
1819 
1820  if (index == -1) {
1821 
1822  //
1823  // Set the media type to unknow and zero the geometry information.
1824  //
1825 
1826  geometry->MediaType = Unknown;
1827 
1828 
1829  } else {
1830  //
1831  // DMF check breaks the insight SCSI floppy, so its disabled for that case
1832  //
1833  PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
1834 
1835  // if (diskData->EnableDMF == TRUE) {
1836 
1837  //
1838  //check to see if DMF
1839  //
1840 
1841  PSCSI_REQUEST_BLOCK srb;
1842  PVOID readData;
1843 
1844  //
1845  // Allocate a Srb for the read command.
1846  //
1847 
1848 #ifndef __REACTOS__
1849  readData = ExAllocatePool(NonPagedPoolNx, geometry->BytesPerSector);
1850 #else
1851  readData = ExAllocatePool(NonPagedPool, geometry->BytesPerSector);
1852 #endif
1853  if (readData == NULL) {
1854  return STATUS_NO_MEMORY;
1855  }
1856 
1857 #ifndef __REACTOS__
1858  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
1859 #else
1861 #endif
1862 
1863  if (srb == NULL) {
1864 
1865  ExFreePool(readData);
1866  return STATUS_NO_MEMORY;
1867  }
1868 
1869  RtlZeroMemory(readData, geometry->BytesPerSector);
1871 
1872  srb->CdbLength = 10;
1873  srb->Cdb[0] = SCSIOP_READ;
1874  srb->Cdb[5] = 0;
1875  srb->Cdb[8] = (UCHAR) 1;
1876 
1877  //
1878  // Set timeout value.
1879  //
1880 
1881  srb->TimeOutValue = fdoExtension->TimeOutValue;
1882 
1883  //
1884  // Send the mode select data.
1885  //
1886 
1888  srb,
1889  readData,
1890  geometry->BytesPerSector,
1891  FALSE
1892  );
1893 
1894  if (NT_SUCCESS(status)) {
1895  char *pchar = (char *)readData;
1896 
1897  pchar += 3; //skip 3 bytes jump code
1898 
1899  // If the MSDMF3. signature is there then mark it as DMF diskette
1900  if (RtlCompareMemory(pchar, "MSDMF3.", 7) == 7) {
1901  diskData->IsDMF = TRUE;
1902  }
1903 
1904  }
1905  ExFreePool(readData);
1906  ExFreePool(srb);
1907  // }// else
1908  }
1909  return status;
1910 }
1911 
1912 ULONG
1915  )
1916 /*++
1917 
1918 Routine Description:
1919 
1920  The routine determines the device type so that the supported medias can be
1921  determined. It does a mode sense for the default parameters. This code
1922  assumes that the returned values are for the maximum device size.
1923 
1924 Arguments:
1925 
1926  DeviceObject - Supplies the device object to be tested.
1927 
1928 Return Value:
1929 
1930  None
1931 
1932 --*/
1933 {
1935  PVOID modeData;
1936  PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
1937  PMODE_FLEXIBLE_DISK_PAGE pageData;
1938  ULONG length;
1939  LONG index;
1940  UCHAR numberOfHeads;
1941  UCHAR sectorsPerTrack;
1942  USHORT maximumTrack;
1943  BOOLEAN applyFix = FALSE;
1944 
1945  PAGED_CODE();
1946 
1947  if (diskData->DriveType != DRIVE_TYPE_NONE) {
1948  return(diskData->DriveType);
1949  }
1950 
1951 #ifndef __REACTOS__
1952  modeData = ExAllocatePool(NonPagedPoolNxCacheAligned, MODE_DATA_SIZE);
1953 #else
1955 #endif
1956 
1957  if (modeData == NULL) {
1958  return(DRIVE_TYPE_NONE);
1959  }
1960 
1961  RtlZeroMemory(modeData, MODE_DATA_SIZE);
1962 
1964  modeData,
1967 
1968  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1969 
1970  //
1971  // Retry the request one more time
1972  // in case of a check condition.
1973  //
1975  modeData,
1978 
1979  if (length < sizeof(MODE_PARAMETER_HEADER)) {
1980 
1981  ExFreePool(modeData);
1982  return(DRIVE_TYPE_NONE);
1983  }
1984  }
1985 
1986  //
1987  // Look for the flexible disk mode page.
1988  //
1989 
1990  pageData = ClassFindModePage( modeData,
1991  length,
1993  TRUE);
1994 
1995  //
1996  // Make sure the page is returned and is large enough.
1997  //
1998 
1999  if ((pageData != NULL) &&
2000  (pageData->PageLength + 2 >=
2001  (UCHAR)offsetof(MODE_FLEXIBLE_DISK_PAGE, StartWritePrecom))) {
2002 
2003  //
2004  // Pull out the heads, cylinders, and sectors.
2005  //
2006 
2007  numberOfHeads = pageData->NumberOfHeads;
2008  maximumTrack = pageData->NumberOfCylinders[1];
2009  maximumTrack |= pageData->NumberOfCylinders[0] << 8;
2010  sectorsPerTrack = pageData->SectorsPerTrack;
2011 
2012 
2013  //
2014  // Convert from number of cylinders to maximum track.
2015  //
2016 
2017  maximumTrack--;
2018 
2019  //
2020  // Search for the maximum supported media. Based on the number of heads,
2021  // sectors per track and number of cylinders
2022  //
2024 
2025  //
2026  // Walk the table forward until the drive capacity holds all of the
2027  // data and the bytes per setor are equal
2028  //
2029 
2030  if (DriveMediaConstants[index].NumberOfHeads == numberOfHeads &&
2031  DriveMediaConstants[index].MaximumTrack == maximumTrack &&
2032  DriveMediaConstants[index].SectorsPerTrack ==sectorsPerTrack) {
2033 
2034  ExFreePool(modeData);
2035 
2036  //
2037  // index is now a drive media combination. Compare this to
2038  // the maximum drive media type in the drive media table.
2039  //
2040 
2041  for (length = 0; length < NUMBER_OF_DRIVE_TYPES; length++) {
2042 
2043  if (DriveMediaLimits[length].HighestDriveMediaType == index) {
2044  return(length);
2045  }
2046  }
2047  return(DRIVE_TYPE_NONE);
2048  }
2049  }
2050 
2051  // If the maximum track is greater than 8 bits then divide the
2052  // number of tracks by 3 and multiply the number of heads by 3.
2053  // This is a special case for the 20.8 MB floppy.
2054  //
2055 
2056  if (!applyFix && maximumTrack >= 0x0100) {
2057  maximumTrack++;
2058  maximumTrack /= 3;
2059  maximumTrack--;
2060  numberOfHeads *= 3;
2061  } else {
2062  ExFreePool(modeData);
2063  return(DRIVE_TYPE_NONE);
2064  }
2065 
2066  }
2067 
2068  ExFreePool(modeData);
2069  return(DRIVE_TYPE_NONE);
2070 }
2071 
2072 
2073 BOOLEAN
2076  IN PFORMAT_PARAMETERS FormatParameters
2077  )
2078 
2079 /*++
2080 
2081 Routine Description:
2082 
2083  This routine checks the supplied format parameters to make sure that
2084  they'll work on the drive to be formatted.
2085 
2086 Arguments:
2087 
2088  DeviceObject - Pointer to the device object to be formated.
2089 
2090  FormatParameters - a pointer to the caller's parameters for the FORMAT.
2091 
2092 Return Value:
2093 
2094  TRUE if parameters are OK.
2095  FALSE if the parameters are bad.
2096 
2097 --*/
2098 
2099 {
2100  PDRIVE_MEDIA_CONSTANTS driveMediaConstants;
2101  DRIVE_MEDIA_TYPE driveMediaType;
2102  ULONG index;
2103 
2104  PAGED_CODE();
2105 
2106  //
2107  // Get the device type.
2108  //
2109 
2111 
2112  if (index == DRIVE_TYPE_NONE) {
2113 
2114  //
2115  // If the determine device type failed then just use the media type
2116  // and try the parameters.
2117  //
2118 
2119  driveMediaType = Drive360Media160;
2120 
2121  while (( DriveMediaConstants[driveMediaType].MediaType !=
2122  FormatParameters->MediaType ) &&
2123  ( driveMediaType < Drive288Media288) ) {
2124 
2125  driveMediaType++;
2126  }
2127 
2128  } else {
2129 
2130  //
2131  // Figure out which entry in the DriveMediaConstants table to use.
2132  //
2133 
2134  driveMediaType =
2136 
2137  while ( ( DriveMediaConstants[driveMediaType].MediaType !=
2138  FormatParameters->MediaType ) &&
2139  ( driveMediaType > DriveMediaLimits[index].
2140  LowestDriveMediaType ) ) {
2141 
2142  driveMediaType--;
2143  }
2144 
2145  }
2146 
2147 
2148  // driveMediaType is bounded below by DriveMediaLimits[].LowestDriveMediaType
2149 #ifdef _MSC_VER
2150 #pragma warning(push)
2151 #pragma warning(disable:33010) // 33010: Enum used as array index may be negative
2152 #endif
2153  if ( DriveMediaConstants[driveMediaType].MediaType !=
2154  FormatParameters->MediaType ) {
2155  return FALSE;
2156 
2157  } else {
2158 
2159  driveMediaConstants = &DriveMediaConstants[driveMediaType];
2160 
2161  if ( ( FormatParameters->StartHeadNumber >
2162  (ULONG)( driveMediaConstants->NumberOfHeads - 1 ) ) ||
2163  ( FormatParameters->EndHeadNumber >
2164  (ULONG)( driveMediaConstants->NumberOfHeads - 1 ) ) ||
2165  ( FormatParameters->StartCylinderNumber >
2166  driveMediaConstants->MaximumTrack ) ||
2167  ( FormatParameters->EndCylinderNumber >
2168  driveMediaConstants->MaximumTrack ) ||
2169  ( FormatParameters->EndCylinderNumber <
2170  FormatParameters->StartCylinderNumber ) ) {
2171 
2172  return FALSE;
2173 
2174  } else {
2175 
2176  return TRUE;
2177  }
2178  }
2179 #ifdef _MSC_VER
2180 #pragma warning(pop)
2181 #endif
2182 }
2183 
2184 NTSTATUS
2187  MEDIA_TYPE MediaType
2188  )
2189 /*++
2190 
2191 Routine Description:
2192 
2193  This routine formats the floppy disk. The entire floppy is formated in
2194  one shot.
2195 
2196 Arguments:
2197 
2198  DeviceObject - Supplies the device object to be tested.
2199 
2200  Irp - Supplies a pointer to the requesting Irp.
2201 
2202  MediaType - Supplies the media type format the device for.
2203 
2204 Return Value:
2205 
2206  Returns a status for the operation.
2207 
2208 --*/
2209 {
2210  PVOID modeData;
2211  PSCSI_REQUEST_BLOCK srb;
2212  PMODE_FLEXIBLE_DISK_PAGE pageData;
2213  DRIVE_MEDIA_TYPE driveMediaType;
2214  PDRIVE_MEDIA_CONSTANTS driveMediaConstants;
2215  ULONG length;
2216  NTSTATUS status;
2217 
2218  PAGED_CODE();
2219 
2220 #ifndef __REACTOS__
2221  modeData = ExAllocatePool(NonPagedPoolNxCacheAligned, MODE_DATA_SIZE);
2222 #else
2224 #endif
2225 
2226  if (modeData == NULL) {
2228  }
2229 
2230  RtlZeroMemory(modeData, MODE_DATA_SIZE);
2231 
2233  modeData,
2236 
2237  if (length < sizeof(MODE_PARAMETER_HEADER)) {
2238  ExFreePool(modeData);
2240  }
2241 
2242  //
2243  // Look for the flexible disk mode page.
2244  //
2245 
2246  pageData = ClassFindModePage( modeData, length, MODE_PAGE_FLEXIBILE, TRUE);
2247 
2248  //
2249  // Make sure the page is returned and is large enough.
2250  //
2251 
2252  if ((pageData == NULL) ||
2253  (pageData->PageLength + 2 <
2254  (UCHAR)offsetof(MODE_FLEXIBLE_DISK_PAGE, StartWritePrecom))) {
2255 
2256  ExFreePool(modeData);
2258 
2259  }
2260 
2261  //
2262  // Look for a drive media type which matches the requested media type.
2263  //
2264  //
2265  //start from Drive120MMedia120M instead of Drive2080Media2080
2266  //
2267  for (driveMediaType = Drive120MMedia120M;
2268  DriveMediaConstants[driveMediaType].MediaType != MediaType;
2269  driveMediaType--) {
2270  if (driveMediaType == Drive360Media160) {
2271 
2272  ExFreePool(modeData);
2273  return(STATUS_INVALID_PARAMETER);
2274 
2275  }
2276  }
2277 
2278  driveMediaConstants = &DriveMediaConstants[driveMediaType];
2279 
2280  if ((pageData->NumberOfHeads != driveMediaConstants->NumberOfHeads) ||
2281  (pageData->SectorsPerTrack != driveMediaConstants->SectorsPerTrack) ||
2282  ((pageData->NumberOfCylinders[0] != (UCHAR)((driveMediaConstants->MaximumTrack+1) >> 8)) &&
2283  (pageData->NumberOfCylinders[1] != (UCHAR)driveMediaConstants->MaximumTrack+1)) ||
2284  (pageData->BytesPerSector[0] != driveMediaConstants->BytesPerSector >> 8 )) {
2285 
2286  //
2287  // Update the flexible parameters page with the new parameters.
2288  //
2289 
2290  pageData->NumberOfHeads = driveMediaConstants->NumberOfHeads;
2291  pageData->SectorsPerTrack = driveMediaConstants->SectorsPerTrack;
2292  pageData->NumberOfCylinders[0] = (UCHAR)((driveMediaConstants->MaximumTrack+1) >> 8);
2293  pageData->NumberOfCylinders[1] = (UCHAR)driveMediaConstants->MaximumTrack+1;
2294  pageData->BytesPerSector[0] = driveMediaConstants->BytesPerSector >> 8;
2295 
2296  //
2297  // Clear the mode parameter header.
2298  //
2299 
2300  RtlZeroMemory(modeData, sizeof(MODE_PARAMETER_HEADER));
2301 
2302  //
2303  // Set the length equal to the length returned for the flexible page.
2304  //
2305 
2306  length = pageData->PageLength + 2;
2307 
2308  //
2309  // Copy the page after the mode parameter header.
2310  //
2311 
2312  RtlMoveMemory((PCHAR) modeData + sizeof(MODE_PARAMETER_HEADER),
2313  pageData,
2314  length
2315  );
2316  length += sizeof(MODE_PARAMETER_HEADER);
2317 
2318 
2319  //
2320  // Allocate a Srb for the format command.
2321  //
2322 
2323 #ifndef __REACTOS__
2324  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
2325 #else
2327 #endif
2328 
2329  if (srb == NULL) {
2330 
2331  ExFreePool(modeData);
2333  }
2334 
2336 
2337  srb->CdbLength = 6;
2338  srb->Cdb[0] = SCSIOP_MODE_SELECT;
2339  srb->Cdb[4] = (UCHAR) length;
2340 
2341  //
2342  // Set the PF bit.
2343  //
2344 
2345  srb->Cdb[1] |= 0x10;
2346 
2347  //
2348  // Set timeout value.
2349  //
2350 
2351  srb->TimeOutValue = 2;
2352 
2353  //
2354  // Send the mode select data.
2355  //
2356 
2358  srb,
2359  modeData,
2360  length,
2361  TRUE
2362  );
2363 
2364  //
2365  // The mode data not needed any more so free it.
2366  //
2367 
2368  ExFreePool(modeData);
2369 
2370  if (!NT_SUCCESS(status)) {
2371  ExFreePool(srb);
2372  return(status);
2373  }
2374 
2375  } else {
2376 
2377  //
2378  // The mode data not needed any more so free it.
2379  //
2380 
2381  ExFreePool(modeData);
2382 
2383  //
2384  // Allocate a Srb for the format command.
2385  //
2386 
2387 #ifndef __REACTOS__
2388  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
2389 #else
2391 #endif
2392 
2393  if (srb == NULL) {
2395  }
2396 
2397  }
2398 
2400 
2401  srb->CdbLength = 6;
2402 
2403  srb->Cdb[0] = SCSIOP_FORMAT_UNIT;
2404 
2405  //
2406  // Set timeout value.
2407  //
2408 
2409  srb->TimeOutValue = 10 * 60;
2410 
2412  srb,
2413  NULL,
2414  0,
2415  FALSE
2416  );
2417  ExFreePool(srb);
2418 
2419  return(status);
2420 
2421 }
2422 
2423 VOID
2424 #ifdef __REACTOS__
2425 NTAPI
2426 #endif
2430  NTSTATUS *Status,
2431  BOOLEAN *Retry
2432  )
2433 /*++
2434 
2435 Routine Description:
2436 
2437  This routine checks the type of error. If the error indicate the floppy
2438  controller needs to be reinitialize a command is made to do it.
2439 
2440 Arguments:
2441 
2442  DeviceObject - Supplies a pointer to the device object.
2443 
2444  Srb - Supplies a pointer to the failing Srb.
2445 
2446  Status - Status with which the IRP will be completed.
2447 
2448  Retry - Indication of whether the request will be retried.
2449 
2450 Return Value:
2451 
2452  None.
2453 
2454 --*/
2455 
2456 {
2458  PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
2459  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2460  PIO_STACK_LOCATION irpStack;
2461  PIRP irp;
2462  PSCSI_REQUEST_BLOCK srb;
2463  LARGE_INTEGER largeInt;
2465  PCDB cdb;
2466  ULONG_PTR alignment;
2467  ULONG majorFunction;
2468 
2471 
2472  largeInt.QuadPart = 1;
2473 
2474  //
2475  // Check the status. The initialization command only needs to be sent
2476  // if UNIT ATTENTION or LUN NOT READY is returned.
2477  //
2478 
2479  if (!(Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID)) {
2480 
2481  //
2482  // The drive does not require reinitialization.
2483  //
2484 
2485  return;
2486  }
2487 
2488  //
2489  // Reset the drive type.
2490  //
2491 
2492  diskData->DriveType = DRIVE_TYPE_NONE;
2493  diskData->IsDMF = FALSE;
2494 
2495  fdoExtension->DiskGeometry.MediaType = Unknown;
2496 
2497  if (fdoExtension->AdapterDescriptor->BusType == BusTypeUsb) {
2498 
2499  // FLPYDISK.SYS never returns a non-zero value for the ChangeCount
2500  // on an IOCTL_DISK_CHECK_VERIFY. Some things seem to work better
2501  // if we do the same. In particular, FatVerifyVolume() can exit between
2502  // the IOCTL_DISK_CHECK_VERIFY and the IOCTL_DISK_GET_DRIVE_GEOMETRY
2503  // if a non-zero ChangeCount is returned, and this appears to cause
2504  // issues formatting unformatted media in some situations.
2505  //
2506  // This is something that should probably be revisited at some point.
2507  //
2508  fdoExtension->MediaChangeCount = 0;
2509 
2510  if (((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_UNIT_ATTENTION) &&
2511  (senseBuffer->AdditionalSenseCode == SCSI_ADSENSE_MEDIUM_CHANGED)) {
2512 
2513  struct _START_STOP *startStopCdb;
2514 
2515  DebugPrint((2,"Sending SCSIOP_START_STOP_UNIT\n"));
2516 
2517 #ifndef __REACTOS__
2518  context = ExAllocatePool(NonPagedPoolNx,
2519 #else
2521 #endif
2522  sizeof(COMPLETION_CONTEXT));
2523 
2524  if (context == NULL) {
2525 
2526  return;
2527  }
2528 #if (NTDDI_VERSION >= NTDDI_WIN8)
2529  srb = &context->Srb.Srb;
2530 #else
2531  srb = &context->Srb;
2532 #endif
2533 
2535 
2536  srb->SrbFlags = SRB_FLAGS_DISABLE_AUTOSENSE;
2537 
2538  srb->CdbLength = 6;
2539 
2540  startStopCdb = (struct _START_STOP *)srb->Cdb;
2541 
2542  startStopCdb->OperationCode = SCSIOP_START_STOP_UNIT;
2543  startStopCdb->Start = 1;
2544 
2545  // A Start Stop Unit request has no transfer buffer.
2546  // Set the request to IRP_MJ_FLUSH_BUFFERS when calling
2547  // IoBuildAsynchronousFsdRequest() so that it ignores
2548  // the buffer pointer and buffer length parameters.
2549  //
2550  majorFunction = IRP_MJ_FLUSH_BUFFERS;
2551 
2552  } else if ((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_MEDIUM_ERROR) {
2553 
2554  // Return ERROR_UNRECOGNIZED_MEDIA instead of
2555  // STATUS_DEVICE_DATA_ERROR to make shell happy.
2556  //
2558  return;
2559 
2560  } else {
2561 
2562  return;
2563  }
2564 
2565 #ifndef __REACTOS__
2566  } else if (((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_NOT_READY) &&
2567  senseBuffer->AdditionalSenseCodeQualifier == SCSI_SENSEQ_INIT_COMMAND_REQUIRED ||
2568  (senseBuffer->SenseKey & 0xf) == SCSI_SENSE_UNIT_ATTENTION) {
2569 #else
2570  } else if ((((senseBuffer->SenseKey & 0xf) == SCSI_SENSE_NOT_READY) &&
2571  senseBuffer->AdditionalSenseCodeQualifier == SCSI_SENSEQ_INIT_COMMAND_REQUIRED) ||
2572  (senseBuffer->SenseKey & 0xf) == SCSI_SENSE_UNIT_ATTENTION) {
2573 #endif
2574 
2575  ULONG sizeNeeded;
2576  ULONG tmpSize;
2577  BOOLEAN overFlow;
2578 
2579  DebugPrint((1, "ScsiFlopProcessError: Reinitializing the floppy.\n"));
2580 
2581  //
2582  // Send the special mode sense command to enable writes on the
2583  // floptical drive.
2584  //
2585 
2586  alignment = DeviceObject->AlignmentRequirement ?
2588 
2589  sizeNeeded = 0;
2590  overFlow = TRUE;
2591  if (SUCCEEDED(ULongAdd(sizeof(COMPLETION_CONTEXT), 0x2a, &tmpSize))) {
2592 
2593  if (SUCCEEDED(ULongAdd(tmpSize, (ULONG) alignment, &sizeNeeded))) {
2594  overFlow = FALSE;
2595  }
2596  }
2597 
2598  context = NULL;
2599 
2600  if (!overFlow) {
2601 #ifndef __REACTOS__
2602  context = ExAllocatePool(NonPagedPoolNx, sizeNeeded);
2603 #else
2604  context = ExAllocatePool(NonPagedPool, sizeNeeded);
2605 #endif
2606  }
2607 
2608  if (context == NULL) {
2609 
2610  //
2611  // If there is not enough memory to fulfill this request,
2612  // simply return. A subsequent retry will fail and another
2613  // chance to start the unit.
2614  //
2615 
2616  return;
2617  }
2618 
2619 #if (NTDDI_VERSION >= NTDDI_WIN8)
2620  srb = &context->Srb.Srb;
2621 #else
2622  srb = &context->Srb;
2623 #endif
2624 
2626 
2627  //
2628  // Set the transfer length.
2629  //
2630 
2631  srb->DataTransferLength = 0x2a;
2633 
2634  //
2635  // The data buffer must be aligned.
2636  //
2637 
2638  srb->DataBuffer = (PVOID) (((ULONG_PTR) (context + 1) + (alignment - 1)) &
2639  ~(alignment - 1));
2640 
2641 
2642  //
2643  // Build the start unit CDB.
2644  //
2645 
2646  srb->CdbLength = 6;
2647  cdb = (PCDB)srb->Cdb;
2648  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
2649  cdb->MODE_SENSE.PageCode = 0x2e;
2650  cdb->MODE_SENSE.AllocationLength = 0x2a;
2651 
2652  majorFunction = IRP_MJ_READ;
2653 
2654  } else {
2655 
2656  return;
2657  }
2658 
2659  context->DeviceObject = DeviceObject;
2660 
2661  //
2662  // Write length to SRB.
2663  //
2664 
2665  srb->Length = SCSI_REQUEST_BLOCK_SIZE;
2666 
2667  srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
2668  srb->TimeOutValue = fdoExtension->TimeOutValue;
2669 
2670  //
2671  // Build the asynchronous request
2672  // to be sent to the port driver.
2673  //
2674 
2675  irp = IoBuildAsynchronousFsdRequest(majorFunction,
2676  DeviceObject,
2677  srb->DataBuffer,
2678  srb->DataTransferLength,
2679  &largeInt,
2680  NULL);
2681 
2682  if(irp == NULL) {
2684  return;
2685  }
2686 
2687 
2690  context,
2691  TRUE,
2692  TRUE,
2693  TRUE);
2694 
2696 
2697  irpStack = IoGetNextIrpStackLocation(irp);
2698 
2699  irpStack->MajorFunction = IRP_MJ_SCSI;
2700 
2701  srb->OriginalRequest = irp;
2702 
2703  //
2704  // Save SRB address in next stack for port driver.
2705  //
2706 
2707  irpStack->Parameters.Others.Argument1 = (PVOID)srb;
2708 
2709  //
2710  // Can't release the remove lock yet - let ClassAsynchronousCompletion
2711  // take care of that for us.
2712  //
2713 
2714  (VOID)IoCallDriver(fdoExtension->CommonExtension.LowerDeviceObject, irp);
2715 
2716  return;
2717 }
2718 
2719 NTSTATUS
2723  )
2724 /*++
2725 
2726 Routine Description:
2727 
2728  This routine is used to do perform a format tracks for the 20.8 MB
2729  floppy. Because the device does not support format tracks and the full
2730  format takes a long time a write of zeros is done instead.
2731 
2732 Arguments:
2733 
2734  DeviceObject - Supplies the device object to be tested.
2735 
2736  Format - Supplies the format parameters.
2737 
2738 Return Value:
2739 
2740  Returns a status for the operation.
2741 
2742 --*/
2743 {
2744  IO_STATUS_BLOCK ioStatus;
2745  PIRP irp;
2746  KEVENT event;
2748  ULONG length;
2749  PVOID buffer;
2750  PDRIVE_MEDIA_CONSTANTS driveMediaConstants;
2751  NTSTATUS status;
2752 
2753  PAGED_CODE();
2754 
2755  driveMediaConstants = &DriveMediaConstants[Drive2080Media2080];
2756 
2757  //
2758  // Calculate the length of the buffer.
2759  //
2760 
2761  length = ((Format->EndCylinderNumber - Format->StartCylinderNumber) *
2762  driveMediaConstants->NumberOfHeads +
2763  Format->EndHeadNumber - Format->StartHeadNumber + 1) *
2764  driveMediaConstants->SectorsPerTrack *
2765  driveMediaConstants->BytesPerSector;
2766 
2767 #ifndef __REACTOS__
2768  buffer = ExAllocatePool(NonPagedPoolNxCacheAligned, length);
2769 #else
2771 #endif
2772 
2773  if (buffer == NULL) {
2775  }
2776 
2778 
2779  offset.QuadPart =
2780  (Format->StartCylinderNumber * driveMediaConstants->NumberOfHeads +
2781  Format->StartHeadNumber) * driveMediaConstants->SectorsPerTrack *
2782  driveMediaConstants->BytesPerSector;
2783 
2784  //
2785  // Set the event object to the unsignaled state.
2786  // It will be used to signal request completion.
2787  //
2788 
2790 
2791  //
2792  // Build the synchronous request with data transfer.
2793  //
2794 
2796  IRP_MJ_WRITE,
2797  DeviceObject,
2798  buffer,
2799  length,
2800  &offset,
2801  &event,
2802  &ioStatus);
2803 
2804  if (irp != NULL) {
2806 
2807  if (status == STATUS_PENDING) {
2808 
2809  //
2810  // Wait for the request to complete if necessary.
2811  //
2812 
2814  }
2815 
2816  //
2817  // If the call driver suceeded then set the status to the status block.
2818  //
2819 
2820  if (NT_SUCCESS(status)) {
2821  status = ioStatus.Status;
2822  }
2823  } else {
2825  }
2826 
2827  ExFreePool(buffer);
2828 
2829  return(status);
2830 
2831 }
2832 
2833 
2834 NTSTATUS
2835 #ifdef __REACTOS__
2836 NTAPI
2837 #endif
2840  IN UCHAR Type
2841  )
2842 /*++
2843 
2844 Routine Description:
2845 
2846  This routine is responsible for releasing any resources in use by the
2847  sfloppy driver. This routine is called
2848  when all outstanding requests have been completed and the driver has
2849  disappeared - no requests may be issued to the lower drivers.
2850 
2851 Arguments:
2852 
2853  DeviceObject - the device object being removed
2854 
2855  Type - the type of remove operation (QUERY, REMOVE or CANCEL)
2856 
2857 Return Value:
2858 
2859  for a query - success if the device can be removed or a failure code
2860  indiciating why not.
2861 
2862  for a remove or cancel - STATUS_SUCCESS
2863 
2864 --*/
2865 
2866 {
2867  PFUNCTIONAL_DEVICE_EXTENSION deviceExtension =
2869  PDISK_DATA diskData = deviceExtension->CommonExtension.DriverData;
2870  NTSTATUS status;
2871 
2872  PAGED_CODE();
2873 
2874  if((Type == IRP_MN_QUERY_REMOVE_DEVICE) ||
2876  return STATUS_SUCCESS;
2877  }
2878 
2879  if (Type == IRP_MN_REMOVE_DEVICE){
2880  if(deviceExtension->DeviceDescriptor) {
2881  ExFreePool(deviceExtension->DeviceDescriptor);
2882  deviceExtension->DeviceDescriptor = NULL;
2883  }
2884 
2885  if(deviceExtension->AdapterDescriptor) {
2886  ExFreePool(deviceExtension->AdapterDescriptor);
2887  deviceExtension->AdapterDescriptor = NULL;
2888  }
2889 
2890  if(deviceExtension->SenseData) {
2891  ExFreePool(deviceExtension->SenseData);
2892  deviceExtension->SenseData = NULL;
2893  }
2894 
2895  ClassDeleteSrbLookasideList(&deviceExtension->CommonExtension);
2896  }
2897 
2898  if(diskData->FloppyInterfaceString.Buffer != NULL) {
2899 
2901  &(diskData->FloppyInterfaceString),
2902  FALSE);
2903 
2904  if (!NT_SUCCESS(status)) {
2905  // Failed to disable device interface during removal. Not a fatal error.
2906  DebugPrint((1, "ScsiFlopRemoveDevice: Unable to set device "
2907  "interface state to FALSE for fdo %p "
2908  "[%08lx]\n",
2909  DeviceObject, status));
2910  }
2911 
2914  }
2915 
2916  if(Type == IRP_MN_REMOVE_DEVICE) {
2918  }
2919 
2920  return STATUS_SUCCESS;
2921 }
2922 
2923 
2924 NTSTATUS
2925 #ifdef __REACTOS__
2926 NTAPI
2927 #endif
2930  IN UCHAR Type
2931  )
2932 {
2935 
2936  return STATUS_SUCCESS;
2937 }
2938 
2939 
2940 NTSTATUS
2943  IN PIRP Irp
2944  )
2945 {
2946 /*++
2947 
2948 Routine Description:
2949 
2950  This routines determines the current or default geometry of the drive
2951  for IOCTL_DISK_GET_DRIVE_GEOMETRY, or all currently supported geometries
2952  of the drive (which is determined by its currently inserted media) for
2953  IOCTL_DISK_GET_MEDIA_TYPES.
2954 
2955  The returned geometries are determined by issuing a Read Format Capacities
2956  request and then matching the returned {Number of Blocks, Block Length}
2957  pairs in a table of known floppy geometries.
2958 
2959 Arguments:
2960 
2961  DeviceObject - Supplies the device object.
2962 
2963  Irp - A IOCTL_DISK_GET_DRIVE_GEOMETRY or a IOCTL_DISK_GET_MEDIA_TYPES Irp.
2964  If NULL, the device geometry is updated with the current device
2965  geometry.
2966 
2967 Return Value:
2968 
2969  Status is returned.
2970 
2971 --*/
2972  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
2973  PIO_STACK_LOCATION irpStack;
2974  ULONG ioControlCode;
2975  PDISK_GEOMETRY outputBuffer;
2976  PDISK_GEOMETRY outputBufferEnd;
2977  ULONG outputBufferLength;
2978  PSCSI_REQUEST_BLOCK srb;
2979  PVOID dataBuffer;
2980  ULONG dataTransferLength;
2981  struct _READ_FORMATTED_CAPACITIES *cdb;
2982  PFORMATTED_CAPACITY_LIST capList;
2983  NTSTATUS status;
2984 
2985  PAGED_CODE();
2986 
2987  fdoExtension = DeviceObject->DeviceExtension;
2988 
2989  if (Irp != NULL) {
2990 
2991  // Get the Irp parameters
2992  //
2993  irpStack = IoGetCurrentIrpStackLocation(Irp);
2994 
2995  ioControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
2996 
2997  Irp->IoStatus.Information = 0;
2998 
2999  outputBuffer = (PDISK_GEOMETRY) Irp->AssociatedIrp.SystemBuffer;
3000 
3001  outputBufferLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
3002 
3003  if (outputBufferLength < sizeof(DISK_GEOMETRY))
3004  {
3005  return STATUS_BUFFER_TOO_SMALL;
3006  }
3007 
3008  // Pointer arithmetic to allow multiple DISK_GEOMETRY's to be returned.
3009  // Rounds BufferEnd down to integral multiple of DISK_GEOMETRY structs.
3010  //
3011  outputBufferEnd = outputBuffer +
3012  outputBufferLength / sizeof(DISK_GEOMETRY);
3013 
3014  } else {
3015 
3016  // No Irp to return the result in, just update the current geometry
3017  // in the device extension.
3018  //
3019  ioControlCode = IOCTL_DISK_GET_DRIVE_GEOMETRY;
3020 
3021  outputBuffer = NULL;
3022 
3023  outputBufferEnd = NULL;
3024 
3025  outputBufferLength = 0;
3026  }
3027 
3028  if (ioControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) {
3029 
3030  fdoExtension->DiskGeometry.MediaType = Unknown;
3031 
3033 
3034  if (!NT_SUCCESS(status))
3035  {
3036  // If the media is not recongized, we want to return the default
3037  // geometry so that the media can be formatted. Unrecognized media
3038  // causes SCSI_SENSE_MEDIUM_ERROR, which gets reported as
3039  // STATUS_DEVICE_DATA_ERROR. Ignore these errors, but return other
3040  // errors, such as STATUS_NO_MEDIA_IN_DEVICE.
3041  //
3043  {
3044  DebugPrint((2,"IOCTL_DISK_GET_DRIVE_GEOMETRY returns %08X\n", status));
3045 
3046  return status;
3047  }
3048  }
3049  }
3050 
3051  // Allocate an SRB for the SCSIOP_READ_FORMATTED_CAPACITY request
3052  //
3053 #ifndef __REACTOS__
3054  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
3055 #else
3057 #endif
3058 
3059  if (srb == NULL)
3060  {
3062  }
3063 
3064  // Allocate a transfer buffer for the SCSIOP_READ_FORMATTED_CAPACITY request
3065  // The length of the returned descriptor array is limited to a byte field
3066  // in the capacity list header.
3067  //
3068  dataTransferLength = sizeof(FORMATTED_CAPACITY_LIST) +
3069  31 * sizeof(FORMATTED_CAPACITY_DESCRIPTOR);
3070 
3071  ASSERT(dataTransferLength < 0x100);
3072 
3073 #ifndef __REACTOS__
3074  dataBuffer = ExAllocatePool(NonPagedPoolNx, dataTransferLength);
3075 #else
3076  dataBuffer = ExAllocatePool(NonPagedPool, dataTransferLength);
3077 #endif
3078 
3079  if (dataBuffer == NULL)
3080  {
3081  ExFreePool(srb);
3083  }
3084 
3085  // Initialize the SRB and CDB
3086  //
3088 
3089  RtlZeroMemory(dataBuffer, dataTransferLength);
3090 
3091  srb->CdbLength = sizeof(struct _READ_FORMATTED_CAPACITIES);
3092 
3093  srb->TimeOutValue = fdoExtension->TimeOutValue;
3094 
3095  cdb = (struct _READ_FORMATTED_CAPACITIES *)srb->Cdb;
3096 
3097  cdb->OperationCode = SCSIOP_READ_FORMATTED_CAPACITY;
3098  cdb->AllocationLength[1] = (UCHAR)dataTransferLength;
3099 
3100  //
3101  // Send down the SCSIOP_READ_FORMATTED_CAPACITY request
3102  //
3104  srb,
3105  dataBuffer,
3106  dataTransferLength,
3107  FALSE);
3108 
3109  capList = (PFORMATTED_CAPACITY_LIST)dataBuffer;
3110 
3111  // If we don't get as much data as requested, it is not an error.
3112  //
3114  {
3116  }
3117 
3118  if (NT_SUCCESS(status) &&
3119  srb->DataTransferLength >= sizeof(FORMATTED_CAPACITY_LIST) &&
3120  capList->CapacityListLength &&
3121  capList->CapacityListLength % sizeof(FORMATTED_CAPACITY_DESCRIPTOR) == 0)
3122  {
3123  ULONG NumberOfBlocks;
3124  ULONG BlockLength;
3125  ULONG count;
3126  ULONG i, j;
3127  LONG currentGeometry;
3128  BOOLEAN capacityMatches[FLOPPY_CAPACITIES];
3129 
3130  // Subtract the size of the Capacity List Header to get
3131  // just the size of the Capacity List Descriptor array.
3132  //
3134 
3135  // Only look at the Capacity List Descriptors that were actually
3136  // returned.
3137  //
3138  if (srb->DataTransferLength < capList->CapacityListLength)
3139  {
3140  count = srb->DataTransferLength /
3142  }
3143  else
3144  {
3145  count = capList->CapacityListLength /
3147  }
3148 
3149  // Updated only if a match is found for the first Capacity List
3150  // Descriptor returned by the device.
3151  //
3152  currentGeometry = -1;
3153 
3154  // Initialize the array of capacities that hit a match.
3155  //
3156  RtlZeroMemory(capacityMatches, sizeof(capacityMatches));
3157 
3158  // Iterate over each Capacity List Descriptor returned from the device
3159  // and record matching capacities in the capacity match array.
3160  //
3161  for (i = 0; i < count; i++)
3162  {
3163  NumberOfBlocks = (capList->Descriptors[i].NumberOfBlocks[0] << 24) +
3164  (capList->Descriptors[i].NumberOfBlocks[1] << 16) +
3165  (capList->Descriptors[i].NumberOfBlocks[2] << 8) +
3166  (capList->Descriptors[i].NumberOfBlocks[3]);
3167 
3168  BlockLength = (capList->Descriptors[i].BlockLength[0] << 16) +
3169  (capList->Descriptors[i].BlockLength[1] << 8) +
3170  (capList->Descriptors[i].BlockLength[2]);
3171 
3172  // Given the {NumberOfBlocks, BlockLength} from this Capacity List
3173  // Descriptor, find a matching entry in FloppyCapacities[].
3174  //
3175  for (j = 0; j < FLOPPY_CAPACITIES; j++)
3176  {
3177  if (NumberOfBlocks == FloppyCapacities[j].NumberOfBlocks &&
3178  BlockLength == FloppyCapacities[j].BlockLength)
3179  {
3180  // A matching capacity was found, record it.
3181  //
3182  capacityMatches[j] = TRUE;
3183 
3184  // A match was found for the first Capacity List
3185  // Descriptor returned by the device.
3186  //
3187  if (i == 0)
3188  {
3189  currentGeometry = j;
3190  }
3191  } else if ((capList->Descriptors[i].Valid) &&
3192  (BlockLength == FloppyCapacities[j].BlockLength)) {
3193 
3194  ULONG inx;
3195  ULONG mediaInx;
3196 
3197  //
3198  // Check if this is 32MB media type. 32MB media
3199  // reports variable NumberOfBlocks. So we cannot
3200  // use that to determine the drive type
3201  //
3203  if (inx != DRIVE_TYPE_NONE) {
3204  mediaInx = DriveMediaLimits[inx].HighestDriveMediaType;
3205  if ((DriveMediaConstants[mediaInx].MediaType)
3206  == F3_32M_512) {
3207  capacityMatches[j] = TRUE;
3208 
3209  if (i == 0) {
3210  currentGeometry = j;
3211  }
3212  }
3213  }
3214  }
3215  }
3216  }
3217 
3218  // Default status is STATUS_UNRECOGNIZED_MEDIA, unless we return
3219  // either STATUS_SUCCESS or STATUS_BUFFER_OVERFLOW.
3220  //
3222 
3223  if (ioControlCode == IOCTL_DISK_GET_DRIVE_GEOMETRY) {
3224 
3225  if (currentGeometry != -1)
3226  {
3227  // Update the current device geometry
3228  //
3229  fdoExtension->DiskGeometry = FloppyGeometries[currentGeometry];
3230 
3231  //
3232  // Calculate sector to byte shift.
3233  //
3234 
3235  WHICH_BIT(fdoExtension->DiskGeometry.BytesPerSector,
3236  fdoExtension->SectorShift);
3237 
3238  fdoExtension->CommonExtension.PartitionLength.QuadPart =
3239  (LONGLONG)FloppyCapacities[currentGeometry].NumberOfBlocks *
3240  FloppyCapacities[currentGeometry].BlockLength;
3241 
3242  DebugPrint((2,"geometry is: %3d %2d %d %2d %4d %2d %08X\n",
3243  fdoExtension->DiskGeometry.Cylinders.LowPart,
3244  fdoExtension->DiskGeometry.MediaType,
3245  fdoExtension->DiskGeometry.TracksPerCylinder,
3246  fdoExtension->DiskGeometry.SectorsPerTrack,
3247  fdoExtension->DiskGeometry.BytesPerSector,
3248  fdoExtension->SectorShift,
3249  fdoExtension->CommonExtension.PartitionLength.LowPart));
3250 
3251  // Return the current device geometry
3252  //
3253  if (Irp != NULL)
3254  {
3255  *outputBuffer = FloppyGeometries[currentGeometry];
3256 
3257  Irp->IoStatus.Information = sizeof(DISK_GEOMETRY);
3258  }
3259 
3261  }
3262 
3263  } else {
3264 
3265  // Iterate over the capacities and return the geometry
3266  // corresponding to each matching Capacity List Descriptor
3267  // returned from the device.
3268  //
3269  // The resulting list should be in sorted ascending order,
3270  // assuming that the FloppyGeometries[] array is in sorted
3271  // ascending order.
3272  //
3273  for (i = 0; i < FLOPPY_CAPACITIES; i++)
3274  {
3275  if (capacityMatches[i] && FloppyCapacities[i].CanFormat)
3276  {
3277  if (outputBuffer < outputBufferEnd)
3278  {
3279  *outputBuffer++ = FloppyGeometries[i];
3280 
3281  Irp->IoStatus.Information += sizeof(DISK_GEOMETRY);
3282 
3283  DebugPrint((2,"geometry : %3d %2d %d %2d %4d\n",
3284  FloppyGeometries[i].Cylinders.LowPart,
3289 
3291  }
3292  else
3293  {
3294  // We ran out of output buffer room before we ran out
3295  // geometries to return.
3296  //
3298  }
3299  }
3300  }
3301  }
3302  }
3303  else if (NT_SUCCESS(status))
3304  {
3305  // The SCSIOP_READ_FORMATTED_CAPACITY request was successful, but
3306  // returned data does not appear valid.
3307  //
3309  }
3310 
3311  ExFreePool(dataBuffer);
3312  ExFreePool(srb);
3313 
3314  return status;
3315 }
3316 
3317 
3318 NTSTATUS
3321  IN PIRP Irp
3322  )
3323 {
3324 /*++
3325 
3326 Routine Description:
3327 
3328  This routines formats the specified tracks. If multiple tracks are
3329  specified, each is formatted with a separate Format Unit request.
3330 
3331 Arguments:
3332 
3333  DeviceObject - Supplies the device object.
3334 
3335  Irp - A IOCTL_DISK_FORMAT_TRACKS Irp.
3336 
3337 Return Value:
3338 
3339  Status is returned.
3340 
3341 --*/
3342  PFUNCTIONAL_DEVICE_EXTENSION fdoExtension;
3343  PIO_STACK_LOCATION irpStack;
3344  PFORMAT_PARAMETERS formatParameters;
3345  PDISK_GEOMETRY geometry;
3346  PFORMATTED_CAPACITY capacity;
3347  PSCSI_REQUEST_BLOCK srb;
3348  PFORMAT_UNIT_PARAMETER_LIST parameterList;
3349  PCDB12FORMAT cdb;
3350  ULONG i;
3351  ULONG cylinder, head;
3353 
3354  PAGED_CODE();
3355 
3356  fdoExtension = DeviceObject->DeviceExtension;
3357 
3358  // Get the Irp parameters
3359  //
3360  irpStack = IoGetCurrentIrpStackLocation(Irp);
3361 
3362  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
3363  sizeof(FORMAT_PARAMETERS))
3364  {
3365  return STATUS_INVALID_PARAMETER;
3366  }
3367 
3368  formatParameters = (PFORMAT_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
3369 
3370  // Find the geometry / capacity entries corresponding to the format
3371  // parameters MediaType
3372  //
3373  geometry = NULL;
3374  capacity = NULL;
3375 
3376  for (i=0; i<FLOPPY_CAPACITIES; i++)
3377  {
3378  if (FloppyGeometries[i].MediaType == formatParameters->MediaType)
3379  {
3380  geometry = &FloppyGeometries[i];
3381  capacity = &FloppyCapacities[i];
3382 
3383  break;
3384  }
3385  }
3386 
3387  if (geometry == NULL)
3388  {
3389  return STATUS_INVALID_PARAMETER;
3390  }
3391 
3392  // Check if the format parameters are valid
3393  //
3394  if ((formatParameters->StartCylinderNumber >
3395  geometry->Cylinders.LowPart - 1) ||
3396 
3397  (formatParameters->EndCylinderNumber >
3398  geometry->Cylinders.LowPart - 1) ||
3399 
3400  (formatParameters->StartHeadNumber >
3401  geometry->TracksPerCylinder - 1) ||
3402 
3403  (formatParameters->EndHeadNumber >
3404  geometry->TracksPerCylinder - 1) ||
3405 
3406  (formatParameters->StartCylinderNumber >
3407  formatParameters->EndCylinderNumber) ||
3408 
3409  (formatParameters->StartHeadNumber >
3410  formatParameters->EndHeadNumber))
3411  {
3412  return STATUS_INVALID_PARAMETER;
3413  }
3414 
3415  // Don't low level format LS-120 media, Imation says it's best to not
3416  // do this.
3417  //
3418  if ((formatParameters->MediaType == F3_120M_512) ||
3419  (formatParameters->MediaType == F3_240M_512) ||
3420  (formatParameters->MediaType == F3_32M_512))
3421  {
3422  return STATUS_SUCCESS;
3423  }
3424 
3425  // Allocate an SRB for the SCSIOP_FORMAT_UNIT request
3426  //
3427 #ifndef __REACTOS__
3428  srb = ExAllocatePool(NonPagedPoolNx, SCSI_REQUEST_BLOCK_SIZE);
3429 #else
3431 #endif
3432 
3433  if (srb == NULL)
3434  {
3436  }
3437 
3438  // Allocate a transfer buffer for the SCSIOP_FORMAT_UNIT parameter list
3439  //
3440 #ifndef __REACTOS__
3441  parameterList = ExAllocatePool(NonPagedPoolNx,
3442 #else
3443  parameterList = ExAllocatePool(NonPagedPool,
3444 #endif
3445  sizeof(FORMAT_UNIT_PARAMETER_LIST));
3446 
3447  if (parameterList == NULL)
3448  {
3449  ExFreePool(srb);
3451  }
3452 
3453  // Initialize the parameter list
3454  //
3455  RtlZeroMemory(parameterList, sizeof(FORMAT_UNIT_PARAMETER_LIST));
3456 
3457  parameterList->DefectListHeader.SingleTrack = 1;
3458  parameterList->DefectListHeader.DisableCert = 1; // TEAC requires this set
3459  parameterList->DefectListHeader.FormatOptionsValid = 1;
3460  parameterList->DefectListHeader.DefectListLengthLsb = 8;
3461 
3462  parameterList->FormatDescriptor.NumberOfBlocks[0] =
3463  (UCHAR)((capacity->NumberOfBlocks >> 24) & 0xFF);
3464 
3465  parameterList->FormatDescriptor.NumberOfBlocks[1] =
3466  (UCHAR)((capacity->NumberOfBlocks >> 16) & 0xFF);
3467 
3468  parameterList->FormatDescriptor.NumberOfBlocks[2] =
3469  (UCHAR)((capacity->NumberOfBlocks >> 8) & 0xFF);
3470 
3471  parameterList->FormatDescriptor.NumberOfBlocks[3] =
3472  (UCHAR)(capacity->NumberOfBlocks & 0xFF);
3473 
3474  parameterList->FormatDescriptor.BlockLength[0] =
3475  (UCHAR)((capacity->BlockLength >> 16) & 0xFF);
3476 
3477  parameterList->FormatDescriptor.BlockLength[1] =
3478  (UCHAR)((capacity->BlockLength >> 8) & 0xFF);
3479 
3480  parameterList->FormatDescriptor.BlockLength[2] =
3481  (UCHAR)(capacity->BlockLength & 0xFF);
3482 
3483 
3484  for (cylinder = formatParameters->StartCylinderNumber;
3485  cylinder <= formatParameters->EndCylinderNumber;
3486  cylinder++)
3487  {
3488  for (head = formatParameters->StartHeadNumber;
3489  head <= formatParameters->EndHeadNumber;
3490  head++)
3491  {
3492  // Initialize the SRB and CDB
3493  //
3495 
3496  srb->CdbLength = sizeof(CDB12FORMAT);
3497 
3498  srb->TimeOutValue = fdoExtension->TimeOutValue;
3499 
3500  cdb = (PCDB12FORMAT)srb->Cdb;
3501 
3503  cdb->DefectListFormat = 7;
3504  cdb->FmtData = 1;
3505  cdb->TrackNumber = (UCHAR)cylinder;
3507 
3508  parameterList->DefectListHeader.Side = (UCHAR)head;
3509 
3510  //
3511  // Send down the SCSIOP_FORMAT_UNIT request
3512  //
3514  srb,
3515  parameterList,
3517  TRUE);
3518 
3519  if (!NT_SUCCESS(status))
3520  {
3521  break;
3522  }
3523  }
3524  if (!NT_SUCCESS(status))
3525  {
3526  break;
3527  }
3528  }
3529 
3530  if (NT_SUCCESS(status) && formatParameters->StartCylinderNumber == 0)
3531  {
3532  // Update the device geometry
3533  //
3534 
3535  DebugPrint((2,"geometry was: %3d %2d %d %2d %4d %2d %08X\n",
3536  fdoExtension->DiskGeometry.Cylinders.LowPart,
3537  fdoExtension->DiskGeometry.MediaType,
3538  fdoExtension->DiskGeometry.TracksPerCylinder,
3539  fdoExtension->DiskGeometry.SectorsPerTrack,
3540  fdoExtension->DiskGeometry.BytesPerSector,
3541  fdoExtension->SectorShift,
3542  fdoExtension->CommonExtension.PartitionLength.LowPart));
3543 
3544  fdoExtension->DiskGeometry = *geometry;
3545 
3546  //
3547  // Calculate sector to byte shift.
3548  //
3549 
3550  WHICH_BIT(fdoExtension->DiskGeometry.BytesPerSector,
3551  fdoExtension->SectorShift);
3552 
3553  fdoExtension->CommonExtension.PartitionLength.QuadPart =
3554  (LONGLONG)capacity->NumberOfBlocks *
3555  capacity->BlockLength;
3556 
3557  DebugPrint((2,"geometry is: %3d %2d %d %2d %4d %2d %08X\n",
3558  fdoExtension->DiskGeometry.Cylinders.LowPart,
3559  fdoExtension->DiskGeometry.MediaType,
3560  fdoExtension->DiskGeometry.TracksPerCylinder,
3561  fdoExtension->DiskGeometry.SectorsPerTrack,
3562  fdoExtension->DiskGeometry.BytesPerSector,
3563  fdoExtension->SectorShift,
3564  fdoExtension->CommonExtension.PartitionLength.LowPart));
3565  }
3566 
3567  // Free everything we allocated
3568  //
3569  ExFreePool(parameterList);
3570  ExFreePool(srb);
3571 
3572  return status;
3573 }
3574 
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
UCHAR InterleaveMsb
Definition: floppy.c:310
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
signed char * PCHAR
Definition: retypes.h:7
ULONG NTAPI ClassInitialize(IN PVOID Argument1, IN PVOID Argument2, IN PCLASS_INIT_DATA InitializationData)
Definition: class.c:120
struct _FOUR_BYTE * PFOUR_BYTE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define SRB_FLAGS_DISABLE_AUTOSENSE
Definition: srb.h:391
UCHAR PortNumber
Definition: scsi_port.h:148
DRIVE_MEDIA_CONSTANTS DriveMediaConstants[]
Definition: floppy.c:173
#define IN
Definition: typedefs.h:38
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define FLOPPY_CAPACITIES
Definition: floppy.c:292
FORMATTED_CAPACITY FloppyCapacities[]
Definition: floppy.c:249
#define IRP_MN_REMOVE_DEVICE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
VOID NTAPI ClassDeleteSrbLookasideList(IN PCOMMON_DEVICE_EXTENSION CommonExtension)
Definition: obsolete.c:899
UCHAR BytesPerSector[2]
Definition: scsi.h:2324
UCHAR Reserved2[3]
Definition: floppy.c:315
struct _MODE_PARAMETER_HEADER MODE_PARAMETER_HEADER
_In_ PDEVICE_OBJECT Pdo
Definition: classpnp.h:301
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSTATUS FormatMedia(PDEVICE_OBJECT DeviceObject, MEDIA_TYPE MediaType)
Definition: floppy.c:2185
Type
Definition: Type.h:6
UCHAR Cdb[16]
Definition: srb.h:271
#define IRP_MJ_FLUSH_BUFFERS
Definition: http.c:6587
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
struct outqueuenode * head
Definition: adnsresfilter.c:66
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Definition: iorsrce.c:830
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
_In_ PIRP Irp
Definition: csq.h:116
struct _DEFECT_LIST_HEADER * PDEFECT_LIST_HEADER
struct _FORMAT_UNIT_PARAMETER_LIST * PFORMAT_UNIT_PARAMETER_LIST
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
UCHAR InterleaveLsb
Definition: floppy.c:311
struct _DRIVE_MEDIA_CONSTANTS * PDRIVE_MEDIA_CONSTANTS
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
GLuint GLuint GLsizei count
Definition: gl.h:1545
DRIVE_MEDIA_LIMITS DriveMediaLimits[NUMBER_OF_DRIVE_TYPES]
Definition: floppy.c:136
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG DataTransferLength
Definition: srb.h:253
GLUquadricObj * cylinder
Definition: cylfrac.c:44
struct _FORMATTED_CAPACITY * PFORMATTED_CAPACITY
#define SFLOPPY_SRB_LIST_SIZE
Definition: floppy.c:51
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
Definition: cdrw_hw.h:28
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:114
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN FindScsiFlops(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath, IN PCLASS_INIT_DATA InitializationData, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG PortNumber)
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
VOID ScsiFlopProcessError(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, NTSTATUS *Status, BOOLEAN *Retry)
Definition: floppy.c:2427
GLintptr offset
Definition: glext.h:5920
ULONG NumberOfBlocks
Definition: floppy.c:240
struct _FORMATTED_CAPACITY FORMATTED_CAPACITY
ULONG NTAPI ClassModeSense(IN PDEVICE_OBJECT Fdo, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
Definition: class.c:4122
NTSTATUS ScsiFlopStartDevice(IN PDEVICE_OBJECT Fdo)
Definition: floppy.c:943
struct _CDB12FORMAT CDB12FORMAT
#define MODE_SENSE_RETURN_ALL
Definition: cdrw_hw.h:857
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
DRIVER_ADD_DEVICE ScsiFlopAddDevice
Definition: floppy.c:345
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
enum _MEDIA_TYPE MEDIA_TYPE
ULONG BytesPerSector
Definition: ntdddisk.h:376
ULONG TracksPerCylinder
Definition: ntdddisk.h:374
_In_ ULONG _In_ ULONG _In_ ULONG NumberOfHeads
Definition: iofuncs.h:2066
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
NTSTATUS ScsiFlopInitDevice(IN PDEVICE_OBJECT Fdo)
Definition: floppy.c:820
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
BOOLEAN IsFloppyDevice(PDEVICE_OBJECT DeviceObject)
Definition: disk.c:3143
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
#define PAGED_CODE()
Definition: video.h:57
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define STATUS_UNRECOGNIZED_MEDIA
Definition: udferr_usr.h:142
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
UCHAR ParameterListLengthLsb
Definition: floppy.c:314
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define IRP_MJ_SCSI
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
UCHAR CmpList
Definition: floppy.c:306
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
PDEVICE_OBJECT DeviceObject
Definition: kstypes.h:153
BOOLEAN CanFormat
Definition: floppy.c:244
DRIVER_INITIALIZE DriverEntry
Definition: floppy.c:341
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 IOCTL_DISK_FORMAT_TRACKS
Definition: cdrw_usr.h:171
NTSTATUS NTAPI ClassSendSrbSynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:2648
UCHAR DefectListLengthMsb
Definition: floppy.c:329
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG SectorsPerTrack
Definition: iofuncs.h:2066
#define IRP_MN_QUERY_REMOVE_DEVICE
DEFECT_LIST_HEADER DefectListHeader
Definition: floppy.c:335
long LONG
Definition: pedump.c:60
#define IOCTL_DISK_VERIFY
Definition: cdrw_usr.h:170
ULONG DeviceCount
Definition: mpu401.c:26
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
struct _FUNCTIONAL_DEVICE_EXTENSION FUNCTIONAL_DEVICE_EXTENSION
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
#define SCSIOP_READ
Definition: cdrw_hw.h:905
DRIVE_MEDIA_TYPE HighestDriveMediaType
Definition: floppy.c:121
#define MODE_FD_SINGLE_SIDE
Definition: cdrw_hw.h:2519
ULONG PortNumber
Definition: storport.c:18
PVOID DeviceExtension
Definition: env_spec_w32.h:418
C_ASSERT((sizeof(FloppyGeometries)/sizeof(FloppyGeometries[0]))==FLOPPY_CAPACITIES)
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define offsetof(TYPE, MEMBER)
#define SCSIOP_READ_FORMATTED_CAPACITY
Definition: scsi.h:272
union _CDB * PCDB
NTSTATUS NTAPI ClassCreateDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PCCHAR ObjectNameBuffer, IN PDEVICE_OBJECT LowerDevice, IN BOOLEAN IsFdo, IN OUT PDEVICE_OBJECT *DeviceObject)
Definition: class.c:5687
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1779
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define IOCTL_DISK_GET_MEDIA_TYPES
Definition: cdrw_usr.h:182
NTSTATUS USBFlopGetMediaTypes(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: floppy.c:2941
MEDIA_TYPE MediaType
Definition: ntdddisk.h:503
BOOLEAN IsDMF
Definition: floppy.c:222
PVOID NTAPI ClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class.c:4209
struct _FORMATTED_CAPACITY_LIST * PFORMATTED_CAPACITY_LIST
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
GLuint index
Definition: glext.h:6031
struct _DISK_DATA * PDISK_DATA
switch(r->id)
Definition: btrfs.c:2691
void * PVOID
Definition: retypes.h:9
ULONG StartCylinderNumber
Definition: ntdddisk.h:504
Windows helper functions for integer overflow prevention.
_DRIVE_MEDIA_TYPE
Definition: floppy.c:74
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 GLint GLint j
Definition: glfuncs.h:250
LARGE_INTEGER StartingOffset
Definition: classpnp.h:595
struct _DRIVE_MEDIA_LIMITS * PDRIVE_MEDIA_LIMITS
UCHAR DefectListLengthLsb
Definition: floppy.c:330
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
int64_t LONGLONG
Definition: typedefs.h:66
struct _DISK_DATA DISK_DATA
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
enum _DRIVE_MEDIA_TYPE DRIVE_MEDIA_TYPE
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define MODE_DATA_SIZE
Definition: floppy.c:49
uint64_t ULONGLONG
Definition: typedefs.h:65
LARGE_INTEGER Cylinders
Definition: ntdddisk.h:372
ULONG SectorsPerTrack
Definition: ntdddisk.h:375
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:699
BOOLEAN FlCheckFormatParameters(IN PDEVICE_OBJECT DeviceObject, IN PFORMAT_PARAMETERS FormatParameters)
Definition: floppy.c:2074
#define SCSI_FLOPPY_TIMEOUT
Definition: floppy.c:50
PSTORAGE_DEVICE_DESCRIPTOR DeviceDescriptor
Definition: classpnp.h:698
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
irpSp
Definition: iofuncs.h:2671
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
#define for
Definition: utility.h:88
MEDIA_TYPE MediaType
Definition: ntdddisk.h:373
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define F3_1Pt2_512
Definition: vfdfmt.c:27
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
UCHAR NumberOfCylinders[2]
Definition: scsi.h:2325
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned char UCHAR
Definition: xmlstorage.h:181
UNICODE_STRING FloppyInterfaceString
Definition: floppy.c:224
struct _DISK_GEOMETRY * PDISK_GEOMETRY
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:88
#define index(s, c)
Definition: various.h:29
static const WCHAR L[]
Definition: oid.c:1250
PDEVICE_OBJECT LowerPdo
Definition: classpnp.h:697
_In_ PVOID _In_ PCLASS_INIT_DATA InitializationData
Definition: classpnp.h:680
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define VOID
Definition: acefi.h:82
ULONG LowPart
Definition: typedefs.h:104
#define SCSIOP_FORMAT_UNIT
Definition: cdrw_hw.h:871
UCHAR LogicalUnitNumber
Definition: floppy.c:308
NTSTATUS CreateFlopDeviceObject(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PortDeviceObject, IN ULONG DeviceCount)
Definition: floppy.c:645
#define NOTHING
Definition: env_spec_w32.h:461
struct _cl_event * event
Definition: glext.h:7739
static __inline NTSTATUS RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1120
struct _DRIVE_MEDIA_LIMITS DRIVE_MEDIA_LIMITS
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
UCHAR Reserved1[2]
Definition: floppy.c:312
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define NUMBER_OF_DRIVE_MEDIA_COMBINATIONS
Definition: floppy.c:214
struct _FORMAT_PARAMETERS * PFORMAT_PARAMETERS
NTSTATUS NTAPI ClassClaimDevice(IN PDEVICE_OBJECT LowerDeviceObject, IN BOOLEAN Release)
Definition: class.c:5985
Status
Definition: gdiplustypes.h:24
MEDIA_TYPE MediaType
Definition: floppy.c:153
FORMATTED_CAPACITY_DESCRIPTOR FormatDescriptor
Definition: floppy.c:336
NTSTATUS ScsiFlopReadWriteVerification(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: floppy.c:1085
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
#define NUMBER_OF_DRIVE_TYPES
Definition: floppy.c:59
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1250
struct _DISK_GEOMETRY DISK_GEOMETRY
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
VOID NTAPI ClassCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN CCHAR PriorityBoost)
Definition: lock.c:376
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
struct _FORMATTED_CAPACITY_LIST FORMATTED_CAPACITY_LIST
unsigned short USHORT
Definition: pedump.c:61
ULONG DetermineDriveType(PDEVICE_OBJECT DeviceObject)
Definition: floppy.c:1913
ULONG NTAPI ClassQueryTimeOutRegistryValue(IN PDEVICE_OBJECT DeviceObject)
Definition: class.c:6190
#define F3_640_512
Definition: vfdfmt.c:24
UCHAR FmtData
Definition: floppy.c:307
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
VOID NTAPI ClassInitializeSrbLookasideList(IN PCOMMON_DEVICE_EXTENSION CommonExtension, IN ULONG NumberElements)
Definition: obsolete.c:941
#define IoAssignArcName(_ArcName, _DeviceName)
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI ClassReadDriveCapacity(IN PDEVICE_OBJECT Fdo)
Definition: class.c:1729
UCHAR FormatOptionsValid
Definition: floppy.c:328
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
DISK_GEOMETRY FloppyGeometries[]
Definition: floppy.c:264
UCHAR OperationCode
Definition: floppy.c:304
struct _CLASS_INIT_DATA CLASS_INIT_DATA
DRIVER_UNLOAD ScsiFlopUnload
Definition: floppy.c:343
NTSTATUS FlopticalFormatMedia(PDEVICE_OBJECT DeviceObject, PFORMAT_PARAMETERS Format)
Definition: floppy.c:2720
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2479
UCHAR ParameterListLengthMsb
Definition: floppy.c:313
struct _FORMATTED_CAPACITY_DESCRIPTOR FORMATTED_CAPACITY_DESCRIPTOR
DRIVE_MEDIA_TYPE LowestDriveMediaType
Definition: floppy.c:122
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
struct _DRIVE_MEDIA_CONSTANTS DRIVE_MEDIA_CONSTANTS
#define IRP_MJ_READ
Definition: rdpdr.c:46
VOID NTAPI ClassInitializeMediaChangeDetection(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PUCHAR EventPrefix)
Definition: autorun.c:2058
#define DRIVE_TYPE_NONE
Definition: floppy.c:61
NTSTATUS ScsiFlopDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
ULONG DriveType
Definition: floppy.c:221
NTSTATUS ScsiFlopRemoveDevice(IN PDEVICE_OBJECT Fdo, IN UCHAR Type)
Definition: floppy.c:2838
Definition: name.c:36
UINT sectorCount[1]
Definition: diskio.c:16
#define MODE_FD_MAXIMUM_TYPE
Definition: cdrw_hw.h:2521
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS DetermineMediaType(PDEVICE_OBJECT DeviceObject)
Definition: floppy.c:1745
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PUNICODE_STRING RegistryPath
Definition: wmip.h:27
struct _DEFECT_LIST_HEADER DEFECT_LIST_HEADER
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
NTSTATUS USBFlopFormatTracks(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: floppy.c:3319
ULONG EndCylinderNumber
Definition: ntdddisk.h:505
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
NTSTATUS ScsiFlopStopDevice(IN PDEVICE_OBJECT Fdo, IN UCHAR Type)
Definition: floppy.c:2928
#define FILE_FLOPPY_DISKETTE
Definition: nt_native.h:809
return STATUS_SUCCESS
Definition: btrfs.c:2725
static __inline NTSTATUS RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1099
static SERVICE_STATUS status
Definition: service.c:31
FORMATTED_CAPACITY_DESCRIPTOR Descriptors[0]
Definition: scsi.h:1804
struct _FORMAT_UNIT_PARAMETER_LIST FORMAT_UNIT_PARAMETER_LIST
NTSTATUS NTAPI ClassSendSrbAsynchronous(PDEVICE_OBJECT Fdo, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class.c:4321
UCHAR DefectListFormat
Definition: floppy.c:305
NTSTATUS NTAPI ClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class.c:2168
struct _CDB12FORMAT * PCDB12FORMAT
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
UCHAR TrackNumber
Definition: floppy.c:309
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define SUCCEEDED(hr)
Definition: intsafe.h:57
LONGLONG QuadPart
Definition: typedefs.h:112
ULONG StartHeadNumber
Definition: ntdddisk.h:506
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
LARGE_INTEGER StartingOffset
Definition: ntdddisk.h:536
#define MODE_PAGE_FLEXIBILE
Definition: scsi.h:196
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288
static DRIVER_DISPATCH ClassDeviceControl
Definition: kbdclass.c:22
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
Definition: ps.c:97