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

📄 tape.c

📁 This directory builds the Tape class driver for Microsoft&reg Windows&reg Server 2003. The class dri
💻 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
#define TAPE_BUFFER_MAXCOUNT                64

#define TAPE_REGISTRY_CONTROL_KEY           L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Tape"
#define TAPE_REGISTRY_SERVICES_KEY          L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tape"
#define TAPE_PERSISTENCE_KEYVALUE           L"Persistence"
#define TAPE_PERSISTENCE_PRIVATE            L"PersistencePrivateCopy"
#define TAPE_DEVICE_UIDTYPE                 L"UIDType"
#define TAPE_DEVICE_UNIQUEID                L"UniqueId"
#define TAPE_DOS_DEVICES_PREFIX_W           L"\\DosDevices"
#define TAPE_DOS_DEVICES_PREFIX_A           "\\DosDevices"
#define TAPE_DEVICE_PREFIX_W                L"\\Device"
#define TAPE_DEVICE_PREFIX_A                "\\Device"
#define TAPE_DEVICE_NAME_PREFIX_W           L"\\TapeDrive%u"
#define TAPE_DEVICE_NAME_PREFIX_A           "\\TapeDrive%u"
#define TAPE_DEVICE_NAME_FORMAT_W           L"TapeDrive%u"
#define TAPE_DEVICE_NAME_FORMAT_A           "TapeDrive%u"
#define TAPE_DEVICE_NAME_PREFIX_LEGACY_W    L"\\Tape%u"
#define TAPE_DEVICE_NAME_PREFIX_LEGACY_A    "\\Tape%u"
#define TAPE_NAME_PREFIX_W                  L"\\Tape%u"
#define TAPE_NAME_PREFIX_A                  "\\Tape%u"
#define TAPE_NAME_FORMAT_W                  L"Tape%u"
#define TAPE_NAME_FORMAT_A                  "Tape%u"

typedef enum _TAPE_UID_TYPE {
    TAPE_UID_CUSTOM = 1
} TAPE_UID_TYPE, *PTAPE_UID_TYPE;

typedef enum _TAPE_PERSISTENCE_OPERATION {
    TAPE_PERSISTENCE_QUERY = 1,
    TAPE_PERSISTENCE_SET
} TAPE_PERSISTENCE_OPERATION, *PTAPE_PERSISTENCE_OPERATION;


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,
    IN BOOLEAN                 LegacyNameFormat
    );

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
    );

NTSTATUS
TapeSymbolicNamePersistencePreference(
    IN PDRIVER_OBJECT DriverObject,
    IN PWCHAR KeyName,
    IN TAPE_PERSISTENCE_OPERATION Operation,
    IN PWCHAR ValueName,
    IN OUT PBOOLEAN PersistencePreference
    );

NTSTATUS
TapeCreateSymbolicName(
    IN PDEVICE_OBJECT Fdo,
    IN BOOLEAN PersistencePreference
    );

NTSTATUS
TapeCreateUniqueId(
    IN PDEVICE_OBJECT Fdo,
    IN TAPE_UID_TYPE UIDType,
    OUT PUCHAR *UniqueId,
    OUT PULONG UniqueIdLen
    );

BOOLEAN
TapeCompareUniqueId(
    IN PUCHAR UniqueId1,
    IN ULONG UniqueId1Len,
    IN PUCHAR UniqueId2,
    IN ULONG UniqueId2Len,
    IN TAPE_UID_TYPE Type
    );

NTSTATUS
TapeGetSubKeyByIndex(
    IN HANDLE RootKey,
    IN ULONG SubKeyIndex,
    OUT PHANDLE SubKey,
    OUT PWCHAR ReturnString
    );

NTSTATUS
TapeGetValuePartialInfo(
    IN HANDLE Key,
    IN PUNICODE_STRING ValueName,
    OUT PKEY_VALUE_PARTIAL_INFORMATION *KeyValueInfo,
    OUT PULONG KeyValueInfoSize
    );

NTSTATUS
TapeCreateNewDeviceSubKey(
    IN HANDLE RootKey,
    IN OUT PULONG FirstNumeralToUse,
    OUT PHANDLE NewSubKey,
    OUT PWCHAR NewSubKeyName
    );

NTSTATUS
TapeCreateNonPersistentSymbolicName(
    IN HANDLE RootKey,
    IN OUT PULONG FirstNumeralToUse,
    OUT PWCHAR NonPersistentSymbolicName
    );

NTSTATUS
TapeAssignSymbolicLink(
    IN ULONG DeviceNumber,
    IN PUNICODE_STRING RegDeviceName,
    IN BOOLEAN LegacyNameFormat,
    IN PWCHAR SymbolicNamePrefix,
    OUT PULONG SymbolicNameNumeral
    );

NTSTATUS
TapeDeassignSymbolicLink(
    IN PWCHAR SymbolicNamePrefix,
    IN ULONG SymbolicNameNumeral,
    IN BOOLEAN LegacyNameFormat
    );


#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)
    #pragma alloc_text(PAGE, TapeSymbolicNamePersistencePreference)
    #pragma alloc_text(PAGE, TapeCreateSymbolicName)
    #pragma alloc_text(PAGE, TapeCreateUniqueId)
    #pragma alloc_text(PAGE, TapeCompareUniqueId)
    #pragma alloc_text(PAGE, TapeGetSubKeyByIndex)
    #pragma alloc_text(PAGE, TapeGetValuePartialInfo)
    #pragma alloc_text(PAGE, TapeCreateNewDeviceSubKey)
    #pragma alloc_text(PAGE, TapeCreateNonPersistentSymbolicName)
    #pragma alloc_text(PAGE, TapeAssignSymbolicLink)
    #pragma alloc_text(PAGE, TapeDeassignSymbolicLink)
#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:

⌨️ 快捷键说明

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