ReactOS  0.4.13-dev-73-gcfe54aa
diskwmi.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4 
5 Module Name:
6 
7  diskwmi.c
8 
9 Abstract:
10 
11  SCSI disk class driver - WMI support routines
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 Revision History:
20 
21 --*/
22 
23 #include "disk.h"
24 
25 #include <wmistr.h>
26 
28 NTAPI
31  PSTORAGE_PREDICT_FAILURE checkFailure
32  );
33 
35 NTAPI
38  PBOOLEAN SupportSmart
39  );
40 
42 NTAPI
45  PFAILURE_PREDICTION_METHOD FailurePredictCapability
46  );
47 
49 NTAPI
52  PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
53  );
54 
56 NTAPI
60  IN UCHAR LogAddress,
62  );
63 
65 NTAPI
69  IN UCHAR LogAddress,
71  );
72 
75  );
76 
77 //
78 // WMI reregistration globals
79 //
80 // Since it will take too long to do a mode sense on some drive, we
81 // need a good way to effect the mode sense for the info exceptions
82 // mode page so that we can determine if SMART is supported and enabled
83 // for the drive. So the strategy is to do an asynchronous mode sense
84 // when the device starts and then look at the info exceptions mode
85 // page within the completion routine. Now within the completion
86 // routine we cannot call IoWMIRegistrationControl since we are at DPC
87 // level, so we create a stack of device objects that will be processed
88 // by a single work item that is fired off only when the stack
89 // transitions from empty to non empty.
90 //
95 
97 {
98  {
100  1,
101  0
102  },
103 
104  {
106  1,
108  },
109 
110  {
112  1,
114  },
115 
116  {
118  1,
120  },
121 
122  {
124  1,
126  },
127 
128  {
130  1,
132  },
133 
134  {
136  1,
137  0
138  },
139 
140 
141 };
142 
143 
145 
146 #define DiskGeometryGuid 0
147 #define SmartStatusGuid 1
148 #define SmartDataGuid 2
149 #define SmartPerformFunction 3
150  #define AllowDisallowPerformanceHit 1
151  #define EnableDisableHardwareFailurePrediction 2
152  #define EnableDisableFailurePredictionPolling 3
153  #define GetFailurePredictionCapability 4
154  #define EnableOfflineDiags 5
155 
156 #define SmartEventGuid 4
157 #define SmartThresholdsGuid 5
158 #define ScsiInfoExceptionsGuid 6
159 
160 #if 0
161  //
162  // Enable this to add WMI support for PDOs
164 {
165  {
166  // {25007F51-57C2-11d1-A528-00A0C9062910}
167  { 0x25007f52, 0x57c2, 0x11d1,
168  { 0xa5, 0x28, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0x10 } },
169  0
170  },
171 
172 };
173 
174 ULONG DiskDummyData[4] = { 1, 2, 3, 4};
175 #endif
176 
177 #ifdef ALLOC_PRAGMA
178 
179 #pragma alloc_text(PAGE, DiskWmiFunctionControl)
180 #pragma alloc_text(PAGE, DiskFdoQueryWmiRegInfo)
181 #pragma alloc_text(PAGE, DiskFdoQueryWmiDataBlock)
182 #pragma alloc_text(PAGE, DiskFdoSetWmiDataBlock)
183 #pragma alloc_text(PAGE, DiskFdoSetWmiDataItem)
184 #pragma alloc_text(PAGE, DiskFdoExecuteWmiMethod)
185 
186 #pragma alloc_text(PAGE, DiskDetectFailurePrediction)
187 #pragma alloc_text(PAGE, DiskEnableDisableFailurePrediction)
188 #pragma alloc_text(PAGE, DiskEnableDisableFailurePredictPolling)
189 #pragma alloc_text(PAGE, DiskReadFailurePredictStatus)
190 #pragma alloc_text(PAGE, DiskReadFailurePredictData)
191 #pragma alloc_text(PAGE, DiskReadFailurePredictThresholds)
192 #pragma alloc_text(PAGE, DiskGetIdentifyInfo)
193 #pragma alloc_text(PAGE, DiskReadSmartLog)
194 #pragma alloc_text(PAGE, DiskWriteSmartLog)
195 
196 #pragma alloc_text(PAGE, DiskPerformSmartCommand)
197 
198 #pragma alloc_text(PAGE, DiskSendFailurePredictIoctl)
199 
200 #pragma alloc_text(PAGE, DiskReregWorker)
201 #pragma alloc_text(PAGE, DiskInitializeReregistration)
202 
203 #endif
204 
205 
206 //
207 // SMART/IDE specific routines
208 
209 //
210 // Read SMART data attributes.
211 // SrbControl should be sizeof(SRB_IO_CONTROL) +
212 // (sizeof(SENDCMDINPARAMS)-1) +
213 // READ_ATTRIBUTE_BUFFER_SIZE
214 // Attribute data returned at &SendCmdOutParams->bBuffer[0]
215 //
216 #define DiskReadSmartData(FdoExtension, \
217  SrbControl, \
218  BufferSize) \
219  DiskPerformSmartCommand(FdoExtension, \
220  IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS, \
221  SMART_CMD, \
222  READ_ATTRIBUTES, \
223  0, \
224  0, \
225  (SrbControl), \
226  (BufferSize))
227 
228 
229 //
230 // Read SMART data thresholds.
231 // SrbControl should be sizeof(SRB_IO_CONTROL) +
232 // (sizeof(SENDCMDINPARAMS)-1) +
233 // READ_THRESHOLD_BUFFER_SIZE
234 // Attribute data returned at &SendCmdOutParams->bBuffer[0]
235 //
236 #define DiskReadSmartThresholds(FdoExtension, \
237  SrbControl, \
238  BufferSize) \
239  DiskPerformSmartCommand(FdoExtension, \
240  IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS, \
241  SMART_CMD, \
242  READ_THRESHOLDS, \
243  0, \
244  0, \
245  (SrbControl), \
246  (BufferSize))
247 
248 
249 //
250 // Read SMART status
251 // SrbControl should be sizeof(SRB_IO_CONTROL) +
252 // (sizeof(SENDCMDINPARAMS)-1) +
253 // sizeof(IDEREGS)
254 // Failure predicted if cmdOutParameters[3] == 0xf4 and [4] == 0x2c
255 //
256 #define DiskReadSmartStatus(FdoExtension, \
257  SrbControl, \
258  BufferSize) \
259  DiskPerformSmartCommand(FdoExtension, \
260  IOCTL_SCSI_MINIPORT_RETURN_STATUS, \
261  SMART_CMD, \
262  RETURN_SMART_STATUS, \
263  0, \
264  0, \
265  (SrbControl), \
266  (BufferSize))
267 
268 
269 //
270 // Read disks IDENTIFY data
271 // SrbControl should be sizeof(SRB_IO_CONTROL) +
272 // (sizeof(SENDCMDINPARAMS)-1) +
273 // sizeof(IDENTIFY_BUFFER_SIZE)
274 // Identify data returned at &cmdOutParams.bBuffer[0]
275 //
276 #define DiskGetIdentifyData(FdoExtension, \
277  SrbControl, \
278  BufferSize) \
279  DiskPerformSmartCommand(FdoExtension, \
280  IOCTL_SCSI_MINIPORT_IDENTIFY, \
281  ID_CMD, \
282  0, \
283  0, \
284  0, \
285  (SrbControl), \
286  (BufferSize))
287 
288 
289 //
290 // Enable SMART
291 //
292 __inline NTSTATUS
295  )
296 {
297  UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
298  ULONG bufferSize = sizeof(srbControl);
299 
302  SMART_CMD,
303  ENABLE_SMART,
304  0,
305  0,
306  (PSRB_IO_CONTROL)srbControl,
307  &bufferSize);
308 }
309 
310 //
311 // Disable SMART
312 //
313 __inline NTSTATUS
316  )
317 {
318  UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
319  ULONG bufferSize = sizeof(srbControl);
322  SMART_CMD,
324  0,
325  0,
326  (PSRB_IO_CONTROL)srbControl,
327  &bufferSize);
328 }
329 
330 //
331 // Enable Attribute Autosave
332 //
333 __inline NTSTATUS
336  )
337 {
338  UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
339  ULONG bufferSize = sizeof(srbControl);
342  SMART_CMD,
344  0xf1,
345  0,
346  (PSRB_IO_CONTROL)srbControl,
347  &bufferSize);
348 }
349 
350 //
351 // Disable Attribute Autosave
352 //
353 __inline NTSTATUS
356  )
357 {
358  UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
359  ULONG bufferSize = sizeof(srbControl);
362  SMART_CMD,
364  0x00,
365  0,
366  (PSRB_IO_CONTROL)srbControl,
367  &bufferSize);
368 }
369 
370 //
371 // Initialize execution of SMART online diagnostics
372 //
373 __inline NTSTATUS
376  UCHAR Subcommand
377  )
378 {
379  UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)];
380  ULONG bufferSize = sizeof(srbControl);
383  SMART_CMD,
385  0,
386  Subcommand,
387  (PSRB_IO_CONTROL)srbControl,
388  &bufferSize);
389 }
390 
391 
392 NTSTATUS
393 NTAPI
397  IN UCHAR LogAddress,
399  )
400 {
401  PSRB_IO_CONTROL srbControl;
403  PSENDCMDOUTPARAMS sendCmdOutParams;
404  ULONG logSize, bufferSize;
405 
406  PAGED_CODE();
407 
409  bufferSize = sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1 +
410  logSize;
411 
412  srbControl = ExAllocatePoolWithTag(NonPagedPool,
413  bufferSize,
415 
416  if (srbControl != NULL)
417  {
420  SMART_CMD,
422  SectorCount,
423  LogAddress,
424  srbControl,
425  &bufferSize);
426 
427  if (NT_SUCCESS(status))
428  {
429  sendCmdOutParams = (PSENDCMDOUTPARAMS)((PUCHAR)srbControl +
430  sizeof(SRB_IO_CONTROL));
432  &sendCmdOutParams->bBuffer[0],
433  logSize);
434  }
435 
436  ExFreePool(srbControl);
437  } else {
439  }
440  return(status);
441 }
442 
443 
444 NTSTATUS
445 NTAPI
449  IN UCHAR LogAddress,
451  )
452 {
453  PSRB_IO_CONTROL srbControl;
455  PSENDCMDINPARAMS sendCmdInParams;
456  ULONG logSize, bufferSize;
457 
458  PAGED_CODE();
459 
461  bufferSize = sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1 +
462  logSize;
463 
464  srbControl = ExAllocatePoolWithTag(NonPagedPool,
465  bufferSize,
467 
468  if (srbControl != NULL)
469  {
470  sendCmdInParams = (PSENDCMDINPARAMS)((PUCHAR)srbControl +
471  sizeof(SRB_IO_CONTROL));
472  RtlCopyMemory(&sendCmdInParams->bBuffer[0],
473  Buffer,
474  logSize);
477  SMART_CMD,
479  SectorCount,
480  LogAddress,
481  srbControl,
482  &bufferSize);
483 
484  ExFreePool(srbControl);
485  } else {
487  }
488  return(status);
489 }
490 
491 NTSTATUS
492 NTAPI
495  IN ULONG SrbControlCode,
496  IN UCHAR Command,
497  IN UCHAR Feature,
499  IN UCHAR SectorNumber,
500  IN OUT PSRB_IO_CONTROL SrbControl,
502  )
503 /*++
504 
505 Routine Description:
506 
507  This routine will perform some SMART command
508 
509 Arguments:
510 
511  FdoExtension is the FDO device extension
512 
513  SrbControlCode is the SRB control code to use for the request
514 
515  Command is the SMART command to be executed. It may be SMART_CMD or
516  ID_CMD.
517 
518  Feature is the value to place in the IDE feature register.
519 
520  SectorCount is the value to place in the IDE SectorCount register
521 
522  SrbControl is the buffer used to build the SRB_IO_CONTROL and pass
523  any input parameters. It also returns the output parameters.
524 
525  *BufferSize on entry has total size of SrbControl and on return has
526  the size used in SrbControl.
527 
528 
529 
530 Return Value:
531 
532  status
533 
534 --*/
535 {
537  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
538  PUCHAR buffer;
539  PSENDCMDINPARAMS cmdInParameters;
540  //PSENDCMDOUTPARAMS cmdOutParameters;
541  //ULONG outBufferSize;
543  ULONG availableBufferSize;
544  KEVENT event;
545  PIRP irp;
546  IO_STATUS_BLOCK ioStatus;
547  SCSI_REQUEST_BLOCK srb;
548  LARGE_INTEGER startingOffset;
549  ULONG length;
550  PIO_STACK_LOCATION irpStack;
551 
552  PAGED_CODE();
553 
554  //
555  // Point to the 'buffer' portion of the SRB_CONTROL and compute how
556  // much room we have left in the srb control
557  //
558 
559  buffer = (PUCHAR)SrbControl;
560  buffer += sizeof(SRB_IO_CONTROL);
561 
562  cmdInParameters = (PSENDCMDINPARAMS)buffer;
563  //cmdOutParameters = (PSENDCMDOUTPARAMS)buffer;
564 
565  availableBufferSize = *BufferSize - sizeof(SRB_IO_CONTROL);
566 
567 #if DBG
568  //
569  // Ensure control codes and buffer lengths passed are correct
570  //
571  {
572  ULONG controlCode;
573  ULONG lengthNeeded = sizeof(SENDCMDINPARAMS) - 1;
574 
575  if (Command == SMART_CMD)
576  {
577  switch (Feature)
578  {
579 
580  case ENABLE_SMART:
581  {
582  controlCode = IOCTL_SCSI_MINIPORT_ENABLE_SMART;
583 
584  break;
585  }
586 
587  case DISABLE_SMART:
588  {
589  controlCode = IOCTL_SCSI_MINIPORT_DISABLE_SMART;
590  break;
591  }
592 
593  case RETURN_SMART_STATUS:
594  {
595  //
596  // Ensure bBuffer is at least 2 bytes (to hold the values of
597  // cylinderLow and cylinderHigh).
598  //
599 
600  lengthNeeded = sizeof(SENDCMDINPARAMS) - 1 + sizeof(IDEREGS);
601 
602  controlCode = IOCTL_SCSI_MINIPORT_RETURN_STATUS;
603  break;
604  }
605 
607  {
609  break;
610  }
611 
613  {
615  break;
616  }
617 
618 
620  {
622  break;
623  }
624 
625  case READ_ATTRIBUTES:
626  {
628  lengthNeeded = READ_ATTRIBUTE_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) - 1;
629  break;
630  }
631 
632  case READ_THRESHOLDS:
633  {
635  lengthNeeded = READ_THRESHOLD_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) - 1;
636  break;
637  }
638 
639  case SMART_READ_LOG:
640  {
642  lengthNeeded = (SectorCount * SMART_LOG_SECTOR_SIZE) +
643  sizeof(SENDCMDINPARAMS) - 1;
644  break;
645  }
646 
647  case SMART_WRITE_LOG:
648  {
650  lengthNeeded = (SectorCount * SMART_LOG_SECTOR_SIZE) +
651  sizeof(SENDCMDINPARAMS) - 1;
652  break;
653  }
654 
655  default:
656  controlCode = 0;
657  break;
658 
659  }
660  } else if (Command == ID_CMD) {
661  controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
662  lengthNeeded = IDENTIFY_BUFFER_SIZE + sizeof(SENDCMDOUTPARAMS) -1;
663  } else {
664  controlCode = 0;
665  ASSERT(FALSE);
666  }
667 
668  ASSERT(controlCode == SrbControlCode);
669  ASSERT(availableBufferSize >= lengthNeeded);
670  }
671 #endif
672 
673  //
674  // Build SrbControl and input to SMART command
675  //
676 
677  SrbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
678  RtlMoveMemory (SrbControl->Signature, "SCSIDISK", 8);
679  SrbControl->Timeout = FdoExtension->TimeOutValue;
680  SrbControl->Length = availableBufferSize;
681 
682  SrbControl->ControlCode = SrbControlCode;
683 
684  cmdInParameters->cBufferSize = sizeof(SENDCMDINPARAMS);
685  cmdInParameters->bDriveNumber = diskData->ScsiAddress.TargetId;
686  cmdInParameters->irDriveRegs.bFeaturesReg = Feature;
687  cmdInParameters->irDriveRegs.bSectorCountReg = SectorCount;
688  cmdInParameters->irDriveRegs.bSectorNumberReg = SectorNumber;
689  cmdInParameters->irDriveRegs.bCylLowReg = SMART_CYL_LOW;
690  cmdInParameters->irDriveRegs.bCylHighReg = SMART_CYL_HI;
691  cmdInParameters->irDriveRegs.bCommandReg = Command;
692 
693 
694  //
695  // Create and send irp
696  //
698 
699  startingOffset.QuadPart = (LONGLONG) 1;
700 
701  length = SrbControl->HeaderLength + SrbControl->Length;
702 
704  IRP_MJ_SCSI,
705  commonExtension->LowerDeviceObject,
706  SrbControl,
707  length,
708  &startingOffset,
709  &event,
710  &ioStatus);
711 
712  if (irp == NULL) {
714  }
715 
716  irpStack = IoGetNextIrpStackLocation(irp);
717 
718  //
719  // Set major and minor codes.
720  //
721 
722  irpStack->MajorFunction = IRP_MJ_SCSI;
723  irpStack->MinorFunction = 1;
724 
725  //
726  // Fill in SRB fields.
727  //
728 
729  irpStack->Parameters.Others.Argument1 = &srb;
730 
731  //
732  // Zero out the srb.
733  //
734 
735  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
736 
737  srb.PathId = diskData->ScsiAddress.PathId;
738  srb.TargetId = diskData->ScsiAddress.TargetId;
739  srb.Lun = diskData->ScsiAddress.Lun;
740 
742  srb.Length = sizeof(SCSI_REQUEST_BLOCK);
743 
744  srb.SrbFlags = FdoExtension->SrbFlags;
748 
750  srb.QueueTag = SP_UNTAGGED;
751 
752  srb.OriginalRequest = irp;
753 
754  //
755  // Set timeout to requested value.
756  //
757 
758  srb.TimeOutValue = SrbControl->Timeout;
759 
760  //
761  // Set the data buffer.
762  //
763 
764  srb.DataBuffer = SrbControl;
766 
767  //
768  // Flush the data buffer for output. This will insure that the data is
769  // written back to memory. Since the data-in flag is the the port driver
770  // will flush the data again for input which will ensure the data is not
771  // in the cache.
772  //
773 
774  KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
775 
776  //
777  // Call port driver to handle this request.
778  //
779 
780  status = IoCallDriver(commonExtension->LowerDeviceObject, irp);
781 
782  if (status == STATUS_PENDING) {
784  status = ioStatus.Status;
785  }
786 
787  return status;
788 }
789 
790 NTSTATUS
791 NTAPI
794  PBOOLEAN SupportSmart
795  )
796 {
797  UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + (sizeof(SENDCMDINPARAMS)-1) + IDENTIFY_BUFFER_SIZE];
798  ULONG outBufferSize = sizeof(outBuffer);
800 
801  PAGED_CODE();
802 
804  (PSRB_IO_CONTROL)outBuffer,
805  &outBufferSize);
806 
807  if (NT_SUCCESS(status))
808  {
809  PUSHORT identifyData = (PUSHORT)&(outBuffer[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS)-1]);
810  USHORT commandSetSupported = identifyData[82];
811 
812  *SupportSmart = ((commandSetSupported != 0xffff) &&
813  (commandSetSupported != 0) &&
814  ((commandSetSupported & 1) == 1));
815  } else {
816  *SupportSmart = FALSE;
817  }
818 
819  DebugPrint((3, "DiskGetIdentifyInfo: SMART %s supported for device %p, status %lx\n",
820  *SupportSmart ? "is" : "is not",
821  FdoExtension->DeviceObject,
822  status));
823 
824  return status;
825 }
826 
827 //
828 // FP Ioctl specific routines
829 //
830 
831 NTSTATUS
832 NTAPI
835  PSTORAGE_PREDICT_FAILURE checkFailure
836  )
837 {
838  KEVENT event;
839  PDEVICE_OBJECT deviceObject;
840  IO_STATUS_BLOCK ioStatus;
841  PIRP irp;
843 
844  PAGED_CODE();
845 
847 
848  deviceObject = IoGetAttachedDeviceReference(FdoExtension->DeviceObject);
849 
852  deviceObject,
853  NULL,
854  0,
855  checkFailure,
856  sizeof(STORAGE_PREDICT_FAILURE),
857  FALSE,
858  &event,
859  &ioStatus);
860 
861  if (irp != NULL)
862  {
863  status = IoCallDriver(deviceObject, irp);
864  if (status == STATUS_PENDING)
865  {
867  status = ioStatus.Status;
868  }
869 
870  } else {
872  }
873 
874  ObDereferenceObject(deviceObject);
875 
876  return status;
877 }
878 
879 //
880 // FP type independent routines
881 //
882 
883 NTSTATUS
884 NTAPI
888  )
889 /*++
890 
891 Routine Description:
892 
893  Enable or disable failure prediction at the hardware level
894 
895 Arguments:
896 
897  FdoExtension
898 
899  Enable
900 
901 Return Value:
902 
903  NT Status
904 
905 --*/
906 {
908  PCOMMON_DEVICE_EXTENSION commonExtension = &(FdoExtension->CommonExtension);
909  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
910 
911  PAGED_CODE();
912 
913  switch(diskData->FailurePredictionCapability)
914  {
916  {
917 
918  if (Enable)
919  {
921  } else {
923  }
924 
925  break;
926  }
927 
930  {
931  //
932  // We assume that the drive is already setup properly for
933  // failure prediction
934  //
936  break;
937  }
938 
939  default:
940  {
942  }
943  }
944  return status;
945 }
946 
947 NTSTATUS
948 NTAPI
951  BOOLEAN Enable,
952  ULONG PollTimeInSeconds
953  )
954 /*++
955 
956 Routine Description:
957 
958  Enable or disable polling for hardware failure detection
959 
960 Arguments:
961 
962  FdoExtension
963 
964  Enable
965 
966  PollTimeInSeconds - if 0 then no change to current polling timer
967 
968 Return Value:
969 
970  NT Status
971 
972 --*/
973 {
976  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
977 
978  PAGED_CODE();
979 
980  if (Enable)
981  {
983  Enable);
984  } else {
986  }
987 
988  if (NT_SUCCESS(status))
989  {
991  Enable ? diskData->FailurePredictionCapability :
993  PollTimeInSeconds);
994 
995  //
996  // Even if this failed we do not want to disable FP on the
997  // hardware. FP is only ever disabled on the hardware by
998  // specific command of the user.
999  //
1000  }
1001 
1002  return status;
1003 }
1004 
1005 NTSTATUS
1006 NTAPI
1009  PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus
1010  )
1011 /*++
1012 
1013 Routine Description:
1014 
1015  Obtains current failure prediction status
1016 
1017 Arguments:
1018 
1019  FdoExtension
1020 
1021  DiskSmartStatus
1022 
1023 Return Value:
1024 
1025  NT Status
1026 
1027 --*/
1028 {
1030  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1031  NTSTATUS status;
1032 
1033  PAGED_CODE();
1034 
1035  DiskSmartStatus->PredictFailure = FALSE;
1036 
1037  switch(diskData->FailurePredictionCapability)
1038  {
1040  {
1041  UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + (sizeof(SENDCMDINPARAMS) - 1 + sizeof(IDEREGS))];
1042  ULONG outBufferSize = sizeof(outBuffer);
1043  PSENDCMDOUTPARAMS cmdOutParameters;
1044 
1046  (PSRB_IO_CONTROL)outBuffer,
1047  &outBufferSize);
1048 
1049  if (NT_SUCCESS(status))
1050  {
1051  cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1052  sizeof(SRB_IO_CONTROL));
1053 
1054  DiskSmartStatus->Reason = 0; // Unknown;
1055  DiskSmartStatus->PredictFailure = ((((PUCHAR)cmdOutParameters->bBuffer)[3] == 0xf4) &&
1056  (((PUCHAR)cmdOutParameters->bBuffer)[4] == 0x2c));
1057  }
1058  break;
1059  }
1060 
1062  {
1063  DiskSmartStatus->Reason = FdoExtension->FailureReason;
1064  DiskSmartStatus->PredictFailure = FdoExtension->FailurePredicted;
1066  break;
1067  }
1068 
1070  case FailurePredictionNone:
1071  default:
1072  {
1074  break;
1075  }
1076  }
1077 
1078  return status;
1079 }
1080 
1081 NTSTATUS
1082 NTAPI
1085  PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData
1086  )
1087 /*++
1088 
1089 Routine Description:
1090 
1091  Obtains current failure prediction data. Not available for
1092  FAILURE_PREDICT_SENSE types.
1093 
1094 Arguments:
1095 
1096  FdoExtension
1097 
1098  DiskSmartData
1099 
1100 Return Value:
1101 
1102  NT Status
1103 
1104 --*/
1105 {
1107  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1108  NTSTATUS status;
1109 
1110  PAGED_CODE();
1111 
1112  switch(diskData->FailurePredictionCapability)
1113  {
1115  {
1116  PUCHAR outBuffer;
1117  ULONG outBufferSize;
1118  PSENDCMDOUTPARAMS cmdOutParameters;
1119 
1120  outBufferSize = sizeof(SRB_IO_CONTROL) +
1121  (sizeof(SENDCMDOUTPARAMS)-1) +
1123 
1124  outBuffer = ExAllocatePoolWithTag(NonPagedPool,
1125  outBufferSize,
1126  DISK_TAG_SMART);
1127 
1128  if (outBuffer != NULL)
1129  {
1131  (PSRB_IO_CONTROL)outBuffer,
1132  &outBufferSize);
1133 
1134  if (NT_SUCCESS(status))
1135  {
1136  cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1137  sizeof(SRB_IO_CONTROL));
1138 
1139  DiskSmartData->Length = READ_ATTRIBUTE_BUFFER_SIZE;
1140  RtlCopyMemory(DiskSmartData->VendorSpecific,
1141  cmdOutParameters->bBuffer,
1143  }
1144  ExFreePool(outBuffer);
1145  } else {
1147  }
1148 
1149  break;
1150  }
1151 
1153  {
1154  DiskSmartData->Length = sizeof(ULONG);
1155  *((PULONG)DiskSmartData->VendorSpecific) = FdoExtension->FailureReason;
1156 
1158  break;
1159  }
1160 
1162  case FailurePredictionNone:
1163  default:
1164  {
1166  break;
1167  }
1168  }
1169 
1170  return status;
1171 }
1172 
1173 NTSTATUS
1174 NTAPI
1177  PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
1178  )
1179 /*++
1180 
1181 Routine Description:
1182 
1183  Obtains current failure prediction thresholds. Not available for
1184  FAILURE_PREDICT_SENSE types.
1185 
1186 Arguments:
1187 
1188  FdoExtension
1189 
1190  DiskSmartData
1191 
1192 Return Value:
1193 
1194  NT Status
1195 
1196 --*/
1197 {
1199  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1200  NTSTATUS status;
1201 
1202  PAGED_CODE();
1203 
1204  switch(diskData->FailurePredictionCapability)
1205  {
1207  {
1208  PUCHAR outBuffer;
1209  PSENDCMDOUTPARAMS cmdOutParameters;
1210  ULONG outBufferSize;
1211 
1212  outBufferSize = sizeof(SRB_IO_CONTROL) +
1213  (sizeof(SENDCMDOUTPARAMS)-1) +
1215 
1216  outBuffer = ExAllocatePoolWithTag(NonPagedPool,
1217  outBufferSize,
1218  DISK_TAG_SMART);
1219 
1220  if (outBuffer != NULL)
1221  {
1223  (PSRB_IO_CONTROL)outBuffer,
1224  &outBufferSize);
1225 
1226  if (NT_SUCCESS(status))
1227  {
1228  cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1229  sizeof(SRB_IO_CONTROL));
1230 
1231  RtlCopyMemory(DiskSmartThresholds->VendorSpecific,
1232  cmdOutParameters->bBuffer,
1234  }
1235  ExFreePool(outBuffer);
1236  } else {
1238  }
1239 
1240  break;
1241  }
1242 
1245  case FailurePredictionNone:
1246  default:
1247  {
1249  break;
1250  }
1251  }
1252 
1253  return status;
1254 }
1255 
1257  IN PVOID Context
1258  )
1259 {
1260  PDISKREREGREQUEST reregRequest;
1261  NTSTATUS status;
1262  PDEVICE_OBJECT deviceObject;
1263  PIRP irp;
1264 
1265  PAGED_CODE();
1266 
1267  do
1268  {
1270  &DiskReregHead,
1272 
1273  deviceObject = reregRequest->DeviceObject;
1274  irp = reregRequest->Irp;
1275 
1276  status = IoWMIRegistrationControl(deviceObject,
1278 
1279  if (! NT_SUCCESS(status))
1280  {
1281  DebugPrint((1, "DiskReregWorker: Reregistration failed %x\n",
1282  status));
1283  }
1284 
1285  //
1286  // Release remove lock and free irp, now that we are done
1287  // processing this
1288  //
1289  ClassReleaseRemoveLock(deviceObject, irp);
1290 
1291  IoFreeMdl(irp->MdlAddress);
1292  IoFreeIrp(irp);
1293 
1294  ExFreePool(reregRequest);
1295 
1297 
1298 
1299 }
1300 
1302  void
1303  )
1304 {
1305  PAGED_CODE();
1306 
1307  //
1308  // Initialize the global work item and spinlock used to manage the
1309  // list of disks reregistering their guids
1310  //
1313  NULL );
1314 
1316 
1317  return(STATUS_SUCCESS);
1318 }
1319 
1322  PIRP Irp
1323  )
1324 {
1325  PDISKREREGREQUEST reregRequest;
1326  NTSTATUS status;
1327 
1328  reregRequest = ExAllocatePoolWithTag(NonPagedPool,
1329  sizeof(DISKREREGREQUEST),
1330  DISK_TAG_SMART);
1331 
1332  if (reregRequest != NULL)
1333  {
1334  //
1335  // add the disk that needs reregistration to the stack of disks
1336  // to reregister. If the list is transitioning from empty to
1337  // non empty then also kick off the work item so that the
1338  // reregistration worker can do the reregister.
1339  //
1340  reregRequest->DeviceObject = DeviceObject;
1341  reregRequest->Irp = Irp;
1343  &DiskReregHead,
1344  &reregRequest->Next,
1346 
1348  {
1350  }
1352  } else {
1353  DebugPrint((1, "DiskPostReregisterRequest: could not allocate reregRequest for %p\n",
1354  DeviceObject));
1356  }
1357 
1358  return(status);
1359 }
1360 
1363  PIRP Irp,
1364  PVOID Context
1365  )
1366 {
1369  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1373  NTSTATUS status;
1374  BOOLEAN retry;
1375  ULONG retryInterval;
1376  ULONG srbStatus;
1377  BOOLEAN freeLockAndIrp = TRUE;
1378  //KIRQL oldIrql;
1379 
1380  ASSERT(fdoExtension->CommonExtension.IsFdo);
1381 
1382  srbStatus = SRB_STATUS(srb->SrbStatus);
1383 
1384  //
1385  // Check SRB status for success of completing request.
1386  // SRB_STATUS_DATA_OVERRUN also indicates success.
1387  //
1388  if ((srbStatus != SRB_STATUS_SUCCESS) &&
1389  (srbStatus != SRB_STATUS_DATA_OVERRUN))
1390  {
1391  DebugPrint((2, "DiskInfoExceptionComplete: IRP %p, SRB %p\n", Irp, srb));
1392 
1393  retry = ClassInterpretSenseInfo(
1394  DeviceObject,
1395  srb,
1396  irpStack->MajorFunction,
1397  0,
1398  MAXIMUM_RETRIES -
1399  ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4),
1400  &status,
1401  &retryInterval);
1402 
1403  //
1404  // If the status is verified required and the this request
1405  // should bypass verify required then retry the request.
1406  //
1407 
1408  if (TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME) &&
1410  {
1412  retry = TRUE;
1413  }
1414 
1415  if (retry && irpStack->Parameters.Others.Argument4)
1416  {
1417  irpStack->Parameters.Others.Argument4 =
1418  (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4 - 1);
1419 
1420  //
1421  // Retry request.
1422  //
1423 
1424  DebugPrint((1, "DiskInfoExceptionComplete: Retry request %p\n", Irp));
1425 
1426  ASSERT(srb->DataBuffer == MmGetMdlVirtualAddress(Irp->MdlAddress));
1427 
1428  //
1429  // Reset byte count of transfer in SRB Extension.
1430  //
1431  srb->DataTransferLength = Irp->MdlAddress->ByteCount;
1432 
1433  //
1434  // Zero SRB statuses.
1435  //
1436 
1437  srb->SrbStatus = srb->ScsiStatus = 0;
1438 
1439  //
1440  // Set the no disconnect flag, disable synchronous data transfers and
1441  // disable tagged queuing. This fixes some errors.
1442  //
1443 
1447 
1449  srb->QueueTag = SP_UNTAGGED;
1450 
1451  //
1452  // Set up major SCSI function.
1453  //
1454 
1455  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
1456 
1457  //
1458  // Save SRB address in next stack for port driver.
1459  //
1460 
1461  nextIrpStack->Parameters.Scsi.Srb = srb;
1462 
1463 
1466  srb,
1467  TRUE, TRUE, TRUE);
1468 
1469  (VOID)IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1470 
1472  }
1473 
1474  } else {
1475 
1476  //
1477  // Get the results from the mode sense
1478  //
1479  PMODE_INFO_EXCEPTIONS pageData;
1480  PMODE_PARAMETER_HEADER modeData;
1481  ULONG modeDataLength;
1482 
1483  modeData = srb->DataBuffer;
1484  modeDataLength = srb->DataTransferLength;
1485 
1486  pageData = ClassFindModePage((PUCHAR) modeData,
1487  modeDataLength,
1489  TRUE);
1490  if (pageData != NULL)
1491  {
1492  DebugPrint((1, "DiskInfoExceptionComplete: %p supports SMART\n",
1493  DeviceObject));
1494 
1495  if (pageData->Dexcpt == 0)
1496  {
1499 
1500  if (NT_SUCCESS(status))
1501  {
1502  //
1503  // Make sure we won't free the remove lock and the irp
1504  // since we need to keep these until after the work
1505  // item has completed running
1506  //
1507  freeLockAndIrp = FALSE;
1508  }
1509  } else {
1510  DebugPrint((1, "DiskInfoExceptionComplete: %p is not enabled for SMART\n",
1511  DeviceObject));
1512 
1513  }
1514 
1515  } else {
1516  DebugPrint((1, "DiskInfoExceptionComplete: %p does not supports SMART\n",
1517  DeviceObject));
1518 
1519  }
1520 
1521  //
1522  // Set status for successful request
1523  //
1524 
1526 
1527  } // end if (SRB_STATUS(srb->SrbStatus) == SRB_STATUS_SUCCESS)
1528 
1529  //
1530  // Free the srb
1531  //
1533  ExFreePool(srb->DataBuffer);
1534  ExFreePool(srb);
1535 
1536  if (freeLockAndIrp)
1537  {
1538  //
1539  // Set status in completing IRP.
1540  //
1541 
1542  Irp->IoStatus.Status = status;
1543 
1544  //
1545  // If pending has be returned for this irp then mark the current stack as
1546  // pending.
1547  //
1548 
1549  if (Irp->PendingReturned) {
1551  }
1552 
1554  IoFreeMdl(Irp->MdlAddress);
1555  IoFreeIrp(Irp);
1556  }
1557 
1559 
1560 }
1561 
1564  )
1565 {
1566  PUCHAR modeData;
1567  PSCSI_REQUEST_BLOCK srb;
1568  PCDB cdb;
1569  PIRP irp;
1570  PIO_STACK_LOCATION irpStack;
1571  PVOID senseInfoBuffer;
1572  ULONG isRemoved;
1573 
1577  if (modeData == NULL)
1578  {
1579  DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate mode data "
1580  "buffer\n"));
1582  }
1583 
1586  DISK_TAG_SRB);
1587  if (srb == NULL)
1588  {
1589  ExFreePool(modeData);
1590  DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate srb "
1591  "buffer\n"));
1593  }
1594 
1595  //
1596  // Build the MODE SENSE CDB.
1597  //
1599 
1600  cdb = (PCDB)srb->Cdb;
1601  srb->CdbLength = 6;
1602  cdb = (PCDB)srb->Cdb;
1603 
1604  //
1605  // Set timeout value from device extension.
1606  //
1607  srb->TimeOutValue = FdoExtension->TimeOutValue;
1608 
1609  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
1610  cdb->MODE_SENSE.PageCode = MODE_PAGE_FAULT_REPORTING;
1611  cdb->MODE_SENSE.AllocationLength = MODE_DATA_SIZE;
1612 
1613  //
1614  // Write length to SRB.
1615  //
1617 
1618  //
1619  // Set SCSI bus address.
1620  //
1621 
1623 
1624  //
1625  // Enable auto request sense.
1626  //
1627 
1629 
1630  //
1631  // Sense buffer is in aligned nonpaged pool.
1632  //
1633 
1636  '7CcS');
1637 
1638  if (senseInfoBuffer == NULL)
1639  {
1640  ExFreePool(srb);
1641  ExFreePool(modeData);
1642  DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate request sense "
1643  "buffer\n"));
1645  }
1646 
1647  srb->SenseInfoBuffer = senseInfoBuffer;
1648  srb->DataBuffer = modeData;
1649 
1650  srb->SrbFlags = FdoExtension->SrbFlags;
1651 
1652 
1654 
1655  //
1656  // Disable synchronous transfer for these requests.
1657  //
1659 
1660  //
1661  // Don't freeze the queue on an error
1662  //
1664 
1666  srb->QueueTag = SP_UNTAGGED;
1667 
1668 
1669  //
1670  // Build device I/O control request with METHOD_NEITHER data transfer.
1671  // We'll queue a completion routine to cleanup the MDL's and such ourself.
1672  //
1673 
1674  irp = IoAllocateIrp(
1675  (CCHAR) (FdoExtension->CommonExtension.LowerDeviceObject->StackSize + 1),
1676  FALSE);
1677 
1678  if (irp == NULL)
1679  {
1680  ExFreePool(senseInfoBuffer);
1681  ExFreePool(srb);
1682  ExFreePool(modeData);
1683  DebugPrint((1, "DiskInfoExceptionCheck: Can't allocate Irp\n"));
1685  }
1686 
1687  isRemoved = ClassAcquireRemoveLock(FdoExtension->DeviceObject, irp);
1688 
1689  if (isRemoved)
1690  {
1691  ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
1692  IoFreeIrp(irp);
1693  ExFreePool(senseInfoBuffer);
1694  ExFreePool(srb);
1695  ExFreePool(modeData);
1696  DebugPrint((1, "DiskInfoExceptionCheck: RemoveLock says isRemoved\n"));
1698  }
1699 
1700  //
1701  // Get next stack location.
1702  //
1703 
1705  irpStack = IoGetCurrentIrpStackLocation(irp);
1706  irpStack->DeviceObject = FdoExtension->DeviceObject;
1707 
1708  //
1709  // Save retry count in current Irp stack.
1710  //
1711  irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
1712 
1713 
1714  irpStack = IoGetNextIrpStackLocation(irp);
1715 
1716  //
1717  // Set up SRB for execute scsi request. Save SRB address in next stack
1718  // for the port driver.
1719  //
1720 
1721  irpStack->MajorFunction = IRP_MJ_SCSI;
1722  irpStack->Parameters.Scsi.Srb = srb;
1723 
1726  srb,
1727  TRUE,
1728  TRUE,
1729  TRUE);
1730 
1731  irp->MdlAddress = IoAllocateMdl( modeData,
1733  FALSE,
1734  FALSE,
1735  irp );
1736  if (irp->MdlAddress == NULL)
1737  {
1738  ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
1739  ExFreePool(srb);
1740  ExFreePool(modeData);
1741  ExFreePool(senseInfoBuffer);
1742  IoFreeIrp( irp );
1743  DebugPrint((1, "DiskINfoExceptionCheck: Can't allocate MDL\n"));
1745  }
1746 
1747  MmBuildMdlForNonPagedPool(irp->MdlAddress);
1748 
1749  //
1750  // Set the transfer length.
1751  //
1753 
1754  //
1755  // Zero out status.
1756  //
1757  srb->ScsiStatus = srb->SrbStatus = 0;
1758  srb->NextSrb = 0;
1759 
1760  //
1761  // Set up IRP Address.
1762  //
1763  srb->OriginalRequest = irp;
1764 
1765  //
1766  // Call the port driver with the request and wait for it to complete.
1767  //
1768 
1769  IoMarkIrpPending(irp);
1770  IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject,
1771  irp);
1772 
1773  return(STATUS_PENDING);
1774 }
1775 
1776 NTSTATUS
1777 NTAPI
1780  PFAILURE_PREDICTION_METHOD FailurePredictCapability
1781  )
1782 /*++
1783 
1784 Routine Description:
1785 
1786  Detect if device has any failure prediction capabilities. First we
1787  check for IDE SMART capability. This is done by sending the drive an
1788  IDENTIFY command and checking if the SMART command set bit is set.
1789 
1790  Next we check if SCSI SMART (aka Information Exception Control Page,
1791  X3T10/94-190 Rev 4). This is done by querying for the Information
1792  Exception mode page.
1793 
1794  Lastly we check if the device has IOCTL failure prediction. This mechanism
1795  a filter driver implements IOCTL_STORAGE_PREDICT_FAILURE and will respond
1796  with the information in the IOCTL. We do this by sending the ioctl and
1797  if the status returned is STATUS_SUCCESS we assume that it is supported.
1798 
1799 Arguments:
1800 
1801  FdoExtension
1802 
1803  *FailurePredictCapability
1804 
1805 Return Value:
1806 
1807  NT Status
1808 
1809 --*/
1810 {
1812  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1813  BOOLEAN supportFP;
1814  NTSTATUS status;
1815  STORAGE_PREDICT_FAILURE checkFailure;
1816  STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
1817  //BOOLEAN logErr;
1818 
1819  PAGED_CODE();
1820 
1821  //
1822  // Assume no failure predict mechanisms
1823  //
1824  *FailurePredictCapability = FailurePredictionNone;
1825 
1826  //
1827  // See if this is an IDE drive that supports SMART. If so enable SMART
1828  // and then ensure that it supports the SMART READ STATUS command
1829  //
1831  &supportFP);
1832 
1833  if (supportFP)
1834  {
1836  if (NT_SUCCESS(status))
1837  {
1838  *FailurePredictCapability = FailurePredictionSmart;
1839 
1841  &diskSmartStatus);
1842 
1843  DebugPrint((1, "Disk: Device %p %s IDE SMART\n",
1844  FdoExtension->DeviceObject,
1845  NT_SUCCESS(status) ? "does" : "does not"));
1846 
1847  if (! NT_SUCCESS(status))
1848  {
1849  *FailurePredictCapability = FailurePredictionNone;
1850  }
1851  }
1852  return(status);
1853  }
1854 
1855  //
1856  // See if there is a a filter driver to intercept
1857  // IOCTL_STORAGE_PREDICT_FAILURE
1858  //
1860  &checkFailure);
1861 
1862  DebugPrint((1, "Disk: Device %p %s IOCTL_STORAGE_FAILURE_PREDICT\n",
1863  FdoExtension->DeviceObject,
1864  NT_SUCCESS(status) ? "does" : "does not"));
1865 
1866  if (NT_SUCCESS(status))
1867  {
1868  *FailurePredictCapability = FailurePredictionIoctl;
1869  if (checkFailure.PredictFailure)
1870  {
1871  checkFailure.PredictFailure = 512;
1873  (PUCHAR)&checkFailure,
1874  sizeof(checkFailure),
1875  (BOOLEAN)(FdoExtension->FailurePredicted == FALSE),
1876  0x11,
1877  diskData->ScsiAddress.PathId,
1878  diskData->ScsiAddress.TargetId,
1879  diskData->ScsiAddress.Lun);
1880 
1881  FdoExtension->FailurePredicted = TRUE;
1882  }
1883  return(status);
1884  }
1885 
1886  //
1887  // Finally we assume it will not be a scsi smart drive. but
1888  // we'll also send off an asynchronous mode sense so that if
1889  // it is SMART we'll reregister the device object
1890  //
1891 
1893 
1894  *FailurePredictCapability = FailurePredictionNone;
1895 
1896  return(STATUS_SUCCESS);
1897 }
1898 
1899 NTSTATUS
1900 NTAPI
1903  IN PIRP Irp,
1904  IN ULONG GuidIndex,
1906  IN BOOLEAN Enable
1907  )
1908 /*++
1909 
1910 Routine Description:
1911 
1912  This routine is a callback into the driver to enabled or disable event
1913  generation or data block collection. A device should only expect a
1914  single enable when the first event or data consumer enables events or
1915  data collection and a single disable when the last event or data
1916  consumer disables events or data collection. Data blocks will only
1917  receive collection enable/disable if they were registered as requiring
1918  it.
1919 
1920 
1921  When NT boots, failure prediction is not automatically enabled, although
1922  it may have been persistently enabled on a previous boot. Polling is also
1923  not automatically enabled. When the first data block that accesses SMART
1924  such as SmartStatusGuid, SmartDataGuid, SmartPerformFunction, or
1925  SmartEventGuid is accessed then SMART is automatically enabled in the
1926  hardware. Polling is enabled when SmartEventGuid is enabled and disabled
1927  when it is disabled. Hardware SMART is only disabled when the DisableSmart
1928  method is called. Polling is also disabled when this is called regardless
1929  of the status of the other guids or events.
1930 
1931 Arguments:
1932 
1933  DeviceObject is the device whose data block is being queried
1934 
1935  GuidIndex is the index into the list of guids provided when the
1936  device registered
1937 
1938  Function specifies which functionality is being enabled or disabled
1939 
1940  Enable is TRUE then the function is being enabled else disabled
1941 
1942 Return Value:
1943 
1944  status
1945 
1946 --*/
1947 {
1949  //PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
1951  //PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1952  //ULONG enableCount;
1953 
1954  PAGED_CODE();
1955 
1956  if ((Function == DataBlockCollection) && Enable)
1957  {
1958  if ((GuidIndex == SmartStatusGuid) ||
1959  (GuidIndex == SmartDataGuid) ||
1962  {
1964  TRUE);
1965  DebugPrint((3, "Disk: DeviceObject %p, Irp %p Enable -> %lx\n",
1966  DeviceObject,
1967  Irp,
1968  status));
1969 
1970  } else {
1971  DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Collection\n",
1972  DeviceObject, Irp,
1973  GuidIndex,
1974  Enable ? "Enabled" : "Disabled")); }
1975  } else if (Function == EventGeneration) {
1976  DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Event Generation\n",
1977  DeviceObject, Irp,
1978  GuidIndex,
1979  Enable ? "Enabled" : "Disabled"));
1980 
1981 
1982  if ((GuidIndex == SmartEventGuid) && Enable)
1983  {
1985  Enable,
1986  0);
1987  DebugPrint((3, "Disk: DeviceObject %p, Irp %p %s -> %lx\n",
1988  DeviceObject,
1989  Irp,
1990  Enable ? "DiskEnableSmartPolling" : "DiskDisableSmartPolling",
1991  status));
1992  }
1993 
1994 #if DBG
1995  } else {
1996  DebugPrint((3, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for function %d\n",
1997  DeviceObject, Irp,
1998  GuidIndex,
1999  Enable ? "Enabled" : "Disabled",
2000  Function));
2001 #endif
2002  }
2003 
2005  Irp,
2006  status,
2007  0,
2008  IO_NO_INCREMENT);
2009  return status;
2010 }
2011 
2012 NTSTATUS
2013 NTAPI
2016  OUT ULONG *RegFlags,
2018  )
2019 /*++
2020 
2021 Routine Description:
2022 
2023  This routine is a callback into the driver to retrieve the list of
2024  guids or data blocks that the driver wants to register with WMI. This
2025  routine may not pend or block. Driver should NOT call
2026  ClassWmiCompleteRequest.
2027 
2028 Arguments:
2029 
2030  DeviceObject is the device whose data block is being queried
2031 
2032  *RegFlags returns with a set of flags that describe the guids being
2033  registered for this device. If the device wants enable and disable
2034  collection callbacks before receiving queries for the registered
2035  guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
2036  returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
2037  the instance name is determined from the PDO associated with the
2038  device object. Note that the PDO must have an associated devnode. If
2039  WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
2040  name for the device.
2041 
2042  InstanceName returns with the instance name for the guids if
2043  WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
2044  caller will call ExFreePool with the buffer returned.
2045 
2046 
2047 Return Value:
2048 
2049  status
2050 
2051 --*/
2052 {
2053  //PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2055  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2056  //NTSTATUS status;
2057 
2058  PAGED_CODE();
2059 
2062 
2063  switch (diskData->FailurePredictionCapability)
2064  {
2066  {
2068  //
2069  // Fall Through
2070  //
2071  }
2073  {
2078 
2079  break;
2080  }
2081 
2083  {
2089  break;
2090  }
2091 
2092 
2093  default:
2094  {
2099  break;
2100  }
2101  }
2102 
2103  //
2104  // Use devnode for FDOs
2106 
2107  return STATUS_SUCCESS;
2108 }
2109 
2110 NTSTATUS
2111 NTAPI
2114  OUT ULONG *RegFlags,
2116  OUT PUNICODE_STRING MofName
2117  )
2118 /*++
2119 
2120 Routine Description:
2121 
2122  This routine is a callback into the driver to retrieve the list of
2123  guids or data blocks that the driver wants to register with WMI. This
2124  routine may not pend or block. Driver should NOT call
2125  ClassWmiCompleteRequest.
2126 
2127 Arguments:
2128 
2129  DeviceObject is the device whose data block is being queried
2130 
2131  *RegFlags returns with a set of flags that describe the guids being
2132  registered for this device. If the device wants enable and disable
2133  collection callbacks before receiving queries for the registered
2134  guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
2135  returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
2136  the instance name is determined from the PDO associated with the
2137  device object. Note that the PDO must have an associated devnode. If
2138  WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
2139  name for the device.
2140 
2141  InstanceName returns with the instance name for the guids if
2142  WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
2143  caller will call ExFreePool with the buffer returned.
2144 
2145  MofName returns initialized with the mof resource name for the
2146  binary mof resource attached to the driver's image file. If the
2147  driver does not have a mof resource then it should leave this
2148  parameter untouched.
2149 
2150 Return Value:
2151 
2152  status
2153 
2154 --*/
2155 {
2156  NTSTATUS status;
2157 
2159  RegFlags,
2160  InstanceName);
2161 
2162  //
2163  // Leave MofName alone since disk doesn't have one
2164  //
2165  return(status);
2166 }
2167 
2168 NTSTATUS
2169 NTAPI
2172  IN PIRP Irp,
2173  IN ULONG GuidIndex,
2175  OUT PUCHAR Buffer
2176  )
2177 /*++
2178 
2179 Routine Description:
2180 
2181  This routine is a callback into the driver to query for the contents of
2182  a data block. When the driver has finished filling the data block it
2183  must call ClassWmiCompleteRequest to complete the irp. The driver can
2184  return STATUS_PENDING if the irp cannot be completed immediately.
2185 
2186 Arguments:
2187 
2188  DeviceObject is the device whose data block is being queried
2189 
2190  Irp is the Irp that makes this request
2191 
2192  GuidIndex is the index into the list of guids provided when the
2193  device registered
2194 
2195  BufferAvail on has the maximum size available to write the data
2196  block.
2197 
2198  Buffer on return is filled with the returned data block
2199 
2200 
2201 Return Value:
2202 
2203  status
2204 
2205 --*/
2206 {
2207  NTSTATUS status;
2210  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2211  ULONG sizeNeeded;
2212 
2213  PAGED_CODE();
2214 
2215  DebugPrint((3, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2216  " BufferAvail %lx Buffer %lx\n",
2217  DeviceObject, Irp,
2219 
2220  switch (GuidIndex)
2221  {
2222  case DiskGeometryGuid:
2223  {
2224  sizeNeeded = sizeof(DISK_GEOMETRY);
2225  if (BufferAvail >= sizeNeeded)
2226  {
2227  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
2228  {
2229  //
2230  // Issue ReadCapacity to update device extension
2231  // with information for current media.
2232  status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
2233 
2234  //
2235  // Note whether the drive is ready.
2236  diskData->ReadyStatus = status;
2237 
2238  if (!NT_SUCCESS(status))
2239  {
2240  break;
2241  }
2242  }
2243 
2244  //
2245  // Copy drive geometry information from device extension.
2247  &(fdoExtension->DiskGeometry),
2248  sizeof(DISK_GEOMETRY));
2249 
2251  } else {
2253  }
2254  break;
2255  }
2256 
2257  case SmartStatusGuid:
2258  {
2259  PSTORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
2260 
2262 
2263 
2264  sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_STATUS);
2265  if (BufferAvail >= sizeNeeded)
2266  {
2267  STORAGE_PREDICT_FAILURE checkFailure;
2268 
2269  diskSmartStatus = (PSTORAGE_FAILURE_PREDICT_STATUS)Buffer;
2270 
2271  status = DiskSendFailurePredictIoctl(fdoExtension,
2272  &checkFailure);
2273 
2274  if (NT_SUCCESS(status))
2275  {
2276  if (diskData->FailurePredictionCapability ==
2278  {
2279  diskSmartStatus->Reason = *((PULONG)checkFailure.VendorSpecific);
2280  } else {
2281  diskSmartStatus->Reason = 0; // unknown
2282  }
2283 
2284  diskSmartStatus->PredictFailure = (checkFailure.PredictFailure != 0);
2285  }
2286  } else {
2288  }
2289  break;
2290  }
2291 
2292  case SmartDataGuid:
2293  {
2294  PSTORAGE_FAILURE_PREDICT_DATA diskSmartData;
2295 
2296  ASSERT((diskData->FailurePredictionCapability ==
2298  (diskData->FailurePredictionCapability ==
2300 
2301  sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_DATA);
2302  if (BufferAvail >= sizeNeeded)
2303  {
2305 
2306  diskSmartData = (PSTORAGE_FAILURE_PREDICT_DATA)Buffer;
2307 
2308  status = DiskSendFailurePredictIoctl(fdoExtension,
2309  checkFailure);
2310 
2311  if (NT_SUCCESS(status))
2312  {
2313  diskSmartData->Length = 512;
2314  }
2315  } else {
2317  }
2318 
2319  break;
2320  }
2321 
2322  case SmartThresholdsGuid:
2323  {
2324  PSTORAGE_FAILURE_PREDICT_THRESHOLDS diskSmartThresholds;
2325 
2326  ASSERT((diskData->FailurePredictionCapability ==
2328 
2329  sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_THRESHOLDS);
2330  if (BufferAvail >= sizeNeeded)
2331  {
2332  diskSmartThresholds = (PSTORAGE_FAILURE_PREDICT_THRESHOLDS)Buffer;
2334  diskSmartThresholds);
2335  } else {
2337  }
2338 
2339  break;
2340  }
2341 
2342  case SmartPerformFunction:
2343  {
2344  sizeNeeded = 0;
2346  break;
2347  }
2348 
2350  {
2351  PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2352  MODE_INFO_EXCEPTIONS modeInfo;
2353 
2354  ASSERT((diskData->FailurePredictionCapability ==
2356 
2357  sizeNeeded = sizeof(STORAGE_SCSI_INFO_EXCEPTIONS);
2358  if (BufferAvail >= sizeNeeded)
2359  {
2360  infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2361  status = DiskGetInfoExceptionInformation(fdoExtension,
2362  &modeInfo);
2363 
2364  if (NT_SUCCESS(status))
2365  {
2366  infoExceptions->PageSavable = modeInfo.PSBit;
2367  infoExceptions->Flags = modeInfo.Flags;
2368  infoExceptions->MRIE = modeInfo.ReportMethod;
2369  infoExceptions->Padding = 0;
2370  REVERSE_BYTES(&infoExceptions->IntervalTimer,
2371  &modeInfo.IntervalTimer);
2372  REVERSE_BYTES(&infoExceptions->ReportCount,
2373  &modeInfo.ReportCount)
2374  }
2375  } else {
2377  }
2378 
2379  break;
2380  }
2381 
2382  default:
2383  {
2384  sizeNeeded = 0;
2386  }
2387  }
2388  DebugPrint((3, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
2389  DeviceObject, Irp, status));
2390 
2392  Irp,
2393  status,
2394  sizeNeeded,
2395  IO_NO_INCREMENT);
2396 
2397  return status;
2398 }
2399 
2400 NTSTATUS
2401 NTAPI
2404  IN PIRP Irp,
2405  IN ULONG GuidIndex,
2407  IN PUCHAR Buffer
2408  )
2409 /*++
2410 
2411 Routine Description:
2412 
2413  This routine is a callback into the driver to query for the contents of
2414  a data block. When the driver has finished filling the data block it
2415  must call ClassWmiCompleteRequest to complete the irp. The driver can
2416  return STATUS_PENDING if the irp cannot be completed immediately.
2417 
2418 Arguments:
2419 
2420  DeviceObject is the device whose data block is being queried
2421 
2422  Irp is the Irp that makes this request
2423 
2424  GuidIndex is the index into the list of guids provided when the
2425  device registered
2426 
2427  BufferSize has the size of the data block passed
2428 
2429  Buffer has the new values for the data block
2430 
2431 
2432 Return Value:
2433 
2434  status
2435 
2436 --*/
2437 {
2438  NTSTATUS status;
2441  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2442 
2443  PAGED_CODE();
2444 
2445  DebugPrint((3, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2446  " BufferSize %#x Buffer %p\n",
2447  DeviceObject, Irp,
2449 
2451  {
2452  PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2453  MODE_INFO_EXCEPTIONS modeInfo;
2454 
2456  {
2457  infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2458 
2460  modeInfo.PageLength = sizeof(MODE_INFO_EXCEPTIONS) - 2;
2461 
2462  modeInfo.PSBit = 0;
2463  modeInfo.Flags = infoExceptions->Flags;
2464 
2465  modeInfo.ReportMethod = infoExceptions->MRIE;
2466 
2467  REVERSE_BYTES(&modeInfo.IntervalTimer[0],
2468  &infoExceptions->IntervalTimer);
2469 
2470  REVERSE_BYTES(&modeInfo.ReportCount[0],
2471  &infoExceptions->ReportCount);
2472 
2473  if (modeInfo.Perf == 1)
2474  {
2475  diskData->AllowFPPerfHit = FALSE;
2476  } else {
2477  diskData->AllowFPPerfHit = TRUE;
2478  }
2479 
2480  status = DiskSetInfoExceptionInformation(fdoExtension,
2481  &modeInfo);
2482  } else {
2484  }
2485 
2486  } else if (GuidIndex <= SmartEventGuid)
2487  {
2489  } else {
2491  }
2492 
2493  DebugPrint((3, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
2494  DeviceObject, Irp, status));
2495 
2497  Irp,
2498  status,
2499  0,
2500  IO_NO_INCREMENT);
2501 
2502  return status;
2503 }
2504 
2505 NTSTATUS
2506 NTAPI
2509  IN PIRP Irp,
2510  IN ULONG GuidIndex,
2513  IN PUCHAR Buffer
2514  )
2515 /*++
2516 
2517 Routine Description:
2518 
2519  This routine is a callback into the driver to query for the contents of
2520  a data block. When the driver has finished filling the data block it
2521  must call ClassWmiCompleteRequest to complete the irp. The driver can
2522  return STATUS_PENDING if the irp cannot be completed immediately.
2523 
2524 Arguments:
2525 
2526  DeviceObject is the device whose data block is being queried
2527 
2528  Irp is the Irp that makes this request
2529 
2530  GuidIndex is the index into the list of guids provided when the
2531  device registered
2532 
2533  DataItemId has the id of the data item being set
2534 
2535  BufferSize has the size of the data item passed
2536 
2537  Buffer has the new values for the data item
2538 
2539 
2540 Return Value:
2541 
2542  status
2543 
2544 --*/
2545 {
2546  NTSTATUS status;
2547 
2548  PAGED_CODE();
2549 
2550  DebugPrint((3, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
2551  " BufferSize %#x Buffer %p\n",
2552  DeviceObject, Irp,
2554 
2555  if (GuidIndex <= SmartEventGuid)
2556  {
2558  } else {
2560  }
2561 
2562  DebugPrint((3, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
2563  DeviceObject, Irp, status));
2564 
2566  Irp,
2567  status,
2568  0,
2569  IO_NO_INCREMENT);
2570 
2571  return status;
2572 }
2573 
2574 NTSTATUS
2575 NTAPI
2578  IN PIRP Irp,
2579  IN ULONG GuidIndex,
2580  IN ULONG MethodId,
2583  IN PUCHAR Buffer
2584  )
2585 /*++
2586 
2587 Routine Description:
2588 
2589  This routine is a callback into the driver to execute a method. When the
2590  driver has finished filling the data block it must call
2591  ClassWmiCompleteRequest to complete the irp. The driver can
2592  return STATUS_PENDING if the irp cannot be completed immediately.
2593 
2594 Arguments:
2595 
2596  DeviceObject is the device whose data block is being queried
2597 
2598  Irp is the Irp that makes this request
2599 
2600  GuidIndex is the index into the list of guids provided when the
2601  device registered
2602 
2603  MethodId has the id of the method being called
2604 
2605  InBufferSize has the size of the data block passed in as the input to
2606  the method.
2607 
2608  OutBufferSize on entry has the maximum size available to write the
2609  returned data block.
2610 
2611  Buffer is filled with the returned data block
2612 
2613 
2614 Return Value:
2615 
2616  status
2617 
2618 --*/
2619 {
2622  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2623  ULONG sizeNeeded;
2624  NTSTATUS status;
2625 
2626  PAGED_CODE();
2627 
2628  DebugPrint((3, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
2629  " InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
2630  DeviceObject, Irp,
2632 
2633  switch(GuidIndex)
2634  {
2635  case SmartPerformFunction:
2636  {
2637 
2638  ASSERT((diskData->FailurePredictionCapability ==
2640  (diskData->FailurePredictionCapability ==
2642  (diskData->FailurePredictionCapability ==
2644 
2645 
2646  switch(MethodId)
2647  {
2648  //
2649  // void AllowPerformanceHit([in] boolean Allow)
2650  //
2652  {
2653  BOOLEAN allowPerfHit;
2654 
2655  sizeNeeded = 0;
2656  if (InBufferSize >= sizeof(BOOLEAN))
2657  {
2659 
2660  allowPerfHit = *((PBOOLEAN)Buffer);
2661  if (diskData->AllowFPPerfHit != allowPerfHit)
2662  {
2663  diskData->AllowFPPerfHit = allowPerfHit;
2664  if (diskData->FailurePredictionCapability ==
2666  {
2667  MODE_INFO_EXCEPTIONS modeInfo;
2668 
2669  status = DiskGetInfoExceptionInformation(fdoExtension,
2670  &modeInfo);
2671  if (NT_SUCCESS(status))
2672  {
2673  modeInfo.Perf = allowPerfHit ? 0 : 1;
2674  status = DiskSetInfoExceptionInformation(fdoExtension,
2675  &modeInfo);
2676  }
2677  }
2678  }
2679 
2680  DebugPrint((3, "DiskFdoWmiExecuteMethod: AllowPerformanceHit %x for device %p --> %lx\n",
2681  allowPerfHit,
2682  fdoExtension->DeviceObject,
2683  status));
2684  } else {
2686  }
2687  break;
2688  }
2689 
2690  //
2691  // void EnableDisableHardwareFailurePrediction([in] boolean Enable)
2692  //
2694  {
2695  BOOLEAN enable;
2696 
2697  sizeNeeded = 0;
2698  if (InBufferSize >= sizeof(BOOLEAN))
2699  {
2701  enable = *((PBOOLEAN)Buffer);
2702  if (! enable)
2703  {
2704  //
2705  // If we are disabling we need to also disable
2706  // polling
2707  //
2709  fdoExtension,
2710  enable,
2711  0);
2712  }
2713 
2715  fdoExtension,
2716  enable);
2717 
2718  DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableDisableHardwareFailurePrediction: %x for device %p --> %lx\n",
2719  enable,
2720  fdoExtension->DeviceObject,
2721  status));
2722  } else {
2724  }
2725  break;
2726  }
2727 
2728  //
2729  // void EnableDisableFailurePredictionPolling(
2730  // [in] uint32 Period,
2731  // [in] boolean Enable)
2732  //
2734  {
2735  BOOLEAN enable;
2736  ULONG period;
2737 
2738  sizeNeeded = 0;
2739  if (InBufferSize >= (sizeof(ULONG) + sizeof(BOOLEAN)))
2740  {
2741  period = *((PULONG)Buffer);
2742  Buffer += sizeof(ULONG);
2743  enable = *((PBOOLEAN)Buffer);
2744 
2746  fdoExtension,
2747  enable,
2748  period);
2749 
2750  DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableDisableFailurePredictionPolling: %x %x for device %p --> %lx\n",
2751  enable,
2752  period,
2753  fdoExtension->DeviceObject,
2754  status));
2755  } else {
2757  }
2758  break;
2759  }
2760 
2761  //
2762  // void GetFailurePredictionCapability([out] uint32 Capability)
2763  //
2765  {
2766  sizeNeeded = sizeof(ULONG);
2767  if (OutBufferSize >= sizeNeeded)
2768  {
2771  DebugPrint((3, "DiskFdoWmiExecuteMethod: GetFailurePredictionCapability: %x for device %p --> %lx\n",
2773  fdoExtension->DeviceObject,
2774  status));
2775  } else {
2777  }
2778  break;
2779  }
2780 
2781  //
2782  // void EnableOfflineDiags([out] boolean Success);
2783  //
2784  case EnableOfflineDiags:
2785  {
2786  sizeNeeded = sizeof(BOOLEAN);
2787  if (OutBufferSize >= sizeNeeded)
2788  {
2789  if (diskData->FailurePredictionCapability ==
2791  {
2792  //
2793  // Initiate or resume offline diagnostics.
2794  // This may cause a loss of performance
2795  // to the disk, but mayincrease the amount
2796  // of disk checking.
2797  //
2798  status = DiskExecuteSmartDiagnostics(fdoExtension,
2799  0);
2800 
2801  } else {
2803  }
2804 
2806 
2807  DebugPrint((3, "DiskFdoWmiExecuteMethod: EnableOfflineDiags for device %p --> %lx\n",
2808  fdoExtension->DeviceObject,
2809  status));
2810  } else {
2812  }
2813  break;
2814  }
2815 
2816  //
2817  // void ReadLogSectors([in] uint8 LogAddress,
2818  // [in] uint8 SectorCount,
2819  // [out] uint32 Length,
2820  // [out, WmiSizeIs("Length")] uint8 LogSectors[]
2821  // );
2822  //
2823  case ReadLogSectors:
2824  {
2825  sizeNeeded = 0;
2826  if (diskData->FailurePredictionCapability ==
2828  {
2829  if (InBufferSize >= sizeof(READ_LOG_SECTORS_IN))
2830  {
2831  PREAD_LOG_SECTORS_IN inParams;
2832  PREAD_LOG_SECTORS_OUT outParams;
2833  ULONG readSize;
2834 
2835  inParams = (PREAD_LOG_SECTORS_IN)Buffer;
2836  readSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
2837  sizeNeeded = FIELD_OFFSET(READ_LOG_SECTORS_OUT,
2838  LogSectors) + readSize;
2839 
2840  if (OutBufferSize >= sizeNeeded)
2841  {
2842  outParams = (PREAD_LOG_SECTORS_OUT)Buffer;
2843  status = DiskReadSmartLog(fdoExtension,
2844  inParams->SectorCount,
2845  inParams->LogAddress,
2846  outParams->LogSectors);
2847 
2848  if (NT_SUCCESS(status))
2849  {
2850  outParams->Length = readSize;
2851  } else {
2852  //
2853  // SMART command failure is
2854  // indicated by successful
2855  // execution, but no data returned
2856  //
2857  outParams->Length = 0;
2859  }
2860  } else {
2862  }
2863 
2864  } else {
2866  }
2867  } else {
2869  }
2870  break;
2871  }
2872 
2873  // void WriteLogSectors([in] uint8 LogAddress,
2874  // [in] uint8 SectorCount,
2875  // [in] uint32 Length,
2876  // [in, WmiSizeIs("Length")] uint8 LogSectors[],
2877  // [out] boolean Success
2878  // );
2879  case WriteLogSectors:
2880  {
2881  sizeNeeded = 0;
2882  if (diskData->FailurePredictionCapability ==
2884  {
2886  LogSectors))
2887  {
2888  PWRITE_LOG_SECTORS_IN inParams;
2889  PWRITE_LOG_SECTORS_OUT outParams;
2890  ULONG writeSize;
2891 
2892  inParams = (PWRITE_LOG_SECTORS_IN)Buffer;
2893  writeSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
2895  LogSectors) +
2896  writeSize))
2897  {
2898  sizeNeeded = sizeof(WRITE_LOG_SECTORS_OUT);
2899 
2900  if (OutBufferSize >= sizeNeeded)
2901  {
2902  outParams = (PWRITE_LOG_SECTORS_OUT)Buffer;
2903  status = DiskWriteSmartLog(fdoExtension,
2904  inParams->SectorCount,
2905  inParams->LogAddress,
2906  inParams->LogSectors);
2907 
2908  if (NT_SUCCESS(status))
2909  {
2910  outParams->Success = TRUE;
2911  } else {
2912  outParams->Success = FALSE;
2914  }
2915  } else {
2917  }
2918  } else {
2920  }
2921  } else {
2923  }
2924  } else {
2926  }
2927  break;
2928  }
2929 
2930  // void ExecuteSelfTest([in] uint8 Subcommand,
2931  // [out,
2932  // Values{"0", "1", "2"},
2933  // ValueMap{"Successful Completion",
2934  // "Captive Mode Required",
2935  // "Unsuccessful Completion"}
2936  // ]
2937  // uint32 ReturnCode);
2938  case ExecuteSelfTest:
2939  {
2940  sizeNeeded = 0;
2941  if (diskData->FailurePredictionCapability ==
2943  {
2944  if (InBufferSize >= sizeof(EXECUTE_SELF_TEST_IN))
2945  {
2946  sizeNeeded = sizeof(EXECUTE_SELF_TEST_OUT);
2947  if (OutBufferSize >= sizeNeeded)
2948  {
2949  PEXECUTE_SELF_TEST_IN inParam;
2950  PEXECUTE_SELF_TEST_OUT outParam;
2951 
2952  inParam = (PEXECUTE_SELF_TEST_IN)Buffer;
2953  outParam = (PEXECUTE_SELF_TEST_OUT)Buffer;
2954 
2955  if (DiskIsValidSmartSelfTest(inParam->Subcommand))
2956  {
2957  status = DiskExecuteSmartDiagnostics(fdoExtension,
2958  inParam->Subcommand);
2959  if (NT_SUCCESS(status))
2960  {
2961  //
2962  // Return self test executed
2963  // without a problem
2964  //
2965  outParam->ReturnCode = 0;
2966  } else {
2967  //
2968  // Return Self test execution
2969  // failed status
2970  //
2971  outParam->ReturnCode = 2;
2973  }
2974  } else {
2975  //
2976  // If self test subcommand requires
2977  // captive mode then return that
2978  // status
2979  //
2980  outParam->ReturnCode = 1;
2982  }
2983 
2984  } else {
2986  }
2987 
2988  } else {
2990  }
2991  } else {
2993  }
2994 
2995  break;
2996  }
2997 
2998  default :
2999  {
3000  sizeNeeded = 0;
3002  break;
3003  }
3004  }
3005 
3006  break;
3007  }
3008 
3009  case DiskGeometryGuid:
3010  case SmartStatusGuid:
3011  case SmartDataGuid:
3012  {
3013 
3014  sizeNeeded = 0;
3016  break;
3017  }
3018 
3019  default:
3020  {
3021  sizeNeeded = 0;
3023  }
3024  }
3025 
3026  DebugPrint((3, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
3027  DeviceObject, Irp, status));
3028 
3030  Irp,
3031  status,
3032  sizeNeeded,
3033  IO_NO_INCREMENT);
3034 
3035  return status;
3036 }
3037 
3038 #if 0
3039 //
3040 // Enable this to add WMI support for PDOs
3041 NTSTATUS
3042 NTAPI
3045  OUT ULONG *RegFlags,
3047  )
3048 /*++
3049 
3050 Routine Description:
3051 
3052  This routine is a callback into the driver to retrieve the list of
3053  guids or data blocks that the driver wants to register with WMI. This
3054  routine may not pend or block. Driver should NOT call
3055  ClassWmiCompleteRequest.
3056 
3057 Arguments:
3058 
3059  DeviceObject is the device whose data block is being queried
3060 
3061  *RegFlags returns with a set of flags that describe the guids being
3062  registered for this device. If the device wants enable and disable
3063  collection callbacks before receiving queries for the registered
3064  guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
3065  returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
3066  the instance name is determined from the PDO associated with the
3067  device object. Note that the PDO must have an associated devnode. If
3068  WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
3069  name for the device.
3070 
3071  InstanceName returns with the instance name for the guids if
3072  WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
3073  caller will call ExFreePool with the buffer returned.
3074 
3075 
3076 Return Value:
3077 
3078  status
3079 
3080 --*/
3081 {
3083  PFUNCTIONAL_DEVICE_EXTENSION parentFunctionalExtension;
3084  ANSI_STRING ansiString;
3085  CHAR name[256];
3086  NTSTATUS status;
3087 
3088  //
3089  // We need to pick a name for PDOs since they do not have a devnode
3090  parentFunctionalExtension = commonExtension->PartitionZeroExtension;
3091  sprintf(name,
3092  "Disk(%d)_Partition(%d)_Start(%#I64x)_Length(%#I64x)",
3093  parentFunctionalExtension->DeviceNumber,
3094  commonExtension->PartitionNumber,
3095  commonExtension->StartingOffset.QuadPart,
3096  commonExtension->PartitionLength.QuadPart);
3097  RtlInitAnsiString(&ansiString,
3098  name);
3099 
3101  &ansiString,
3102  TRUE);
3103 
3104  return status;
3105 }
3106 
3107 NTSTATUS
3108 NTAPI
3111  IN PIRP Irp,
3112  IN ULONG GuidIndex,
3114  OUT PUCHAR Buffer
3115  )
3116 /*++
3117 
3118 Routine Description:
3119 
3120  This routine is a callback into the driver to query for the contents of
3121  a data block. When the driver has finished filling the data block it
3122  must call ClassWmiCompleteRequest to complete the irp. The driver can
3123  return STATUS_PENDING if the irp cannot be completed immediately.
3124 
3125 Arguments:
3126 
3127  DeviceObject is the device whose data block is being queried
3128 
3129  Irp is the Irp that makes this request
3130 
3131  GuidIndex is the index into the list of guids provided when the
3132  device registered
3133 
3134  BufferAvail on has the maximum size available to write the data
3135  block.
3136 
3137  Buffer on return is filled with the returned data block
3138 
3139 
3140 Return Value:
3141 
3142  status
3143 
3144 --*/
3145 {
3146  NTSTATUS status;
3148  PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3149  ULONG sizeNeeded;
3150 
3151  DebugPrint((3, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
3152  " BufferAvail %#x Buffer %p\n",
3153  DeviceObject, Irp,
3155 
3156  switch (GuidIndex)
3157  {
3158  case 0:
3159  {
3160  sizeNeeded = 4 * sizeof(ULONG);
3161  if (BufferAvail >= sizeNeeded)
3162  {
3163  RtlCopyMemory(Buffer, DiskDummyData, sizeNeeded);
3165  } else {
3167  }
3168  break;
3169  }
3170 
3171  default:
3172  {
3174  }
3175  }
3176 
3177  DebugPrint((3, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
3178  DeviceObject, Irp, status));
3179 
3181  Irp,
3182  status,
3183  sizeNeeded,
3184  IO_NO_INCREMENT);
3185 
3186  return status;
3187 }
3188 
3189 NTSTATUS
3190 NTAPI
3193  IN PIRP Irp,
3194  IN ULONG GuidIndex,
3196  IN PUCHAR Buffer
3197  )
3198 /*++
3199 
3200 Routine Description:
3201 
3202  This routine is a callback into the driver to query for the contents of
3203  a data block. When the driver has finished filling the data block it
3204  must call ClassWmiCompleteRequest to complete the irp. The driver can
3205  return STATUS_PENDING if the irp cannot be completed immediately.
3206 
3207 Arguments:
3208 
3209  DeviceObject is the device whose data block is being queried
3210 
3211  Irp is the Irp that makes this request
3212 
3213  GuidIndex is the index into the list of guids provided when the
3214  device registered
3215 
3216  BufferSize has the size of the data block passed
3217 
3218  Buffer has the new values for the data block
3219 
3220 
3221 Return Value:
3222 
3223  status
3224 
3225 --*/
3226 {
3227  NTSTATUS status;
3229  ULONG sizeNeeded;
3230 
3231  DebugPrint((3, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
3232  " BufferSize %#x Buffer %p\n",
3233  DeviceObject, Irp,
3235 
3236  switch(GuidIndex)
3237  {
3238  case 0:
3239  {
3240  sizeNeeded = 4 * sizeof(ULONG);
3241  if (BufferSize == sizeNeeded)
3242  {
3243  RtlCopyMemory(DiskDummyData, Buffer, sizeNeeded);
3245  } else {
3247  }
3248  break;
3249  }
3250 
3251  default:
3252  {
3254  }
3255  }
3256 
3257  DebugPrint((3, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
3258  DeviceObject, Irp, status));
3259 
3261  Irp,
3262  status,
3263  0,
3264  IO_NO_INCREMENT);
3265 
3266  return status;
3267 }
3268 
3269 NTSTATUS
3270 NTAPI
3273  IN PIRP Irp,
3274  IN ULONG GuidIndex,
3277  IN PUCHAR Buffer
3278  )
3279 /*++
3280 
3281 Routine Description:
3282 
3283  This routine is a callback into the driver to query for the contents of
3284  a data block. When the driver has finished filling the data block it
3285  must call ClassWmiCompleteRequest to complete the irp. The driver can
3286  return STATUS_PENDING if the irp cannot be completed immediately.
3287 
3288 Arguments:
3289 
3290  DeviceObject is the device whose data block is being queried
3291 
3292  Irp is the Irp that makes this request
3293 
3294  GuidIndex is the index into the list of guids provided when the
3295  device registered
3296 
3297  DataItemId has the id of the data item being set
3298 
3299  BufferSize has the size of the data item passed
3300 
3301  Buffer has the new values for the data item
3302 
3303 
3304 Return Value:
3305 
3306  status
3307 
3308 --*/
3309 {
3310  NTSTATUS status;
3311 
3312  DebugPrint((3, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
3313  " BufferSize %#x Buffer %p\n",
3314  DeviceObject, Irp,
3316 
3317  switch(GuidIndex)
3318  {
3319  case 0:
3320  {
3321  if ((BufferSize == sizeof(ULONG)) &&
3322  (DataItemId <= 3))
3323  {
3324  DiskDummyData[DataItemId] = *((PULONG)Buffer);
3326  } else {
3328  }
3329  break;
3330  }
3331 
3332  default:
3333  {
3335  }
3336  }
3337 
3338 
3339  DebugPrint((3, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
3340  DeviceObject, Irp, status));
3341 
3343  Irp,
3344  status,
3345  0,
3346  IO_NO_INCREMENT);
3347 
3348  return status;
3349 }
3350 
3351 NTSTATUS
3352 NTAPI
3355  IN PIRP Irp,
3356  IN ULONG GuidIndex,
3357  IN ULONG MethodId,
3360  IN PUCHAR Buffer
3361  )
3362 /*++
3363 
3364 Routine Description:
3365 
3366  This routine is a callback into the driver to execute a method. When the
3367  driver has finished filling the data block it must call
3368  ClassWmiCompleteRequest to complete the irp. The driver can
3369  return STATUS_PENDING if the irp cannot be completed immediately.
3370 
3371 Arguments:
3372 
3373  DeviceObject is the device whose data block is being queried
3374 
3375  Irp is the Irp that makes this request
3376 
3377  GuidIndex is the index into the list of guids provided when the
3378  device registered
3379 
3380  MethodId has the id of the method being called
3381 
3382  InBufferSize has the size of the data block passed in as the input to
3383  the method.
3384 
3385  OutBufferSize on entry has the maximum size available to write the
3386  returned data block.
3387 
3388  Buffer is filled with the returned data block
3389 
3390 
3391 Return Value:
3392 
3393  status
3394 
3395 --*/
3396 {
3397  ULONG sizeNeeded = 4 * sizeof(ULONG);
3398  NTSTATUS status;
3399  ULONG tempData[4];
3400 
3401  DebugPrint((3, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
3402  " InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
3403  DeviceObject, Irp,
3405 
3406  switch(GuidIndex)
3407  {
3408  case 0:
3409  {
3410  if (MethodId == 1)
3411  {
3412  if (OutBufferSize >= sizeNeeded)
3413  {
3414 
3415  if (InBufferSize == sizeNeeded)
3416  {
3417  RtlCopyMemory(tempData, Buffer, sizeNeeded);
3418  RtlCopyMemory(Buffer, DiskDummyData, sizeNeeded);
3419  RtlCopyMemory(DiskDummyData, tempData, sizeNeeded);
3420 
3422  } else {
3424  }
3425  } else {
3427  }
3428  } else {
3430  }
3431  break;
3432  }
3433 
3434  default:
3435  {
3437  }
3438  }
3439 
3440  DebugPrint((3, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
3441  DeviceObject, Irp, status));
3442 
3444  Irp,
3445  status,
3446  0,
3447  IO_NO_INCREMENT);
3448 
3449  return status;
3450 }
3451 #endif
UCHAR PathId
Definition: scsi_port.h:149
NTSTATUS NTAPI DiskInitializeReregistration(void)
Definition: diskwmi.c:1301
ULONG cBufferSize
Definition: helper.h:31
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS STORAGE_FAILURE_PREDICT_THRESHOLDS
KSPIN_LOCK DiskReregSpinlock
Definition: diskwmi.c:93
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:414
LARGE_INTEGER PartitionLength
Definition: classpnp.h:594
#define SMART_LOG_SECTOR_SIZE
Definition: ntdddisk.h:614
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:217
#define DiskReadSmartThresholds(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:236
struct _DISK_DATA * PDISK_DATA
#define IN
Definition: typedefs.h:38
UCHAR IntervalTimer[4]
Definition: scsi.h:2444
struct _STORAGE_SCSI_INFO_EXCEPTIONS * PSTORAGE_SCSI_INFO_EXCEPTIONS
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS NTAPI DiskReadSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, OUT PUCHAR Buffer)
Definition: diskwmi.c:394
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define WriteLogSectors
Definition: wmidata.h:3387
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:97
ULONG SrbFlags
Definition: srb.h:252
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
UCHAR bSectorNumberReg
Definition: helper.h:11
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:762
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
UCHAR bBuffer[1]
Definition: helper.h:36
struct _STORAGE_FAILURE_PREDICT_DATA STORAGE_FAILURE_PREDICT_DATA
Definition: ntbasedef.h:635
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
VOID NTAPI ClassNotifyFailurePredicted(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PUCHAR Buffer, ULONG BufferSize, BOOLEAN LogError, ULONG UniqueErrorValue, UCHAR PathId, UCHAR TargetId, UCHAR Lun)
Definition: autorun.c:3468
#define MmGetMdlVirtualAddress(_Mdl)
PIRP NTAPI IoBuildSynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:1069
#define TEST_FLAG(Flags, Bit)
Definition: classpnp.h:156
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:704
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIRP _In_ ULONG _In_ ULONG DataItemId
Definition: classpnp.h:419
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PVOID DataBuffer
Definition: srb.h:255
#define SMART_CYL_LOW
Definition: ntdddisk.h:559
#define SmartEventGuid
Definition: diskwmi.c:156
__inline NTSTATUS DiskDisableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:314
unsigned char * PUCHAR
Definition: retypes.h:3
NTSTATUS ReadyStatus
Definition: disk.h:222
char CHAR
Definition: xmlstorage.h:175
ULONG DataTransferLength
Definition: srb.h:253
PDEVICE_OBJECT DeviceObject
Definition: disk.h:346
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
#define DiskReadSmartStatus(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:256
#define ENABLE_DISABLE_AUTOSAVE
Definition: ntdddisk.h:626
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:575
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:695
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPushEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PSINGLE_LIST_ENTRY ListEntry, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:227
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:140
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:2707
#define WMIREG_FLAG_EVENT_ONLY_GUID
Definition: wmistr.h:75
SCSI_ADDRESS ScsiAddress
Definition: disk.h:236
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG OutBufferSize
Definition: classpnp.h:429
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
NTSTATUS NTAPI DiskPdoQueryWmiRegInfo(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName)
struct _STORAGE_FAILURE_PREDICT_STATUS STORAGE_FAILURE_PREDICT_STATUS
UCHAR CdbLength
Definition: srb.h:250
GLuint buffer
Definition: glext.h:5915
struct _STORAGE_FAILURE_PREDICT_DATA * PSTORAGE_FAILURE_PREDICT_DATA
GUIDREGINFO DiskWmiFdoGuidList[]
Definition: diskwmi.c:96
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:612
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS * PSTORAGE_FAILURE_PREDICT_THRESHOLDS
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
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)
Definition: diskwmi.c:493
#define DISABLE_SMART
Definition: ntdddisk.h:632
Definition: shell.h:41
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
UCHAR QueueAction
Definition: srb.h:249
struct _WRITE_LOG_SECTORS_OUT * PWRITE_LOG_SECTORS_OUT
#define STATUS_WMI_READ_ONLY
Definition: ntstatus.h:804
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define WMI_STORAGE_FAILURE_PREDICT_DATA_GUID
Definition: wmidata.h:332
ULONG TimeOutValue
Definition: srb.h:254
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR SrbStatus
Definition: srb.h:243
UCHAR bSectorCountReg
Definition: helper.h:10
#define DiskGeometryGuid
Definition: diskwmi.c:146
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
NTSTATUS NTAPI DiskFdoQueryWmiRegInfo(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName)
Definition: diskwmi.c:2014
LONG DiskReregWorkItems
Definition: diskwmi.c:94
BOOLEAN AllowFPPerfHit
Definition: disk.h:258
#define ENABLE_SMART
Definition: ntdddisk.h:631
#define PAGED_CODE()
Definition: video.h:57
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
struct _STORAGE_FAILURE_PREDICT_STATUS * PSTORAGE_FAILURE_PREDICT_STATUS
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
NTSTATUS NTAPI DiskDetectFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability)
Definition: diskwmi.c:1778
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define SP_UNTAGGED
Definition: srb.h:225
#define IRP_MJ_SCSI
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:49
NTSTATUS NTAPI DiskFdoQueryWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferAvail, OUT PUCHAR Buffer)
Definition: diskwmi.c:2170
struct _SENDCMDINPARAMS SENDCMDINPARAMS
void NTAPI DiskReregWorker(IN PVOID Context)
Definition: diskwmi.c:1256
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
NTSTATUS NTAPI DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:885
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
struct _EXECUTE_SELF_TEST_OUT * PEXECUTE_SELF_TEST_OUT
static LPOVERLAPPED_COMPLETION_ROUTINE Function
Definition: sync.c:684
long LONG
Definition: pedump.c:60
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
UCHAR ScsiStatus
Definition: srb.h:244
#define CLEAR_FLAG(Flags, Bit)
Definition: classpnp.h:155
NTSTATUS NTAPI DiskSendFailurePredictIoctl(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_PREDICT_FAILURE checkFailure)
Definition: diskwmi.c:833
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
#define ScsiInfoExceptionsGuid
Definition: diskwmi.c:158
NTSTATUS NTAPI DiskFdoQueryWmiRegInfoEx(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING MofName)
Definition: diskwmi.c:2112
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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)
Definition: diskwmi.c:2576
unsigned char BOOLEAN
_Out_ ULONG * RegFlags
Definition: classpnp.h:386
smooth NULL
Definition: ftsmooth.c:416
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
union _CDB * PCDB
#define WMI_STORAGE_FAILURE_PREDICT_STATUS_GUID
Definition: wmidata.h:334
_In_ PIRP _In_ ULONG GuidIndex
Definition: classpnp.h:401
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1779
#define WMIREG_FLAG_INSTANCE_PDO
Definition: wmistr.h:69
#define WMI_STORAGE_FAILURE_PREDICT_THRESHOLDS_GUID
Definition: wmidata.h:335
Definition: bufpool.h:45
PVOID NTAPI ClassFindModePage(IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode, IN BOOLEAN Use6Byte)
Definition: class.c:4209
#define READ_THRESHOLD_BUFFER_SIZE
Definition: ntdddisk.h:613
#define ReadLogSectors
Definition: wmidata.h:3374
void * PVOID
Definition: retypes.h:9
UCHAR QueueTag
Definition: srb.h:248
UCHAR TargetId
Definition: srb.h:246
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:633
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:611
NTSTATUS NTAPI DiskWmiFunctionControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN CLASSENABLEDISABLEFUNCTION Function, IN BOOLEAN Enable)
Definition: diskwmi.c:1901
#define ExecuteSelfTest
Definition: wmidata.h:3407
#define MAXIMUM_RETRIES
Definition: class2.h:14
struct _EXECUTE_SELF_TEST_IN * PEXECUTE_SELF_TEST_IN
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1405
#define EXECUTE_OFFLINE_DIAGS
Definition: ntdddisk.h:628
NTSTATUS NTAPI IoWMIRegistrationControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG Action)
Definition: wmi.c:68
struct _CDB::_MODE_SENSE MODE_SENSE
LARGE_INTEGER StartingOffset
Definition: classpnp.h:595
_In_ PIRP _In_ ULONG _In_ ULONG MethodId
Definition: classpnp.h:429
int64_t LONGLONG
Definition: typedefs.h:66
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPopEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:201
NTSTATUS NTAPI DiskFdoSetWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferSize, IN PUCHAR Buffer)
Definition: diskwmi.c:2402
#define ID_CMD
Definition: helper.h:20
#define READ_THRESHOLDS
Definition: ntdddisk.h:625
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
_In_ PIRP _In_ ULONG _In_ ULONG _In_ ULONG InBufferSize
Definition: classpnp.h:429
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:627
GUIDREGINFO DiskWmiPdoGuidList[]
IDEREGS irDriveRegs
Definition: helper.h:32
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
GUID DiskPredictFailureEventGuid
Definition: diskwmi.c:144
#define WMIREG_FLAG_REMOVE_GUID
Definition: wmistr.h:70
char CCHAR
Definition: typedefs.h:50
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:860
struct Command Command
#define DiskIsValidSmartSelfTest(Subcommand)
Definition: disk.h:533
UCHAR Function
Definition: srb.h:242
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
NTSTATUS NTAPI DiskPdoSetWmiDataItem(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer)
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
struct _EXECUTE_SELF_TEST_OUT EXECUTE_SELF_TEST_OUT
UCHAR bCommandReg
Definition: helper.h:15
NTSTATUS NTAPI DiskEnableDisableFailurePredictPolling(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
Definition: diskwmi.c:949
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
enum FAILURE_PREDICTION_METHOD * PFAILURE_PREDICTION_METHOD
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define BufferSize
Definition: classpnp.h:419
BOOLEAN NTAPI ClassInterpretSenseInfo(IN PDEVICE_OBJECT Fdo, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status, OUT OPTIONAL ULONG *RetryInterval)
Definition: class.c:2994
NTSTATUS NTAPI DiskGetIdentifyInfo(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PBOOLEAN SupportSmart)
Definition: diskwmi.c:792
#define SRB_FLAGS_NO_KEEP_AWAKE
Definition: srb.h:404
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2866
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
USHORT Length
Definition: srb.h:241
#define SmartStatusGuid
Definition: diskwmi.c:147
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
#define READ_ATTRIBUTES
Definition: ntdddisk.h:624
NTSTATUS NTAPI DiskWriteSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, IN PUCHAR Buffer)
Definition: diskwmi.c:446
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define WMI_STORAGE_FAILURE_PREDICT_FUNCTION_GUID
Definition: wmidata.h:333
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:693
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG
Definition: scsi.h:1420
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSTATUS NTAPI DiskFdoSetWmiDataItem(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG DataItemId, IN ULONG BufferSize, IN PUCHAR Buffer)
Definition: diskwmi.c:2507
char * PBOOLEAN
Definition: retypes.h:11
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)
#define EnableDisableFailurePredictionPolling
Definition: diskwmi.c:152
#define InterlockedDecrement
Definition: armddk.h:52
SINGLE_LIST_ENTRY Next
Definition: disk.h:345
CLASSENABLEDISABLEFUNCTION
Definition: classpnp.h:224
#define EnableDisableHardwareFailurePrediction
Definition: diskwmi.c:151
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:309
UCHAR bCylLowReg
Definition: helper.h:12
#define SmartThresholdsGuid
Definition: diskwmi.c:157
#define VOID
Definition: acefi.h:82
NTSTATUS NTAPI DiskReadFailurePredictData(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
Definition: diskwmi.c:1083
NTSTATUS NTAPI ClassSetFailurePredictionPoll(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, FAILURE_PREDICTION_METHOD FailurePredictionMethod, ULONG PollingPeriod)
Definition: autorun.c:3552
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:257
struct _STORAGE_SCSI_INFO_EXCEPTIONS STORAGE_SCSI_INFO_EXCEPTIONS
_In_ PIRP _In_ ULONG _In_ ULONG BufferAvail
Definition: classpnp.h:401
NTSTATUS NTAPI DiskPdoQueryWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferAvail, OUT PUCHAR Buffer)
NTSTATUS NTAPI DiskReadFailurePredictThresholds(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds)
Definition: diskwmi.c:1175
__inline NTSTATUS DiskEnableSmartAttributeAutosave(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:334
struct _cl_event * event
Definition: glext.h:7739
NTSTATUS NTAPI DiskPostReregisterRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: diskwmi.c:1320
ULONG SectorCount
Definition: part_xbox.c:32
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2647
#define DISK_TAG_SMART
Definition: disk.h:48
#define WMIREG_ACTION_UPDATE_GUIDS
#define SET_FLAG(Flags, Bit)
Definition: classpnp.h:154
SINGLE_LIST_ENTRY DiskReregHead
Definition: diskwmi.c:92
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SMART_CMD
Definition: helper.h:21
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
UCHAR bFeaturesReg
Definition: helper.h:9
#define SMART_CYL_HI
Definition: ntdddisk.h:560
SCSIPORTAPI NTSTATUS NTAPI ClassWmiCompleteRequest(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status, IN ULONG BufferUsed, IN CCHAR PriorityBoost)
Definition: classwmi.c:559
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__inline NTSTATUS DiskDisableSmartAttributeAutosave(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:354
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR SenseInfoBufferLength
Definition: srb.h:251
UCHAR VendorSpecific[512]
Definition: ntddstor.h:409
#define AllowDisallowPerformanceHit
Definition: diskwmi.c:150
struct _DISK_GEOMETRY DISK_GEOMETRY
struct _READ_LOG_SECTORS_IN * PREAD_LOG_SECTORS_IN
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:135
#define WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID
Definition: wmidata.h:336
GLboolean enable
Definition: glext.h:11120
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:161
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
__inline NTSTATUS DiskExecuteSmartDiagnostics(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, UCHAR Subcommand)
Definition: diskwmi.c:374
#define InterlockedIncrement
Definition: armddk.h:53
UCHAR PathId
Definition: srb.h:245
unsigned short USHORT
Definition: pedump.c:61
struct _SRB_IO_CONTROL SRB_IO_CONTROL
UCHAR ReportCount[4]
Definition: scsi.h:2445
#define DiskReadSmartData(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:216
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define DiskGetIdentifyData(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:276
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
NTSTATUS NTAPI DiskInfoExceptionComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: diskwmi.c:1361
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG
Definition: scsi.h:1421
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
struct _WRITE_LOG_SECTORS_IN * PWRITE_LOG_SECTORS_IN
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1007
#define SMART_READ_LOG
Definition: ntdddisk.h:629
unsigned int * PULONG
Definition: retypes.h:1
struct _MODE_INFO_EXCEPTIONS MODE_INFO_EXCEPTIONS
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:574
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
UCHAR bCylHighReg
Definition: helper.h:13
#define DISK_TAG_SRB
Definition: disk.h:61
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
NTSTATUS NTAPI DiskInfoExceptionCheck(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:1562
UCHAR bBuffer[1]
Definition: helper.h:27
#define WMI_STORAGE_SCSI_INFO_EXCEPTIONS_GUID
Definition: wmidata.h:337
struct _READ_LOG_SECTORS_OUT * PREAD_LOG_SECTORS_OUT
PVOID SenseInfoBuffer
Definition: srb.h:256
struct DISKREREGREQUEST * PDISKREREGREQUEST
Definition: name.c:36
_Must_inspect_result_ _Inout_ PFLT_VOLUME _In_opt_ PCUNICODE_STRING InstanceName
Definition: fltkernel.h:1162
#define BOOLEAN
Definition: pedump.c:73
#define OUT
Definition: typedefs.h:39
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define MODE_DATA_SIZE
Definition: cdrom.c:173
#define SmartPerformFunction
Definition: diskwmi.c:149
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define SmartDataGuid
Definition: diskwmi.c:148
#define STATUS_WMI_ITEMID_NOT_FOUND
Definition: ntstatus.h:764
NTSTATUS NTAPI DiskGetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS ReturnPageData)
Definition: disk.c:4862
struct tagContext Context
Definition: acpixf.h:1012
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define SMART_WRITE_LOG
Definition: ntdddisk.h:630
#define WMI_DISK_GEOMETRY_GUID
Definition: ntdddisk.h:295
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _IDEREGS IDEREGS
__inline NTSTATUS DiskEnableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:293
WORK_QUEUE_ITEM DiskReregWorkItem
Definition: diskwmi.c:91
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
UCHAR bDriveNumber
Definition: helper.h:33
#define EnableOfflineDiags
Definition: diskwmi.c:154
#define GetFailurePredictionCapability
Definition: diskwmi.c:153
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2771
return STATUS_SUCCESS
Definition: btrfs.c:2725
IoMarkIrpPending(Irp)
Definition: helper.h:8
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI DiskSetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData)
Definition: disk.c:4954
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
unsigned short * PUSHORT
Definition: retypes.h:2
#define WMIREG_FLAG_EXPENSIVE
Definition: wmistr.h:66
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
NTSTATUS NTAPI DiskPdoSetWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferSize, IN PUCHAR Buffer)
struct _WRITE_LOG_SECTORS_OUT WRITE_LOG_SECTORS_OUT
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
LONGLONG QuadPart
Definition: typedefs.h:112
VOID NTAPI ClassReleaseRemoveLock(IN PDEVICE_OBJECT DeviceObject, IN OPTIONAL PIRP Tag)
Definition: lock.c:212
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
Definition: ps.c:97