📄 floppy.c
字号:
status = STATUS_SUCCESS;
break;
}
status = FormatMedia( DeviceObject, formatParameters->MediaType);
break;
}
case IOCTL_DISK_IS_WRITABLE: {
if ((fdoExtension->DiskGeometry.MediaType) == F3_32M_512) {
//
// 32MB media is READ ONLY. Just return
// STATUS_MEDIA_WRITE_PROTECTED
//
status = STATUS_MEDIA_WRITE_PROTECTED;
break;
}
//
// Determine if the device is writable.
//
modeData = ExAllocatePool(NonPagedPoolCacheAligned, MODE_DATA_SIZE);
if (modeData == NULL) {
status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
RtlZeroMemory(modeData, MODE_DATA_SIZE);
length = ClassModeSense(DeviceObject,
(PUCHAR) modeData,
MODE_DATA_SIZE,
MODE_SENSE_RETURN_ALL);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
//
// Retry the request in case of a check condition.
//
length = ClassModeSense(DeviceObject,
(PUCHAR) modeData,
MODE_DATA_SIZE,
MODE_SENSE_RETURN_ALL);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
status = STATUS_IO_DEVICE_ERROR;
ExFreePool(modeData);
break;
}
}
if (modeData->DeviceSpecificParameter & MODE_DSP_WRITE_PROTECT) {
status = STATUS_MEDIA_WRITE_PROTECTED;
} else {
status = STATUS_SUCCESS;
}
DebugPrint((2,"IOCTL_DISK_IS_WRITABLE returns %08X\n", status));
ExFreePool(modeData);
break;
}
default: {
DebugPrint((3,"ScsiIoDeviceControl: Unsupported device IOCTL\n"));
//
// Free the Srb, since it is not needed.
//
ExFreePool(srb);
//
// Pass the request to the common device control routine.
//
return(ClassDeviceControl(DeviceObject, Irp));
break;
}
} // end switch( ...
//
// Check if SL_OVERRIDE_VERIFY_VOLUME flag is set in the IRP.
// If so, do not return STATUS_VERIFY_REQUIRED
//
if ((status == STATUS_VERIFY_REQUIRED) &&
(TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME))) {
status = STATUS_IO_DEVICE_ERROR;
}
Irp->IoStatus.Status = status;
if (!NT_SUCCESS(status) && IoIsErrorUserInduced(status)) {
IoSetHardErrorOrVerifyDevice(Irp, DeviceObject);
}
KeRaiseIrql(DISPATCH_LEVEL, ¤tIrql);
ClassReleaseRemoveLock(DeviceObject, Irp);
ClassCompleteRequest(DeviceObject, Irp, 0);
KeLowerIrql(currentIrql);
ExFreePool(srb);
return status;
} // end ScsiFlopDeviceControl()
#if 0
BOOLEAN
IsFloppyDevice(
PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
The routine performs the necessary funcitons to deterime if the device is
really a floppy rather than a harddisk. This is done by a mode sense
command. First a check is made to see if the medimum type is set. Second
a check is made for the flexible parameters mode page.
Arguments:
DeviceObject - Supplies the device object to be tested.
Return Value:
Return TRUE if the indicated device is a floppy.
--*/
{
PVOID modeData;
PUCHAR pageData;
ULONG length;
modeData = ExAllocatePool(NonPagedPoolCacheAligned, MODE_DATA_SIZE);
if (modeData == NULL) {
return(FALSE);
}
RtlZeroMemory(modeData, MODE_DATA_SIZE);
length = ClassModeSense(DeviceObject, modeData, MODE_DATA_SIZE, MODE_SENSE_RETURN_ALL);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
//
// Retry the request in case of a check condition.
//
length = ClassModeSense(DeviceObject,
modeData,
MODE_DATA_SIZE,
MODE_SENSE_RETURN_ALL);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
ExFreePool(modeData);
return(FALSE);
}
}
#if 0
//
// Some drives incorrectly report this. In particular the SONY RMO-S350
// when in disk mode.
//
if (((PMODE_PARAMETER_HEADER) modeData)->MediumType >= MODE_FD_SINGLE_SIDE
&& ((PMODE_PARAMETER_HEADER) modeData)->MediumType <= MODE_FD_MAXIMUM_TYPE) {
DebugPrint((1, "ScsiFlop: MediumType value %2x, This is a floppy.\n", ((PMODE_PARAMETER_HEADER) modeData)->MediumType));
ExFreePool(modeData);
return(TRUE);
}
#endif
//
// If the length is greater than length indiated by the mode data reset
// the data to the mode data.
//
if (length > (ULONG)((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1) {
length = (ULONG)((PMODE_PARAMETER_HEADER) modeData)->ModeDataLength + 1;
}
//
// Look for the flexible disk mode page.
//
pageData = ClassFindModePage( modeData, length, MODE_PAGE_FLEXIBILE, TRUE);
if (pageData != NULL) {
DebugPrint((1, "ScsiFlop: Flexible disk page found, This is a floppy.\n"));
//
// As a special case for the floptical driver do a magic mode sense to
// enable the drive.
//
ClassModeSense(DeviceObject, modeData, 0x2a, 0x2e);
ExFreePool(modeData);
return(TRUE);
}
ExFreePool(modeData);
return(FALSE);
}
#endif
NTSTATUS
DetermineMediaType(
PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine determines the floppy media type based on the size of the
device. The geometry information is set for the device object.
Arguments:
DeviceObject - Supplies the device object to be tested.
Return Value:
None
--*/
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
PDISK_GEOMETRY geometry;
LONG index;
NTSTATUS status;
geometry = &(fdoExtension->DiskGeometry);
//
// Issue ReadCapacity to update device extension
// with information for current media.
//
status = ClassReadDriveCapacity(DeviceObject);
if (!NT_SUCCESS(status)) {
//
// Set the media type to unknow and zero the geometry information.
//
geometry->MediaType = Unknown;
return status;
}
//
// Look at the capcity of disk to determine its type.
//
for (index = NUMBER_OF_DRIVE_MEDIA_COMBINATIONS - 1; index >= 0; index--) {
//
// Walk the table backward untill the drive capacity holds all of the
// data and the bytes per setor are equal
//
if ((ULONG) (DriveMediaConstants[index].NumberOfHeads *
(DriveMediaConstants[index].MaximumTrack + 1) *
DriveMediaConstants[index].SectorsPerTrack *
DriveMediaConstants[index].BytesPerSector) <=
fdoExtension->CommonExtension.PartitionLength.LowPart &&
DriveMediaConstants[index].BytesPerSector ==
geometry->BytesPerSector) {
geometry->MediaType = DriveMediaConstants[index].MediaType;
geometry->TracksPerCylinder = DriveMediaConstants[index].NumberOfHeads;
geometry->SectorsPerTrack = DriveMediaConstants[index].SectorsPerTrack;
geometry->Cylinders.LowPart = DriveMediaConstants[index].MaximumTrack+1;
break;
}
}
if (index == -1) {
//
// Set the media type to unknow and zero the geometry information.
//
geometry->MediaType = Unknown;
} else {
//
// DMF check breaks the insight SCSI floppy, so its disabled for that case
//
PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
// if (diskData->EnableDMF == TRUE) {
//
//check to see if DMF
//
PSCSI_REQUEST_BLOCK srb;
PVOID readData;
//
// Allocate a Srb for the read command.
//
readData = ExAllocatePool(NonPagedPool, geometry->BytesPerSector);
if (readData == NULL) {
return STATUS_NO_MEMORY;
}
srb = ExAllocatePool(NonPagedPool, SCSI_REQUEST_BLOCK_SIZE);
if (srb == NULL) {
ExFreePool(readData);
return STATUS_NO_MEMORY;
}
RtlZeroMemory(readData, geometry->BytesPerSector);
RtlZeroMemory(srb, SCSI_REQUEST_BLOCK_SIZE);
srb->CdbLength = 10;
srb->Cdb[0] = SCSIOP_READ;
srb->Cdb[5] = 0;
srb->Cdb[8] = (UCHAR) 1;
//
// Set timeout value.
//
srb->TimeOutValue = fdoExtension->TimeOutValue;
//
// Send the mode select data.
//
status = ClassSendSrbSynchronous(DeviceObject,
srb,
readData,
geometry->BytesPerSector,
FALSE
);
if (NT_SUCCESS(status)) {
char *pchar = (char *)readData;
pchar += 3; //skip 3 bytes jump code
// If the MSDMF3. signature is there then mark it as DMF diskette
if (RtlCompareMemory(pchar, "MSDMF3.", 7) == 7) {
diskData->IsDMF = TRUE;
}
}
ExFreePool(readData);
ExFreePool(srb);
// }// else
}
return status;
}
ULONG
DetermineDriveType(
PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
The routine determines the device type so that the supported medias can be
determined. It does a mode sense for the default parameters. This code
assumes that the returned values are for the maximum device size.
Arguments:
DeviceObject - Supplies the device object to be tested.
Return Value:
None
--*/
{
PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
PVOID modeData;
PDISK_DATA diskData = (PDISK_DATA) fdoExtension->CommonExtension.DriverData;
PMODE_FLEXIBLE_DISK_PAGE pageData;
ULONG length;
LONG index;
UCHAR numberOfHeads;
UCHAR sectorsPerTrack;
USHORT maximumTrack;
BOOLEAN applyFix = FALSE;
if (diskData->DriveType != DRIVE_TYPE_NONE) {
return(diskData->DriveType);
}
modeData = ExAllocatePool(NonPagedPoolCacheAligned, MODE_DATA_SIZE);
if (modeData == NULL) {
return(DRIVE_TYPE_NONE);
}
RtlZeroMemory(modeData, MODE_DATA_SIZE);
length = ClassModeSense(DeviceObject,
modeData,
MODE_DATA_SIZE,
MODE_PAGE_FLEXIBILE);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
//
// Retry the request one more time
// in case of a check condition.
//
length = ClassModeSense(DeviceObject,
modeData,
MODE_DATA_SIZE,
MODE_PAGE_FLEXIBILE);
if (length < sizeof(MODE_PARAMETER_HEADER)) {
ExFreePool(modeData);
return(DRIVE_TYPE_NONE);
}
}
//
// Look for the flexible disk mode page.
//
pageData = ClassFindModePage( modeData,
length,
MODE_PAGE_FLEXIBILE,
TRUE);
//
// Make sure the page is returned and is large enough.
//
if ((pageData != NULL) &&
(pageData->PageLength + 2 >=
offsetof(MODE_FLEXIBLE_DISK_PAGE, StartWritePrecom))) {
//
// Pull out the heads, cylinders, and sectors.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -