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

📄 tape.c

📁 This sample is a working example of Exabyte2 Tape Minidriver. This module contains device-specific r
💻 C
📖 第 1 页 / 共 5 页
字号:

Return Value:

    none - this routine may not fail

--*/

{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
    PTAPE_DATA                   tapeData = (PTAPE_DATA)fdoExtension->CommonExtension.DriverData;
    WCHAR                        dosNameBuffer[64];
    UNICODE_STRING               dosUnicodeString;
    NTSTATUS                     status;

    PAGED_CODE();

    if((Type == IRP_MN_QUERY_REMOVE_DEVICE) ||
       (Type == IRP_MN_CANCEL_REMOVE_DEVICE)) {
        return STATUS_SUCCESS;
    }

    //
    // Free all allocated memory.
    //

    if (fdoExtension->DeviceDescriptor) {
        ExFreePool(fdoExtension->DeviceDescriptor);
        fdoExtension->DeviceDescriptor = NULL;
    }
    if (fdoExtension->AdapterDescriptor) {
        ExFreePool(fdoExtension->AdapterDescriptor);
        fdoExtension->AdapterDescriptor = NULL;
    }
    if (fdoExtension->SenseData) {
        ExFreePool(fdoExtension->SenseData);
        fdoExtension->SenseData = NULL;
    }

    //
    // Remove the lookaside list.
    //

    ClassDeleteSrbLookasideList(&fdoExtension->CommonExtension);

    if(tapeData->TapeInterfaceString.Buffer != NULL) {
        IoSetDeviceInterfaceState(&(tapeData->TapeInterfaceString),
                                  FALSE);

        RtlFreeUnicodeString(&(tapeData->TapeInterfaceString));

        //
        // Clear it.
        //

        RtlInitUnicodeString(&(tapeData->TapeInterfaceString), NULL);
    }

    if(tapeData->DosNameCreated) {
        //
        // Delete the symbolic link "tapeN".
        //

        swprintf(dosNameBuffer,
                 L"\\DosDevices\\TAPE%d",
                 fdoExtension->DeviceNumber);

        RtlInitUnicodeString(&dosUnicodeString, dosNameBuffer);

        IoDeleteSymbolicLink(&dosUnicodeString);

        tapeData->DosNameCreated = FALSE;
    }

    IoGetConfigurationInformation()->TapeCount--;

    return STATUS_SUCCESS;
}


NTSTATUS
TapeStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR Type
    )
{
    PAGED_CODE();
    return STATUS_SUCCESS;
}


BOOLEAN
ScsiTapeNtStatusToTapeStatus(
    IN  NTSTATUS        NtStatus,
    OUT PTAPE_STATUS    TapeStatus
    )

/*++

Routine Description:

    This routine translates an NT status code to a TAPE status code.

Arguments:

    NtStatus    - Supplies the NT status code.

    TapeStatus  - Returns the tape status code.

Return Value:

    FALSE   - No tranlation was possible.

    TRUE    - Success.

--*/

{
    switch (NtStatus) {

        case STATUS_SUCCESS:
            *TapeStatus = TAPE_STATUS_SUCCESS;
            break;

        case STATUS_INSUFFICIENT_RESOURCES:
            *TapeStatus = TAPE_STATUS_INSUFFICIENT_RESOURCES;
            break;

        case STATUS_NOT_IMPLEMENTED:
            *TapeStatus = TAPE_STATUS_NOT_IMPLEMENTED;
            break;

        case STATUS_INVALID_DEVICE_REQUEST:
            *TapeStatus = TAPE_STATUS_INVALID_DEVICE_REQUEST;
            break;

        case STATUS_INVALID_PARAMETER:
            *TapeStatus = TAPE_STATUS_INVALID_PARAMETER;
            break;

        case STATUS_VERIFY_REQUIRED:
        case STATUS_MEDIA_CHANGED:
            *TapeStatus = TAPE_STATUS_MEDIA_CHANGED;
            break;

        case STATUS_BUS_RESET:
            *TapeStatus = TAPE_STATUS_BUS_RESET;
            break;

        case STATUS_SETMARK_DETECTED:
            *TapeStatus = TAPE_STATUS_SETMARK_DETECTED;
            break;

        case STATUS_FILEMARK_DETECTED:
            *TapeStatus = TAPE_STATUS_FILEMARK_DETECTED;
            break;

        case STATUS_BEGINNING_OF_MEDIA:
            *TapeStatus = TAPE_STATUS_BEGINNING_OF_MEDIA;
            break;

        case STATUS_END_OF_MEDIA:
            *TapeStatus = TAPE_STATUS_END_OF_MEDIA;
            break;

        case STATUS_BUFFER_OVERFLOW:
            *TapeStatus = TAPE_STATUS_BUFFER_OVERFLOW;
            break;

        case STATUS_NO_DATA_DETECTED:
            *TapeStatus = TAPE_STATUS_NO_DATA_DETECTED;
            break;

        case STATUS_EOM_OVERFLOW:
            *TapeStatus = TAPE_STATUS_EOM_OVERFLOW;
            break;

        case STATUS_NO_MEDIA:
        case STATUS_NO_MEDIA_IN_DEVICE:
            *TapeStatus = TAPE_STATUS_NO_MEDIA;
            break;

        case STATUS_IO_DEVICE_ERROR:
        case STATUS_NONEXISTENT_SECTOR:
            *TapeStatus = TAPE_STATUS_IO_DEVICE_ERROR;
            break;

        case STATUS_UNRECOGNIZED_MEDIA:
            *TapeStatus = TAPE_STATUS_UNRECOGNIZED_MEDIA;
            break;

        case STATUS_DEVICE_NOT_READY:
            *TapeStatus = TAPE_STATUS_DEVICE_NOT_READY;
            break;

        case STATUS_MEDIA_WRITE_PROTECTED:
            *TapeStatus = TAPE_STATUS_MEDIA_WRITE_PROTECTED;
            break;

        case STATUS_DEVICE_DATA_ERROR:
            *TapeStatus = TAPE_STATUS_DEVICE_DATA_ERROR;
            break;

        case STATUS_NO_SUCH_DEVICE:
            *TapeStatus = TAPE_STATUS_NO_SUCH_DEVICE;
            break;

        case STATUS_INVALID_BLOCK_LENGTH:
            *TapeStatus = TAPE_STATUS_INVALID_BLOCK_LENGTH;
            break;

        case STATUS_IO_TIMEOUT:
            *TapeStatus = TAPE_STATUS_IO_TIMEOUT;
            break;

        case STATUS_DEVICE_NOT_CONNECTED:
            *TapeStatus = TAPE_STATUS_DEVICE_NOT_CONNECTED;
            break;

        case STATUS_DATA_OVERRUN:
            *TapeStatus = TAPE_STATUS_DATA_OVERRUN;
            break;

        case STATUS_DEVICE_BUSY:
            *TapeStatus = TAPE_STATUS_DEVICE_BUSY;
            break;

        case STATUS_CLEANER_CARTRIDGE_INSTALLED:
            *TapeStatus = TAPE_STATUS_CLEANER_CARTRIDGE_INSTALLED;
            break;

        default:
            return FALSE;

    }

    return TRUE;
}


BOOLEAN
ScsiTapeTapeStatusToNtStatus(
    IN  TAPE_STATUS TapeStatus,
    OUT PNTSTATUS   NtStatus
    )

/*++

Routine Description:

    This routine translates a TAPE status code to an NT status code.

Arguments:

    TapeStatus  - Supplies the tape status code.

    NtStatus    - Returns the NT status code.


Return Value:

    FALSE   - No tranlation was possible.

    TRUE    - Success.

--*/

{
    switch (TapeStatus) {

        case TAPE_STATUS_SUCCESS:
            *NtStatus = STATUS_SUCCESS;
            break;

        case TAPE_STATUS_INSUFFICIENT_RESOURCES:
            *NtStatus = STATUS_INSUFFICIENT_RESOURCES;
            break;

        case TAPE_STATUS_NOT_IMPLEMENTED:
            *NtStatus = STATUS_NOT_IMPLEMENTED;
            break;

        case TAPE_STATUS_INVALID_DEVICE_REQUEST:
            *NtStatus = STATUS_INVALID_DEVICE_REQUEST;
            break;

        case TAPE_STATUS_INVALID_PARAMETER:
            *NtStatus = STATUS_INVALID_PARAMETER;
            break;

        case TAPE_STATUS_MEDIA_CHANGED:
            *NtStatus = STATUS_VERIFY_REQUIRED;
            break;

        case TAPE_STATUS_BUS_RESET:
            *NtStatus = STATUS_BUS_RESET;
            break;

        case TAPE_STATUS_SETMARK_DETECTED:
            *NtStatus = STATUS_SETMARK_DETECTED;
            break;

        case TAPE_STATUS_FILEMARK_DETECTED:
            *NtStatus = STATUS_FILEMARK_DETECTED;
            break;

        case TAPE_STATUS_BEGINNING_OF_MEDIA:
            *NtStatus = STATUS_BEGINNING_OF_MEDIA;
            break;

        case TAPE_STATUS_END_OF_MEDIA:
            *NtStatus = STATUS_END_OF_MEDIA;
            break;

        case TAPE_STATUS_BUFFER_OVERFLOW:
            *NtStatus = STATUS_BUFFER_OVERFLOW;
            break;

        case TAPE_STATUS_NO_DATA_DETECTED:
            *NtStatus = STATUS_NO_DATA_DETECTED;
            break;

        case TAPE_STATUS_EOM_OVERFLOW:
            *NtStatus = STATUS_EOM_OVERFLOW;
            break;

        case TAPE_STATUS_NO_MEDIA:
            *NtStatus = STATUS_NO_MEDIA;
            break;

        case TAPE_STATUS_IO_DEVICE_ERROR:
            *NtStatus = STATUS_IO_DEVICE_ERROR;
            break;

        case TAPE_STATUS_UNRECOGNIZED_MEDIA:
            *NtStatus = STATUS_UNRECOGNIZED_MEDIA;
            break;

        case TAPE_STATUS_DEVICE_NOT_READY:
            *NtStatus = STATUS_DEVICE_NOT_READY;
            break;

        case TAPE_STATUS_MEDIA_WRITE_PROTECTED:
            *NtStatus = STATUS_MEDIA_WRITE_PROTECTED;
            break;

        case TAPE_STATUS_DEVICE_DATA_ERROR:
            *NtStatus = STATUS_DEVICE_DATA_ERROR;
            break;

        case TAPE_STATUS_NO_SUCH_DEVICE:
            *NtStatus = STATUS_NO_SUCH_DEVICE;
            break;

        case TAPE_STATUS_INVALID_BLOCK_LENGTH:
            *NtStatus = STATUS_INVALID_BLOCK_LENGTH;
            break;

        case TAPE_STATUS_IO_TIMEOUT:
            *NtStatus = STATUS_IO_TIMEOUT;
            break;

        case TAPE_STATUS_DEVICE_NOT_CONNECTED:
            *NtStatus = STATUS_DEVICE_NOT_CONNECTED;
            break;

        case TAPE_STATUS_DATA_OVERRUN:
            *NtStatus = STATUS_DATA_OVERRUN;
            break;

        case TAPE_STATUS_DEVICE_BUSY:
            *NtStatus = STATUS_DEVICE_BUSY;
            break;

        case TAPE_STATUS_REQUIRES_CLEANING:
            *NtStatus = STATUS_DEVICE_REQUIRES_CLEANING;
            break;

        case TAPE_STATUS_CLEANER_CARTRIDGE_INSTALLED:
            *NtStatus = STATUS_CLEANER_CARTRIDGE_INSTALLED;
            break;

        default:
            return FALSE;

    }

    return TRUE;
}


VOID
TapeError(
    IN      PDEVICE_OBJECT      FDO,
    IN      PSCSI_REQUEST_BLOCK Srb,
    IN OUT  PNTSTATUS           Status,
    IN OUT  PBOOLEAN            Retry
    )

/*++

Routine Description:

    When a request completes with error, the routine ScsiClassInterpretSenseInfo is
    called to determine from the sense data whether the request should be
    retried and what NT status to set in the IRP. Then this routine is called
    for tape requests to handle tape-specific errors and update the nt status
    and retry boolean.

Arguments:

    DeviceObject - Supplies a pointer to the device object.

    Srb - Supplies a pointer to the failing Srb.

    Status - NT Status used to set the IRP's completion status.

    Retry - Indicates that this request should be retried.

Return Value:

    None.

--*/

{
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = FDO->DeviceExtension;
    PTAPE_DATA tapeData = (PTAPE_DATA)(fdoExtension->CommonExtension.DriverData);
    PTAPE_INIT_DATA_EX tapeInitData = &tapeData->TapeInitData;
    PVOID minitapeExtension = (tapeData + 1);
    PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
    PIRP irp = Srb->OriginalRequest;
    LONG residualBlocks;
    LONG length;
    TAPE_STATUS tapeStatus, oldTapeStatus;
    TARGET_DEVICE_CUSTOM_NOTIFICATION  NotificationStructure[2];

    //
    // Never retry tape requests.
    //

    *Retry = FALSE;

    //
    // Check that request sense buffer is valid.
    //

    if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID) {

        DebugPrint((1, 
                    "Sense Code : %x, Ad Sense : %x, Ad Sense Qual : %x\n",
                    ((senseBuffer->SenseKey) & 0xf),
                    (senseBuffer->AdditionalSenseCode),
                    (senseBuffer->AdditionalSenseCodeQualifier)));

        switch (senseBuffer->SenseKey & 0xf) {

            case SCSI_SENSE_UNIT_ATTENTION:

                switch (senseBuffer->AdditionalSenseCode) {

                    case SCSI_ADSENSE_MEDIUM_CHANGED:
                        DebugPrint((1,
                                    "InterpretSenseInfo: Media changed\n"));

                        *Status = STATUS_MEDIA_CHANGED;

                        break;

                    default:
                        DebugPrint((1,
                                    "InterpretSenseInfo: Bus reset\n"));

                        *Status = STATUS_BUS_RESET;

                        break;

                }

                break;

            case SCSI_SENSE_RECOVERED_ERROR:

                //
                // Check other indicators
                //

                if (senseBuffer->FileMark) {

                    switch (senseBuffer->AdditionalSenseCodeQualifier) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -