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

📄 tape.c

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

Copyright (C) Microsoft Corporation, 1994 - 1999

Module Name:

    scsitape.c

Abstract:

    This is the tape class driver.

Environment:

    kernel mode only

Revision History:

--*/

#include "tape.h"

//
// Define the maximum inquiry data length.
//

#define MAXIMUM_TAPE_INQUIRY_DATA   252
#define UNDEFINED_BLOCK_SIZE        ((ULONG) -1)
#define TAPE_SRB_LIST_SIZE          4

NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    );

VOID
TapeUnload(
    IN PDRIVER_OBJECT DriverObject
    );

NTSTATUS
TapeAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT Pdo
    );

NTSTATUS
TapeStartDevice(
    IN PDEVICE_OBJECT Fdo
    );

NTSTATUS
CreateTapeDeviceObject(
    IN PDRIVER_OBJECT          DriverObject,
    IN PDEVICE_OBJECT          PhysicalDeviceObject,
    IN PTAPE_INIT_DATA_EX      TapeInitData
    );

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

NTSTATUS
TapeReadWriteVerification(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

VOID
TapeReadWrite(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP Irp
    );

VOID
SplitTapeRequest(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP Irp,
    IN ULONG MaximumBytes
    );

NTSTATUS
TapeIoCompleteAssociated(
    IN PDEVICE_OBJECT Fdo,
    IN PIRP Irp,
    IN PVOID Context
    );

NTSTATUS
TapeDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

NTSTATUS
TapeInitDevice(
    IN PDEVICE_OBJECT Fdo
    );

NTSTATUS
TapeRemoveDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR Type
    );

NTSTATUS
TapeStopDevice(
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR Type
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, TapeUnload)
#pragma alloc_text(PAGE, TapeClassInitialize)
#pragma alloc_text(PAGE, TapeAddDevice)
#pragma alloc_text(PAGE, CreateTapeDeviceObject)
#pragma alloc_text(PAGE, TapeStartDevice)
#pragma alloc_text(PAGE, TapeInitDevice)
#pragma alloc_text(PAGE, TapeRemoveDevice)
#pragma alloc_text(PAGE, TapeStopDevice)
#pragma alloc_text(PAGE, TapeDeviceControl)
#pragma alloc_text(PAGE, TapeReadWriteVerification)
#pragma alloc_text(PAGE, TapeReadWrite)
#pragma alloc_text(PAGE, SplitTapeRequest)
#pragma alloc_text(PAGE, ScsiTapeFreeSrbBuffer)
#pragma alloc_text(PAGE, TapeClassZeroMemory)
#pragma alloc_text(PAGE, TapeClassCompareMemory)
#pragma alloc_text(PAGE, TapeClassLiDiv)
#pragma alloc_text(PAGE, GetTimeoutDeltaFromRegistry)
#endif


NTSTATUS
DriverEntry(
  IN PDRIVER_OBJECT DriverObject,
  IN PUNICODE_STRING RegistryPath
  )

/*++

Routine Description:

    This is the entry point for this EXPORT DRIVER.  It does nothing.

--*/

{
    return STATUS_SUCCESS;
}


ULONG
TapeClassInitialize(
    IN  PVOID           Argument1,
    IN  PVOID           Argument2,
    IN  PTAPE_INIT_DATA_EX TapeInitData
    )

/*++

Routine Description:

    This routine is called by a tape mini-class driver during its
    DriverEntry routine to initialize the driver.

Arguments:

    Argument1       - Supplies the first argument to DriverEntry.

    Argument2       - Supplies the second argument to DriverEntry.

    TapeInitData    - Supplies the tape initialization data.

Return Value:

    A valid return code for a DriverEntry routine.

--*/

{
    PDRIVER_OBJECT  driverObject = Argument1;
    PUNICODE_STRING registryPath = Argument2;
    PTAPE_INIT_DATA_EX driverExtension;
    NTSTATUS        status;
    CLASS_INIT_DATA initializationData;
    TAPE_INIT_DATA_EX tmpInitData;

    PAGED_CODE();

    DebugPrint((1,"\n\nSCSI Tape Class Driver\n"));

    //
    // Zero InitData
    //

    RtlZeroMemory (&tmpInitData, sizeof(TAPE_INIT_DATA_EX));

    //
    // Save the tape init data passed in from the miniclass driver. When AddDevice gets called, it will be used.
    // First a check for 4.0 vs. later miniclass drivers.
    //

    if (TapeInitData->InitDataSize != sizeof(TAPE_INIT_DATA_EX)) {

        //
        // Earlier rev. Copy the bits around so that the EX structure is correct.
        //

        RtlCopyMemory(&tmpInitData.VerifyInquiry, TapeInitData, sizeof(TAPE_INIT_DATA));
        //
        // Mark it as an earlier rev.
        //

        tmpInitData.InitDataSize = sizeof(TAPE_INIT_DATA);
    } else {
        RtlCopyMemory(&tmpInitData, TapeInitData, sizeof(TAPE_INIT_DATA_EX));
    }

    //
    // Get the driverExtension

    status = IoAllocateDriverObjectExtension(driverObject,
                                             TapeClassInitialize,
                                             sizeof(TAPE_INIT_DATA_EX),
                                             &driverExtension);

    if (!NT_SUCCESS(status)) {

        if(status == STATUS_OBJECT_NAME_COLLISION) {

            //
            // An extension already exists for this key.  Get a pointer to it
            //

            driverExtension = IoGetDriverObjectExtension(driverObject,
                                                         TapeClassInitialize);
            if (driverExtension == NULL) {
                DebugPrint((1, "TapeClassInitialize : driverExtension NULL\n"));
                return STATUS_INSUFFICIENT_RESOURCES;
            }
        } else {

            //
            // As this failed, the tape init data won't be able to be stored.
            //

            DebugPrint((1, "TapeClassInitialize: Error %x allocating driver extension.\n",
                            status));

            return status;
        }
    }

    RtlCopyMemory(driverExtension, &tmpInitData, sizeof(TAPE_INIT_DATA_EX));

    RtlZeroMemory (&initializationData, sizeof(CLASS_INIT_DATA));

    //
    // Set sizes
    //

    initializationData.InitializationDataSize = sizeof(CLASS_INIT_DATA);


    initializationData.FdoData.DeviceExtensionSize = sizeof(FUNCTIONAL_DEVICE_EXTENSION) +
                                                     sizeof(TAPE_DATA) + tmpInitData.MinitapeExtensionSize;

    initializationData.FdoData.DeviceType = FILE_DEVICE_TAPE;
    initializationData.FdoData.DeviceCharacteristics =   FILE_REMOVABLE_MEDIA |
                                                         FILE_DEVICE_SECURE_OPEN;

    //
    // Set entry points
    //

    initializationData.FdoData.ClassStartDevice = TapeStartDevice;
    initializationData.FdoData.ClassStopDevice = TapeStopDevice;
    initializationData.FdoData.ClassInitDevice = TapeInitDevice;
    initializationData.FdoData.ClassRemoveDevice = TapeRemoveDevice;
    initializationData.ClassAddDevice = TapeAddDevice;

    initializationData.FdoData.ClassError = TapeError;
    initializationData.FdoData.ClassReadWriteVerification = TapeReadWriteVerification;
    initializationData.FdoData.ClassDeviceControl = TapeDeviceControl;


    initializationData.FdoData.ClassShutdownFlush = NULL;
    initializationData.FdoData.ClassCreateClose = NULL;

    //
    // Routines for WMI support
    //
    initializationData.FdoData.ClassWmiInfo.GuidCount = 6; 
    initializationData.FdoData.ClassWmiInfo.GuidRegInfo = TapeWmiGuidList;
    initializationData.FdoData.ClassWmiInfo.ClassQueryWmiRegInfo = TapeQueryWmiRegInfo;
    initializationData.FdoData.ClassWmiInfo.ClassQueryWmiDataBlock = TapeQueryWmiDataBlock;
    initializationData.FdoData.ClassWmiInfo.ClassSetWmiDataBlock = TapeSetWmiDataBlock;
    initializationData.FdoData.ClassWmiInfo.ClassSetWmiDataItem = TapeSetWmiDataItem;
    initializationData.FdoData.ClassWmiInfo.ClassExecuteWmiMethod = TapeExecuteWmiMethod;
    initializationData.FdoData.ClassWmiInfo.ClassWmiFunctionControl = TapeWmiFunctionControl;

    initializationData.ClassUnload = TapeUnload;

    //
    // Call the class init routine last, so can cleanup if it fails
    //

    status = ClassInitialize( driverObject, registryPath, &initializationData);

    if (!NT_SUCCESS(status)) {
        DebugPrint((1, "TapeClassInitialize: Error %x from classinit\n", status));
        TapeUnload(driverObject);
    }

    return status;
}

VOID
TapeUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    PAGED_CODE();
    UNREFERENCED_PARAMETER(DriverObject);
    return;
}

NTSTATUS
TapeAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )

/*++

Routine Description:

    This routine creates and initializes a new FDO for the corresponding
    PDO.  It may perform property queries on the FDO but cannot do any
    media access operations.

Arguments:

    DriverObject - Tape class driver object.

    Pdo - the physical device object we are being added to

Return Value:

    status

--*/

{
    PTAPE_INIT_DATA_EX tapeInitData;
    NTSTATUS status;
    PULONG tapeCount;

    PAGED_CODE();

    //
    // Get the saved-off tape init data.
    //

    tapeInitData = IoGetDriverObjectExtension(DriverObject, TapeClassInitialize);

    ASSERT(tapeInitData);

    //
    // Get the address of the count of the number of tape devices already initialized.
    //

    tapeCount = &IoGetConfigurationInformation()->TapeCount;

    status = CreateTapeDeviceObject(DriverObject,
                                    PhysicalDeviceObject,
                                    tapeInitData);


    if(NT_SUCCESS(status)) {

        (*tapeCount)++;
    }

    return status;
}


NTSTATUS
CreateTapeDeviceObject(
    IN PDRIVER_OBJECT          DriverObject,
    IN PDEVICE_OBJECT          PhysicalDeviceObject,
    IN PTAPE_INIT_DATA_EX      TapeInitData
    )

/*++

Routine Description:

    This routine creates an object for the device.

Arguments:

    DriverObject - Pointer to driver object created by system.
    PhysicalDeviceObject - DeviceObject of the attached to device.
    TapeInitData - Supplies the tape initialization data.

Return Value:

    NTSTATUS

--*/

{
    UCHAR                   deviceNameBuffer[64];
    NTSTATUS                status;
    PDEVICE_OBJECT          deviceObject;
    PTAPE_INIT_DATA_EX      tapeInitData;
    PDEVICE_OBJECT          lowerDevice;
    PTAPE_DATA              tapeData;
    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = NULL;
    WCHAR                   dosNameBuffer[64];
    WCHAR                   wideNameBuffer[64];
    UNICODE_STRING          dosUnicodeString;
    UNICODE_STRING          deviceUnicodeString;
    ULONG                   tapeCount;

    PAGED_CODE();

    DebugPrint((3,"CreateDeviceObject: Enter routine\n"));

    lowerDevice = IoGetAttachedDeviceReference(PhysicalDeviceObject);

    //
    // Claim the device. Note that any errors after this
    // will goto the generic handler, where the device will
    // be released.
    //

    status = ClassClaimDevice(lowerDevice, FALSE);

    if(!NT_SUCCESS(status)) {

        //
        // Someone already had this device - we're in trouble
        //

        ObDereferenceObject(lowerDevice);

        return status;
    }

    //
    // Create device object for this device.
    //

    tapeCount = 0;
    do {
       sprintf(deviceNameBuffer,
               "\\Device\\Tape%d",
               tapeCount);
   
       status = ClassCreateDeviceObject(DriverObject,
                                        deviceNameBuffer,
                                        PhysicalDeviceObject,
                                        TRUE,
                                        &deviceObject);
       tapeCount++;
    } while (status == STATUS_OBJECT_NAME_COLLISION);
    
    if (!NT_SUCCESS(status)) {
        DebugPrint((1,"CreateTapeDeviceObjects: Can not create device %s\n",
                    deviceNameBuffer));

        goto CreateTapeDeviceObjectExit;
    }

    //
    // Indicate that IRPs should include MDLs.
    //

    deviceObject->Flags |= DO_DIRECT_IO;

⌨️ 快捷键说明

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