Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / drivers / storage / class / disk_new / diskwmi.c
diff --git a/reactos/drivers/storage/class/disk_new/diskwmi.c b/reactos/drivers/storage/class/disk_new/diskwmi.c
deleted file mode 100644 (file)
index fbe334d..0000000
+++ /dev/null
@@ -1,3451 +0,0 @@
-/*++
-
-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"
-
-#include <wmistr.h>
-
-NTSTATUS
-NTAPI
-DiskSendFailurePredictIoctl(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_PREDICT_FAILURE checkFailure
-    );
-
-NTSTATUS
-NTAPI
-DiskGetIdentifyInfo(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PBOOLEAN SupportSmart
-    );
-
-NTSTATUS
-NTAPI
-DiskDetectFailurePrediction(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PFAILURE_PREDICTION_METHOD FailurePredictCapability
-    );
-
-NTSTATUS
-NTAPI
-DiskReadFailurePredictThresholds(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
-    );
-
-NTSTATUS
-NTAPI
-DiskReadSmartLog(
-    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    IN UCHAR SectorCount,
-    IN UCHAR LogAddress,
-    OUT PUCHAR Buffer
-    );
-
-NTSTATUS
-NTAPI
-DiskWriteSmartLog(
-    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    IN UCHAR SectorCount,
-    IN UCHAR LogAddress,
-    IN PUCHAR Buffer
-    );
-
-void NTAPI 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
-NTAPI
-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
-NTAPI
-DiskWriteSmartLog(
-    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    IN UCHAR SectorCount,
-    IN UCHAR LogAddress,
-    IN PUCHAR Buffer
-    )
-{
-    PSRB_IO_CONTROL srbControl;
-    NTSTATUS status;
-    PSENDCMDINPARAMS sendCmdInParams;
-    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)
-    {
-        sendCmdInParams = (PSENDCMDINPARAMS)((PUCHAR)srbControl +
-                                               sizeof(SRB_IO_CONTROL));
-        RtlCopyMemory(&sendCmdInParams->bBuffer[0],
-                      Buffer,
-                      logSize);
-        status = DiskPerformSmartCommand(FdoExtension,
-                                         IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG,
-                                         SMART_CMD,
-                                         SMART_WRITE_LOG,
-                                         SectorCount,
-                                         LogAddress,
-                                         srbControl,
-                                         &bufferSize);
-
-        ExFreePool(srbControl);
-    } else {
-        status = STATUS_INSUFFICIENT_RESOURCES;
-    }
-    return(status);
-}
-
-NTSTATUS
-NTAPI
-DiskPerformSmartCommand(
-    IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    IN ULONG SrbControlCode,
-    IN UCHAR Command,
-    IN UCHAR Feature,
-    IN UCHAR SectorCount,
-    IN UCHAR SectorNumber,
-    IN OUT PSRB_IO_CONTROL SrbControl,
-    OUT PULONG BufferSize
-    )
-/*++
-
-Routine Description:
-
-    This routine will perform some SMART command
-
-Arguments:
-
-    FdoExtension is the FDO device extension
-
-    SrbControlCode is the SRB control code to use for the request
-
-    Command is the SMART command to be executed. It may be SMART_CMD or
-        ID_CMD.
-
-    Feature is the value to place in the IDE feature register.
-
-    SectorCount is the value to place in the IDE SectorCount register
-
-    SrbControl is the buffer used to build the SRB_IO_CONTROL and pass
-        any input parameters. It also returns the output parameters.
-
-    *BufferSize on entry has total size of SrbControl and on return has
-        the size used in SrbControl.
-
-
-
-Return Value:
-
-    status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    PUCHAR buffer;
-    PSENDCMDINPARAMS cmdInParameters;
-    //PSENDCMDOUTPARAMS cmdOutParameters;
-    //ULONG outBufferSize;
-    NTSTATUS status;
-    ULONG availableBufferSize;
-    KEVENT event;
-    PIRP irp;
-    IO_STATUS_BLOCK ioStatus;
-    SCSI_REQUEST_BLOCK      srb;
-    LARGE_INTEGER           startingOffset;
-    ULONG length;
-    PIO_STACK_LOCATION      irpStack;
-
-    PAGED_CODE();
-
-    //
-    // Point to the 'buffer' portion of the SRB_CONTROL and compute how
-    // much room we have left in the srb control
-    //
-
-    buffer = (PUCHAR)SrbControl;
-    buffer +=  sizeof(SRB_IO_CONTROL);
-
-    cmdInParameters = (PSENDCMDINPARAMS)buffer;
-    //cmdOutParameters = (PSENDCMDOUTPARAMS)buffer;
-
-    availableBufferSize = *BufferSize - sizeof(SRB_IO_CONTROL);
-
-#if DBG
-    //
-    // Ensure control codes and buffer lengths passed are correct
-    //
-    {
-        ULONG controlCode;
-        ULONG lengthNeeded = sizeof(SENDCMDINPARAMS) - 1;
-
-        if (Command == SMART_CMD)
-        {
-            switch (Feature)
-            {
-
-                case ENABLE_SMART:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_ENABLE_SMART;
-
-                    break;
-                }
-
-                case DISABLE_SMART:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_DISABLE_SMART;
-                    break;
-                }
-
-                case  RETURN_SMART_STATUS:
-                {
-                     //
-                    // Ensure bBuffer is at least 2 bytes (to hold the values of
-                    // cylinderLow and cylinderHigh).
-                    //
-
-                    lengthNeeded = sizeof(SENDCMDINPARAMS) - 1 + sizeof(IDEREGS);
-
-                    controlCode = IOCTL_SCSI_MINIPORT_RETURN_STATUS;
-                    break;
-                }
-
-                case ENABLE_DISABLE_AUTOSAVE:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE;
-                    break;
-                }
-
-                case SAVE_ATTRIBUTE_VALUES:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES;
-                    break;
-                }
-
-
-                case EXECUTE_OFFLINE_DIAGS:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS;
-                    break;
-                }
-
-                case READ_ATTRIBUTES:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS;
-                    lengthNeeded = READ_ATTRIBUTE_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) - 1;
-                    break;
-                }
-
-                case READ_THRESHOLDS:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS;
-                    lengthNeeded = READ_THRESHOLD_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) - 1;
-                    break;
-                }
-
-                case SMART_READ_LOG:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_READ_SMART_LOG;
-                    lengthNeeded = (SectorCount * SMART_LOG_SECTOR_SIZE) +
-                                   sizeof(SENDCMDINPARAMS) - 1;
-                    break;
-                }
-
-                case SMART_WRITE_LOG:
-                {
-                    controlCode = IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG;
-                    lengthNeeded = (SectorCount * SMART_LOG_SECTOR_SIZE) +
-                                   sizeof(SENDCMDINPARAMS) - 1;
-                    break;
-                }
-                
-                default:
-                    controlCode = 0;
-                    break;
-                
-            }
-        } else if (Command == ID_CMD) {
-            controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
-            lengthNeeded = IDENTIFY_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) -1;
-        } else {
-            controlCode = 0;
-            ASSERT(FALSE);
-        }
-
-        ASSERT(controlCode == SrbControlCode);
-        ASSERT(availableBufferSize >= lengthNeeded);
-    }
-#endif
-
-    //
-    // Build SrbControl and input to SMART command
-    //
-
-    SrbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
-    RtlMoveMemory (SrbControl->Signature, "SCSIDISK", 8);
-    SrbControl->Timeout = FdoExtension->TimeOutValue;
-    SrbControl->Length = availableBufferSize;
-
-    SrbControl->ControlCode = SrbControlCode;
-
-    cmdInParameters->cBufferSize = sizeof(SENDCMDINPARAMS);
-    cmdInParameters->bDriveNumber = diskData->ScsiAddress.TargetId;
-    cmdInParameters->irDriveRegs.bFeaturesReg = Feature;
-    cmdInParameters->irDriveRegs.bSectorCountReg = SectorCount;
-    cmdInParameters->irDriveRegs.bSectorNumberReg = SectorNumber;
-    cmdInParameters->irDriveRegs.bCylLowReg = SMART_CYL_LOW;
-    cmdInParameters->irDriveRegs.bCylHighReg = SMART_CYL_HI;
-    cmdInParameters->irDriveRegs.bCommandReg = Command;
-
-
-    //
-    // Create and send irp
-    //
-    KeInitializeEvent(&event, NotificationEvent, FALSE);
-
-    startingOffset.QuadPart = (LONGLONG) 1;
-
-    length = SrbControl->HeaderLength + SrbControl->Length;
-
-    irp = IoBuildSynchronousFsdRequest(
-                IRP_MJ_SCSI,
-                commonExtension->LowerDeviceObject,
-                SrbControl,
-                length,
-                &startingOffset,
-                &event,
-                &ioStatus);
-
-    if (irp == NULL) {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    irpStack = IoGetNextIrpStackLocation(irp);
-
-    //
-    // Set major and minor codes.
-    //
-
-    irpStack->MajorFunction = IRP_MJ_SCSI;
-    irpStack->MinorFunction = 1;
-
-    //
-    // Fill in SRB fields.
-    //
-
-    irpStack->Parameters.Others.Argument1 = &srb;
-
-    //
-    // Zero out the srb.
-    //
-
-    RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
-
-    srb.PathId = diskData->ScsiAddress.PathId;
-    srb.TargetId = diskData->ScsiAddress.TargetId;
-    srb.Lun = diskData->ScsiAddress.Lun;
-
-    srb.Function = SRB_FUNCTION_IO_CONTROL;
-    srb.Length = sizeof(SCSI_REQUEST_BLOCK);
-
-    srb.SrbFlags = FdoExtension->SrbFlags;
-    SET_FLAG(srb.SrbFlags, SRB_FLAGS_DATA_IN);
-    SET_FLAG(srb.SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
-    SET_FLAG(srb.SrbFlags, SRB_FLAGS_NO_KEEP_AWAKE);
-
-    srb.QueueAction = SRB_SIMPLE_TAG_REQUEST;
-    srb.QueueTag = SP_UNTAGGED;
-
-    srb.OriginalRequest = irp;
-
-    //
-    // Set timeout to requested value.
-    //
-
-    srb.TimeOutValue = SrbControl->Timeout;
-
-    //
-    // Set the data buffer.
-    //
-
-    srb.DataBuffer = SrbControl;
-    srb.DataTransferLength = length;
-
-    //
-    // Flush the data buffer for output. This will insure that the data is
-    // written back to memory.  Since the data-in flag is the the port driver
-    // will flush the data again for input which will ensure the data is not
-    // in the cache.
-    //
-
-    KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
-
-    //
-    // Call port driver to handle this request.
-    //
-
-    status = IoCallDriver(commonExtension->LowerDeviceObject, irp);
-
-    if (status == STATUS_PENDING) {
-        KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
-        status = ioStatus.Status;
-    }
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskGetIdentifyInfo(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PBOOLEAN SupportSmart
-    )
-{
-    UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + (sizeof(SENDCMDINPARAMS)-1) + IDENTIFY_BUFFER_SIZE];
-    ULONG outBufferSize = sizeof(outBuffer);
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    status = DiskGetIdentifyData(FdoExtension,
-                                 (PSRB_IO_CONTROL)outBuffer,
-                                 &outBufferSize);
-
-    if (NT_SUCCESS(status))
-    {
-        PUSHORT identifyData = (PUSHORT)&(outBuffer[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS)-1]);
-        USHORT commandSetSupported = identifyData[82];
-
-        *SupportSmart = ((commandSetSupported != 0xffff) &&
-                         (commandSetSupported != 0) &&
-                         ((commandSetSupported & 1) == 1));
-    } else {
-        *SupportSmart = FALSE;
-    }
-
-    DebugPrint((3, "DiskGetIdentifyInfo: SMART %s supported for device %p, status %lx\n",
-                   *SupportSmart ? "is" : "is not",
-                   FdoExtension->DeviceObject,
-                   status));
-
-    return status;
-}
-
-//
-// FP Ioctl specific routines
-//
-
-NTSTATUS
-NTAPI
-DiskSendFailurePredictIoctl(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_PREDICT_FAILURE checkFailure
-    )
-{
-    KEVENT event;
-    PDEVICE_OBJECT deviceObject;
-    IO_STATUS_BLOCK ioStatus;
-    PIRP irp;
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    KeInitializeEvent(&event, SynchronizationEvent, FALSE);
-
-    deviceObject = IoGetAttachedDeviceReference(FdoExtension->DeviceObject);
-
-    irp = IoBuildDeviceIoControlRequest(
-                    IOCTL_STORAGE_PREDICT_FAILURE,
-                    deviceObject,
-                    NULL,
-                    0,
-                    checkFailure,
-                    sizeof(STORAGE_PREDICT_FAILURE),
-                    FALSE,
-                    &event,
-                    &ioStatus);
-
-    if (irp != NULL)
-    {
-        status = IoCallDriver(deviceObject, irp);
-        if (status == STATUS_PENDING)
-        {
-            KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
-            status = ioStatus.Status;
-        }
-
-    } else {
-        status = STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    ObDereferenceObject(deviceObject);
-
-    return status;
-}
-
-//
-// FP type independent routines
-//
-
-NTSTATUS
-NTAPI
-DiskEnableDisableFailurePrediction(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    BOOLEAN Enable
-    )
-/*++
-
-Routine Description:
-
-    Enable or disable failure prediction at the hardware level
-
-Arguments:
-
-    FdoExtension
-
-    Enable
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    NTSTATUS status;
-    PCOMMON_DEVICE_EXTENSION commonExtension = &(FdoExtension->CommonExtension);
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-
-    PAGED_CODE();
-
-    switch(diskData->FailurePredictionCapability)
-    {
-        case FailurePredictionSmart:
-        {
-
-            if (Enable)
-            {
-                status = DiskEnableSmart(FdoExtension);
-            } else {
-                status = DiskDisableSmart(FdoExtension);
-            }
-
-            break;
-        }
-
-        case  FailurePredictionSense:
-        case  FailurePredictionIoctl:
-        {
-            //
-            // We assume that the drive is already setup properly for
-            // failure prediction
-            //
-            status = STATUS_SUCCESS;
-            break;
-        }
-
-        default:
-        {
-            status = STATUS_INVALID_DEVICE_REQUEST;
-        }
-    }
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskEnableDisableFailurePredictPolling(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    BOOLEAN Enable,
-    ULONG PollTimeInSeconds
-    )
-/*++
-
-Routine Description:
-
-    Enable or disable polling for hardware failure detection
-
-Arguments:
-
-    FdoExtension
-
-    Enable
-
-    PollTimeInSeconds - if 0 then no change to current polling timer
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    NTSTATUS status;
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-
-    PAGED_CODE();
-
-    if (Enable)
-    {
-        status = DiskEnableDisableFailurePrediction(FdoExtension,
-                                           Enable);
-    } else {
-        status = STATUS_SUCCESS;
-    }
-
-    if (NT_SUCCESS(status))
-    {
-        status = ClassSetFailurePredictionPoll(FdoExtension,
-                        Enable ? diskData->FailurePredictionCapability :
-                                 FailurePredictionNone,
-                                     PollTimeInSeconds);
-
-        //
-        // Even if this failed we do not want to disable FP on the
-        // hardware. FP is only ever disabled on the hardware by
-        // specific command of the user.
-        //
-    }
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskReadFailurePredictStatus(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus
-    )
-/*++
-
-Routine Description:
-
-    Obtains current failure prediction status
-
-Arguments:
-
-    FdoExtension
-
-    DiskSmartStatus
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    DiskSmartStatus->PredictFailure = FALSE;
-
-    switch(diskData->FailurePredictionCapability)
-    {
-        case FailurePredictionSmart:
-        {
-            UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + (sizeof(SENDCMDINPARAMS) - 1 + sizeof(IDEREGS))];
-            ULONG outBufferSize = sizeof(outBuffer);
-            PSENDCMDOUTPARAMS cmdOutParameters;
-
-            status = DiskReadSmartStatus(FdoExtension,
-                                     (PSRB_IO_CONTROL)outBuffer,
-                                     &outBufferSize);
-
-            if (NT_SUCCESS(status))
-            {
-                cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
-                                               sizeof(SRB_IO_CONTROL));
-
-                DiskSmartStatus->Reason = 0; // Unknown;
-                DiskSmartStatus->PredictFailure = ((((PUCHAR)cmdOutParameters->bBuffer)[3] == 0xf4) &&
-                                                   (((PUCHAR)cmdOutParameters->bBuffer)[4] == 0x2c));
-            }
-            break;
-        }
-
-        case FailurePredictionSense:
-        {
-            DiskSmartStatus->Reason = FdoExtension->FailureReason;
-            DiskSmartStatus->PredictFailure = FdoExtension->FailurePredicted;
-            status = STATUS_SUCCESS;
-            break;
-        }
-
-        case FailurePredictionIoctl:
-        case FailurePredictionNone:
-        default:
-        {
-            status = STATUS_INVALID_DEVICE_REQUEST;
-            break;
-        }
-    }
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskReadFailurePredictData(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData
-    )
-/*++
-
-Routine Description:
-
-    Obtains current failure prediction data. Not available for
-    FAILURE_PREDICT_SENSE types.
-
-Arguments:
-
-    FdoExtension
-
-    DiskSmartData
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    switch(diskData->FailurePredictionCapability)
-    {
-        case FailurePredictionSmart:
-        {
-            PUCHAR outBuffer;
-            ULONG outBufferSize;
-            PSENDCMDOUTPARAMS cmdOutParameters;
-
-            outBufferSize = sizeof(SRB_IO_CONTROL) +
-                            (sizeof(SENDCMDOUTPARAMS)-1) +
-                            READ_ATTRIBUTE_BUFFER_SIZE;
-
-            outBuffer = ExAllocatePoolWithTag(NonPagedPool,
-                                              outBufferSize,
-                                              DISK_TAG_SMART);
-
-            if (outBuffer != NULL)
-            {
-                status = DiskReadSmartData(FdoExtension,
-                                           (PSRB_IO_CONTROL)outBuffer,
-                                           &outBufferSize);
-
-                if (NT_SUCCESS(status))
-                {
-                    cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
-                                                    sizeof(SRB_IO_CONTROL));
-
-                    DiskSmartData->Length = READ_ATTRIBUTE_BUFFER_SIZE;
-                    RtlCopyMemory(DiskSmartData->VendorSpecific,
-                                  cmdOutParameters->bBuffer,
-                                  READ_ATTRIBUTE_BUFFER_SIZE);
-                }
-                ExFreePool(outBuffer);
-            } else {
-                status = STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            break;
-        }
-
-        case FailurePredictionSense:
-        {
-            DiskSmartData->Length = sizeof(ULONG);
-            *((PULONG)DiskSmartData->VendorSpecific) = FdoExtension->FailureReason;
-
-            status = STATUS_SUCCESS;
-            break;
-        }
-
-        case FailurePredictionIoctl:
-        case FailurePredictionNone:
-        default:
-        {
-            status = STATUS_INVALID_DEVICE_REQUEST;
-            break;
-        }
-    }
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskReadFailurePredictThresholds(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
-    )
-/*++
-
-Routine Description:
-
-    Obtains current failure prediction thresholds. Not available for
-    FAILURE_PREDICT_SENSE types.
-
-Arguments:
-
-    FdoExtension
-
-    DiskSmartData
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    switch(diskData->FailurePredictionCapability)
-    {
-        case FailurePredictionSmart:
-        {
-            PUCHAR outBuffer;
-            PSENDCMDOUTPARAMS cmdOutParameters;
-            ULONG outBufferSize;
-
-            outBufferSize = sizeof(SRB_IO_CONTROL) +
-                            (sizeof(SENDCMDOUTPARAMS)-1) +
-                            READ_THRESHOLD_BUFFER_SIZE;
-            
-            outBuffer = ExAllocatePoolWithTag(NonPagedPool,
-                                              outBufferSize,
-                                              DISK_TAG_SMART);
-
-            if (outBuffer != NULL)
-            {
-                status = DiskReadSmartThresholds(FdoExtension,
-                                                (PSRB_IO_CONTROL)outBuffer,
-                                                &outBufferSize);
-
-                if (NT_SUCCESS(status))
-                {
-                    cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
-                                           sizeof(SRB_IO_CONTROL));
-
-                    RtlCopyMemory(DiskSmartThresholds->VendorSpecific,
-                                  cmdOutParameters->bBuffer,
-                                  READ_THRESHOLD_BUFFER_SIZE);
-                }
-                ExFreePool(outBuffer);
-            } else {
-                status = STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            break;
-        }
-
-        case FailurePredictionSense:
-        case FailurePredictionIoctl:
-        case FailurePredictionNone:
-        default:
-        {
-            status = STATUS_INVALID_DEVICE_REQUEST;
-            break;
-        }
-    }
-
-    return status;
-}
-
-void NTAPI DiskReregWorker(
-    IN PVOID Context
-    )
-{
-    PDISKREREGREQUEST reregRequest;
-    NTSTATUS status;
-    PDEVICE_OBJECT deviceObject;
-    PIRP irp;
-
-    PAGED_CODE();
-    
-    do
-    {
-        reregRequest = (PDISKREREGREQUEST)ExInterlockedPopEntryList(
-            &DiskReregHead,
-            &DiskReregSpinlock);
-
-        deviceObject = reregRequest->DeviceObject;
-        irp = reregRequest->Irp;
-        
-        status = IoWMIRegistrationControl(deviceObject,
-                                          WMIREG_ACTION_UPDATE_GUIDS);
-
-        if (! NT_SUCCESS(status))
-        {
-            DebugPrint((1, "DiskReregWorker: Reregistration failed %x\n",
-                        status));
-        }
-
-        //
-        // Release remove lock and free irp, now that we are done
-        // processing this
-        //
-        ClassReleaseRemoveLock(deviceObject, irp);
-
-        IoFreeMdl(irp->MdlAddress);
-        IoFreeIrp(irp);
-        
-        ExFreePool(reregRequest);
-        
-    } while (InterlockedDecrement(&DiskReregWorkItems));
-
-    
-}
-
-NTSTATUS NTAPI DiskInitializeReregistration(
-    void
-    )
-{
-    PAGED_CODE();
-    
-    //
-    // Initialize the global work item and spinlock used to manage the
-    // list of disks reregistering their guids
-    //
-    ExInitializeWorkItem( &DiskReregWorkItem,
-                          DiskReregWorker,
-                          NULL );
-
-    KeInitializeSpinLock(&DiskReregSpinlock);
-
-    return(STATUS_SUCCESS);
-}
-
-NTSTATUS NTAPI DiskPostReregisterRequest(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp
-    )
-{
-    PDISKREREGREQUEST reregRequest;
-    NTSTATUS status;
-    
-    reregRequest = ExAllocatePoolWithTag(NonPagedPool,
-                                         sizeof(DISKREREGREQUEST),
-                                         DISK_TAG_SMART);
-
-    if (reregRequest != NULL)
-    {
-        //
-        // add the disk that needs reregistration to the stack of disks
-        // to reregister. If the list is transitioning from empty to
-        // non empty then also kick off the work item so that the
-        // reregistration worker can do the reregister.
-        //
-        reregRequest->DeviceObject = DeviceObject;
-        reregRequest->Irp = Irp;
-        ExInterlockedPushEntryList(
-                                   &DiskReregHead,
-                                   &reregRequest->Next,
-                                   &DiskReregSpinlock);
-    
-        if (InterlockedIncrement(&DiskReregWorkItems) == 1)
-        {
-            ExQueueWorkItem( &DiskReregWorkItem, DelayedWorkQueue );
-        }
-        status = STATUS_SUCCESS;
-    } else {
-        DebugPrint((1, "DiskPostReregisterRequest: could not allocate reregRequest for %p\n",
-                    DeviceObject));
-        status = STATUS_INSUFFICIENT_RESOURCES;
-    }
-    
-    return(status);
-}
-
-NTSTATUS NTAPI DiskInfoExceptionComplete(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp,
-    PVOID Context
-    )
-{
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
-    PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
-    PSCSI_REQUEST_BLOCK srb = Context;
-    NTSTATUS status;
-    BOOLEAN retry;
-    ULONG retryInterval;
-    ULONG srbStatus;
-    BOOLEAN freeLockAndIrp = TRUE;
-    //KIRQL oldIrql;
-
-    ASSERT(fdoExtension->CommonExtension.IsFdo);
-
-    srbStatus = SRB_STATUS(srb->SrbStatus);
-
-    //
-    // Check SRB status for success of completing request.
-    // SRB_STATUS_DATA_OVERRUN also indicates success.
-    //
-    if ((srbStatus != SRB_STATUS_SUCCESS) &&
-        (srbStatus != SRB_STATUS_DATA_OVERRUN))
-    {    
-        DebugPrint((2, "DiskInfoExceptionComplete: IRP %p, SRB %p\n", Irp, srb));
-
-        retry = ClassInterpretSenseInfo(
-                    DeviceObject,
-                    srb,
-                    irpStack->MajorFunction,
-                     0,
-                    MAXIMUM_RETRIES -
-                        ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4),
-                    &status,
-                    &retryInterval);
-
-        //
-        // If the status is verified required and the this request
-        // should bypass verify required then retry the request.
-        //
-
-        if (TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME) &&
-            status == STATUS_VERIFY_REQUIRED)
-        {
-            status = STATUS_IO_DEVICE_ERROR;
-            retry = TRUE;
-        }
-
-        if (retry && irpStack->Parameters.Others.Argument4)
-        {
-            irpStack->Parameters.Others.Argument4 =
-                (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4 - 1);
-
-            //
-            // Retry request.
-            //
-
-            DebugPrint((1, "DiskInfoExceptionComplete: Retry request %p\n", Irp));
-            
-            ASSERT(srb->DataBuffer == MmGetMdlVirtualAddress(Irp->MdlAddress));
-            
-            //
-            // Reset byte count of transfer in SRB Extension.
-            //
-            srb->DataTransferLength = Irp->MdlAddress->ByteCount;
-            
-            //
-            // Zero SRB statuses.
-            //
-
-            srb->SrbStatus = srb->ScsiStatus = 0;
-
-            //
-            // Set the no disconnect flag, disable synchronous data transfers and
-            // disable tagged queuing. This fixes some errors.
-            //
-
-            SET_FLAG(srb->SrbFlags, SRB_FLAGS_DISABLE_DISCONNECT);
-            SET_FLAG(srb->SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
-            CLEAR_FLAG(srb->SrbFlags, SRB_FLAGS_QUEUE_ACTION_ENABLE);
-
-            srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
-            srb->QueueTag = SP_UNTAGGED;
-
-            //
-            // Set up major SCSI function.
-            //
-
-            nextIrpStack->MajorFunction = IRP_MJ_SCSI;
-
-            //
-            // Save SRB address in next stack for port driver.
-            //
-
-            nextIrpStack->Parameters.Scsi.Srb = srb;
-
-
-            IoSetCompletionRoutine(Irp,
-                                   DiskInfoExceptionComplete,
-                                   srb,
-                                   TRUE, TRUE, TRUE);
-            
-            (VOID)IoCallDriver(commonExtension->LowerDeviceObject, Irp);
-        
-            return STATUS_MORE_PROCESSING_REQUIRED;
-        }
-    
-    } else {
-
-        //
-        // Get the results from the mode sense
-        //
-        PMODE_INFO_EXCEPTIONS pageData;
-        PMODE_PARAMETER_HEADER modeData;
-        ULONG modeDataLength;
-
-        modeData = srb->DataBuffer;
-        modeDataLength = srb->DataTransferLength;
-        
-        pageData = ClassFindModePage((PUCHAR) modeData,
-                                     modeDataLength,
-                                     MODE_PAGE_FAULT_REPORTING,
-                                     TRUE);
-        if (pageData != NULL)
-        {
-            DebugPrint((1, "DiskInfoExceptionComplete: %p supports SMART\n",
-                        DeviceObject));
-
-            if (pageData->Dexcpt == 0)
-            {
-                diskData->FailurePredictionCapability = FailurePredictionSense;
-                status = DiskPostReregisterRequest(DeviceObject, Irp);
-
-                if (NT_SUCCESS(status))
-                {
-                    //
-                    // Make sure we won't free the remove lock and the irp
-                    // since we need to keep these until after the work
-                    // item has completed running
-                    //
-                    freeLockAndIrp = FALSE;
-                }
-            } else {
-                DebugPrint((1, "DiskInfoExceptionComplete: %p is not enabled for SMART\n",
-                        DeviceObject));
-            
-            }
-            
-        } else {
-            DebugPrint((1, "DiskInfoExceptionComplete: %p does not supports SMART\n",
-                        DeviceObject));
-            
-        }
-        
-        //
-        // Set status for successful request
-        //
-
-        status = STATUS_SUCCESS;
-
-    } // end if (SRB_STATUS(srb->SrbStatus) == SRB_STATUS_SUCCESS)
-
-    //
-    // Free the srb
-    //
-    ExFreePool(srb->SenseInfoBuffer);
-    ExFreePool(srb->DataBuffer);
-    ExFreePool(srb);
-        
-    if (freeLockAndIrp)
-    {
-        //
-        // Set status in completing IRP.
-        //
-
-        Irp->IoStatus.Status = status;
-
-        //
-        // If pending has be returned for this irp then mark the current stack as
-        // pending.
-        //
-
-        if (Irp->PendingReturned) {
-            IoMarkIrpPending(Irp);
-        }
-
-        ClassReleaseRemoveLock(DeviceObject, Irp);
-        IoFreeMdl(Irp->MdlAddress);
-        IoFreeIrp(Irp);
-    }
-    
-    return(STATUS_MORE_PROCESSING_REQUIRED);
-    
-}
-
-NTSTATUS NTAPI DiskInfoExceptionCheck(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
-    )
-{
-    PUCHAR modeData;
-    PSCSI_REQUEST_BLOCK srb;
-    PCDB cdb;
-    PIRP irp;
-    PIO_STACK_LOCATION irpStack;
-    PVOID senseInfoBuffer;
-    ULONG isRemoved;
-    
-    modeData = ExAllocatePoolWithTag(NonPagedPoolCacheAligned,
-                                     MODE_DATA_SIZE,
-                                     DISK_TAG_INFO_EXCEPTION);
-    if (modeData == NULL)
-    {
-        DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate mode data "
-                        "buffer\n"));
-        return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-        
-    srb = ExAllocatePoolWithTag(NonPagedPool,
-                                SCSI_REQUEST_BLOCK_SIZE,
-                                DISK_TAG_SRB);
-    if (srb == NULL)
-    {
-        ExFreePool(modeData);
-        DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate srb "
-                        "buffer\n"));
-        return(STATUS_INSUFFICIENT_RESOURCES);      
-    }
-    
-    //
-    // Build the MODE SENSE CDB.
-    //
-    RtlZeroMemory(srb, SCSI_REQUEST_BLOCK_SIZE);
-    
-    cdb = (PCDB)srb->Cdb;
-    srb->CdbLength = 6;
-    cdb = (PCDB)srb->Cdb;
-    
-    //
-    // Set timeout value from device extension.
-    //
-    srb->TimeOutValue = FdoExtension->TimeOutValue;
-
-    cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
-    cdb->MODE_SENSE.PageCode = MODE_PAGE_FAULT_REPORTING;
-    cdb->MODE_SENSE.AllocationLength = MODE_DATA_SIZE;
-    
-    //
-    // Write length to SRB.
-    //
-    srb->Length = SCSI_REQUEST_BLOCK_SIZE;
-
-    //
-    // Set SCSI bus address.
-    //
-
-    srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
-
-    //
-    // Enable auto request sense.
-    //  
-    
-    srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
-
-    //
-    // Sense buffer is in aligned nonpaged pool.
-    //
-
-    senseInfoBuffer = ExAllocatePoolWithTag(NonPagedPoolCacheAligned,
-                                     SENSE_BUFFER_SIZE,
-                                     '7CcS');
-
-    if (senseInfoBuffer == NULL)
-    {
-        ExFreePool(srb);
-        ExFreePool(modeData);
-        DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate request sense "
-                        "buffer\n"));
-        return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-
-    srb->SenseInfoBuffer = senseInfoBuffer;
-    srb->DataBuffer = modeData;
-    
-    srb->SrbFlags = FdoExtension->SrbFlags;
-
-
-    SET_FLAG(srb->SrbFlags, SRB_FLAGS_DATA_IN);
-    
-    //
-    // Disable synchronous transfer for these requests.
-    //
-    SET_FLAG(srb->SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
-
-    //
-    // Don't freeze the queue on an error
-    //  
-    SET_FLAG(srb->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
-
-    srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
-    srb->QueueTag = SP_UNTAGGED;
-
-        
-    //
-    // Build device I/O control request with METHOD_NEITHER data transfer.
-    // We'll queue a completion routine to cleanup the MDL's and such ourself.
-    //
-
-    irp = IoAllocateIrp(
-            (CCHAR) (FdoExtension->CommonExtension.LowerDeviceObject->StackSize + 1),
-            FALSE);
-
-    if (irp == NULL)
-    {
-        ExFreePool(senseInfoBuffer);
-        ExFreePool(srb);
-        ExFreePool(modeData);
-        DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate Irp\n"));
-        return(STATUS_INSUFFICIENT_RESOURCES);
-    }
-
-    isRemoved = ClassAcquireRemoveLock(FdoExtension->DeviceObject, irp);
-
-    if (isRemoved)
-    {
-        ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
-        IoFreeIrp(irp);
-        ExFreePool(senseInfoBuffer);
-        ExFreePool(srb);
-        ExFreePool(modeData);
-        DebugPrint((1, "DiskInfoExceptionCheck: RemoveLock says isRemoved\n"));
-        return(STATUS_DEVICE_DOES_NOT_EXIST);
-    }
-    
-    //
-    // Get next stack location.
-    //
-
-    IoSetNextIrpStackLocation(irp);
-    irpStack = IoGetCurrentIrpStackLocation(irp);
-    irpStack->DeviceObject = FdoExtension->DeviceObject;
-
-    //
-    // Save retry count in current Irp stack.
-    //
-    irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
-    
-    
-    irpStack = IoGetNextIrpStackLocation(irp);
-
-    //
-    // Set up SRB for execute scsi request. Save SRB address in next stack
-    // for the port driver.
-    //
-
-    irpStack->MajorFunction = IRP_MJ_SCSI;
-    irpStack->Parameters.Scsi.Srb = srb;
-
-    IoSetCompletionRoutine(irp,
-                           DiskInfoExceptionComplete,
-                           srb,
-                           TRUE,
-                           TRUE,
-                           TRUE);
-
-    irp->MdlAddress = IoAllocateMdl( modeData,
-                                     MODE_DATA_SIZE,
-                                     FALSE,
-                                     FALSE,
-                                     irp );
-    if (irp->MdlAddress == NULL)
-    {
-        ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
-        ExFreePool(srb);
-        ExFreePool(modeData);
-        ExFreePool(senseInfoBuffer);
-        IoFreeIrp( irp );
-        DebugPrint((1, "DiskINfoExceptionCheck: Can't allocate MDL\n"));
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    MmBuildMdlForNonPagedPool(irp->MdlAddress);
-        
-    //
-    // Set the transfer length.
-    //
-    srb->DataTransferLength = MODE_DATA_SIZE;
-
-    //
-    // Zero out status.
-    //
-    srb->ScsiStatus = srb->SrbStatus = 0;
-    srb->NextSrb = 0;
-
-    //
-    // Set up IRP Address.
-    //
-    srb->OriginalRequest = irp;
-    
-    //
-    // Call the port driver with the request and wait for it to complete.
-    //
-
-    IoMarkIrpPending(irp);
-    IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject,
-                          irp);
-
-    return(STATUS_PENDING);
-}
-
-NTSTATUS
-NTAPI
-DiskDetectFailurePrediction(
-    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
-    PFAILURE_PREDICTION_METHOD FailurePredictCapability
-    )
-/*++
-
-Routine Description:
-
-    Detect if device has any failure prediction capabilities. First we
-    check for IDE SMART capability. This is done by sending the drive an
-    IDENTIFY command and checking if the SMART command set bit is set.
-
-    Next we check if SCSI SMART (aka Information Exception Control Page,
-    X3T10/94-190 Rev 4). This is done by querying for the Information
-    Exception mode page.
-
-    Lastly we check if the device has IOCTL failure prediction. This mechanism
-    a filter driver implements IOCTL_STORAGE_PREDICT_FAILURE and will respond
-    with the information in the IOCTL. We do this by sending the ioctl and
-    if the status returned is STATUS_SUCCESS we assume that it is supported.
-
-Arguments:
-
-    FdoExtension
-
-    *FailurePredictCapability
-
-Return Value:
-
-    NT Status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = (PCOMMON_DEVICE_EXTENSION)FdoExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    BOOLEAN supportFP;
-    NTSTATUS status;
-    STORAGE_PREDICT_FAILURE checkFailure;
-    STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
-    //BOOLEAN logErr;
-
-    PAGED_CODE();
-
-    //
-    // Assume no failure predict mechanisms
-    //
-    *FailurePredictCapability = FailurePredictionNone;
-
-    //
-    // See if this is an IDE drive that supports SMART. If so enable SMART
-    // and then ensure that it supports the SMART READ STATUS command
-    //
-    status = DiskGetIdentifyInfo(FdoExtension,
-                                 &supportFP);
-
-    if (supportFP)
-    {
-        status = DiskEnableSmart(FdoExtension);
-        if (NT_SUCCESS(status))
-        {
-            *FailurePredictCapability = FailurePredictionSmart;
-
-            status = DiskReadFailurePredictStatus(FdoExtension,
-                                                  &diskSmartStatus);
-
-            DebugPrint((1, "Disk: Device %p %s IDE SMART\n",
-                       FdoExtension->DeviceObject,
-                       NT_SUCCESS(status) ? "does" : "does not"));
-
-            if (! NT_SUCCESS(status))
-            {
-                *FailurePredictCapability = FailurePredictionNone;
-            }
-        }
-        return(status);
-    }
-
-    //
-    // See if there is a a filter driver to intercept
-    // IOCTL_STORAGE_PREDICT_FAILURE
-    //
-    status = DiskSendFailurePredictIoctl(FdoExtension,
-                                         &checkFailure);
-
-    DebugPrint((1, "Disk: Device %p %s IOCTL_STORAGE_FAILURE_PREDICT\n",
-                       FdoExtension->DeviceObject,
-                       NT_SUCCESS(status) ? "does" : "does not"));
-
-    if (NT_SUCCESS(status))
-    {
-        *FailurePredictCapability = FailurePredictionIoctl;
-        if (checkFailure.PredictFailure)
-        {
-            checkFailure.PredictFailure = 512;
-            ClassNotifyFailurePredicted(FdoExtension,
-                                            (PUCHAR)&checkFailure,
-                                            sizeof(checkFailure),
-                                            (BOOLEAN)(FdoExtension->FailurePredicted == FALSE),
-                                            0x11,
-                                            diskData->ScsiAddress.PathId,
-                                            diskData->ScsiAddress.TargetId,
-                                            diskData->ScsiAddress.Lun);
-
-            FdoExtension->FailurePredicted = TRUE;
-        }
-        return(status);
-    }
-    
-    //
-    // Finally we assume it will not be a scsi smart drive. but
-    // we'll also send off an asynchronous mode sense so that if
-    // it is SMART we'll reregister the device object
-    //
-
-    DiskInfoExceptionCheck(FdoExtension);
-    
-    *FailurePredictCapability = FailurePredictionNone;
-
-    return(STATUS_SUCCESS);
-}
-
-NTSTATUS
-NTAPI
-DiskWmiFunctionControl(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN CLASSENABLEDISABLEFUNCTION Function,
-    IN BOOLEAN Enable
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to enabled or disable event
-    generation or data block collection. A device should only expect a
-    single enable when the first event or data consumer enables events or
-    data collection and a single disable when the last event or data
-    consumer disables events or data collection. Data blocks will only
-    receive collection enable/disable if they were registered as requiring
-    it.
-
-
-    When NT boots, failure prediction is not automatically enabled, although
-    it may have been persistently enabled on a previous boot. Polling is also
-    not automatically enabled. When the first data block that accesses SMART
-    such as SmartStatusGuid, SmartDataGuid, SmartPerformFunction, or
-    SmartEventGuid is accessed then SMART is automatically enabled in the
-    hardware. Polling is enabled when SmartEventGuid is enabled and disabled
-    when it is disabled. Hardware SMART is only disabled when the DisableSmart
-    method is called. Polling is also disabled when this is called regardless
-    of the status of the other guids or events.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    Function specifies which functionality is being enabled or disabled
-
-    Enable is TRUE then the function is being enabled else disabled
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status = STATUS_SUCCESS;
-    //PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    //PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    //ULONG enableCount;
-
-    PAGED_CODE();
-
-    if ((Function == DataBlockCollection) && Enable)
-    {
-        if ((GuidIndex == SmartStatusGuid) ||
-            (GuidIndex == SmartDataGuid) ||
-            (GuidIndex == SmartThresholdsGuid) ||
-            (GuidIndex == SmartPerformFunction))
-        {
-            status = DiskEnableDisableFailurePrediction(fdoExtension,
-                                                        TRUE);
-            DebugPrint((3, "Disk: DeviceObject %p, Irp %p Enable -> %lx\n",
-                       DeviceObject,
-                       Irp,
-                       status));
-
-        } else {
-            DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Collection\n",
-                      DeviceObject, Irp,
-                      GuidIndex,
-                      Enable ? "Enabled" : "Disabled"));        }
-    } else if (Function == EventGeneration) {
-        DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Event Generation\n",
-                  DeviceObject, Irp,
-                  GuidIndex,
-                  Enable ? "Enabled" : "Disabled"));
-
-
-        if ((GuidIndex == SmartEventGuid) && Enable)
-        {
-            status = DiskEnableDisableFailurePredictPolling(fdoExtension,
-                                                   Enable,
-                                                   0);
-            DebugPrint((3, "Disk: DeviceObject %p, Irp %p %s -> %lx\n",
-                       DeviceObject,
-                       Irp,
-                       Enable ? "DiskEnableSmartPolling" : "DiskDisableSmartPolling",
-                       status));
-        }
-
-#if DBG
-    } else {
-        DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for function %d\n",
-                  DeviceObject, Irp,
-                  GuidIndex,
-                  Enable ? "Enabled" : "Disabled",
-                  Function));
-#endif
-    }
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskFdoQueryWmiRegInfo(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT ULONG *RegFlags,
-    OUT PUNICODE_STRING InstanceName
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to retrieve the list of
-    guids or data blocks that the driver wants to register with WMI. This
-    routine may not pend or block. Driver should NOT call
-    ClassWmiCompleteRequest.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    *RegFlags returns with a set of flags that describe the guids being
-        registered for this device. If the device wants enable and disable
-        collection callbacks before receiving queries for the registered
-        guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
-        returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
-        the instance name is determined from the PDO associated with the
-        device object. Note that the PDO must have an associated devnode. If
-        WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
-        name for the device.
-
-    InstanceName returns with the instance name for the guids if
-        WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
-        caller will call ExFreePool with the buffer returned.
-
-
-Return Value:
-
-    status
-
---*/
-{
-    //PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    //NTSTATUS status;
-
-    PAGED_CODE();
-
-    SET_FLAG(DiskWmiFdoGuidList[SmartThresholdsGuid].Flags,  WMIREG_FLAG_REMOVE_GUID);
-    SET_FLAG(DiskWmiFdoGuidList[ScsiInfoExceptionsGuid].Flags,  WMIREG_FLAG_REMOVE_GUID);
-    
-    switch (diskData->FailurePredictionCapability)
-    {
-        case FailurePredictionSmart:
-        {
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartThresholdsGuid].Flags,  WMIREG_FLAG_REMOVE_GUID);
-            //
-            // Fall Through
-            //
-        }
-        case FailurePredictionIoctl:
-        {
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartStatusGuid].Flags,      WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartDataGuid].Flags,        WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartEventGuid].Flags,       WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartPerformFunction].Flags, WMIREG_FLAG_REMOVE_GUID);
-                  
-            break;
-        }
-
-        case FailurePredictionSense:
-        {
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartStatusGuid].Flags,      WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartEventGuid].Flags,       WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[SmartPerformFunction].Flags, WMIREG_FLAG_REMOVE_GUID);
-            CLEAR_FLAG(DiskWmiFdoGuidList[ScsiInfoExceptionsGuid].Flags,  WMIREG_FLAG_REMOVE_GUID);
-            SET_FLAG  (DiskWmiFdoGuidList[SmartDataGuid].Flags,        WMIREG_FLAG_REMOVE_GUID);
-            break;
-        }
-
-
-        default:
-        {
-            SET_FLAG  (DiskWmiFdoGuidList[SmartStatusGuid].Flags,      WMIREG_FLAG_REMOVE_GUID);
-            SET_FLAG  (DiskWmiFdoGuidList[SmartDataGuid].Flags,        WMIREG_FLAG_REMOVE_GUID);
-            SET_FLAG  (DiskWmiFdoGuidList[SmartEventGuid].Flags,       WMIREG_FLAG_REMOVE_GUID);
-            SET_FLAG  (DiskWmiFdoGuidList[SmartPerformFunction].Flags, WMIREG_FLAG_REMOVE_GUID);
-            break;
-        }
-    }
-
-    //
-    // Use devnode for FDOs
-    *RegFlags = WMIREG_FLAG_INSTANCE_PDO;
-
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-NTAPI
-DiskFdoQueryWmiRegInfoEx(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT ULONG *RegFlags,
-    OUT PUNICODE_STRING InstanceName,
-    OUT PUNICODE_STRING MofName                      
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to retrieve the list of
-    guids or data blocks that the driver wants to register with WMI. This
-    routine may not pend or block. Driver should NOT call
-    ClassWmiCompleteRequest.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    *RegFlags returns with a set of flags that describe the guids being
-        registered for this device. If the device wants enable and disable
-        collection callbacks before receiving queries for the registered
-        guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
-        returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
-        the instance name is determined from the PDO associated with the
-        device object. Note that the PDO must have an associated devnode. If
-        WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
-        name for the device.
-
-    InstanceName returns with the instance name for the guids if
-        WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
-        caller will call ExFreePool with the buffer returned.
-
-    MofName returns initialized with the mof resource name for the
-        binary mof resource attached to the driver's image file. If the
-        driver does not have a mof resource then it should leave this
-        parameter untouched.
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-    
-    status = DiskFdoQueryWmiRegInfo(DeviceObject,
-                                    RegFlags,
-                                    InstanceName);
-
-    //
-    // Leave MofName alone since disk doesn't have one
-    //
-    return(status);
-}
-
-NTSTATUS
-NTAPI
-DiskFdoQueryWmiDataBlock(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG BufferAvail,
-    OUT PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    BufferAvail on has the maximum size available to write the data
-        block.
-
-    Buffer on return is filled with the returned data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    ULONG sizeNeeded;
-
-    PAGED_CODE();
-
-    DebugPrint((3, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
-             "      BufferAvail %lx Buffer %lx\n",
-             DeviceObject, Irp,
-             GuidIndex, BufferAvail, Buffer));
-
-    switch (GuidIndex)
-    {
-        case DiskGeometryGuid:
-        {
-            sizeNeeded = sizeof(DISK_GEOMETRY);
-            if (BufferAvail >= sizeNeeded)
-            {
-                if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
-                {
-                    //
-                    // Issue ReadCapacity to update device extension
-                    // with information for current media.
-                    status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
-
-                    //
-                    // Note whether the drive is ready.
-                    diskData->ReadyStatus = status;
-
-                    if (!NT_SUCCESS(status))
-                    {
-                        break;
-                    }
-                }
-
-                //
-                // Copy drive geometry information from device extension.
-                RtlMoveMemory(Buffer,
-                              &(fdoExtension->DiskGeometry),
-                              sizeof(DISK_GEOMETRY));
-
-                status = STATUS_SUCCESS;
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-            break;
-        }
-
-        case SmartStatusGuid:
-        {
-            PSTORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
-
-            ASSERT(diskData->FailurePredictionCapability != FailurePredictionNone);
-
-
-            sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_STATUS);
-            if (BufferAvail >= sizeNeeded)
-            {
-                STORAGE_PREDICT_FAILURE checkFailure;
-
-                diskSmartStatus = (PSTORAGE_FAILURE_PREDICT_STATUS)Buffer;
-
-                status = DiskSendFailurePredictIoctl(fdoExtension,
-                                                     &checkFailure);
-
-                if (NT_SUCCESS(status))
-                {
-                    if (diskData->FailurePredictionCapability ==
-                                                      FailurePredictionSense)
-                    {
-                        diskSmartStatus->Reason =  *((PULONG)checkFailure.VendorSpecific);
-                    } else {
-                        diskSmartStatus->Reason =  0; // unknown
-                    }
-
-                    diskSmartStatus->PredictFailure = (checkFailure.PredictFailure != 0);
-                }
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-            break;
-        }
-
-        case SmartDataGuid:
-        {
-            PSTORAGE_FAILURE_PREDICT_DATA diskSmartData;
-
-            ASSERT((diskData->FailurePredictionCapability ==
-                                                  FailurePredictionSmart) ||
-                   (diskData->FailurePredictionCapability ==
-                                                  FailurePredictionIoctl));
-
-            sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_DATA);
-            if (BufferAvail >= sizeNeeded)
-            {
-                PSTORAGE_PREDICT_FAILURE checkFailure = (PSTORAGE_PREDICT_FAILURE)Buffer;
-
-                diskSmartData = (PSTORAGE_FAILURE_PREDICT_DATA)Buffer;
-
-                status = DiskSendFailurePredictIoctl(fdoExtension,
-                                                     checkFailure);
-
-                if (NT_SUCCESS(status))
-                {
-                    diskSmartData->Length = 512;
-                }
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-
-            break;
-        }
-        
-        case SmartThresholdsGuid:
-        {
-            PSTORAGE_FAILURE_PREDICT_THRESHOLDS diskSmartThresholds;
-
-            ASSERT((diskData->FailurePredictionCapability ==
-                                                  FailurePredictionSmart));
-
-            sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_THRESHOLDS);
-            if (BufferAvail >= sizeNeeded)
-            {
-                diskSmartThresholds = (PSTORAGE_FAILURE_PREDICT_THRESHOLDS)Buffer;
-                status = DiskReadFailurePredictThresholds(fdoExtension,
-                                                          diskSmartThresholds);
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-
-            break;
-        }
-
-        case SmartPerformFunction:
-        {
-            sizeNeeded = 0;
-            status = STATUS_SUCCESS;
-            break;
-        }
-
-        case ScsiInfoExceptionsGuid:
-        {
-            PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
-            MODE_INFO_EXCEPTIONS modeInfo;
-
-            ASSERT((diskData->FailurePredictionCapability ==
-                                                  FailurePredictionSense));
-            
-            sizeNeeded = sizeof(STORAGE_SCSI_INFO_EXCEPTIONS);
-            if (BufferAvail >= sizeNeeded)
-            {
-                infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
-                status = DiskGetInfoExceptionInformation(fdoExtension,
-                                                         &modeInfo);
-
-                if (NT_SUCCESS(status))
-                {
-                    infoExceptions->PageSavable = modeInfo.PSBit;
-                    infoExceptions->Flags = modeInfo.Flags;
-                    infoExceptions->MRIE = modeInfo.ReportMethod;
-                    infoExceptions->Padding = 0;
-                    REVERSE_BYTES(&infoExceptions->IntervalTimer,
-                                  &modeInfo.IntervalTimer);
-                    REVERSE_BYTES(&infoExceptions->ReportCount,
-                                  &modeInfo.ReportCount)
-                }
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-
-            break;
-        }
-
-        default:
-        {
-            sizeNeeded = 0;
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-    DebugPrint((3, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     sizeNeeded,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskFdoSetWmiDataBlock(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG BufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    BufferSize has the size of the data block passed
-
-    Buffer has the new values for the data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-
-    PAGED_CODE();
-
-    DebugPrint((3, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
-             "      BufferSize %#x Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, BufferSize, Buffer));
-
-    if (GuidIndex == ScsiInfoExceptionsGuid)
-    {
-        PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
-        MODE_INFO_EXCEPTIONS modeInfo;
-
-        if (BufferSize >= sizeof(STORAGE_SCSI_INFO_EXCEPTIONS))
-        {
-            infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
-
-            modeInfo.PageCode = MODE_PAGE_FAULT_REPORTING;
-            modeInfo.PageLength = sizeof(MODE_INFO_EXCEPTIONS) - 2;
-
-            modeInfo.PSBit = 0;
-            modeInfo.Flags = infoExceptions->Flags;
-            
-            modeInfo.ReportMethod = infoExceptions->MRIE;
-
-            REVERSE_BYTES(&modeInfo.IntervalTimer[0],
-                          &infoExceptions->IntervalTimer);
-            
-            REVERSE_BYTES(&modeInfo.ReportCount[0],
-                          &infoExceptions->ReportCount);
-
-            if (modeInfo.Perf == 1)
-            {
-                diskData->AllowFPPerfHit = FALSE;
-            } else {
-                diskData->AllowFPPerfHit = TRUE;
-            }
-            
-            status = DiskSetInfoExceptionInformation(fdoExtension,
-                                                     &modeInfo);
-        } else {
-            status = STATUS_INVALID_PARAMETER;
-        }
-        
-    } else if (GuidIndex <= SmartEventGuid)
-    {
-        status = STATUS_WMI_READ_ONLY;
-    } else {
-        status = STATUS_WMI_GUID_NOT_FOUND;
-    }
-
-    DebugPrint((3, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskFdoSetWmiDataItem(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG DataItemId,
-    IN ULONG BufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    DataItemId has the id of the data item being set
-
-    BufferSize has the size of the data item passed
-
-    Buffer has the new values for the data item
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    DebugPrint((3, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
-             "      BufferSize %#x Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, DataItemId, BufferSize, Buffer));
-
-    if (GuidIndex <= SmartEventGuid)
-    {
-        status = STATUS_WMI_READ_ONLY;
-    } else {
-        status = STATUS_WMI_GUID_NOT_FOUND;
-    }
-
-    DebugPrint((3, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskFdoExecuteWmiMethod(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG MethodId,
-    IN ULONG InBufferSize,
-    IN ULONG OutBufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to execute a method. When the
-    driver has finished filling the data block it must call
-    ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    MethodId has the id of the method being called
-
-    InBufferSize has the size of the data block passed in as the input to
-        the method.
-
-    OutBufferSize on entry has the maximum size available to write the
-        returned data block.
-
-    Buffer is filled with the returned data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    ULONG sizeNeeded;
-    NTSTATUS status;
-
-    PAGED_CODE();
-
-    DebugPrint((3, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
-             "      InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, MethodId, InBufferSize, OutBufferSize, Buffer));
-
-    switch(GuidIndex)
-    {
-        case SmartPerformFunction:
-        {
-
-            ASSERT((diskData->FailurePredictionCapability ==
-                                                  FailurePredictionSmart) ||
-                   (diskData->FailurePredictionCapability ==
-                                                  FailurePredictionIoctl) ||
-                   (diskData->FailurePredictionCapability ==
-                                                  FailurePredictionSense));
-
-
-            switch(MethodId)
-            {
-                //
-                // void AllowPerformanceHit([in] boolean Allow)
-                //
-                case AllowDisallowPerformanceHit:
-                {
-                    BOOLEAN allowPerfHit;
-
-                    sizeNeeded = 0;
-                    if (InBufferSize >= sizeof(BOOLEAN))
-                    {
-                        status = STATUS_SUCCESS;
-
-                        allowPerfHit = *((PBOOLEAN)Buffer);
-                        if (diskData->AllowFPPerfHit !=  allowPerfHit)
-                        {
-                            diskData->AllowFPPerfHit = allowPerfHit;
-                            if (diskData->FailurePredictionCapability ==
-                                FailurePredictionSense)
-                            {
-                                MODE_INFO_EXCEPTIONS modeInfo;
-
-                                status = DiskGetInfoExceptionInformation(fdoExtension,
-                                                                         &modeInfo);
-                                if (NT_SUCCESS(status))
-                                {
-                                    modeInfo.Perf = allowPerfHit ? 0 : 1;
-                                    status = DiskSetInfoExceptionInformation(fdoExtension,
-                                                                             &modeInfo);
-                                }
-                            }
-                        }
-
-                        DebugPrint((3, "DiskFdoWmiExecuteMethod: AllowPerformanceHit %x for device %p --> %lx\n",
-                                    allowPerfHit,
-                                    fdoExtension->DeviceObject,
-                                    status));
-                    } else {
-                        status = STATUS_INVALID_PARAMETER;
-                    }
-                    break;
-                }
-
-                //
-                // void EnableDisableHardwareFailurePrediction([in] boolean Enable)
-                //
-                case EnableDisableHardwareFailurePrediction:
-                {
-                    BOOLEAN enable;
-
-                    sizeNeeded = 0;
-                    if (InBufferSize >= sizeof(BOOLEAN))
-                    {
-                        status = STATUS_SUCCESS;
-                        enable = *((PBOOLEAN)Buffer);
-                        if (! enable)
-                        {
-                            //
-                            // If we are disabling we need to also disable
-                            // polling
-                            //
-                            DiskEnableDisableFailurePredictPolling(
-                                                               fdoExtension,
-                                                               enable,
-                                                               0);
-                        }
-
-                        status = DiskEnableDisableFailurePrediction(
-                                                           fdoExtension,
-                                                           enable);
-
-                        DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableDisableHardwareFailurePrediction: %x for device %p --> %lx\n",
-                                    enable,
-                                    fdoExtension->DeviceObject,
-                                    status));
-                    } else {
-                        status = STATUS_INVALID_PARAMETER;
-                    }
-                    break;
-                }
-
-                //
-                // void EnableDisableFailurePredictionPolling(
-                //                               [in] uint32 Period,
-                //                               [in] boolean Enable)
-                //
-                case EnableDisableFailurePredictionPolling:
-                {
-                    BOOLEAN enable;
-                    ULONG period;
-
-                    sizeNeeded = 0;
-                    if (InBufferSize >= (sizeof(ULONG) + sizeof(BOOLEAN)))
-                    {
-                        period = *((PULONG)Buffer);
-                        Buffer += sizeof(ULONG);
-                        enable = *((PBOOLEAN)Buffer);
-
-                           status = DiskEnableDisableFailurePredictPolling(
-                                                               fdoExtension,
-                                                               enable,
-                                                               period);
-
-                        DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableDisableFailurePredictionPolling: %x %x for device %p --> %lx\n",
-                                    enable,
-                                    period,
-                                    fdoExtension->DeviceObject,
-                                    status));
-                    } else {
-                        status = STATUS_INVALID_PARAMETER;
-                    }
-                    break;
-                }
-
-                //
-                // void GetFailurePredictionCapability([out] uint32 Capability)
-                //
-                case GetFailurePredictionCapability:
-                {
-                    sizeNeeded = sizeof(ULONG);
-                    if (OutBufferSize >= sizeNeeded)
-                    {
-                        status = STATUS_SUCCESS;
-                        *((PFAILURE_PREDICTION_METHOD)Buffer) = diskData->FailurePredictionCapability;
-                        DebugPrint((3, "DiskFdoWmiExecuteMethod: GetFailurePredictionCapability: %x for device %p --> %lx\n",
-                                    *((PFAILURE_PREDICTION_METHOD)Buffer),
-                                    fdoExtension->DeviceObject,
-                                    status));
-                    } else {
-                        status = STATUS_BUFFER_TOO_SMALL;
-                    }
-                    break;
-                }
-
-                //
-                // void EnableOfflineDiags([out] boolean Success);
-                //
-                case EnableOfflineDiags:
-                {
-                    sizeNeeded = sizeof(BOOLEAN);
-                    if (OutBufferSize >= sizeNeeded)
-                    {
-                        if (diskData->FailurePredictionCapability ==
-                                  FailurePredictionSmart)
-                        {
-                            //
-                            // Initiate or resume offline diagnostics.
-                            // This may cause a loss of performance
-                            // to the disk, but mayincrease the amount
-                            // of disk checking.
-                            //
-                            status = DiskExecuteSmartDiagnostics(fdoExtension,
-                                                                0);
-
-                        } else {
-                            status = STATUS_INVALID_DEVICE_REQUEST;
-                        }
-
-                        *((PBOOLEAN)Buffer) = NT_SUCCESS(status);
-
-                        DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableOfflineDiags for device %p --> %lx\n",
-                                    fdoExtension->DeviceObject,
-                                    status));
-                    } else {
-                        status = STATUS_BUFFER_TOO_SMALL;
-                    }
-                    break;
-                }
-
-                //
-                //    void ReadLogSectors([in] uint8 LogAddress,
-                //        [in] uint8 SectorCount,
-                //        [out] uint32 Length,
-                //        [out, WmiSizeIs("Length")] uint8 LogSectors[]
-                //       );
-                //
-                case ReadLogSectors:
-                {
-                    sizeNeeded = 0;
-                    if (diskData->FailurePredictionCapability ==
-                                  FailurePredictionSmart)
-                    {
-                        if (InBufferSize >= sizeof(READ_LOG_SECTORS_IN))
-                        {
-                            PREAD_LOG_SECTORS_IN inParams;
-                            PREAD_LOG_SECTORS_OUT outParams;
-                            ULONG readSize;
-
-                            inParams = (PREAD_LOG_SECTORS_IN)Buffer;
-                            readSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
-                            sizeNeeded = FIELD_OFFSET(READ_LOG_SECTORS_OUT,
-                                                  LogSectors) + readSize;
-                                                  
-                            if (OutBufferSize >= sizeNeeded)
-                            {
-                                outParams = (PREAD_LOG_SECTORS_OUT)Buffer;
-                                status = DiskReadSmartLog(fdoExtension,
-                                                        inParams->SectorCount,
-                                                        inParams->LogAddress,
-                                                        outParams->LogSectors);
-
-                                if (NT_SUCCESS(status))
-                                {
-                                    outParams->Length = readSize;
-                                } else {
-                                    //
-                                    // SMART command failure is
-                                    // indicated by successful
-                                    // execution, but no data returned
-                                    //
-                                    outParams->Length = 0;
-                                    status = STATUS_SUCCESS;
-                                }
-                            } else {
-                                status = STATUS_BUFFER_TOO_SMALL;
-                            }
-                            
-                        } else {
-                            status = STATUS_INVALID_PARAMETER;
-                        }
-                    } else {
-                        status = STATUS_INVALID_DEVICE_REQUEST;
-                    }
-                    break;
-                }
-
-                //    void WriteLogSectors([in] uint8 LogAddress,
-                //        [in] uint8 SectorCount,
-                //        [in] uint32 Length,
-                //        [in, WmiSizeIs("Length")] uint8 LogSectors[],
-                //        [out] boolean Success
-                //       );
-                case WriteLogSectors:
-                {
-                    sizeNeeded = 0;
-                    if (diskData->FailurePredictionCapability ==
-                                  FailurePredictionSmart)
-                    {
-                        if (InBufferSize >= FIELD_OFFSET(WRITE_LOG_SECTORS_IN,
-                                                        LogSectors))
-                        {
-                            PWRITE_LOG_SECTORS_IN inParams;
-                            PWRITE_LOG_SECTORS_OUT outParams;
-                            ULONG writeSize;
-
-                            inParams = (PWRITE_LOG_SECTORS_IN)Buffer;
-                            writeSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
-                            if (InBufferSize >= (FIELD_OFFSET(WRITE_LOG_SECTORS_IN,
-                                                             LogSectors) +
-                                                 writeSize))
-                            {
-                                sizeNeeded = sizeof(WRITE_LOG_SECTORS_OUT);
-                                                  
-                                if (OutBufferSize >= sizeNeeded)
-                                {
-                                    outParams = (PWRITE_LOG_SECTORS_OUT)Buffer;
-                                    status = DiskWriteSmartLog(fdoExtension,
-                                                        inParams->SectorCount,
-                                                        inParams->LogAddress,
-                                                        inParams->LogSectors);
-
-                                    if (NT_SUCCESS(status))
-                                    {
-                                        outParams->Success = TRUE;
-                                    } else {
-                                        outParams->Success = FALSE;
-                                        status = STATUS_SUCCESS;
-                                    }                                   
-                                } else {
-                                    status = STATUS_BUFFER_TOO_SMALL;
-                                }
-                            } else {
-                                status = STATUS_INVALID_PARAMETER;
-                            }                           
-                        } else {
-                            status = STATUS_INVALID_PARAMETER;
-                        }
-                    } else {
-                        status = STATUS_INVALID_DEVICE_REQUEST;
-                    }
-                    break;
-                }
-
-                //    void ExecuteSelfTest([in] uint8 Subcommand,
-                //         [out, 
-                //          Values{"0", "1", "2"},
-                //          ValueMap{"Successful Completion",
-                //                   "Captive Mode Required",
-                //                   "Unsuccessful Completion"}
-                //         ]
-                //         uint32 ReturnCode);
-                case ExecuteSelfTest:
-                {
-                    sizeNeeded = 0;
-                    if (diskData->FailurePredictionCapability ==
-                              FailurePredictionSmart)
-                    {
-                        if (InBufferSize >= sizeof(EXECUTE_SELF_TEST_IN))
-                        {
-                            sizeNeeded = sizeof(EXECUTE_SELF_TEST_OUT);
-                            if (OutBufferSize >= sizeNeeded)
-                            {
-                                PEXECUTE_SELF_TEST_IN inParam;
-                                PEXECUTE_SELF_TEST_OUT outParam;
-
-                                inParam = (PEXECUTE_SELF_TEST_IN)Buffer;
-                                outParam = (PEXECUTE_SELF_TEST_OUT)Buffer;
-
-                                if (DiskIsValidSmartSelfTest(inParam->Subcommand))
-                                {
-                                   status = DiskExecuteSmartDiagnostics(fdoExtension,
-                                                            inParam->Subcommand);
-                                   if (NT_SUCCESS(status))
-                                   {
-                                       //
-                                       // Return self test executed
-                                       // without a problem
-                                       //
-                                       outParam->ReturnCode = 0;
-                                   } else {
-                                       //
-                                       // Return Self test execution
-                                       // failed status
-                                       //
-                                       outParam->ReturnCode = 2;
-                                       status = STATUS_SUCCESS;
-                                   }
-                                } else {
-                                    //
-                                    // If self test subcommand requires
-                                    // captive mode then return that
-                                    // status
-                                    //
-                                    outParam->ReturnCode = 1;
-                                    status = STATUS_SUCCESS;
-                                }
-
-                            } else {
-                                status = STATUS_BUFFER_TOO_SMALL;
-                            }
-                            
-                        } else {
-                            status = STATUS_INVALID_PARAMETER;
-                        }
-                    } else {
-                        status = STATUS_INVALID_DEVICE_REQUEST;
-                    }
-                            
-                    break;
-                }
-
-                default :
-                {
-                    sizeNeeded = 0;
-                    status = STATUS_WMI_ITEMID_NOT_FOUND;
-                    break;
-                }
-            }
-
-            break;
-        }
-
-        case DiskGeometryGuid:
-        case SmartStatusGuid:
-        case SmartDataGuid:
-        {
-
-            sizeNeeded = 0;
-            status = STATUS_INVALID_DEVICE_REQUEST;
-            break;
-        }
-
-        default:
-        {
-            sizeNeeded = 0;
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-
-    DebugPrint((3, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     sizeNeeded,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-#if 0
-//
-// Enable this to add WMI support for PDOs
-NTSTATUS
-NTAPI
-DiskPdoQueryWmiRegInfo(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT ULONG *RegFlags,
-    OUT PUNICODE_STRING InstanceName
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to retrieve the list of
-    guids or data blocks that the driver wants to register with WMI. This
-    routine may not pend or block. Driver should NOT call
-    ClassWmiCompleteRequest.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    *RegFlags returns with a set of flags that describe the guids being
-        registered for this device. If the device wants enable and disable
-        collection callbacks before receiving queries for the registered
-        guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
-        returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
-        the instance name is determined from the PDO associated with the
-        device object. Note that the PDO must have an associated devnode. If
-        WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
-        name for the device.
-
-    InstanceName returns with the instance name for the guids if
-        WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
-        caller will call ExFreePool with the buffer returned.
-
-
-Return Value:
-
-    status
-
---*/
-{
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PFUNCTIONAL_DEVICE_EXTENSION parentFunctionalExtension;
-    ANSI_STRING ansiString;
-    CHAR name[256];
-    NTSTATUS status;
-
-    //
-    // We need to pick a name for PDOs since they do not have a devnode
-    parentFunctionalExtension = commonExtension->PartitionZeroExtension;
-    sprintf(name,
-                "Disk(%d)_Partition(%d)_Start(%#I64x)_Length(%#I64x)",
-                parentFunctionalExtension->DeviceNumber,
-                commonExtension->PartitionNumber,
-                commonExtension->StartingOffset.QuadPart,
-                commonExtension->PartitionLength.QuadPart);
-    RtlInitAnsiString(&ansiString,
-                          name);
-
-    status = RtlAnsiStringToUnicodeString(InstanceName,
-                                     &ansiString,
-                                     TRUE);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskPdoQueryWmiDataBlock(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG BufferAvail,
-    OUT PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    BufferAvail on has the maximum size available to write the data
-        block.
-
-    Buffer on return is filled with the returned data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
-    ULONG sizeNeeded;
-
-    DebugPrint((3, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
-             "      BufferAvail %#x Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, BufferAvail, Buffer));
-
-    switch (GuidIndex)
-    {
-        case 0:
-        {
-            sizeNeeded = 4 * sizeof(ULONG);
-            if (BufferAvail >= sizeNeeded)
-            {
-                RtlCopyMemory(Buffer, DiskDummyData, sizeNeeded);
-                status = STATUS_SUCCESS;
-            } else {
-                status = STATUS_BUFFER_TOO_SMALL;
-            }
-            break;
-        }
-
-        default:
-        {
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-
-    DebugPrint((3, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     sizeNeeded,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskPdoSetWmiDataBlock(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG BufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    BufferSize has the size of the data block passed
-
-    Buffer has the new values for the data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-    PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
-    ULONG sizeNeeded;
-
-    DebugPrint((3, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
-             "      BufferSize %#x Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, BufferSize, Buffer));
-
-    switch(GuidIndex)
-    {
-        case 0:
-        {
-            sizeNeeded = 4 * sizeof(ULONG);
-            if (BufferSize == sizeNeeded)
-              {
-                RtlCopyMemory(DiskDummyData, Buffer, sizeNeeded);
-                status = STATUS_SUCCESS;
-               } else {
-                status = STATUS_INFO_LENGTH_MISMATCH;
-            }
-            break;
-        }
-
-        default:
-        {
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-
-    DebugPrint((3, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskPdoSetWmiDataItem(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG DataItemId,
-    IN ULONG BufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to query for the contents of
-    a data block. When the driver has finished filling the data block it
-    must call ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    DataItemId has the id of the data item being set
-
-    BufferSize has the size of the data item passed
-
-    Buffer has the new values for the data item
-
-
-Return Value:
-
-    status
-
---*/
-{
-    NTSTATUS status;
-
-    DebugPrint((3, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
-             "      BufferSize %#x Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, DataItemId, BufferSize, Buffer));
-
-    switch(GuidIndex)
-    {
-        case 0:
-        {
-            if ((BufferSize == sizeof(ULONG)) &&
-                (DataItemId <= 3))
-              {
-                  DiskDummyData[DataItemId] = *((PULONG)Buffer);
-                   status = STATUS_SUCCESS;
-               } else {
-                   status = STATUS_INVALID_DEVICE_REQUEST;
-               }
-            break;
-        }
-
-        default:
-        {
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-
-
-    DebugPrint((3, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-
-NTSTATUS
-NTAPI
-DiskPdoExecuteWmiMethod(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PIRP Irp,
-    IN ULONG GuidIndex,
-    IN ULONG MethodId,
-    IN ULONG InBufferSize,
-    IN ULONG OutBufferSize,
-    IN PUCHAR Buffer
-    )
-/*++
-
-Routine Description:
-
-    This routine is a callback into the driver to execute a method. When the
-    driver has finished filling the data block it must call
-    ClassWmiCompleteRequest to complete the irp. The driver can
-    return STATUS_PENDING if the irp cannot be completed immediately.
-
-Arguments:
-
-    DeviceObject is the device whose data block is being queried
-
-    Irp is the Irp that makes this request
-
-    GuidIndex is the index into the list of guids provided when the
-        device registered
-
-    MethodId has the id of the method being called
-
-    InBufferSize has the size of the data block passed in as the input to
-        the method.
-
-    OutBufferSize on entry has the maximum size available to write the
-        returned data block.
-
-    Buffer is filled with the returned data block
-
-
-Return Value:
-
-    status
-
---*/
-{
-    ULONG sizeNeeded = 4 * sizeof(ULONG);
-    NTSTATUS status;
-    ULONG tempData[4];
-
-    DebugPrint((3, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
-             "      InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
-             DeviceObject, Irp,
-             GuidIndex, MethodId, InBufferSize, OutBufferSize, Buffer));
-
-    switch(GuidIndex)
-    {
-        case 0:
-        {
-            if (MethodId == 1)
-            {
-                if (OutBufferSize >= sizeNeeded)
-                {
-
-                    if (InBufferSize == sizeNeeded)
-                    {
-                        RtlCopyMemory(tempData, Buffer, sizeNeeded);
-                        RtlCopyMemory(Buffer, DiskDummyData, sizeNeeded);
-                        RtlCopyMemory(DiskDummyData, tempData, sizeNeeded);
-
-                        status = STATUS_SUCCESS;
-                    } else {
-                        status = STATUS_INVALID_DEVICE_REQUEST;
-                    }
-                } else {
-                    status = STATUS_BUFFER_TOO_SMALL;
-                }
-            } else {
-                   status = STATUS_INVALID_DEVICE_REQUEST;
-            }
-            break;
-        }
-
-        default:
-        {
-            status = STATUS_WMI_GUID_NOT_FOUND;
-        }
-    }
-
-    DebugPrint((3, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
-             DeviceObject, Irp, status));
-
-    status = ClassWmiCompleteRequest(DeviceObject,
-                                     Irp,
-                                     status,
-                                     0,
-                                     IO_NO_INCREMENT);
-
-    return status;
-}
-#endif