ReactOS 0.4.15-dev-7918-g2a2556c
diskwmi.c
Go to the documentation of this file.
1/*++
2
3Copyright (C) Microsoft Corporation, 1991 - 2010
4
5Module Name:
6
7 diskwmi.c
8
9Abstract:
10
11 SCSI disk class driver - WMI support routines
12
13Environment:
14
15 kernel mode only
16
17Notes:
18
19Revision History:
20
21--*/
22
23#include "disk.h"
24
25#ifdef DEBUG_USE_WPP
26#include "diskwmi.tmh"
27#endif
28
32 PSTORAGE_PREDICT_FAILURE checkFailure
33 );
34
38 PBOOLEAN SupportSmart
39 );
40
44 PFAILURE_PREDICTION_METHOD FailurePredictCapability,
45 BOOLEAN ScsiAddressAvailable
46 );
47
51 PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
52 );
53
58 IN UCHAR LogAddress,
60 );
61
66 IN UCHAR LogAddress,
68 );
69
70IO_WORKITEM_ROUTINE DiskReregWorker;
71
72IO_COMPLETION_ROUTINE DiskInfoExceptionComplete;
73
74//
75// WMI reregistration globals
76//
77// Since it will take too long to do a mode sense on some drive, we
78// need a good way to effect the mode sense for the info exceptions
79// mode page so that we can determine if SMART is supported and enabled
80// for the drive. So the strategy is to do an asynchronous mode sense
81// when the device starts and then look at the info exceptions mode
82// page within the completion routine. Now within the completion
83// routine we cannot call IoWMIRegistrationControl since we are at DPC
84// level, so we create a stack of device objects that will be processed
85// by a single work item that is fired off only when the stack
86// transitions from empty to non empty.
87//
91
93{
94 {
96 1,
97 0
98 },
99
100 {
102 1,
104 },
105
106 {
108 1,
110 },
111
112 {
114 1,
116 },
117
118 {
120 1,
122 },
123
124 {
126 1,
128 },
129
130 {
132 1,
133 0
134 }
135};
136
137
139
140#define DiskGeometryGuid 0
141#define SmartStatusGuid 1
142#define SmartDataGuid 2
143#define SmartPerformFunction 3
144 #define AllowDisallowPerformanceHit 1
145 #define EnableDisableHardwareFailurePrediction 2
146 #define EnableDisableFailurePredictionPolling 3
147 #define GetFailurePredictionCapability 4
148 #define EnableOfflineDiags 5
149
150#define SmartEventGuid 4
151#define SmartThresholdsGuid 5
152#define ScsiInfoExceptionsGuid 6
153
154#ifdef ALLOC_PRAGMA
155
156#pragma alloc_text(PAGE, DiskWmiFunctionControl)
157#pragma alloc_text(PAGE, DiskFdoQueryWmiRegInfo)
158#pragma alloc_text(PAGE, DiskFdoQueryWmiDataBlock)
159#pragma alloc_text(PAGE, DiskFdoSetWmiDataBlock)
160#pragma alloc_text(PAGE, DiskFdoSetWmiDataItem)
161#pragma alloc_text(PAGE, DiskFdoExecuteWmiMethod)
162
163#pragma alloc_text(PAGE, DiskDetectFailurePrediction)
164#pragma alloc_text(PAGE, DiskEnableDisableFailurePrediction)
165#pragma alloc_text(PAGE, DiskEnableDisableFailurePredictPolling)
166#pragma alloc_text(PAGE, DiskReadFailurePredictStatus)
167#pragma alloc_text(PAGE, DiskReadFailurePredictData)
168#pragma alloc_text(PAGE, DiskReadFailurePredictThresholds)
169#pragma alloc_text(PAGE, DiskGetIdentifyInfo)
170#pragma alloc_text(PAGE, DiskReadSmartLog)
171#pragma alloc_text(PAGE, DiskWriteSmartLog)
172#pragma alloc_text(PAGE, DiskPerformSmartCommand)
173#pragma alloc_text(PAGE, DiskSendFailurePredictIoctl)
174#pragma alloc_text(PAGE, DiskReregWorker)
175#pragma alloc_text(PAGE, DiskInitializeReregistration)
176
177#if (NTDDI_VERSION >= NTDDI_WINBLUE)
178#pragma alloc_text(PAGE, DiskGetModePage)
179#pragma alloc_text(PAGE, DiskEnableInfoExceptions)
180#endif // (NTDDI_VERSION >= NTDDI_WINBLUE)
181
182#endif
183
184
185//
186// Note:
187// Some port drivers assume that the SENDCMDINPARAMS structure will always be atleast
188// sizeof(SENDCMDINPARAMS). So do not adjust for the [pBuffer] if it isn't being used
189//
190
191//
192// SMART/IDE specific routines
193//
194
195//
196// Read SMART data attributes.
197// SrbControl should be : sizeof(SRB_IO_CONTROL) + MAX[ sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + READ_ATTRIBUTE_BUFFER_SIZE ]
198// Attribute data returned at &SendCmdOutParams->bBuffer[0]
199//
200#define DiskReadSmartData(FdoExtension, \
201 SrbControl, \
202 BufferSize) \
203 DiskPerformSmartCommand(FdoExtension, \
204 IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS, \
205 SMART_CMD, \
206 READ_ATTRIBUTES, \
207 0, \
208 0, \
209 (SrbControl), \
210 (BufferSize))
211
212
213//
214// Read SMART data thresholds.
215// SrbControl should be : sizeof(SRB_IO_CONTROL) + MAX[ sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + READ_THRESHOLD_BUFFER_SIZE ]
216// Attribute data returned at &SendCmdOutParams->bBuffer[0]
217//
218#define DiskReadSmartThresholds(FdoExtension, \
219 SrbControl, \
220 BufferSize) \
221 DiskPerformSmartCommand(FdoExtension, \
222 IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS, \
223 SMART_CMD, \
224 READ_THRESHOLDS, \
225 0, \
226 0, \
227 (SrbControl), \
228 (BufferSize))
229
230
231//
232// Read SMART status
233// SrbControl should be : sizeof(SRB_IO_CONTROL) + MAX[ sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS) ]
234// Failure predicted if SendCmdOutParams->bBuffer[3] == 0xf4 and SendCmdOutParams->bBuffer[4] == 0x2c
235//
236#define DiskReadSmartStatus(FdoExtension, \
237 SrbControl, \
238 BufferSize) \
239 DiskPerformSmartCommand(FdoExtension, \
240 IOCTL_SCSI_MINIPORT_RETURN_STATUS, \
241 SMART_CMD, \
242 RETURN_SMART_STATUS, \
243 0, \
244 0, \
245 (SrbControl), \
246 (BufferSize))
247
248
249//
250// Read disks IDENTIFY data
251// SrbControl should be : sizeof(SRB_IO_CONTROL) + MAX[ sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + IDENTIFY_BUFFER_SIZE ]
252// Identify data returned at &SendCmdOutParams->bBuffer[0]
253//
254#define DiskGetIdentifyData(FdoExtension, \
255 SrbControl, \
256 BufferSize) \
257 DiskPerformSmartCommand(FdoExtension, \
258 IOCTL_SCSI_MINIPORT_IDENTIFY, \
259 ID_CMD, \
260 0, \
261 0, \
262 0, \
263 (SrbControl), \
264 (BufferSize))
265
266
267//
268// Enable SMART
269//
270static NTSTATUS
273 )
274{
275 UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)] = {0};
276 ULONG bufferSize = sizeof(srbControl);
277
280 SMART_CMD,
282 0,
283 0,
284 (PSRB_IO_CONTROL)srbControl,
285 &bufferSize);
286}
287
288
289//
290// Disable SMART
291//
292static NTSTATUS
295 )
296{
297 UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)] = {0};
298 ULONG bufferSize = sizeof(srbControl);
299
302 SMART_CMD,
304 0,
305 0,
306 (PSRB_IO_CONTROL)srbControl,
307 &bufferSize);
308}
309
310#ifndef __REACTOS__ // functions are not used
311//
312// Enable Attribute Autosave
313//
314_inline NTSTATUS
317 )
318{
319 UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)] = {0};
320 ULONG bufferSize = sizeof(srbControl);
321
324 SMART_CMD,
326 0xf1,
327 0,
328 (PSRB_IO_CONTROL)srbControl,
329 &bufferSize);
330}
331
332
333//
334// Disable Attribute Autosave
335//
336_inline NTSTATUS
339 )
340{
341 UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)] = {0};
342 ULONG bufferSize = sizeof(srbControl);
343
346 SMART_CMD,
348 0x00,
349 0,
350 (PSRB_IO_CONTROL)srbControl,
351 &bufferSize);
352}
353#endif
354
355//
356// Initialize execution of SMART online diagnostics
357//
358static NTSTATUS
361 UCHAR Subcommand
362 )
363{
364 UCHAR srbControl[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS)] = {0};
365 ULONG bufferSize = sizeof(srbControl);
366
369 SMART_CMD,
371 0,
372 Subcommand,
373 (PSRB_IO_CONTROL)srbControl,
374 &bufferSize);
375}
376
377
382 IN UCHAR LogAddress,
384 )
385{
386 PSRB_IO_CONTROL srbControl;
388 PSENDCMDOUTPARAMS sendCmdOutParams;
389 ULONG logSize, bufferSize;
390
391 PAGED_CODE();
392
394 bufferSize = sizeof(SRB_IO_CONTROL) + max( sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + logSize );
395
396 srbControl = ExAllocatePoolWithTag(NonPagedPoolNx,
399
400 if (srbControl != NULL)
401 {
404 SMART_CMD,
407 LogAddress,
408 srbControl,
409 &bufferSize);
410
411 if (NT_SUCCESS(status))
412 {
413 sendCmdOutParams = (PSENDCMDOUTPARAMS)((PUCHAR)srbControl +
414 sizeof(SRB_IO_CONTROL));
416 &sendCmdOutParams->bBuffer[0],
417 logSize);
418 }
419
420 FREE_POOL(srbControl);
421 } else {
423 }
424 return(status);
425}
426
427
432 IN UCHAR LogAddress,
434 )
435{
436 PSRB_IO_CONTROL srbControl;
438 PSENDCMDINPARAMS sendCmdInParams;
439 ULONG logSize, bufferSize;
440
441 PAGED_CODE();
442
444 bufferSize = sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDINPARAMS) - 1 +
445 logSize;
446
447 srbControl = ExAllocatePoolWithTag(NonPagedPoolNx,
450
451 if (srbControl != NULL)
452 {
453 sendCmdInParams = (PSENDCMDINPARAMS)((PUCHAR)srbControl +
454 sizeof(SRB_IO_CONTROL));
455 RtlCopyMemory(&sendCmdInParams->bBuffer[0],
456 Buffer,
457 logSize);
460 SMART_CMD,
463 LogAddress,
464 srbControl,
465 &bufferSize);
466
467 FREE_POOL(srbControl);
468 } else {
470 }
471 return(status);
472}
473
474
478 IN ULONG SrbControlCode,
482 IN UCHAR SectorNumber,
483 IN OUT PSRB_IO_CONTROL SrbControl,
485 )
486/*++
487
488Routine Description:
489
490 This routine will perform some SMART command
491
492Arguments:
493
494 FdoExtension is the FDO device extension
495
496 SrbControlCode is the SRB control code to use for the request
497
498 Command is the SMART command to be executed. It may be SMART_CMD or
499 ID_CMD.
500
501 Feature is the value to place in the IDE feature register.
502
503 SectorCount is the value to place in the IDE SectorCount register
504
505 SrbControl is the buffer used to build the SRB_IO_CONTROL and pass
506 any input parameters. It also returns the output parameters.
507
508 *BufferSize on entry has total size of SrbControl and on return has
509 the size used in SrbControl.
510
511
512
513Return Value:
514
515 status
516
517--*/
518{
520 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
522 PSENDCMDINPARAMS cmdInParameters;
524 ULONG availableBufferSize;
526 PIRP irp;
527 IO_STATUS_BLOCK ioStatus = { 0 };
528 SCSI_REQUEST_BLOCK srb = {0};
529 LARGE_INTEGER startingOffset;
531 PIO_STACK_LOCATION irpStack;
534 PSTOR_ADDR_BTL8 storAddrBtl8;
535
536 PAGED_CODE();
537
538 //
539 // Point to the 'buffer' portion of the SRB_CONTROL and compute how
540 // much room we have left in the srb control. Abort if the buffer
541 // isn't at least the size of SRB_IO_CONTROL.
542 //
543
544 buffer = (PUCHAR)SrbControl + sizeof(SRB_IO_CONTROL);
545
546 cmdInParameters = (PSENDCMDINPARAMS)buffer;
547
548 if (*BufferSize >= sizeof(SRB_IO_CONTROL)) {
549 availableBufferSize = *BufferSize - sizeof(SRB_IO_CONTROL);
550 } else {
552 }
553
554#if DBG
555
556 //
557 // Ensure control codes and buffer lengths passed are correct
558 //
559 {
560 ULONG controlCode = 0;
561 ULONG lengthNeeded = sizeof(SENDCMDINPARAMS);
562
563 if (Command == SMART_CMD)
564 {
565 switch (Feature)
566 {
567 case ENABLE_SMART:
568 {
570 break;
571 }
572
573 case DISABLE_SMART:
574 {
576 break;
577 }
578
580 {
582 lengthNeeded = max( lengthNeeded, sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS) );
583 break;
584 }
585
587 {
589 break;
590 }
591
593 {
595 break;
596 }
597
598
600 {
602 break;
603 }
604
605 case READ_ATTRIBUTES:
606 {
608 lengthNeeded = max( lengthNeeded, sizeof(SENDCMDOUTPARAMS) - 1 + READ_ATTRIBUTE_BUFFER_SIZE );
609 break;
610 }
611
612 case READ_THRESHOLDS:
613 {
615 lengthNeeded = max( lengthNeeded, sizeof(SENDCMDOUTPARAMS) - 1 + READ_THRESHOLD_BUFFER_SIZE );
616 break;
617 }
618
619 case SMART_READ_LOG:
620 {
622 lengthNeeded = max( lengthNeeded, sizeof(SENDCMDOUTPARAMS) - 1 + (SectorCount * SMART_LOG_SECTOR_SIZE) );
623 break;
624 }
625
626 case SMART_WRITE_LOG:
627 {
629 lengthNeeded = lengthNeeded - 1 + (SectorCount * SMART_LOG_SECTOR_SIZE);
630 break;
631 }
632
633 }
634
635 } else if (Command == ID_CMD) {
636
637 controlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
638 lengthNeeded = max( lengthNeeded, sizeof(SENDCMDOUTPARAMS) - 1 + IDENTIFY_BUFFER_SIZE );
639
640 } else {
641
643 }
644
645 NT_ASSERT(controlCode == SrbControlCode);
646 NT_ASSERT(availableBufferSize >= lengthNeeded);
647 }
648
649#endif
650
651 //
652 // Build SrbControl and input to SMART command
653 //
654 SrbControl->HeaderLength = sizeof(SRB_IO_CONTROL);
655 RtlMoveMemory (SrbControl->Signature, "SCSIDISK", 8);
656 SrbControl->Timeout = FdoExtension->TimeOutValue;
657 SrbControl->Length = availableBufferSize;
658 SrbControl->ControlCode = SrbControlCode;
659
660 cmdInParameters->cBufferSize = sizeof(SENDCMDINPARAMS);
661 cmdInParameters->bDriveNumber = diskData->ScsiAddress.TargetId;
662 cmdInParameters->irDriveRegs.bFeaturesReg = Feature;
663 cmdInParameters->irDriveRegs.bSectorCountReg = SectorCount;
664 cmdInParameters->irDriveRegs.bSectorNumberReg = SectorNumber;
665 cmdInParameters->irDriveRegs.bCylLowReg = SMART_CYL_LOW;
666 cmdInParameters->irDriveRegs.bCylHighReg = SMART_CYL_HI;
667 cmdInParameters->irDriveRegs.bCommandReg = Command;
668
669 //
670 // Create and send irp
671 //
673
674 startingOffset.QuadPart = (LONGLONG) 1;
675
676 length = SrbControl->HeaderLength + SrbControl->Length;
677
680 commonExtension->LowerDeviceObject,
681 SrbControl,
682 length,
683 &startingOffset,
684 &event,
685 &ioStatus);
686
687 if (irp == NULL) {
689 }
690
691 irpStack = IoGetNextIrpStackLocation(irp);
692
693 //
694 // Set major and minor codes.
695 //
696
697 irpStack->MajorFunction = IRP_MJ_SCSI;
698 irpStack->MinorFunction = 1;
699
700 //
701 // Fill in SRB fields.
702 //
703
704 if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
705 irpStack->Parameters.Others.Argument1 = srbEx;
706
707 //
708 // Set up STORAGE_REQUEST_BLOCK fields
709 //
710
712 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
713 srbEx->Signature = SRB_SIGNATURE;
714 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
715 srbEx->SrbLength = sizeof(srbExBuffer);
716 srbEx->SrbFunction = SRB_FUNCTION_IO_CONTROL;
717 srbEx->RequestPriority = IoGetIoPriorityHint(irp);
718 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
719
720 srbEx->SrbFlags = FdoExtension->SrbFlags;
721 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_DATA_IN);
722 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
723 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_NO_KEEP_AWAKE);
724
725 srbEx->RequestAttribute = SRB_SIMPLE_TAG_REQUEST;
726 srbEx->RequestTag = SP_UNTAGGED;
727
728 srbEx->OriginalRequest = irp;
729
730 //
731 // Set timeout to requested value.
732 //
733
734 srbEx->TimeOutValue = SrbControl->Timeout;
735
736 //
737 // Set the data buffer.
738 //
739
740 srbEx->DataBuffer = SrbControl;
741 srbEx->DataTransferLength = length;
742
743 //
744 // Set up address fields
745 //
746
747 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
748 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
749 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
750 storAddrBtl8->Path = diskData->ScsiAddress.PathId;
751 storAddrBtl8->Target = diskData->ScsiAddress.TargetId;
752 storAddrBtl8->Lun = srb.Lun = diskData->ScsiAddress.Lun;
753
754 } else {
755 irpStack->Parameters.Others.Argument1 = &srb;
756
757 srb.PathId = diskData->ScsiAddress.PathId;
758 srb.TargetId = diskData->ScsiAddress.TargetId;
759 srb.Lun = diskData->ScsiAddress.Lun;
760
762 srb.Length = sizeof(SCSI_REQUEST_BLOCK);
763
764 srb.SrbFlags = FdoExtension->SrbFlags;
768
770 srb.QueueTag = SP_UNTAGGED;
771
772 srb.OriginalRequest = irp;
773
774 //
775 // Set timeout to requested value.
776 //
777
778 srb.TimeOutValue = SrbControl->Timeout;
779
780 //
781 // Set the data buffer.
782 //
783
784 srb.DataBuffer = SrbControl;
786 }
787
788 //
789 // Flush the data buffer for output. This will insure that the data is
790 // written back to memory. Since the data-in flag is the the port driver
791 // will flush the data again for input which will ensure the data is not
792 // in the cache.
793 //
794
795 KeFlushIoBuffers(irp->MdlAddress, FALSE, TRUE);
796
797 //
798 // Call port driver to handle this request.
799 //
800
801 status = IoCallDriver(commonExtension->LowerDeviceObject, irp);
802
803 if (status == STATUS_PENDING) {
805 status = ioStatus.Status;
806 }
807
808 return status;
809}
810
811
815 PBOOLEAN SupportSmart
816 )
817{
818 UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + max( sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + IDENTIFY_BUFFER_SIZE )] = {0};
819 ULONG outBufferSize = sizeof(outBuffer);
821
822 PAGED_CODE();
823
826 &outBufferSize);
827
828 if (NT_SUCCESS(status))
829 {
830 PUSHORT identifyData = (PUSHORT)&(outBuffer[sizeof(SRB_IO_CONTROL) + sizeof(SENDCMDOUTPARAMS) - 1]);
831 USHORT commandSetSupported = identifyData[82];
832
833 *SupportSmart = ((commandSetSupported != 0xffff) &&
834 (commandSetSupported != 0) &&
835 ((commandSetSupported & 1) == 1));
836 } else {
837 *SupportSmart = FALSE;
838 }
839
840 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_IOCTL, "DiskGetIdentifyInfo: SMART %s supported for device %p, status %lx\n",
841 *SupportSmart ? "is" : "is not",
842 FdoExtension->DeviceObject,
843 status));
844
845 return status;
846}
847
848
849//
850// FP Ioctl specific routines
851//
852
856 PSTORAGE_PREDICT_FAILURE checkFailure
857 )
858{
861 IO_STATUS_BLOCK ioStatus = { 0 };
862 PIRP irp;
864
865 PAGED_CODE();
866
868
870
874 NULL,
875 0,
876 checkFailure,
878 FALSE,
879 &event,
880 &ioStatus);
881
882 if (irp != NULL)
883 {
885 if (status == STATUS_PENDING)
886 {
888 status = ioStatus.Status;
889 }
890
891 } else {
893 }
894
896
897 return status;
898}
899
900#if (NTDDI_VERSION >= NTDDI_WINBLUE)
901
908 _Inout_ PULONG ModeDataSize,
909 _Out_ PVOID* PageData
910 )
911{
912 ULONG size = 0;
913 PVOID pageData = NULL;
914
915 PAGED_CODE();
916
917 if (ModeData == NULL ||
918 ModeDataSize == NULL ||
919 *ModeDataSize < sizeof(MODE_PARAMETER_HEADER) ||
920 PageData == NULL) {
922 }
923
924 RtlZeroMemory (ModeData, *ModeDataSize);
925
927 (PCHAR) ModeData,
928 *ModeDataSize,
929 PageMode,
931
932 if (size < sizeof(MODE_PARAMETER_HEADER)) {
933
934 //
935 // Retry the request in case of a check condition.
936 //
938 (PCHAR) ModeData,
939 *ModeDataSize,
940 PageMode,
942
943 if (size < sizeof(MODE_PARAMETER_HEADER)) {
944 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskGetModePage: Mode Sense for Page Mode %d with Page Control %d failed\n",
946 *ModeDataSize = 0;
948 }
949 }
950
951 //
952 // If the length is greater than length indicated by the mode data reset
953 // the data to the mode data.
954 //
955 if (size > (ULONG) (ModeData->ModeDataLength + 1)) {
956 size = ModeData->ModeDataLength + 1;
957 }
958
959 *ModeDataSize = size;
960
961 //
962 // Find the mode page
963 //
964 pageData = ClassFindModePage((PCHAR) ModeData,
965 size,
966 PageMode,
967 TRUE);
968
969 if (pageData) {
970 *PageData = pageData;
971 return STATUS_SUCCESS;
972 } else {
973 *PageData = NULL;
975 }
976}
977
982 )
983{
984 PDISK_DATA diskData = (PDISK_DATA)(FdoExtension->CommonExtension.DriverData);
986 PMODE_PARAMETER_HEADER modeData;
987 PMODE_INFO_EXCEPTIONS pageData;
988 MODE_INFO_EXCEPTIONS changeablePageData;
989 ULONG modeDataSize;
990
991 PAGED_CODE();
992
993 modeDataSize = MODE_DATA_SIZE;
994
995 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
996 modeDataSize,
998
999 if (modeData == NULL) {
1000
1001 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: Unable to allocate mode "
1002 "data buffer\n"));
1004 }
1005
1006 //
1007 // First see which data is actually changeable.
1008 //
1009 status = DiskGetModePage(FdoExtension->DeviceObject,
1011 1, // Page Control = 1 indicates we want changeable values.
1012 modeData,
1013 &modeDataSize,
1014 (PVOID*)&pageData);
1015
1016 if (!NT_SUCCESS(status) || pageData == NULL) {
1017 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: does NOT support SMART for device %p\n",
1018 FdoExtension->DeviceObject));
1019 FREE_POOL(modeData);
1020 return STATUS_NOT_SUPPORTED;
1021 }
1022
1023 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: DOES support SMART for device %p\n",
1024 FdoExtension->DeviceObject));
1025
1026 //
1027 // At the very least, the DEXCPT bit must be changeable.
1028 // If it's not, bail out now.
1029 //
1030 if (pageData->Dexcpt == 0) {
1031 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: does NOT support DEXCPT bit for device %p\n",
1032 FdoExtension->DeviceObject));
1033 FREE_POOL(modeData);
1034 return STATUS_NOT_SUPPORTED;
1035 }
1036
1037 //
1038 // Cache away which values are changeable.
1039 //
1040 RtlCopyMemory(&changeablePageData, pageData, sizeof(MODE_INFO_EXCEPTIONS));
1041
1042 //
1043 // Now get the current values.
1044 //
1045 status = DiskGetModePage(FdoExtension->DeviceObject,
1047 0, // Page Control = 0 indicates we want current values.
1048 modeData,
1049 &modeDataSize,
1050 (PVOID*)&pageData);
1051
1052 if (!NT_SUCCESS(status) || pageData == NULL) {
1053 //
1054 // At this point we know the device supports this mode page so
1055 // assert if something goes wrong here.
1056 //
1057 NT_ASSERT(NT_SUCCESS(status) && pageData);
1058 FREE_POOL(modeData);
1059 return STATUS_NOT_SUPPORTED;
1060 }
1061
1062 //
1063 // If the device is currently configured to not report any informational
1064 // exceptions and we cannot change the value of that field, there's
1065 // nothing to be done.
1066 //
1067 if (pageData->ReportMethod == 0 && changeablePageData.ReportMethod == 0) {
1068 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskEnableInfoExceptions: MRIE field is 0 and is not changeable for device %p\n",
1069 FdoExtension->DeviceObject));
1070 FREE_POOL(modeData);
1071 return STATUS_NOT_SUPPORTED;
1072 }
1073
1074 //
1075 // If the PERF bit is changeable, set it now.
1076 //
1077 if (changeablePageData.Perf) {
1078 pageData->Perf = diskData->AllowFPPerfHit ? 0 : 1;
1079 }
1080
1081 //
1082 // If the MRIE field is changeable, set it to 4 so that informational
1083 // exceptions get reported with the "Recovered Error" sense key.
1084 //
1085 if (changeablePageData.ReportMethod) {
1086 pageData->ReportMethod = 4;
1087 }
1088
1089 //
1090 // Finally, set the DEXCPT bit appropriately to enable/disable
1091 // informational exception reporting and send the Mode Select.
1092 //
1093 pageData->Dexcpt = !Enable;
1094
1095 status = ClassModeSelect(FdoExtension->DeviceObject,
1096 (PCHAR)modeData,
1097 modeDataSize,
1098 pageData->PSBit);
1099
1100 //
1101 // Update the failure prediction state. Note that for this particular
1102 // mode FailurePredictionNone is used when it's not enabled.
1103 //
1104 if (NT_SUCCESS(status)) {
1105 if (Enable) {
1107 diskData->FailurePredictionEnabled = TRUE;
1108 } else {
1110 diskData->FailurePredictionEnabled = FALSE;
1111 }
1112 }
1113
1114 FREE_POOL(modeData);
1115
1116 return status;
1117}
1118#endif
1119
1120
1121//
1122// FP type independent routines
1123//
1124
1129 )
1130/*++
1131
1132Routine Description:
1133
1134 Enable or disable failure prediction at the hardware level
1135
1136Arguments:
1137
1138 FdoExtension
1139
1140 Enable
1141
1142Return Value:
1143
1144 NT Status
1145
1146--*/
1147{
1149 PCOMMON_DEVICE_EXTENSION commonExtension = &(FdoExtension->CommonExtension);
1150 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1151
1152 PAGED_CODE();
1153
1154 switch(diskData->FailurePredictionCapability)
1155 {
1157 {
1158 if (Enable)
1159 {
1161 } else {
1163 }
1164
1165 if (NT_SUCCESS(status)) {
1166 diskData->FailurePredictionEnabled = Enable;
1167 }
1168
1169 break;
1170 }
1171
1174 {
1175 //
1176 // We assume that the drive is already setup properly for
1177 // failure prediction
1178 //
1180 break;
1181 }
1182
1183 default:
1184 {
1186 }
1187 }
1188 return status;
1189}
1190
1191
1196 ULONG PollTimeInSeconds
1197 )
1198/*++
1199
1200Routine Description:
1201
1202 Enable or disable polling for hardware failure detection
1203
1204Arguments:
1205
1206 FdoExtension
1207
1208 Enable
1209
1210 PollTimeInSeconds - if 0 then no change to current polling timer
1211
1212Return Value:
1213
1214 NT Status
1215
1216--*/
1217{
1220 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1221
1222 PAGED_CODE();
1223
1224 if (Enable)
1225 {
1227 Enable);
1228 } else {
1230 }
1231
1232 if (NT_SUCCESS(status))
1233 {
1234 status = ClassSetFailurePredictionPoll(FdoExtension,
1237 PollTimeInSeconds);
1238
1239 //
1240 // Even if this failed we do not want to disable FP on the
1241 // hardware. FP is only ever disabled on the hardware by
1242 // specific command of the user.
1243 //
1244 }
1245
1246 return status;
1247}
1248
1249
1253 PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus
1254 )
1255/*++
1256
1257Routine Description:
1258
1259 Obtains current failure prediction status
1260
1261Arguments:
1262
1263 FdoExtension
1264
1265 DiskSmartStatus
1266
1267Return Value:
1268
1269 NT Status
1270
1271--*/
1272{
1274 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1276
1277 PAGED_CODE();
1278
1279 DiskSmartStatus->PredictFailure = FALSE;
1280
1281 switch(diskData->FailurePredictionCapability)
1282 {
1284 {
1285 UCHAR outBuffer[sizeof(SRB_IO_CONTROL) + max( sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + sizeof(IDEREGS) )] = {0};
1286 ULONG outBufferSize = sizeof(outBuffer);
1287 PSENDCMDOUTPARAMS cmdOutParameters;
1288
1291 &outBufferSize);
1292
1293 if (NT_SUCCESS(status))
1294 {
1295 cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1296 sizeof(SRB_IO_CONTROL));
1297
1298 DiskSmartStatus->Reason = 0; // Unknown;
1299 DiskSmartStatus->PredictFailure = ((cmdOutParameters->bBuffer[3] == 0xf4) &&
1300 (cmdOutParameters->bBuffer[4] == 0x2c));
1301 }
1302 break;
1303 }
1304
1306 {
1307 DiskSmartStatus->Reason = FdoExtension->FailureReason;
1308 DiskSmartStatus->PredictFailure = FdoExtension->FailurePredicted;
1310 break;
1311 }
1312
1315 default:
1316 {
1318 break;
1319 }
1320 }
1321
1322 return status;
1323}
1324
1325
1329 PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData
1330 )
1331/*++
1332
1333Routine Description:
1334
1335 Obtains current failure prediction data. Not available for
1336 FAILURE_PREDICT_SENSE types.
1337
1338Arguments:
1339
1340 FdoExtension
1341
1342 DiskSmartData
1343
1344Return Value:
1345
1346 NT Status
1347
1348--*/
1349{
1351 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1353
1354 PAGED_CODE();
1355
1356 switch(diskData->FailurePredictionCapability)
1357 {
1359 {
1361 ULONG outBufferSize;
1362 PSENDCMDOUTPARAMS cmdOutParameters;
1363
1364 outBufferSize = sizeof(SRB_IO_CONTROL) + max( sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + READ_ATTRIBUTE_BUFFER_SIZE );
1365
1366 outBuffer = ExAllocatePoolWithTag(NonPagedPoolNx,
1367 outBufferSize,
1369
1370 if (outBuffer != NULL)
1371 {
1374 &outBufferSize);
1375
1376 if (NT_SUCCESS(status))
1377 {
1378 cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1379 sizeof(SRB_IO_CONTROL));
1380
1381 DiskSmartData->Length = READ_ATTRIBUTE_BUFFER_SIZE;
1382 RtlCopyMemory(DiskSmartData->VendorSpecific,
1383 cmdOutParameters->bBuffer,
1384 min(READ_ATTRIBUTE_BUFFER_SIZE, sizeof(DiskSmartData->VendorSpecific)));
1385 }
1387 } else {
1389 }
1390
1391 break;
1392 }
1393
1395 {
1396 DiskSmartData->Length = sizeof(ULONG);
1397 *((PULONG)DiskSmartData->VendorSpecific) = FdoExtension->FailureReason;
1398
1400 break;
1401 }
1402
1405 default:
1406 {
1408 break;
1409 }
1410 }
1411
1412 return status;
1413}
1414
1415
1419 PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds
1420 )
1421/*++
1422
1423Routine Description:
1424
1425 Obtains current failure prediction thresholds. Not available for
1426 FAILURE_PREDICT_SENSE types.
1427
1428Arguments:
1429
1430 FdoExtension
1431
1432 DiskSmartData
1433
1434Return Value:
1435
1436 NT Status
1437
1438--*/
1439{
1441 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1443
1444 PAGED_CODE();
1445
1446 switch(diskData->FailurePredictionCapability)
1447 {
1449 {
1451 PSENDCMDOUTPARAMS cmdOutParameters;
1452 ULONG outBufferSize;
1453
1454 outBufferSize = sizeof(SRB_IO_CONTROL) + max( sizeof(SENDCMDINPARAMS), sizeof(SENDCMDOUTPARAMS) - 1 + READ_THRESHOLD_BUFFER_SIZE );
1455
1456 outBuffer = ExAllocatePoolWithTag(NonPagedPoolNx,
1457 outBufferSize,
1459
1460 if (outBuffer != NULL)
1461 {
1464 &outBufferSize);
1465
1466 if (NT_SUCCESS(status))
1467 {
1468 cmdOutParameters = (PSENDCMDOUTPARAMS)(outBuffer +
1469 sizeof(SRB_IO_CONTROL));
1470
1471 RtlCopyMemory(DiskSmartThresholds->VendorSpecific,
1472 cmdOutParameters->bBuffer,
1473 min(READ_THRESHOLD_BUFFER_SIZE, sizeof(DiskSmartThresholds->VendorSpecific)));
1474 }
1476 } else {
1478 }
1479
1480 break;
1481 }
1482
1486 default:
1487 {
1489 break;
1490 }
1491 }
1492
1493 return status;
1494}
1495
1496
1497VOID
1498NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1500 IN PDEVICE_OBJECT DevObject,
1502 )
1503{
1504 PDISKREREGREQUEST reregRequest;
1507 PIRP irp;
1508
1509 PAGED_CODE();
1510 UNREFERENCED_PARAMETER(DevObject);
1511
1514
1515 do
1516 {
1520
1521 if (reregRequest != NULL)
1522 {
1523 deviceObject = reregRequest->DeviceObject;
1524 irp = reregRequest->Irp;
1525
1528
1529 //
1530 // Release remove lock and free irp, now that we are done
1531 // processing this
1532 //
1534
1535 IoFreeMdl(irp->MdlAddress);
1536 IoFreeIrp(irp);
1537
1538 FREE_POOL(reregRequest);
1539
1540 } else {
1541
1542 NT_ASSERTMSG("Disk Re-registration request list should not be empty", FALSE);
1543
1545 }
1546
1547 if (!NT_SUCCESS(status))
1548 {
1549 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "DiskReregWorker: Reregistration failed %x\n",
1550 status));
1551 }
1552
1554
1556}
1557
1558
1561 VOID
1562 )
1563{
1564 PAGED_CODE();
1565
1566 //
1567 // Initialize the spinlock used to manage the
1568 // list of disks reregistering their guids
1569 //
1571
1572 return(STATUS_SUCCESS);
1573}
1574
1575
1579 PIRP Irp
1580 )
1581{
1582 PDISKREREGREQUEST reregRequest;
1583 PIO_WORKITEM workItem;
1585
1586 workItem = IoAllocateWorkItem(DeviceObject);
1587
1588 if (!workItem) {
1590 }
1591
1592 reregRequest = ExAllocatePoolWithTag(NonPagedPoolNx,
1593 sizeof(DISKREREGREQUEST),
1595 if (reregRequest != NULL)
1596 {
1597 //
1598 // add the disk that needs reregistration to the stack of disks
1599 // to reregister. If the list is transitioning from empty to
1600 // non empty then also kick off the work item so that the
1601 // reregistration worker can do the reregister.
1602 //
1603 reregRequest->DeviceObject = DeviceObject;
1604 reregRequest->Irp = Irp;
1607 &reregRequest->Next,
1609
1611 {
1612 //
1613 // There is no worker routine running, queue this one.
1614 // When the work item runs, it will process the reregistration
1615 // list.
1616 //
1617
1618 IoQueueWorkItem(workItem,
1621 workItem);
1622 } else {
1623
1624 //
1625 // There is a worker routine already running, so we
1626 // can free this unused work item.
1627 //
1628
1629 IoFreeWorkItem(workItem);
1630 }
1631
1633
1634 } else {
1635
1636 IoFreeWorkItem(workItem);
1637 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL, "DiskPostReregisterRequest: could not allocate reregRequest for %p\n",
1638 DeviceObject));
1640 }
1641
1642 return(status);
1643}
1644
1645
1647NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1650 PIRP Irp,
1652 )
1653{
1654 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
1655 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
1660 BOOLEAN retry;
1661 ULONG retryInterval;
1662 ULONG srbStatus;
1663 BOOLEAN freeLockAndIrp = TRUE;
1664 PVOID originalSenseInfoBuffer = irpStack->Parameters.Others.Argument3;
1667 ULONG dataLength = 0;
1668 PVOID senseBuffer = NULL;
1669 UCHAR cdbLength8 = 0;
1670 ULONG cdbLength32 = 0;
1671 UCHAR senseBufferLength = 0;
1672
1673 srbStatus = SRB_STATUS(srb->SrbStatus);
1674
1676 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
1677 dataBuffer = srbEx->DataBuffer;
1678 dataLength = srbEx->DataTransferLength;
1679 if ((srbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI) &&
1680 (srbEx->NumSrbExData > 0)) {
1681 (void)GetSrbScsiData(srbEx, &cdbLength8, &cdbLength32, NULL, &senseBuffer, &senseBufferLength);
1682 }
1683 } else {
1684 dataBuffer = srb->DataBuffer;
1686 senseBuffer = srb->SenseInfoBuffer;
1687 }
1688
1689 //
1690 // Check SRB status for success of completing request.
1691 // SRB_STATUS_DATA_OVERRUN also indicates success.
1692 //
1693 if ((srbStatus != SRB_STATUS_SUCCESS) &&
1694 (srbStatus != SRB_STATUS_DATA_OVERRUN))
1695 {
1696 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "DiskInfoExceptionComplete: IRP %p, SRB %p\n", Irp, srb));
1697
1699 {
1701 }
1702
1705 srb,
1706 irpStack->MajorFunction,
1707 0,
1709 ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4),
1710 &status,
1711 &retryInterval);
1712
1713 //
1714 // If the status is verified required and the this request
1715 // should bypass verify required then retry the request.
1716 //
1717
1718 if (TEST_FLAG(irpStack->Flags, SL_OVERRIDE_VERIFY_VOLUME) &&
1720 {
1722 retry = TRUE;
1723 }
1724
1725 retry = retry && irpStack->Parameters.Others.Argument4;
1726
1727 irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4 - 1);
1728
1729 if (retry)
1730 {
1731 //
1732 // Retry request.
1733 //
1734
1735 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "DiskInfoExceptionComplete: Retry request %p\n", Irp));
1736
1738
1740
1741 //
1742 // Reset byte count of transfer in SRB Extension.
1743 //
1744 srbEx->DataTransferLength = Irp->MdlAddress->ByteCount;
1745
1746 //
1747 // Zero SRB statuses.
1748 //
1749
1750 srbEx->SrbStatus = 0;
1751 if ((srbEx->SrbFunction == SRB_FUNCTION_EXECUTE_SCSI) &&
1752 (srbEx->NumSrbExData > 0)) {
1753 SetSrbScsiData(srbEx, cdbLength8, cdbLength32, 0, senseBuffer, senseBufferLength);
1754 }
1755
1756 //
1757 // Set the no disconnect flag, disable synchronous data transfers and
1758 // disable tagged queuing. This fixes some errors.
1759 //
1760
1761 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_DISABLE_DISCONNECT);
1763 CLEAR_FLAG(srbEx->SrbFlags, SRB_FLAGS_QUEUE_ACTION_ENABLE);
1764
1765 srbEx->RequestAttribute = SRB_SIMPLE_TAG_REQUEST;
1766 srbEx->RequestTag = SP_UNTAGGED;
1767
1768 } else {
1769
1770 //
1771 // Reset byte count of transfer in SRB Extension.
1772 //
1773 srb->DataTransferLength = Irp->MdlAddress->ByteCount;
1774
1775 //
1776 // Zero SRB statuses.
1777 //
1778
1779 srb->SrbStatus = srb->ScsiStatus = 0;
1780
1781 //
1782 // Set the no disconnect flag, disable synchronous data transfers and
1783 // disable tagged queuing. This fixes some errors.
1784 //
1785
1789
1791 srb->QueueTag = SP_UNTAGGED;
1792 }
1793
1794 //
1795 // Set up major SCSI function.
1796 //
1797
1798 nextIrpStack->MajorFunction = IRP_MJ_SCSI;
1799
1800 //
1801 // Save SRB address in next stack for port driver.
1802 //
1803
1804 nextIrpStack->Parameters.Scsi.Srb = srb;
1805
1806
1809 srb,
1810 TRUE, TRUE, TRUE);
1811
1812 (VOID)IoCallDriver(commonExtension->LowerDeviceObject, Irp);
1813
1815 }
1816
1817 } else {
1818
1819 //
1820 // Get the results from the mode sense
1821 //
1822 PMODE_INFO_EXCEPTIONS pageData;
1823 PMODE_PARAMETER_HEADER modeData;
1824 ULONG modeDataLength;
1825
1826 modeData = dataBuffer;
1827 modeDataLength = dataLength;
1828
1829 pageData = ClassFindModePage((PCHAR)modeData,
1830 modeDataLength,
1832 TRUE);
1833 if (pageData != NULL)
1834 {
1835 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskInfoExceptionComplete: %p supports SMART\n",
1836 DeviceObject));
1837
1839
1840 //
1841 // The DEXCPT bit must be 0 and the MRIE field must be valid.
1842 //
1843 if (pageData->Dexcpt == 0 &&
1844 pageData->ReportMethod >= 2 &&
1845 pageData->ReportMethod <= 6)
1846 {
1848 diskData->FailurePredictionEnabled = TRUE;
1850
1851 if (NT_SUCCESS(status))
1852 {
1853 //
1854 // Make sure we won't free the remove lock and the irp
1855 // since we need to keep these until after the work
1856 // item has completed running
1857 //
1858 freeLockAndIrp = FALSE;
1859 }
1860 } else {
1861 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionComplete: %p is not enabled for SMART\n",
1862 DeviceObject));
1863
1864 }
1865
1866 } else {
1867 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionComplete: %p does not supports SMART\n",
1868 DeviceObject));
1869
1870 }
1871
1872 //
1873 // Set status for successful request
1874 //
1875
1877
1878 } // end if (SRB_STATUS(srb->SrbStatus) == SRB_STATUS_SUCCESS)
1879
1880 //
1881 // Free the srb
1882 //
1883 if (senseBuffer != originalSenseInfoBuffer)
1884 {
1885 //
1886 // Free the original sense info buffer in case the port driver has overwritten it
1887 //
1888 FREE_POOL(originalSenseInfoBuffer);
1889 }
1890
1891 FREE_POOL(senseBuffer);
1893 FREE_POOL(srb);
1894
1895 if (freeLockAndIrp)
1896 {
1897 //
1898 // Set status in completing IRP.
1899 //
1900
1901 Irp->IoStatus.Status = status;
1902
1903 //
1904 // If pending has be returned for this irp then mark the current stack as
1905 // pending.
1906 //
1907
1908 if (Irp->PendingReturned) {
1910 }
1911
1913 IoFreeMdl(Irp->MdlAddress);
1914 IoFreeIrp(Irp);
1915 }
1916
1918}
1919
1920
1924 )
1925{
1926 PUCHAR modeData;
1928 PCDB cdb;
1929 PIRP irp;
1930 PIO_STACK_LOCATION irpStack;
1932 UCHAR senseInfoBufferLength = 0;
1933 ULONG isRemoved;
1934 ULONG srbSize;
1936 PSTOR_ADDR_BTL8 storAddrBtl8 = NULL;
1937 PSRBEX_DATA_SCSI_CDB16 srbExDataCdb16 = NULL;
1938
1939 modeData = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
1942 if (modeData == NULL)
1943 {
1944 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionCheck: Can't allocate mode data "
1945 "buffer\n"));
1947 }
1948
1949 if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1951 } else {
1952 srbSize = SCSI_REQUEST_BLOCK_SIZE;
1953 }
1954 srb = ExAllocatePoolWithTag(NonPagedPoolNx,
1955 srbSize,
1956 DISK_TAG_SRB);
1957 if (srb == NULL)
1958 {
1959 FREE_POOL(modeData);
1960 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionCheck: Can't allocate srb "
1961 "buffer\n"));
1963 }
1964 RtlZeroMemory(srb, srbSize);
1965
1966 //
1967 // Sense buffer is in aligned nonpaged pool.
1968 //
1969
1970 senseInfoBuffer = ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
1972 '7CcS');
1973
1974 if (senseInfoBuffer == NULL)
1975 {
1976 FREE_POOL(srb);
1977 FREE_POOL(modeData);
1978 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionCheck: Can't allocate request sense "
1979 "buffer\n"));
1981 }
1982
1983 senseInfoBufferLength = SENSE_BUFFER_SIZE_EX;
1984
1985 //
1986 // Build device I/O control request with METHOD_NEITHER data transfer.
1987 // We'll queue a completion routine to cleanup the MDL's and such ourself.
1988 //
1989
1991 (CCHAR) (FdoExtension->CommonExtension.LowerDeviceObject->StackSize + 1),
1992 FALSE);
1993
1994 if (irp == NULL)
1995 {
1997 FREE_POOL(srb);
1998 FREE_POOL(modeData);
1999 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionCheck: Can't allocate Irp\n"));
2001 }
2002
2003 isRemoved = ClassAcquireRemoveLock(FdoExtension->DeviceObject, irp);
2004
2005 if (isRemoved)
2006 {
2007 ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
2008 IoFreeIrp(irp);
2010 FREE_POOL(srb);
2011 FREE_POOL(modeData);
2012 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskInfoExceptionCheck: RemoveLock says isRemoved\n"));
2014 }
2015
2016 //
2017 // Get next stack location.
2018 //
2019
2022 irpStack->DeviceObject = FdoExtension->DeviceObject;
2023
2024 //
2025 // Save retry count in current Irp stack.
2026 //
2027 irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
2028
2029 //
2030 // Save allocated sense info buffer in case the port driver overwrites it
2031 //
2032 irpStack->Parameters.Others.Argument3 = senseInfoBuffer;
2033
2034 irpStack = IoGetNextIrpStackLocation(irp);
2035
2036 //
2037 // Set up SRB for execute scsi request. Save SRB address in next stack
2038 // for the port driver.
2039 //
2040
2041 irpStack->MajorFunction = IRP_MJ_SCSI;
2042 irpStack->Parameters.Scsi.Srb = srb;
2043
2046 srb,
2047 TRUE,
2048 TRUE,
2049 TRUE);
2050
2051 irp->MdlAddress = IoAllocateMdl( modeData,
2053 FALSE,
2054 FALSE,
2055 irp );
2056 if (irp->MdlAddress == NULL)
2057 {
2058 ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
2059 FREE_POOL(srb);
2060 FREE_POOL(modeData);
2062 IoFreeIrp( irp );
2063 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskINfoExceptionCheck: Can't allocate MDL\n"));
2065 }
2066
2067 MmBuildMdlForNonPagedPool(irp->MdlAddress);
2068
2069 //
2070 // Build the MODE SENSE CDB.
2071 //
2072
2073 if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
2074
2075 //
2076 // Set up STORAGE_REQUEST_BLOCK fields
2077 //
2078
2079 srbEx = (PSTORAGE_REQUEST_BLOCK)srb;
2081 srbEx->Function = SRB_FUNCTION_STORAGE_REQUEST_BLOCK;
2082 srbEx->Signature = SRB_SIGNATURE;
2083 srbEx->Version = STORAGE_REQUEST_BLOCK_VERSION_1;
2084 srbEx->SrbLength = srbSize;
2085 srbEx->SrbFunction = SRB_FUNCTION_EXECUTE_SCSI;
2086 srbEx->RequestPriority = IoGetIoPriorityHint(irp);
2087 srbEx->AddressOffset = sizeof(STORAGE_REQUEST_BLOCK);
2088 srbEx->NumSrbExData = 1;
2089
2090 // Set timeout value from device extension.
2091 srbEx->TimeOutValue = FdoExtension->TimeOutValue;
2092
2093 // Set the transfer length.
2094 srbEx->DataTransferLength = MODE_DATA_SIZE;
2095 srbEx->DataBuffer = modeData;
2096
2097 srbEx->SrbFlags = FdoExtension->SrbFlags;
2098
2099 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_DATA_IN);
2100
2101 //
2102 // Disable synchronous transfer for these requests.
2103 //
2105
2106 //
2107 // Don't freeze the queue on an error
2108 //
2109 SET_FLAG(srbEx->SrbFlags, SRB_FLAGS_NO_QUEUE_FREEZE);
2110
2111 srbEx->RequestAttribute = SRB_SIMPLE_TAG_REQUEST;
2112 srbEx->RequestTag = SP_UNTAGGED;
2113
2114 // Set up IRP Address.
2115 srbEx->OriginalRequest = irp;
2116
2117 //
2118 // Set up address fields
2119 //
2120
2121 storAddrBtl8 = (PSTOR_ADDR_BTL8) ((PUCHAR)srbEx + srbEx->AddressOffset);
2122 storAddrBtl8->Type = STOR_ADDRESS_TYPE_BTL8;
2123 storAddrBtl8->AddressLength = STOR_ADDR_BTL8_ADDRESS_LENGTH;
2124
2125 //
2126 // Set up SCSI SRB extended data fields
2127 //
2128
2129 srbEx->SrbExDataOffset[0] = sizeof(STORAGE_REQUEST_BLOCK) +
2130 sizeof(STOR_ADDR_BTL8);
2131 if ((srbEx->SrbExDataOffset[0] + sizeof(SRBEX_DATA_SCSI_CDB16)) <= srbEx->SrbLength) {
2132 srbExDataCdb16 = (PSRBEX_DATA_SCSI_CDB16)((PUCHAR)srbEx + srbEx->SrbExDataOffset[0]);
2133 srbExDataCdb16->Type = SrbExDataTypeScsiCdb16;
2134 srbExDataCdb16->Length = SRBEX_DATA_SCSI_CDB16_LENGTH;
2135 srbExDataCdb16->CdbLength = 6;
2136
2137 // Enable auto request sense.
2138 srbExDataCdb16->SenseInfoBufferLength = senseInfoBufferLength;
2139 srbExDataCdb16->SenseInfoBuffer = senseInfoBuffer;
2140
2141 cdb = (PCDB)srbExDataCdb16->Cdb;
2142 } else {
2143 // Should not happen
2145
2146 ClassReleaseRemoveLock(FdoExtension->DeviceObject, irp);
2147 FREE_POOL(srb);
2148 FREE_POOL(modeData);
2150 IoFreeIrp( irp );
2151 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_WMI, "DiskINfoExceptionCheck: Insufficient extended SRB size\n"));
2152 return STATUS_INTERNAL_ERROR;
2153 }
2154
2155 } else {
2156
2157 //
2158 // Write length to SRB.
2159 //
2161
2162 //
2163 // Set SCSI bus address.
2164 //
2165
2167
2168 //
2169 // Enable auto request sense.
2170 //
2171
2172 srb->SenseInfoBufferLength = senseInfoBufferLength;
2174
2175 //
2176 // Set timeout value from device extension.
2177 //
2178 srb->TimeOutValue = FdoExtension->TimeOutValue;
2179
2180 //
2181 // Set the transfer length.
2182 //
2184 srb->DataBuffer = modeData;
2185
2186 srb->SrbFlags = FdoExtension->SrbFlags;
2187
2189
2190 //
2191 // Disable synchronous transfer for these requests.
2192 //
2194
2195 //
2196 // Don't freeze the queue on an error
2197 //
2199
2201 srb->QueueTag = SP_UNTAGGED;
2202
2203 //
2204 // Set up IRP Address.
2205 //
2206 srb->OriginalRequest = irp;
2207
2208 srb->CdbLength = 6;
2209 cdb = (PCDB)srb->Cdb;
2210
2211 }
2212
2213 cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
2214 cdb->MODE_SENSE.PageCode = MODE_PAGE_FAULT_REPORTING;
2215 cdb->MODE_SENSE.AllocationLength = MODE_DATA_SIZE;
2216
2217 //
2218 // Call the port driver with the request and wait for it to complete.
2219 //
2220
2222 IoCallDriver(FdoExtension->CommonExtension.LowerDeviceObject,
2223 irp);
2224
2225 return(STATUS_PENDING);
2226}
2227
2228
2232 PFAILURE_PREDICTION_METHOD FailurePredictCapability,
2233 BOOLEAN ScsiAddressAvailable
2234 )
2235/*++
2236
2237Routine Description:
2238
2239 Detect if device has any failure prediction capabilities. First we
2240 check for IDE SMART capability. This is done by sending the drive an
2241 IDENTIFY command and checking if the SMART command set bit is set.
2242
2243 Next we check if SCSI SMART (aka Information Exception Control Page,
2244 X3T10/94-190 Rev 4). This is done by querying for the Information
2245 Exception mode page.
2246
2247 Lastly we check if the device has IOCTL failure prediction. This mechanism
2248 a filter driver implements IOCTL_STORAGE_PREDICT_FAILURE and will respond
2249 with the information in the IOCTL. We do this by sending the ioctl and
2250 if the status returned is STATUS_SUCCESS we assume that it is supported.
2251
2252Arguments:
2253
2254 FdoExtension
2255
2256 *FailurePredictCapability
2257
2258 ScsiAddressAvailable TRUE if there is a valid SCSI_ADDRESS available
2259 for this device, FALSE otherwise.
2260 If FALSE we do not allow SMART IOCTLs (FailurePredictionSmart capability)
2261 which require a valid SCSI_ADDRESS. The other capabilities
2262 <FailurePredictionIoctl, FailurePredictionSense) do not requere
2263 SCSI_ADDRESS so we'll still try to initialize them.
2264
2265Return Value:
2266
2267 NT Status
2268
2269--*/
2270{
2272 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2273 BOOLEAN supportFP;
2275 STORAGE_PREDICT_FAILURE checkFailure;
2276 STORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
2277
2278 PAGED_CODE();
2279
2280 //
2281 // Assume no failure predict mechanisms
2282 //
2283 *FailurePredictCapability = FailurePredictionNone;
2284
2285 //
2286 // See if this is an IDE drive that supports SMART. If so enable SMART
2287 // and then ensure that it suports the SMART READ STATUS command
2288 //
2289
2290 if (ScsiAddressAvailable)
2291 {
2292 DiskGetIdentifyInfo(FdoExtension, &supportFP);
2293
2294 if (supportFP)
2295 {
2297 if (NT_SUCCESS(status))
2298 {
2299 *FailurePredictCapability = FailurePredictionSmart;
2300 diskData->FailurePredictionEnabled = TRUE;
2301
2303 &diskSmartStatus);
2304
2305 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: Device %p %s IDE SMART\n",
2306 FdoExtension->DeviceObject,
2307 NT_SUCCESS(status) ? "does" : "does not"));
2308
2309 if (!NT_SUCCESS(status))
2310 {
2311 *FailurePredictCapability = FailurePredictionNone;
2312 diskData->FailurePredictionEnabled = FALSE;
2313 }
2314 }
2315 return(status);
2316 }
2317 }
2318 //
2319 // See if there is a a filter driver to intercept
2320 // IOCTL_STORAGE_PREDICT_FAILURE
2321 //
2323 &checkFailure);
2324
2325 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: Device %p %s IOCTL_STORAGE_FAILURE_PREDICT\n",
2326 FdoExtension->DeviceObject,
2327 NT_SUCCESS(status) ? "does" : "does not"));
2328
2329 if (NT_SUCCESS(status))
2330 {
2331 *FailurePredictCapability = FailurePredictionIoctl;
2332 diskData->FailurePredictionEnabled = TRUE;
2333 if (checkFailure.PredictFailure)
2334 {
2335 checkFailure.PredictFailure = 512;
2336 ClassNotifyFailurePredicted(FdoExtension,
2337 (PUCHAR)&checkFailure,
2338 sizeof(checkFailure),
2339 (BOOLEAN)(FdoExtension->FailurePredicted == FALSE),
2340 0x11,
2341 diskData->ScsiAddress.PathId,
2342 diskData->ScsiAddress.TargetId,
2343 diskData->ScsiAddress.Lun);
2344
2345 FdoExtension->FailurePredicted = TRUE;
2346 }
2347 return(status);
2348 }
2349
2350 //
2351 // Finally we assume it will not be a scsi smart drive. but
2352 // we'll also send off an asynchronous mode sense so that if
2353 // it is SMART we'll reregister the device object
2354 //
2355
2356 *FailurePredictCapability = FailurePredictionNone;
2357
2359
2360 return(STATUS_SUCCESS);
2361}
2362
2363
2365NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2368 IN PIRP Irp,
2372 )
2373/*++
2374
2375Routine Description:
2376
2377 This routine is a callback into the driver to enabled or disable event
2378 generation or data block collection. A device should only expect a
2379 single enable when the first event or data consumer enables events or
2380 data collection and a single disable when the last event or data
2381 consumer disables events or data collection. Data blocks will only
2382 receive collection enable/disable if they were registered as requiring
2383 it.
2384
2385
2386 When NT boots, failure prediction is not automatically enabled, although
2387 it may have been persistantly enabled on a previous boot. Polling is also
2388 not automatically enabled. When the first data block that accesses SMART
2389 such as SmartStatusGuid, SmartDataGuid, SmartPerformFunction, or
2390 SmartEventGuid is accessed then SMART is automatically enabled in the
2391 hardware. Polling is enabled when SmartEventGuid is enabled and disabled
2392 when it is disabled. Hardware SMART is only disabled when the DisableSmart
2393 method is called. Polling is also disabled when this is called regardless
2394 of the status of the other guids or events.
2395
2396Arguments:
2397
2398 DeviceObject is the device whose data block is being queried
2399
2400 GuidIndex is the index into the list of guids provided when the
2401 device registered
2402
2403 Function specifies which functionality is being enabled or disabled
2404
2405 Enable is TRUE then the function is being enabled else disabled
2406
2407Return Value:
2408
2409 status
2410
2411--*/
2412{
2414 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2415
2416 PAGED_CODE();
2417
2419 {
2420 if ((GuidIndex == SmartStatusGuid) ||
2421 (GuidIndex == SmartDataGuid) ||
2424 {
2426 TRUE);
2427 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DeviceObject %p, Irp %p Enable -> %lx\n",
2429 Irp,
2430 status));
2431
2432 } else {
2433 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Collection\n",
2435 GuidIndex,
2436 Enable ? "Enabled" : "Disabled"));
2437 }
2438 } else if (Function == EventGeneration) {
2439 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for Event Generation\n",
2441 GuidIndex,
2442 Enable ? "Enabled" : "Disabled"));
2443
2444
2445 if ((GuidIndex == SmartEventGuid) && Enable)
2446 {
2448 Enable,
2449 0);
2450 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DeviceObject %p, Irp %p %s -> %lx\n",
2452 Irp,
2453 Enable ? "DiskEnableSmartPolling" : "DiskDisableSmartPolling",
2454 status));
2455 }
2456
2457#if DBG
2458 } else {
2459 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DeviceObject %p, Irp %p, GuidIndex %d %s for function %d\n",
2461 GuidIndex,
2462 Enable ? "Enabled" : "Disabled",
2463 Function));
2464#endif
2465 }
2466
2468 Irp,
2469 status,
2470 0,
2472 return status;
2473}
2474
2475
2476
2478NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2483 )
2484/*++
2485
2486Routine Description:
2487
2488 This routine is a callback into the driver to retrieve the list of
2489 guids or data blocks that the driver wants to register with WMI. This
2490 routine may not pend or block. Driver should NOT call
2491 ClassWmiCompleteRequest.
2492
2493Arguments:
2494
2495 DeviceObject is the device whose data block is being queried
2496
2497 *RegFlags returns with a set of flags that describe the guids being
2498 registered for this device. If the device wants enable and disable
2499 collection callbacks before receiving queries for the registered
2500 guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
2501 returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
2502 the instance name is determined from the PDO associated with the
2503 device object. Note that the PDO must have an associated devnode. If
2504 WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
2505 name for the device.
2506
2507 InstanceName returns with the instance name for the guids if
2508 WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
2509 caller will call ExFreePool with the buffer returned.
2510
2511
2512Return Value:
2513
2514 status
2515
2516--*/
2517{
2518 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2519 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2520
2521 PAGED_CODE();
2523
2526
2527 switch (diskData->FailurePredictionCapability)
2528 {
2530 {
2532 //
2533 // Fall Through
2534 //
2535 }
2537 {
2542
2543 break;
2544 }
2545
2547 {
2553 break;
2554 }
2555
2556
2557 default:
2558 {
2563 break;
2564 }
2565 }
2566
2567 //
2568 // Use devnode for FDOs
2570
2571 return STATUS_SUCCESS;
2572}
2573
2574
2576NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2581 OUT PUNICODE_STRING MofName
2582 )
2583/*++
2584
2585Routine Description:
2586
2587 This routine is a callback into the driver to retrieve the list of
2588 guids or data blocks that the driver wants to register with WMI. This
2589 routine may not pend or block. Driver should NOT call
2590 ClassWmiCompleteRequest.
2591
2592Arguments:
2593
2594 DeviceObject is the device whose data block is being queried
2595
2596 *RegFlags returns with a set of flags that describe the guids being
2597 registered for this device. If the device wants enable and disable
2598 collection callbacks before receiving queries for the registered
2599 guids then it should return the WMIREG_FLAG_EXPENSIVE flag. Also the
2600 returned flags may specify WMIREG_FLAG_INSTANCE_PDO in which case
2601 the instance name is determined from the PDO associated with the
2602 device object. Note that the PDO must have an associated devnode. If
2603 WMIREG_FLAG_INSTANCE_PDO is not set then Name must return a unique
2604 name for the device.
2605
2606 InstanceName returns with the instance name for the guids if
2607 WMIREG_FLAG_INSTANCE_PDO is not set in the returned *RegFlags. The
2608 caller will call ExFreePool with the buffer returned.
2609
2610 MofName returns initialized with the mof resource name for the
2611 binary mof resource attached to the driver's image file. If the
2612 driver does not have a mof resource then it should leave this
2613 parameter untouched.
2614
2615Return Value:
2616
2617 status
2618
2619--*/
2620{
2622
2623 UNREFERENCED_PARAMETER(MofName);
2624
2626 RegFlags,
2627 InstanceName);
2628
2629 //
2630 // Leave MofName alone since disk doesn't have one
2631 //
2632 return(status);
2633}
2634
2635
2637NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2640 IN PIRP Irp,
2644 )
2645/*++
2646
2647Routine Description:
2648
2649 This routine is a callback into the driver to query for the contents of
2650 a data block. When the driver has finished filling the data block it
2651 must call ClassWmiCompleteRequest to complete the irp. The driver can
2652 return STATUS_PENDING if the irp cannot be completed immediately.
2653
2654Arguments:
2655
2656 DeviceObject is the device whose data block is being queried
2657
2658 Irp is the Irp that makes this request
2659
2660 GuidIndex is the index into the list of guids provided when the
2661 device registered
2662
2663 BufferAvail on has the maximum size available to write the data
2664 block.
2665
2666 Buffer on return is filled with the returned data block
2667
2668
2669Return Value:
2670
2671 status
2672
2673--*/
2674{
2676 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2677 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2678 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2679 ULONG sizeNeeded;
2680
2681 PAGED_CODE();
2682
2683 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskQueryWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2684 " BufferAvail %lx Buffer %p\n",
2687
2688 switch (GuidIndex)
2689 {
2690 case DiskGeometryGuid:
2691 {
2692 sizeNeeded = sizeof(DISK_GEOMETRY);
2693 if (BufferAvail >= sizeNeeded)
2694 {
2695 if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA)
2696 {
2697 //
2698 // Issue ReadCapacity to update device extension
2699 // with information for current media.
2700 status = DiskReadDriveCapacity(commonExtension->PartitionZeroExtension->DeviceObject);
2701
2702 //
2703 // Note whether the drive is ready.
2704 diskData->ReadyStatus = status;
2705
2706 if (!NT_SUCCESS(status))
2707 {
2708 break;
2709 }
2710 }
2711
2712 //
2713 // Copy drive geometry information from device extension.
2715 &(fdoExtension->DiskGeometry),
2716 sizeof(DISK_GEOMETRY));
2717
2719 } else {
2721 }
2722 break;
2723 }
2724
2725 case SmartStatusGuid:
2726 {
2727 PSTORAGE_FAILURE_PREDICT_STATUS diskSmartStatus;
2728
2730
2731 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_STATUS);
2732 if (BufferAvail >= sizeNeeded)
2733 {
2734 STORAGE_PREDICT_FAILURE checkFailure;
2735
2736 diskSmartStatus = (PSTORAGE_FAILURE_PREDICT_STATUS)Buffer;
2737
2738 status = DiskSendFailurePredictIoctl(fdoExtension,
2739 &checkFailure);
2740
2741 if (NT_SUCCESS(status))
2742 {
2743 if (diskData->FailurePredictionCapability ==
2745 {
2746 diskSmartStatus->Reason = *((PULONG)checkFailure.VendorSpecific);
2747 } else {
2748 diskSmartStatus->Reason = 0; // unknown
2749 }
2750
2751 diskSmartStatus->PredictFailure = (checkFailure.PredictFailure != 0);
2752 }
2753 } else {
2755 }
2756 break;
2757 }
2758
2759 case SmartDataGuid:
2760 {
2761 PSTORAGE_FAILURE_PREDICT_DATA diskSmartData;
2762
2765 (diskData->FailurePredictionCapability ==
2767
2768 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_DATA);
2769 if (BufferAvail >= sizeNeeded)
2770 {
2772
2773 diskSmartData = (PSTORAGE_FAILURE_PREDICT_DATA)Buffer;
2774
2775 status = DiskSendFailurePredictIoctl(fdoExtension,
2776 checkFailure);
2777
2778 if (NT_SUCCESS(status))
2779 {
2780 diskSmartData->Length = 512;
2781 }
2782 } else {
2784 }
2785
2786 break;
2787 }
2788
2790 {
2791 PSTORAGE_FAILURE_PREDICT_THRESHOLDS diskSmartThresholds;
2792
2795
2796 sizeNeeded = sizeof(STORAGE_FAILURE_PREDICT_THRESHOLDS);
2797 if (BufferAvail >= sizeNeeded)
2798 {
2799 diskSmartThresholds = (PSTORAGE_FAILURE_PREDICT_THRESHOLDS)Buffer;
2801 diskSmartThresholds);
2802 } else {
2804 }
2805
2806 break;
2807 }
2808
2810 {
2811 sizeNeeded = 0;
2813 break;
2814 }
2815
2817 {
2818 PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2819 MODE_INFO_EXCEPTIONS modeInfo;
2820
2823
2824 sizeNeeded = sizeof(STORAGE_SCSI_INFO_EXCEPTIONS);
2825 if (BufferAvail >= sizeNeeded)
2826 {
2827 infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2829 &modeInfo);
2830 if (NT_SUCCESS(status))
2831 {
2832 infoExceptions->PageSavable = modeInfo.PSBit;
2833 infoExceptions->Flags = modeInfo.Flags;
2834 infoExceptions->MRIE = modeInfo.ReportMethod;
2835 infoExceptions->Padding = 0;
2836 REVERSE_BYTES(&infoExceptions->IntervalTimer,
2837 &modeInfo.IntervalTimer);
2838 REVERSE_BYTES(&infoExceptions->ReportCount,
2839 &modeInfo.ReportCount)
2840 }
2841 } else {
2843 }
2844
2845 break;
2846 }
2847
2848 default:
2849 {
2850 sizeNeeded = 0;
2852 }
2853 }
2854 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskQueryWmiDataBlock Device %p, Irp %p returns %lx\n",
2856
2858 Irp,
2859 status,
2860 sizeNeeded,
2862
2863 return status;
2864}
2865
2866
2868NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2871 IN PIRP Irp,
2875 )
2876/*++
2877
2878Routine Description:
2879
2880 This routine is a callback into the driver to query for the contents of
2881 a data block. When the driver has finished filling the data block it
2882 must call ClassWmiCompleteRequest to complete the irp. The driver can
2883 return STATUS_PENDING if the irp cannot be completed immediately.
2884
2885Arguments:
2886
2887 DeviceObject is the device whose data block is being queried
2888
2889 Irp is the Irp that makes this request
2890
2891 GuidIndex is the index into the list of guids provided when the
2892 device registered
2893
2894 BufferSize has the size of the data block passed
2895
2896 Buffer has the new values for the data block
2897
2898
2899Return Value:
2900
2901 status
2902
2903--*/
2904{
2906 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
2907 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
2908 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
2909
2910 PAGED_CODE();
2911
2912 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataBlock, Device %p, Irp %p, GuiIndex %d\n"
2913 " BufferSize %#x Buffer %p\n",
2916
2918 {
2919 PSTORAGE_SCSI_INFO_EXCEPTIONS infoExceptions;
2920 MODE_INFO_EXCEPTIONS modeInfo = {0};
2921
2923 {
2924 infoExceptions = (PSTORAGE_SCSI_INFO_EXCEPTIONS)Buffer;
2925
2927 modeInfo.PageLength = sizeof(MODE_INFO_EXCEPTIONS) - 2;
2928
2929 modeInfo.PSBit = 0;
2930 modeInfo.Flags = infoExceptions->Flags;
2931
2932 modeInfo.ReportMethod = infoExceptions->MRIE;
2933
2934 REVERSE_BYTES(&modeInfo.IntervalTimer[0],
2935 &infoExceptions->IntervalTimer);
2936
2937 REVERSE_BYTES(&modeInfo.ReportCount[0],
2938 &infoExceptions->ReportCount);
2939
2940 if (modeInfo.Perf == 1)
2941 {
2942 diskData->AllowFPPerfHit = FALSE;
2943 } else {
2944 diskData->AllowFPPerfHit = TRUE;
2945 }
2946
2948 &modeInfo);
2949 } else {
2951 }
2952
2953 } else if (GuidIndex <= SmartThresholdsGuid)
2954 {
2956 } else {
2958 }
2959
2960 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataBlock Device %p, Irp %p returns %lx\n",
2962
2964 Irp,
2965 status,
2966 0,
2968
2969 return status;
2970}
2971
2972
2974NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
2977 IN PIRP Irp,
2982 )
2983/*++
2984
2985Routine Description:
2986
2987 This routine is a callback into the driver to query for the contents of
2988 a data block. When the driver has finished filling the data block it
2989 must call ClassWmiCompleteRequest to complete the irp. The driver can
2990 return STATUS_PENDING if the irp cannot be completed immediately.
2991
2992Arguments:
2993
2994 DeviceObject is the device whose data block is being queried
2995
2996 Irp is the Irp that makes this request
2997
2998 GuidIndex is the index into the list of guids provided when the
2999 device registered
3000
3001 DataItemId has the id of the data item being set
3002
3003 BufferSize has the size of the data item passed
3004
3005 Buffer has the new values for the data item
3006
3007
3008Return Value:
3009
3010 status
3011
3012--*/
3013{
3015
3016 PAGED_CODE();
3017
3018 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataItem, Device %p, Irp %p, GuiIndex %d, DataId %d\n"
3019 " BufferSize %#x Buffer %p\n",
3022
3024 {
3026 } else {
3028 }
3029
3030 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskSetWmiDataItem Device %p, Irp %p returns %lx\n",
3032
3034 Irp,
3035 status,
3036 0,
3038
3039 return status;
3040}
3041
3042
3044NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
3047 IN PIRP Irp,
3053 )
3054/*++
3055
3056Routine Description:
3057
3058 This routine is a callback into the driver to execute a method. When the
3059 driver has finished filling the data block it must call
3060 ClassWmiCompleteRequest to complete the irp. The driver can
3061 return STATUS_PENDING if the irp cannot be completed immediately.
3062
3063Arguments:
3064
3065 DeviceObject is the device whose data block is being queried
3066
3067 Irp is the Irp that makes this request
3068
3069 GuidIndex is the index into the list of guids provided when the
3070 device registered
3071
3072 MethodId has the id of the method being called
3073
3074 InBufferSize has the size of the data block passed in as the input to
3075 the method.
3076
3077 OutBufferSize on entry has the maximum size available to write the
3078 returned data block.
3079
3080 Buffer is filled with the returned data block
3081
3082
3083Return Value:
3084
3085 status
3086
3087--*/
3088{
3089 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = DeviceObject->DeviceExtension;
3090 PCOMMON_DEVICE_EXTENSION commonExtension = DeviceObject->DeviceExtension;
3091 PDISK_DATA diskData = (PDISK_DATA)(commonExtension->DriverData);
3092 ULONG sizeNeeded = 0;
3094
3095 PAGED_CODE();
3096
3097 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskExecuteWmiMethod, DeviceObject %p, Irp %p, Guid Id %d, MethodId %d\n"
3098 " InBufferSize %#x, OutBufferSize %#x, Buffer %p\n",
3101
3102 switch(GuidIndex)
3103 {
3105 {
3106
3109 (diskData->FailurePredictionCapability ==
3111 (diskData->FailurePredictionCapability ==
3113
3114
3115 switch(MethodId)
3116 {
3117 //
3118 // void AllowPerformanceHit([in] boolean Allow)
3119 //
3121 {
3122 BOOLEAN allowPerfHit;
3123
3124 sizeNeeded = 0;
3125 if (InBufferSize >= sizeof(BOOLEAN))
3126 {
3128
3129 allowPerfHit = *((PBOOLEAN)Buffer);
3130 if (diskData->AllowFPPerfHit != allowPerfHit)
3131 {
3132 diskData->AllowFPPerfHit = allowPerfHit;
3133 if (diskData->FailurePredictionCapability ==
3135 {
3136 MODE_INFO_EXCEPTIONS modeInfo;
3137
3139 &modeInfo);
3140 if (NT_SUCCESS(status))
3141 {
3142 modeInfo.Perf = allowPerfHit ? 0 : 1;
3144 &modeInfo);
3145 }
3146 }
3147 else
3148 {
3150 }
3151 }
3152
3153 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: AllowPerformanceHit %x for device %p --> %lx\n",
3154 allowPerfHit,
3155 fdoExtension->DeviceObject,
3156 status));
3157 } else {
3159 }
3160 break;
3161 }
3162
3163 //
3164 // void EnableDisableHardwareFailurePrediction([in] boolean Enable)
3165 //
3167 {
3169
3170 sizeNeeded = 0;
3171 if (InBufferSize >= sizeof(BOOLEAN))
3172 {
3174 enable = *((PBOOLEAN)Buffer);
3175 if (!enable)
3176 {
3177 //
3178 // If we are disabling we need to also disable
3179 // polling
3180 //
3182 fdoExtension,
3183 enable,
3184 0);
3185 }
3186
3188 fdoExtension,
3189 enable);
3190
3191 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableDisableHardwareFailurePrediction: %x for device %p --> %lx\n",
3192 enable,
3193 fdoExtension->DeviceObject,
3194 status));
3195 } else {
3197 }
3198 break;
3199 }
3200
3201 //
3202 // void EnableDisableFailurePredictionPolling(
3203 // [in] uint32 Period,
3204 // [in] boolean Enable)
3205 //
3207 {
3209 ULONG period;
3210
3211 sizeNeeded = 0;
3212 if (InBufferSize >= (sizeof(ULONG) + sizeof(BOOLEAN)))
3213 {
3214 period = *((PULONG)Buffer);
3215 Buffer += sizeof(ULONG);
3216 enable = *((PBOOLEAN)Buffer);
3217
3219 fdoExtension,
3220 enable,
3221 period);
3222
3223 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableDisableFailurePredictionPolling: %x %x for device %p --> %lx\n",
3224 enable,
3225 period,
3226 fdoExtension->DeviceObject,
3227 status));
3228 } else {
3230 }
3231 break;
3232 }
3233
3234 //
3235 // void GetFailurePredictionCapability([out] uint32 Capability)
3236 //
3238 {
3239 sizeNeeded = sizeof(ULONG);
3240 if (OutBufferSize >= sizeNeeded)
3241 {
3244 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: GetFailurePredictionCapability: %x for device %p --> %lx\n",
3246 fdoExtension->DeviceObject,
3247 status));
3248 } else {
3250 }
3251 break;
3252 }
3253
3254 //
3255 // void EnableOfflineDiags([out] boolean Success);
3256 //
3257 case EnableOfflineDiags:
3258 {
3259 sizeNeeded = sizeof(BOOLEAN);
3260 if (OutBufferSize >= sizeNeeded)
3261 {
3262 if (diskData->FailurePredictionCapability ==
3264 {
3265 //
3266 // Initiate or resume offline diagnostics.
3267 // This may cause a loss of performance
3268 // to the disk, but mayincrease the amount
3269 // of disk checking.
3270 //
3271 status = DiskExecuteSmartDiagnostics(fdoExtension,
3272 0);
3273
3274 } else {
3276 }
3277
3279
3280 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "DiskFdoWmiExecuteMethod: EnableOfflineDiags for device %p --> %lx\n",
3281 fdoExtension->DeviceObject,
3282 status));
3283 } else {
3285 }
3286 break;
3287 }
3288
3289 //
3290 // void ReadLogSectors([in] uint8 LogAddress,
3291 // [in] uint8 SectorCount,
3292 // [out] uint32 Length,
3293 // [out, WmiSizeIs("Length")] uint8 LogSectors[]
3294 // );
3295 //
3296 case ReadLogSectors:
3297 {
3298 if (diskData->FailurePredictionCapability ==
3300 {
3301 if (InBufferSize >= sizeof(READ_LOG_SECTORS_IN))
3302 {
3303 PREAD_LOG_SECTORS_IN inParams;
3304 PREAD_LOG_SECTORS_OUT outParams;
3305 ULONG readSize;
3306
3307 inParams = (PREAD_LOG_SECTORS_IN)Buffer;
3308 readSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
3310 LogSectors) + readSize;
3311
3312 if (OutBufferSize >= sizeNeeded)
3313 {
3314 outParams = (PREAD_LOG_SECTORS_OUT)Buffer;
3315 status = DiskReadSmartLog(fdoExtension,
3316 inParams->SectorCount,
3317 inParams->LogAddress,
3318 outParams->LogSectors);
3319
3320 if (NT_SUCCESS(status))
3321 {
3322 outParams->Length = readSize;
3323 } else {
3324 //
3325 // SMART command failure is
3326 // indicated by successful
3327 // execution, but no data returned
3328 //
3329 outParams->Length = 0;
3331 }
3332 } else {
3334 }
3335
3336 } else {
3338 }
3339 } else {
3341 }
3342 break;
3343 }
3344
3345 // void WriteLogSectors([in] uint8 LogAddress,
3346 // [in] uint8 SectorCount,
3347 // [in] uint32 Length,
3348 // [in, WmiSizeIs("Length")] uint8 LogSectors[],
3349 // [out] boolean Success
3350 // );
3351 case WriteLogSectors:
3352 {
3353 if (diskData->FailurePredictionCapability ==
3355 {
3357 LogSectors))
3358 {
3359 PWRITE_LOG_SECTORS_IN inParams;
3360 PWRITE_LOG_SECTORS_OUT outParams;
3361 ULONG writeSize;
3362
3363 inParams = (PWRITE_LOG_SECTORS_IN)Buffer;
3364 writeSize = inParams->SectorCount * SMART_LOG_SECTOR_SIZE;
3366 LogSectors) +
3367 writeSize))
3368 {
3369 sizeNeeded = sizeof(WRITE_LOG_SECTORS_OUT);
3370
3371 if (OutBufferSize >= sizeNeeded)
3372 {
3373 outParams = (PWRITE_LOG_SECTORS_OUT)Buffer;
3374 status = DiskWriteSmartLog(fdoExtension,
3375 inParams->SectorCount,
3376 inParams->LogAddress,
3377 inParams->LogSectors);
3378
3379 if (NT_SUCCESS(status))
3380 {
3381 outParams->Success = TRUE;
3382 } else {
3383 outParams->Success = FALSE;
3385 }
3386 } else {
3388 }
3389 } else {
3391 }
3392 } else {
3394 }
3395 } else {
3397 }
3398 break;
3399 }
3400
3401 // void ExecuteSelfTest([in] uint8 Subcommand,
3402 // [out,
3403 // Values{"0", "1", "2"},
3404 // ValueMap{"Successful Completion",
3405 // "Captive Mode Required",
3406 // "Unsuccessful Completion"}
3407 // ]
3408 // uint32 ReturnCode);
3409 case ExecuteSelfTest:
3410 {
3411 if (diskData->FailurePredictionCapability ==
3413 {
3414 if (InBufferSize >= sizeof(EXECUTE_SELF_TEST_IN))
3415 {
3416 sizeNeeded = sizeof(EXECUTE_SELF_TEST_OUT);
3417 if (OutBufferSize >= sizeNeeded)
3418 {
3419 PEXECUTE_SELF_TEST_IN inParam;
3420 PEXECUTE_SELF_TEST_OUT outParam;
3421
3422 inParam = (PEXECUTE_SELF_TEST_IN)Buffer;
3423 outParam = (PEXECUTE_SELF_TEST_OUT)Buffer;
3424
3426 {
3427 status = DiskExecuteSmartDiagnostics(fdoExtension,
3428 inParam->Subcommand);
3429 if (NT_SUCCESS(status))
3430 {
3431 //
3432 // Return self test executed
3433 // without a problem
3434 //
3435 outParam->ReturnCode = 0;
3436 } else {
3437 //
3438 // Return Self test execution
3439 // failed status
3440 //
3441 outParam->ReturnCode = 2;
3443 }
3444 } else {
3445 //
3446 // If self test subcommand requires
3447 // captive mode then return that
3448 // status
3449 //
3450 outParam->ReturnCode = 1;
3452 }
3453
3454 } else {
3456 }
3457
3458 } else {
3460 }
3461 } else {
3463 }
3464
3465 break;
3466 }
3467
3468 default :
3469 {
3470 sizeNeeded = 0;
3472 break;
3473 }
3474 }
3475
3476 break;
3477 }
3478
3479 case DiskGeometryGuid:
3480 case SmartStatusGuid:
3481 case SmartDataGuid:
3482 case SmartEventGuid:
3485 {
3486 sizeNeeded = 0;
3488 break;
3489 }
3490
3491 default:
3492 {
3493 sizeNeeded = 0;
3495 }
3496 }
3497
3498 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_WMI, "Disk: DiskExecuteMethod Device %p, Irp %p returns %lx\n",
3500
3502 Irp,
3503 status,
3504 sizeNeeded,
3506
3507 return status;
3508}
3509
3510
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
#define VOID
Definition: acefi.h:82
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define ID_CMD
Definition: helper.h:20
#define SMART_CMD
Definition: helper.h:21
struct _SENDCMDINPARAMS SENDCMDINPARAMS
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
LONG NTSTATUS
Definition: precomp.h:26
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1326
#define MODE_DATA_SIZE
Definition: cdrom.h:691
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
_In_ CDROM_SCAN_FOR_SPECIAL_INFO _In_ PCDROM_SCAN_FOR_SPECIAL_HANDLER Function
Definition: cdrom.h:1156
_In_ ULONG const _In_ FEATURE_NUMBER const Feature
Definition: cdrom.h:1077
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define CLEAR_FLAG(Flags, Bit)
Definition: cdrom.h:1494
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
_In_ ULONG _In_ UCHAR _In_ UCHAR PageControl
Definition: cdrom.h:1319
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
union _CDB * PCDB
Definition: bufpool.h:45
#define CLASS_SRBEX_NO_SRBEX_DATA_BUFFER_SIZE
Definition: classpnp.h:696
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
_Out_ ULONG * RegFlags
Definition: classpnp.h:403
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
_In_ PIRP _In_ ULONG GuidIndex
Definition: classpnp.h:419
enum FAILURE_PREDICTION_METHOD * PFAILURE_PREDICTION_METHOD
CLASSENABLEDISABLEFUNCTION
Definition: classpnp.h:228
@ DataBlockCollection
Definition: classpnp.h:230
@ EventGeneration
Definition: classpnp.h:229
_In_ PIRP _In_ ULONG _In_ ULONG BufferAvail
Definition: classpnp.h:420
@ FailurePredictionSense
Definition: classpnp.h:237
@ FailurePredictionSmart
Definition: classpnp.h:236
@ FailurePredictionNone
Definition: classpnp.h:234
@ FailurePredictionIoctl
Definition: classpnp.h:235
SCSIPORT_API NTSTATUS NTAPI ClassWmiCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp, _In_ NTSTATUS Status, _In_ ULONG BufferUsed, _In_ CCHAR PriorityBoost)
Definition: classwmi.c:1009
_In_ PIRP Irp
Definition: csq.h:116
NTSTATUS DiskEnableDisableFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable)
Definition: diskwmi.c:1126
#define SmartDataGuid
Definition: diskwmi.c:142
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:2975
NTSTATUS NTAPI DiskWmiFunctionControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN CLASSENABLEDISABLEFUNCTION Function, IN BOOLEAN Enable)
Definition: diskwmi.c:2366
GUIDREGINFO DiskWmiFdoGuidList[]
Definition: diskwmi.c:92
NTSTATUS 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:476
#define DiskReadSmartStatus(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:236
NTSTATUS DiskDetectFailurePrediction(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PFAILURE_PREDICTION_METHOD FailurePredictCapability, BOOLEAN ScsiAddressAvailable)
Definition: diskwmi.c:2230
NTSTATUS NTAPI DiskFdoQueryWmiRegInfoEx(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName, OUT PUNICODE_STRING MofName)
Definition: diskwmi.c:2577
#define ScsiInfoExceptionsGuid
Definition: diskwmi.c:152
#define DiskReadSmartData(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:200
SINGLE_LIST_ENTRY DiskReregHead
Definition: diskwmi.c:88
GUID DiskPredictFailureEventGuid
Definition: diskwmi.c:138
#define SmartEventGuid
Definition: diskwmi.c:150
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:3045
NTSTATUS DiskInitializeReregistration(VOID)
Definition: diskwmi.c:1560
_inline NTSTATUS DiskEnableSmartAttributeAutosave(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:315
NTSTATUS DiskSendFailurePredictIoctl(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_PREDICT_FAILURE checkFailure)
Definition: diskwmi.c:854
#define SmartPerformFunction
Definition: diskwmi.c:143
NTSTATUS DiskEnableInfoExceptions(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ BOOLEAN Enable)
Definition: diskwmi.c:979
_inline NTSTATUS DiskDisableSmartAttributeAutosave(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:337
static NTSTATUS DiskEnableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:271
NTSTATUS DiskWriteSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, IN PUCHAR Buffer)
Definition: diskwmi.c:429
#define GetFailurePredictionCapability
Definition: diskwmi.c:147
NTSTATUS DiskInfoExceptionCheck(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:1922
IO_COMPLETION_ROUTINE DiskInfoExceptionComplete
Definition: diskwmi.c:72
KSPIN_LOCK DiskReregSpinlock
Definition: diskwmi.c:89
NTSTATUS DiskGetIdentifyInfo(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PBOOLEAN SupportSmart)
Definition: diskwmi.c:813
LONG DiskReregWorkItems
Definition: diskwmi.c:90
#define EnableDisableFailurePredictionPolling
Definition: diskwmi.c:146
#define EnableDisableHardwareFailurePrediction
Definition: diskwmi.c:145
IO_WORKITEM_ROUTINE DiskReregWorker
Definition: diskwmi.c:70
#define EnableOfflineDiags
Definition: diskwmi.c:148
NTSTATUS DiskReadFailurePredictThresholds(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_THRESHOLDS DiskSmartThresholds)
Definition: diskwmi.c:1417
NTSTATUS DiskReadFailurePredictStatus(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_STATUS DiskSmartStatus)
Definition: diskwmi.c:1251
NTSTATUS DiskPostReregisterRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: diskwmi.c:1577
NTSTATUS NTAPI DiskFdoQueryWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferAvail, OUT PUCHAR Buffer)
Definition: diskwmi.c:2638
#define DiskGeometryGuid
Definition: diskwmi.c:140
#define DiskReadSmartThresholds(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:218
#define SmartStatusGuid
Definition: diskwmi.c:141
static NTSTATUS DiskExecuteSmartDiagnostics(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, UCHAR Subcommand)
Definition: diskwmi.c:359
#define SmartThresholdsGuid
Definition: diskwmi.c:151
static NTSTATUS DiskDisableSmart(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: diskwmi.c:293
#define AllowDisallowPerformanceHit
Definition: diskwmi.c:144
NTSTATUS NTAPI DiskFdoQueryWmiRegInfo(IN PDEVICE_OBJECT DeviceObject, OUT ULONG *RegFlags, OUT PUNICODE_STRING InstanceName)
Definition: diskwmi.c:2479
NTSTATUS DiskEnableDisableFailurePredictPolling(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, BOOLEAN Enable, ULONG PollTimeInSeconds)
Definition: diskwmi.c:1193
NTSTATUS DiskReadFailurePredictData(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, PSTORAGE_FAILURE_PREDICT_DATA DiskSmartData)
Definition: diskwmi.c:1327
NTSTATUS DiskGetModePage(_In_ PDEVICE_OBJECT Fdo, _In_ UCHAR PageMode, _In_ UCHAR PageControl, _In_ PMODE_PARAMETER_HEADER ModeData, _Inout_ PULONG ModeDataSize, _Out_ PVOID *PageData)
Definition: diskwmi.c:903
NTSTATUS NTAPI DiskFdoSetWmiDataBlock(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG GuidIndex, IN ULONG BufferSize, IN PUCHAR Buffer)
Definition: diskwmi.c:2869
#define DiskGetIdentifyData(FdoExtension, SrbControl, BufferSize)
Definition: diskwmi.c:254
NTSTATUS DiskReadSmartLog(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN UCHAR SectorCount, IN UCHAR LogAddress, OUT PUCHAR Buffer)
Definition: diskwmi.c:379
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR Signature[]
Definition: parser.c:141
struct _COMMON_DEVICE_EXTENSION * PCOMMON_DEVICE_EXTENSION
PVOID NTAPI ClassFindModePage(_In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ BOOLEAN Use6Byte)
Definition: class.c:6798
NTSTATUS NTAPI ClassModeSelect(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSelectBuffer, _In_ ULONG Length, _In_ BOOLEAN SavePages)
Definition: class.c:6873
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
ULONG NTAPI ClassModeSenseEx(_In_ PDEVICE_OBJECT Fdo, _In_reads_bytes_(Length) PCHAR ModeSenseBuffer, _In_ ULONG Length, _In_ UCHAR PageMode, _In_ UCHAR PageControl)
Definition: class.c:6656
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_opt_ _Deref_out_range_(0, 100) ULONG *RetryInterval)
Definition: class.c:4452
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
NTSTATUS DiskGetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS ReturnPageData)
Definition: disk.c:2896
NTSTATUS DiskSetInfoExceptionInformation(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN PMODE_INFO_EXCEPTIONS PageData)
Definition: disk.c:2985
#define DiskIsValidSmartSelfTest(Subcommand)
Definition: disk.h:619
struct DISKREREGREQUEST * PDISKREREGREQUEST
FORCEINLINE VOID SetSrbScsiData(_In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_ UCHAR CdbLength8, _In_ ULONG CdbLength32, _In_ UCHAR ScsiStatus, _In_opt_ PVOID SenseInfoBuffer, _In_ UCHAR SenseInfoBufferLength)
Definition: disk.h:1184
#define DiskReadDriveCapacity(Fdo)
Definition: disk.h:818
#define DISK_TAG_SRB
Definition: disk.h:67
struct _DISK_DATA * PDISK_DATA
#define DISK_TAG_INFO_EXCEPTION
Definition: disk.h:55
#define DISK_TAG_SMART
Definition: disk.h:54
FORCEINLINE PCDB GetSrbScsiData(_In_ PSTORAGE_REQUEST_BLOCK SrbEx, _In_opt_ PUCHAR CdbLength8, _In_opt_ PULONG CdbLength32, _In_opt_ PUCHAR ScsiStatus, _In_opt_ PVOID *SenseInfoBuffer, _In_opt_ PUCHAR SenseInfoBufferLength)
Definition: disk.h:994
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG
Definition: scsi.h:1421
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG
Definition: scsi.h:1420
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:282
#define SP_UNTAGGED
Definition: srb.h:233
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:317
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:396
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_FLAGS_NO_KEEP_AWAKE
Definition: srb.h:412
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:404
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
@ FdoExtension
Definition: precomp.h:48
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
_Must_inspect_result_ _Inout_ PFLT_VOLUME _In_opt_ PCUNICODE_STRING InstanceName
Definition: fltkernel.h:1163
MxDeviceObject deviceObject
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
PVOID dataBuffer
FxIrp * irp
size_t bufferSize
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLboolean enable
Definition: glext.h:11120
PSINGLE_LIST_ENTRY NTAPI ExInterlockedPopEntryList(IN OUT PSINGLE_LIST_ENTRY ListHead, IN OUT PKSPIN_LOCK Lock)
Definition: interlocked.c:201
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
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
IoMarkIrpPending(Irp)
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:424
#define min(a, b)
Definition: monoChain.cc:55
#define _Inout_
Definition: ms_sal.h:378
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define KernelMode
Definition: asm.h:34
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define SMART_WRITE_LOG
Definition: ntdddisk.h:750
#define SMART_CYL_LOW
Definition: ntdddisk.h:679
#define EXECUTE_OFFLINE_DIAGS
Definition: ntdddisk.h:748
#define READ_ATTRIBUTE_BUFFER_SIZE
Definition: ntdddisk.h:731
#define ENABLE_SMART
Definition: ntdddisk.h:751
struct _DISK_GEOMETRY DISK_GEOMETRY
#define SAVE_ATTRIBUTE_VALUES
Definition: ntdddisk.h:747
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:753
#define READ_THRESHOLDS
Definition: ntdddisk.h:745
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:732
#define SMART_READ_LOG
Definition: ntdddisk.h:749
#define SMART_LOG_SECTOR_SIZE
Definition: ntdddisk.h:734
#define DISABLE_SMART
Definition: ntdddisk.h:752
#define WMI_DISK_GEOMETRY_GUID
Definition: ntdddisk.h:369
#define READ_ATTRIBUTES
Definition: ntdddisk.h:744
#define READ_THRESHOLD_BUFFER_SIZE
Definition: ntdddisk.h:733
#define ENABLE_DISABLE_AUTOSAVE
Definition: ntdddisk.h:746
#define SMART_CYL_HI
Definition: ntdddisk.h:680
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define IOCTL_STORAGE_PREDICT_FAILURE
Definition: ntddstor.h:146
struct _STORAGE_PREDICT_FAILURE * PSTORAGE_PREDICT_FAILURE
@ NotificationEvent
@ SynchronizationEvent
PDEVICE_OBJECT NTAPI IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1406
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
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
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
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
NTSTATUS NTAPI IoWMIRegistrationControl(IN PDEVICE_OBJECT DeviceObject, IN ULONG Action)
Definition: wmi.c:68
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_WMI_ITEMID_NOT_FOUND
Definition: ntstatus.h:778
#define STATUS_WMI_GUID_NOT_FOUND
Definition: ntstatus.h:776
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_WMI_READ_ONLY
Definition: ntstatus.h:818
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
ULONG SectorCount
Definition: part_xbox.c:31
#define BOOLEAN
Definition: pedump.c:73
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
struct _SRB_IO_CONTROL SRB_IO_CONTROL
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 * PSTOR_ADDR_BTL8
#define MODE_PAGE_FAULT_REPORTING
Definition: scsi.h:218
struct _MODE_INFO_EXCEPTIONS MODE_INFO_EXCEPTIONS
#define STOR_ADDRESS_TYPE_BTL8
Definition: scsi.h:3525
struct STOR_ADDRESS_ALIGN _STOR_ADDR_BTL8 STOR_ADDR_BTL8
PFIXED_SENSE_DATA senseInfoBuffer
Definition: scsi.h:3710
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
PFIXED_SENSE_DATA outBuffer
Definition: scsi.h:4022
#define STOR_ADDR_BTL8_ADDRESS_LENGTH
Definition: scsi.h:3528
ULONG dataLength
Definition: scsi.h:3751
#define SRB_SIGNATURE
Definition: srb.h:616
#define STORAGE_REQUEST_BLOCK_VERSION_1
Definition: srb.h:617
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 SRBEX_DATA_SCSI_CDB16
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
#define SRB_FUNCTION_STORAGE_REQUEST_BLOCK
Definition: srb.h:108
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:661
@ SrbExDataTypeScsiCdb16
Definition: srb.h:459
struct SRB_ALIGN _SRBEX_DATA_SCSI_CDB16 * PSRBEX_DATA_SCSI_CDB16
STORAGE_REQUEST_BLOCK
Definition: srb.h:661
#define SRBEX_DATA_SCSI_CDB16_LENGTH
Definition: srb.h:489
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:174
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
Definition: shell.h:41
SINGLE_LIST_ENTRY Next
Definition: disk.h:430
PDEVICE_OBJECT DeviceObject
Definition: disk.h:431
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
BOOLEAN AllowFPPerfHit
Definition: disk.h:332
NTSTATUS ReadyStatus
Definition: disk.h:319
BOOLEAN ScsiInfoExceptionsSupported
Definition: disk.h:340
FAILURE_PREDICTION_METHOD FailurePredictionCapability
Definition: disk.h:331
BOOLEAN FailurePredictionEnabled
Definition: disk.h:346
SCSI_ADDRESS ScsiAddress
Definition: disk.h:325
PDEVICE_OBJECT DeviceObject
Definition: classpnp.h:871
DISK_GEOMETRY DiskGeometry
Definition: classpnp.h:888
Definition: helper.h:8
UCHAR bCylHighReg
Definition: helper.h:13
UCHAR bSectorNumberReg
Definition: helper.h:11
UCHAR bCylLowReg
Definition: helper.h:12
UCHAR bSectorCountReg
Definition: helper.h:10
UCHAR bFeaturesReg
Definition: helper.h:9
UCHAR bCommandReg
Definition: helper.h:15
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3978::@4017 Others
union _IO_STACK_LOCATION::@1564 Parameters
struct _IO_STACK_LOCATION::@3978::@4000 Scsi
UCHAR ReportCount[4]
Definition: scsi.h:3029
UCHAR IntervalTimer[4]
Definition: scsi.h:3028
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR QueueTag
Definition: srb.h:256
ULONG TimeOutValue
Definition: srb.h:262
UCHAR TargetId
Definition: srb.h:254
PVOID OriginalRequest
Definition: srb.h:266
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID DataBuffer
Definition: srb.h:263
UCHAR PathId
Definition: srb.h:253
UCHAR QueueAction
Definition: srb.h:257
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
UCHAR bDriveNumber
Definition: helper.h:33
ULONG cBufferSize
Definition: helper.h:31
IDEREGS irDriveRegs
Definition: helper.h:32
UCHAR bBuffer[1]
Definition: helper.h:36
UCHAR bBuffer[1]
Definition: helper.h:27
Definition: ntbasedef.h:628
UCHAR VendorSpecific[512]
Definition: ntddstor.h:501
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char CCHAR
Definition: typedefs.h:51
char * PCHAR
Definition: typedefs.h:51
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: cdrw_hw.h:28
struct _CDB::_MODE_SENSE MODE_SENSE
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
_In_ ULONG OutBufferSize
Definition: wdfwmi.h:87
_In_ ULONG InBufferSize
Definition: wdfwmi.h:106
_In_ ULONG MethodId
Definition: wdfwmi.h:142
_In_ ULONG DataItemId
Definition: wdfwmi.h:123
struct _STORAGE_FAILURE_PREDICT_DATA * PSTORAGE_FAILURE_PREDICT_DATA
#define ReadLogSectors
Definition: wmidata.h:3374
struct _STORAGE_FAILURE_PREDICT_STATUS * PSTORAGE_FAILURE_PREDICT_STATUS
#define WMI_STORAGE_FAILURE_PREDICT_FUNCTION_GUID
Definition: wmidata.h:333
struct _STORAGE_SCSI_INFO_EXCEPTIONS * PSTORAGE_SCSI_INFO_EXCEPTIONS
#define WMI_STORAGE_FAILURE_PREDICT_THRESHOLDS_GUID
Definition: wmidata.h:335
struct _EXECUTE_SELF_TEST_IN * PEXECUTE_SELF_TEST_IN
#define ExecuteSelfTest
Definition: wmidata.h:3407
struct _WRITE_LOG_SECTORS_OUT WRITE_LOG_SECTORS_OUT
#define WMI_STORAGE_SCSI_INFO_EXCEPTIONS_GUID
Definition: wmidata.h:337
struct _WRITE_LOG_SECTORS_IN * PWRITE_LOG_SECTORS_IN
#define WriteLogSectors
Definition: wmidata.h:3387
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS STORAGE_FAILURE_PREDICT_THRESHOLDS
#define WMI_STORAGE_FAILURE_PREDICT_STATUS_GUID
Definition: wmidata.h:334
struct _READ_LOG_SECTORS_IN * PREAD_LOG_SECTORS_IN
struct _STORAGE_FAILURE_PREDICT_STATUS STORAGE_FAILURE_PREDICT_STATUS
struct _STORAGE_FAILURE_PREDICT_THRESHOLDS * PSTORAGE_FAILURE_PREDICT_THRESHOLDS
struct _STORAGE_FAILURE_PREDICT_DATA STORAGE_FAILURE_PREDICT_DATA
struct _STORAGE_SCSI_INFO_EXCEPTIONS STORAGE_SCSI_INFO_EXCEPTIONS
struct _EXECUTE_SELF_TEST_OUT * PEXECUTE_SELF_TEST_OUT
struct _EXECUTE_SELF_TEST_OUT EXECUTE_SELF_TEST_OUT
#define WMI_STORAGE_PREDICT_FAILURE_EVENT_GUID
Definition: wmidata.h:336
struct _WRITE_LOG_SECTORS_OUT * PWRITE_LOG_SECTORS_OUT
#define WMI_STORAGE_FAILURE_PREDICT_DATA_GUID
Definition: wmidata.h:332
struct _READ_LOG_SECTORS_OUT * PREAD_LOG_SECTORS_OUT
#define WMIREG_FLAG_INSTANCE_PDO
Definition: wmistr.h:69
#define WMIREG_FLAG_REMOVE_GUID
Definition: wmistr.h:70
#define WMIREG_FLAG_EVENT_ONLY_GUID
Definition: wmistr.h:75
#define WMIREG_FLAG_EXPENSIVE
Definition: wmistr.h:66
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
@ DelayedWorkQueue
Definition: extypes.h:190
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
NTKRNLVISTAAPI IO_PRIORITY_HINT NTAPI IoGetIoPriorityHint(_In_ PIRP Irp)
Definition: io.c:123
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2680
#define IRP_MJ_SCSI
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define WMIREG_ACTION_UPDATE_GUIDS
@ Executive
Definition: ketypes.h:415
#define MmGetMdlVirtualAddress(_Mdl)
#define ObDereferenceObject
Definition: obfuncs.h:203
#define NT_ASSERT
Definition: rtlfuncs.h:3310
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3311
unsigned char UCHAR
Definition: xmlstorage.h:181