⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 floppy.c

📁 The sfloppy sample is a super floppy driver that resides in the directory \NtddkSrcStoragesfloppy. I
💻 C
📖 第 1 页 / 共 5 页
字号:
            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, &currentIrql);
    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 + -