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

📄 diskwmi.c

📁 The Disk sample is used with Classpnp.sys as disk driver. The sample supports Plug and Play, Power M
💻 C
📖 第 1 页 / 共 5 页
字号:
/*++

Copyright (C) Microsoft Corporation, 1991 - 1999

Module Name:

    diskwmi.c

Abstract:

    SCSI disk class driver - WMI support routines

Environment:

    kernel mode only

Notes:

Revision History:

--*/

#include "disk.h"

NTSTATUS
DiskSendFailurePredictIoctl(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    PSTORAGE_PREDICT_FAILURE checkFailure
    );

NTSTATUS
DiskGetIdentifyInfo(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    PBOOLEAN SupportSmart
    );

NTSTATUS
DiskDetectFailurePrediction(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    PFAILURE_PREDICTION_METHOD FailurePredictCapability
    );

NTSTATUS
DiskReadFailurePredictThresholds(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
    );

NTSTATUS
DiskReadSmartLog(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN UCHAR SectorCount,
    IN UCHAR LogAddress,
    OUT PUCHAR Buffer
    );

NTSTATUS
DiskWriteSmartLog(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN UCHAR SectorCount,
    IN UCHAR LogAddress,
    IN PUCHAR Buffer
    );

void DiskReregWorker(
    IN PVOID Context
    );

//
// WMI reregistration globals
//
// Since it will take too long to do a mode sense on some drive, we
// need a good way to effect the mode sense for the info exceptions
// mode page so that we can determine if SMART is supported and enabled
// for the drive. So the strategy is to do an asynchronous mode sense
// when the device starts and then look at the info exceptions mode
// page within the completion routine. Now within the completion
// routine we cannot call IoWMIRegistrationControl since we are at DPC
// level, so we create a stack of device objects that will be processed
// by a single work item that is fired off only when the stack
// transitions from empty to non empty.
//
WORK_QUEUE_ITEM DiskReregWorkItem;
SINGLE_LIST_ENTRY DiskReregHead;
KSPIN_LOCK DiskReregSpinlock;
LONG DiskReregWorkItems;

GUIDREGINFO DiskWmiFdoGuidList[] =
{
    {
        WMI_DISK_GEOMETRY_GUID,
        1,
        0
    },

    {
        WMI_STORAGE_FAILURE_PREDICT_STATUS_GUID,
        1,
        WMIREG_FLAG_EXPENSIVE
    },
    
    {
        WMI_STORAGE_FAILURE_PREDICT_DATA_GUID,
        1,
        WMIREG_FLAG_EXPENSIVE
    },

    {
        WMI_STORAGE_FAILURE_PREDICT_FUNCTION_GUID,
        1,
        WMIREG_FLAG_EXPENSIVE
    },

    {
        WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID,
        1,
        WMIREG_FLAG_EVENT_ONLY_GUID
    },

    {
        WMI_STORAGE_FAILURE_PREDICT_THRESHOLDS_GUID,
        1,
        WMIREG_FLAG_EXPENSIVE
    },

    {
        WMI_STORAGE_SCSI_INFO_EXCEPTIONS_GUID,
        1,
        0
    },

    
};


GUID DiskPredictFailureEventGuid = WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID;

#define DiskGeometryGuid           0
#define SmartStatusGuid            1
#define SmartDataGuid              2
#define SmartPerformFunction       3
    #define AllowDisallowPerformanceHit                 1
    #define EnableDisableHardwareFailurePrediction      2
    #define EnableDisableFailurePredictionPolling       3
    #define GetFailurePredictionCapability              4
    #define EnableOfflineDiags                          5

#define SmartEventGuid             4
#define SmartThresholdsGuid        5
#define ScsiInfoExceptionsGuid     6

#if 0
    //
    // Enable this to add WMI support for PDOs
GUIDREGINFO DiskWmiPdoGuidList[] =
{
    {
        // {25007F51-57C2-11d1-A528-00A0C9062910}
        { 0x25007f52, 0x57c2, 0x11d1,
                       { 0xa5, 0x28, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 } },
        0
    },

};

ULONG DiskDummyData[4] = { 1, 2, 3, 4};
#endif

#ifdef ALLOC_PRAGMA

#pragma alloc_text(PAGE, DiskWmiFunctionControl)
#pragma alloc_text(PAGE, DiskFdoQueryWmiRegInfo)
#pragma alloc_text(PAGE, DiskFdoQueryWmiDataBlock)
#pragma alloc_text(PAGE, DiskFdoSetWmiDataBlock)
#pragma alloc_text(PAGE, DiskFdoSetWmiDataItem)
#pragma alloc_text(PAGE, DiskFdoExecuteWmiMethod)

#pragma alloc_text(PAGE, DiskDetectFailurePrediction)
#pragma alloc_text(PAGE, DiskEnableDisableFailurePrediction)
#pragma alloc_text(PAGE, DiskEnableDisableFailurePredictPolling)
#pragma alloc_text(PAGE, DiskReadFailurePredictStatus)
#pragma alloc_text(PAGE, DiskReadFailurePredictData)
#pragma alloc_text(PAGE, DiskReadFailurePredictThresholds)
#pragma alloc_text(PAGE, DiskGetIdentifyInfo)
#pragma alloc_text(PAGE, DiskReadSmartLog)
#pragma alloc_text(PAGE, DiskWriteSmartLog)

#pragma alloc_text(PAGE, DiskPerformSmartCommand)

#pragma alloc_text(PAGE, DiskSendFailurePredictIoctl)

#pragma alloc_text(PAGE, DiskReregWorker)
#pragma alloc_text(PAGE, DiskInitializeReregistration)

#endif


//
// SMART/IDE specific routines

//
// Read SMART data attributes.
// SrbControl should be sizeof(SRB_IO_CONTROL) +
//                      (sizeof(SENDCMDINPARAMS)-1) +
//                      READ_ATTRIBUTE_BUFFER_SIZE
// Attribute data returned at &SendCmdOutParams->bBuffer[0]
//
#define DiskReadSmartData(FdoExtension, \
                          SrbControl, \
                          BufferSize) \
    DiskPerformSmartCommand(FdoExtension, \
                            IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS,  \
                            SMART_CMD, \
                            READ_ATTRIBUTES, \
                            0, \
                            0, \
                            (SrbControl), \
                            (BufferSize))


//
// Read SMART data thresholds.
// SrbControl should be sizeof(SRB_IO_CONTROL) +
//                      (sizeof(SENDCMDINPARAMS)-1) +
//                      READ_THRESHOLD_BUFFER_SIZE
// Attribute data returned at &SendCmdOutParams->bBuffer[0]
//
#define DiskReadSmartThresholds(FdoExtension, \
                          SrbControl, \
                          BufferSize) \
    DiskPerformSmartCommand(FdoExtension, \
                            IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS, \
                            SMART_CMD, \
                            READ_THRESHOLDS, \
                            0, \
                            0, \
                            (SrbControl), \
                            (BufferSize))


//
// Read SMART status
// SrbControl should be sizeof(SRB_IO_CONTROL) +
//                      (sizeof(SENDCMDINPARAMS)-1) +
//                      sizeof(IDEREGS)
// Failure predicted if cmdOutParameters[3] == 0xf4 and [4] == 0x2c
//
#define DiskReadSmartStatus(FdoExtension, \
                          SrbControl, \
                          BufferSize) \
    DiskPerformSmartCommand(FdoExtension, \
                            IOCTL_SCSI_MINIPORT_RETURN_STATUS, \
                            SMART_CMD, \
                            RETURN_SMART_STATUS, \
                            0, \
                            0, \
                            (SrbControl), \
                            (BufferSize))


//
// Read disks IDENTIFY data
// SrbControl should be sizeof(SRB_IO_CONTROL) +
//                      (sizeof(SENDCMDINPARAMS)-1) +
//                      sizeof(IDENTIFY_BUFFER_SIZE)
// Identify data returned at &cmdOutParams.bBuffer[0]
//
#define DiskGetIdentifyData(FdoExtension, \
                          SrbControl, \
                          BufferSize) \
    DiskPerformSmartCommand(FdoExtension, \
                            IOCTL_SCSI_MINIPORT_IDENTIFY, \
                            ID_CMD, \
                            0, \
                            0, \
                            0, \
                            (SrbControl), \
                            (BufferSize))


//
// Enable SMART
//
_inline NTSTATUS
DiskEnableSmart(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
    ULONG bufferSize = sizeof(srbControl);

    return DiskPerformSmartCommand(FdoExtension,
                                   IOCTL_SCSI_MINIPORT_ENABLE_SMART,
                                   SMART_CMD,
                                   ENABLE_SMART,
                                   0,
                                   0,
                                   (PSRB_IO_CONTROL)srbControl,
                                   &bufferSize);
}

//
// Disable SMART
//
_inline NTSTATUS
DiskDisableSmart(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
    ULONG bufferSize = sizeof(srbControl);
    return DiskPerformSmartCommand(FdoExtension,
                                   IOCTL_SCSI_MINIPORT_DISABLE_SMART,
                                   SMART_CMD,
                                   DISABLE_SMART,
                                   0,
                                   0,
                                   (PSRB_IO_CONTROL)srbControl,
                                   &bufferSize);
}

//
// Enable Attribute Autosave
//
_inline NTSTATUS
DiskEnableSmartAttributeAutosave(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
    ULONG bufferSize = sizeof(srbControl);
    return DiskPerformSmartCommand(FdoExtension,
                                   IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE,
                                   SMART_CMD,
                                   ENABLE_DISABLE_AUTOSAVE,
                                   0xf1,
                                   0,
                                   (PSRB_IO_CONTROL)srbControl,
                                   &bufferSize);
}

//
// Disable Attribute Autosave
//
_inline NTSTATUS
DiskDisableSmartAttributeAutosave(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
    ULONG bufferSize = sizeof(srbControl);
    return DiskPerformSmartCommand(FdoExtension,
                                   IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE,
                                   SMART_CMD,
                                   ENABLE_DISABLE_AUTOSAVE,
                                   0x00,
                                   0,
                                   (PSRB_IO_CONTROL)srbControl,
                                   &bufferSize);
}

//
// Initialize execution of SMART online diagnostics
//
_inline NTSTATUS
DiskExecuteSmartDiagnostics(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    UCHAR Subcommand
    )
{
    UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
    ULONG bufferSize = sizeof(srbControl);
    return DiskPerformSmartCommand(FdoExtension,
                                   IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS,
                                   SMART_CMD,
                                   EXECUTE_OFFLINE_DIAGS,
                                   0,
                                   Subcommand,
                                   (PSRB_IO_CONTROL)srbControl,
                                   &bufferSize);
}


NTSTATUS
DiskReadSmartLog(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN UCHAR SectorCount,
    IN UCHAR LogAddress,
    OUT PUCHAR Buffer
    )
{
    PSRB_IO_CONTROL srbControl;
    NTSTATUS status;
    PSENDCMDOUTPARAMS sendCmdOutParams;
    ULONG logSize, bufferSize;

    PAGED_CODE();

    logSize = SectorCount * SMART_LOG_SECTOR_SIZE;
    bufferSize = sizeof(SRB_IO_CONTROL) +  sizeof(SENDCMDINPARAMS) - 1 +
                 logSize;

    srbControl = ExAllocatePoolWithTag(NonPagedPool,
                                       bufferSize,
                                       DISK_TAG_SMART);
    
    if (srbControl != NULL)
    {
        status = DiskPerformSmartCommand(FdoExtension,
                                         IOCTL_SCSI_MINIPORT_READ_SMART_LOG,
                                         SMART_CMD,
                                         SMART_READ_LOG,
                                         SectorCount,
                                         LogAddress,
                                         srbControl,
                                         &bufferSize);

        if (NT_SUCCESS(status))
        {
            sendCmdOutParams = (PSENDCMDOUTPARAMS)((PUCHAR)srbControl +
                                                   sizeof(SRB_IO_CONTROL));
            RtlCopyMemory(Buffer,
                          &sendCmdOutParams->bBuffer[0],
                          logSize);
        }
        
        ExFreePool(srbControl);
    } else {
        status = STATUS_INSUFFICIENT_RESOURCES;
    }
    return(status);
}


NTSTATUS
DiskWriteSmartLog(
    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
    IN UCHAR SectorCount,
    IN UCHAR LogAddress,
    IN PUCHAR Buffer
    )

⌨️ 快捷键说明

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