1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
|
/*++
Copyright (C) 2004 Microsoft Corporation
Module Name:
prototypes.h
Abstract:
Contains function prototypes for all the functions defined
by Microsoft Device Specific Module (DSM).
Environment:
kernel mode only
Notes:
--*/
#pragma warning (disable:4214) // bit field usage
#pragma warning (disable:4200) // zero-sized array
#ifndef _PROTOTYPES_H_
#define _PROTOTYPES_H_
#define DSM_VENDOR_ID_LEN 8
#define DSM_PRODUCT_ID_LEN 16
#define DSM_VENDPROD_ID_LEN 24
//
// In accordance with SPC-3 specs
//
#define SPC3_TARGET_PORT_GROUPS_HEADER_SIZE 4
typedef struct _SPC3_CDB_REPORT_TARGET_PORT_GROUPS {
UCHAR OperationCode;
UCHAR ServiceAction : 5;
UCHAR Reserved1 : 3;
UCHAR Reserved2[4];
UCHAR AllocationLength[4];
UCHAR Reserved3;
UCHAR Control;
} SPC3_CDB_REPORT_TARGET_PORT_GROUPS, *PSPC3_CDB_REPORT_TARGET_PORT_GROUPS;
typedef struct _SPC3_REPORT_TARGET_PORT_GROUP_DESCRIPTOR {
UCHAR AsymmetricAccessState : 4;
UCHAR Reserved : 3;
UCHAR Preferred : 1;
UCHAR ActiveOptimizedSupported : 1;
UCHAR ActiveUnoptimizedSupported : 1;
UCHAR StandbySupported : 1;
UCHAR UnavailableSupported : 1;
UCHAR Reserved2 : 3;
UCHAR TransitioningSupported : 1;
USHORT TPG_Identifier;
UCHAR Reserved3;
UCHAR StatusCode;
UCHAR VendorUnique;
UCHAR NumberTargetPorts;
ULONG TargetPortIds[0];
} SPC3_REPORT_TARGET_PORT_GROUP_DESCRIPTOR, *PSPC3_REPORT_TARGET_PORT_GROUP_DESCRIPTOR;
typedef struct _SPC3_CDB_SET_TARGET_PORT_GROUPS {
UCHAR OperationCode;
UCHAR ServiceAction : 5;
UCHAR Reserved1 : 3;
UCHAR Reserved2[4];
UCHAR ParameterListLength[4];
UCHAR Reserved3;
UCHAR Control;
} SPC3_CDB_SET_TARGET_PORT_GROUPS, *PSPC3_CDB_SET_TARGET_PORT_GROUPS;
typedef struct _SPC3_SET_TARGET_PORT_GROUP_DESCRIPTOR {
UCHAR AsymmetricAccessState : 4;
UCHAR Reserved1 : 4;
UCHAR Reserved2;
USHORT TPG_Identifier;
} SPC3_SET_TARGET_PORT_GROUP_DESCRIPTOR, *PSPC3_SET_TARGET_PORT_GROUP_DESCRIPTOR;
typedef struct _SPC3_CONTROL_EXTENSION_MODE_PAGE {
UCHAR PageCode : 6;
UCHAR SubpageFormat : 1;
UCHAR ParametersSavable : 1;
UCHAR SubpageCode;
UCHAR PageLength[2];
UCHAR ImplicitALUAEnable : 1;
UCHAR ScsiPrecendence : 1;
UCHAR TimestampChangeable : 1;
UCHAR Reserved1 : 5;
UCHAR InitialPriority : 4;
UCHAR Reserved2 : 4;
UCHAR Reserved3[26];
} SPC3_CONTROL_EXTENSION_MODE_PAGE, *PSPC3_CONTROL_EXTENSION_MODE_PAGE;
#define SPC3_SCSIOP_REPORT_TARGET_PORT_GROUPS 0xA3
#define SPC3_SCSIOP_SET_TARGET_PORT_GROUPS 0xA4
#define SPC3_SERVICE_ACTION_TARGET_PORT_GROUPS 0xA
#define SPC3_RESERVATION_ACTION_REPORT_CAPABILITIES 0x2
#define SPC3_SCSI_ADSENSE_COMMANDS_CLEARED_BY_ANOTHER_INITIATOR 0x2F
#define SPC3_SCSI_ADSENSE_LOGICAL_UNIT_COMMAND_FAILED 0x67
#define SPC3_SCSI_SENSEQ_MODE_PARAMETERS_CHANGED 0x1
#define SPC3_SCSI_SENSEQ_RESERVATIONS_PREEMPTED 0x3
#define SPC3_SCSI_SENSEQ_RESERVATIONS_RELEASED 0x4
#define SPC3_SCSI_SENSEQ_REGISTRATIONS_PREEMPTED 0x5
#define SPC3_SCSI_SENSEQ_ASYMMETRIC_ACCESS_STATE_CHANGED 0x6
#define SPC3_SCSI_SENSEQ_IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED 0x7
#define SPC3_SCSI_SENSEQ_CAPACITY_DATA_HAS_CHANGED 0x9
#define SPC3_SCSI_SENSEQ_ASYMMETRIC_ACCESS_STATE_TRANSITION 0xA
#define SPC3_SCSI_SENSEQ_TARGET_PORT_IN_STANDBY_STATE 0xB
#define SPC3_SCSI_SENSEQ_TARGET_PORT_IN_UNAVAILABLE_STATE 0xC
#define SPC3_SCSI_SENSEQ_SET_TARGET_PORT_GROUPS_FAILED 0xA
#define SPC3_SET_TARGET_PORT_GROUPS_TIMEOUT 10
#define SPC3_REPORT_TARGET_PORT_GROUPS_TIMEOUT 10
//
// Function prototypes for functions intrface.c
//
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DsmDriverUnload;
NTSTATUS
DsmInquire (
_In_ IN PVOID DsmContext,
_In_ IN PDEVICE_OBJECT TargetDevice,
_In_ IN PDEVICE_OBJECT PortObject,
_In_ IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
_In_ IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceIdList,
_Out_ OUT PVOID *DsmIdentifier
);
BOOLEAN
DsmCompareDevices(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId1,
_In_ IN PVOID DsmId2
);
NTSTATUS
DsmGetControllerInfo(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId,
_In_ IN ULONG Flags,
_Inout_ IN OUT PCONTROLLER_INFO *ControllerInfo
);
NTSTATUS
DsmSetDeviceInfo(
_In_ IN PVOID DsmContext,
_In_ IN PDEVICE_OBJECT TargetObject,
_In_ IN PVOID DsmId,
_Inout_ IN OUT PVOID *PathId
);
BOOLEAN
DsmIsPathActive(
_In_ IN PVOID DsmContext,
_In_ IN PVOID PathId,
_In_ IN PVOID DsmId
);
NTSTATUS
DsmPathVerify(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId,
_In_ IN PVOID PathId
);
NTSTATUS
DsmInvalidatePath(
_In_ IN PVOID DsmContext,
_In_ IN ULONG ErrorMask,
_In_ IN PVOID PathId,
_Inout_ IN OUT PVOID *NewPathId
);
NTSTATUS
DsmMoveDevice(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PVOID MPIOPath,
_In_ IN PVOID SuggestedPath,
_In_ IN ULONG Flags
);
NTSTATUS
DsmRemovePending(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId
);
NTSTATUS
DsmRemoveDevice(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId,
_In_ IN PVOID PathId
);
NTSTATUS
DsmRemovePath(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PVOID PathId
);
NTSTATUS
DsmSrbDeviceControl(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PKEVENT Event
);
PVOID
DsmLBGetPath(
_In_ IN PVOID DsmContext,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PDSM_IDS DsmList,
_In_ IN PVOID CurrentPath,
_Out_ OUT NTSTATUS *Status
);
ULONG
DsmInterpretError(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_Inout_ IN OUT NTSTATUS *Status,
_Out_ OUT PBOOLEAN Retry,
_Out_ OUT PLONG RetryInterval,
...
);
NTSTATUS
DsmUnload(
_In_ IN PVOID DsmContext
);
VOID
DsmSetCompletion(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_Inout_ IN OUT PDSM_COMPLETION_INFO DsmCompletion
);
_Success_(return == DSM_PATH_SET)
ULONG
DsmCategorizeRequest(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PVOID CurrentPath,
_Outptr_result_maybenull_ OUT PVOID *PathId,
_Out_ OUT NTSTATUS *Status
);
NTSTATUS
DsmBroadcastRequest(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PKEVENT Event
);
BOOLEAN
DsmIsAddressTypeSupported(
_In_ IN PVOID DsmContext,
_In_ IN ULONG AddressType
);
NTSTATUS
DsmDeviceNotUsed(
_In_ IN PVOID DsmContext,
_In_ IN PVOID DsmId
);
//
// Function prototypes for functions in dsmmain.c
//
VOID
DsmpFreeDSMResources(
_In_ IN PDSM_CONTEXT DsmContext
);
PDSM_GROUP_ENTRY
DsmpFindDevice(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN BOOLEAN AcquireDSMLockExclusive
);
PDSM_GROUP_ENTRY
DsmpBuildGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
NTSTATUS
DsmpParseTargetPortGroupsInformation(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_reads_bytes_(TargetPortGroupsInfoLength) IN PUCHAR TargetPortGroupsInfo,
_In_ IN ULONG TargetPortGroupsInfoLength
);
PDSM_TARGET_PORT_GROUP_ENTRY
DsmpFindTargetPortGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_reads_bytes_(TPGs_BufferLength) IN PUCHAR TargetPortGroupsDescriptor,
_In_ IN ULONG TPGs_BufferLength
);
_Success_(return!=0)
PDSM_TARGET_PORT_GROUP_ENTRY
DsmpUpdateTargetPortGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_TARGET_PORT_GROUP_ENTRY TargetPortGroup,
_In_reads_bytes_(TPGs_BufferLength) IN PUCHAR TargetPortGroupsDescriptor,
_In_ IN ULONG TPGs_BufferLength,
_Out_ OUT PULONG DescriptorSize
);
PDSM_TARGET_PORT_GROUP_ENTRY
DsmpBuildTargetPortGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_reads_bytes_(TPGs_BufferLength) IN PUCHAR TargetPortGroupsDescriptor,
_In_ IN ULONG TPGs_BufferLength,
_Out_ OUT PULONG DescriptorSize
);
PDSM_TARGET_PORT_LIST_ENTRY
DsmpFindTargetPortListEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_TARGET_PORT_GROUP_ENTRY TargetPortGroup,
_In_ IN ULONG RelativeTargetPortId
);
PDSM_TARGET_PORT_LIST_ENTRY
DsmpBuildTargetPortListEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_TARGET_PORT_GROUP_ENTRY TargetPortGroup,
_In_ IN ULONG RelativeTargetPortId
);
PDSM_TARGET_PORT_GROUP_ENTRY
DsmpFindTargetPortGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PUSHORT TargetPortGroupId
);
PDSM_TARGET_PORT_LIST_ENTRY
DsmpFindTargetPort(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_TARGET_PORT_GROUP_ENTRY TargetPortGroup,
_In_ IN PULONG TargetPortGroupId
);
NTSTATUS
DsmpAddDeviceEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
PDSM_CONTROLLER_LIST_ENTRY
DsmpFindControllerEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDEVICE_OBJECT PortObject,
_In_ IN PSCSI_ADDRESS ScsiAddress,
_In_reads_(ControllerSerialNumberLength) IN PSTR ControllerSerialNumber,
_In_ IN SIZE_T ControllerSerialNumberLength,
_In_ IN STORAGE_IDENTIFIER_CODE_SET CodeSet,
_In_ IN BOOLEAN AcquireLock
);
_Ret_maybenull_
_Must_inspect_result_
_When_(return != NULL, __drv_allocatesMem(Mem))
PDSM_CONTROLLER_LIST_ENTRY
DsmpBuildControllerEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_opt_ IN PDEVICE_OBJECT DeviceObject,
_In_ IN PDEVICE_OBJECT PortObject,
_In_ IN PSCSI_ADDRESS ScsiAddress,
_In_ IN PSTR ControllerSerialNumber,
_In_ IN STORAGE_IDENTIFIER_CODE_SET CodeSet,
_In_ IN BOOLEAN AcquireLock
);
VOID
DsmpFreeControllerEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ __drv_freesMem(Mem) IN PDSM_CONTROLLER_LIST_ENTRY ControllerEntry
);
BOOLEAN
DsmpIsDeviceBelongsToController(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN PDSM_CONTROLLER_LIST_ENTRY ControllerEntry
);
PDSM_DEVICE_INFO
DsmpFindDevInfoFromGroupAndFOGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_FAILOVER_GROUP FOGroup
);
PDSM_FAILOVER_GROUP
DsmpFindFOGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PVOID PathId
);
PDSM_FAILOVER_GROUP
DsmpBuildFOGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN PVOID *PathId
);
NTSTATUS
DsmpUpdateFOGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_FAILOVER_GROUP FailGroup,
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
VOID
DsmpRemoveDeviceFailGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_FAILOVER_GROUP FailGroup,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN BOOLEAN AcquireDSMLockExclusive
);
ULONG
DsmpRemoveDeviceEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
VOID
DsmpRemoveDeviceFromTargetPortList(
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
PDSM_FAILOVER_GROUP
DsmpSetNewPath(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO FailingDevice
);
PDSM_FAILOVER_GROUP
DsmpSetNewPathUsingGroup(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY Group
);
VOID
DsmpRemoveZombieGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY ZombieGroup
);
NTSTATUS
DsmpUpdateTargetPortGroupDevicesStates(
_In_ IN PDSM_TARGET_PORT_GROUP_ENTRY TargetPortGroup,
_In_ IN DSM_DEVICE_STATE NewState
);
VOID
DsmpIncrementCounters(
_In_ PDSM_FAILOVER_GROUP FailGroup,
_In_ PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
DsmpDecrementCounters(
_In_ PDSM_FAILOVER_GROUP FailGroup,
_In_ PSCSI_REQUEST_BLOCK Srb
);
PDSM_FAILOVER_GROUP
DsmpGetPath(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmList,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN ULONG SpecialHandlingFlag
);
PVOID
DsmpGetPathIdFromPassThroughPath(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmList,
_In_ IN PIRP Irp,
_Inout_ IN OUT NTSTATUS *Status
);
VOID
DsmpRemoveGroupEntry(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_GROUP_ENTRY GroupEntry,
_In_ IN BOOLEAN AcquireDSMLockExclusive
);
BOOLEAN
DsmpMpioPassThroughPathCommand(
_In_ IN PIRP Irp
);
BOOLEAN
DsmpReservationCommand(
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb
);
VOID
DsmpRequestComplete(
_In_ IN PVOID DsmId,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PVOID DsmContext
);
NTSTATUS
DsmpRegisterPersistentReservationKeys(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN BOOLEAN Register
);
BOOLEAN
DsmpShouldRetryPassThroughRequest(
_In_ IN PVOID SenseData,
_In_ IN UCHAR SenseDataSize
);
BOOLEAN
DsmpShouldRetryPersistentReserveCommand(
_In_ IN PVOID SenseData,
_In_ IN UCHAR SenseDataSize
);
BOOLEAN
DsmpShouldRetryTPGRequest(
_In_ IN PVOID SenseData,
_In_ IN UCHAR SenseDataSize
);
BOOLEAN
DsmpIsDeviceRemoved(
_In_ IN PVOID SenseData,
_In_ IN UCHAR SenseDataSize
);
PDSM_DEVICE_INFO
DsmpGetActivePathToBeUsed(
_In_ PDSM_GROUP_ENTRY Group,
_In_ BOOLEAN Symmetric,
_In_ IN ULONG SpecialHandlingFlag
);
PDSM_DEVICE_INFO
DsmpGetAnyActivePath(
_In_ PDSM_GROUP_ENTRY Group,
_In_ BOOLEAN Exception,
_In_opt_ PDSM_DEVICE_INFO DeviceInfo,
_In_ IN ULONG SpecialHandlingFlag
);
PDSM_DEVICE_INFO
DsmpFindStandbyPathToActivate(
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN ULONG SpecialHandlingFlag
);
PDSM_DEVICE_INFO
DsmpFindStandbyPathToActivateALUA(
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PBOOLEAN SendTPG,
_In_ IN ULONG SpecialHandlingFlag
);
PDSM_DEVICE_INFO
DsmpFindStandbyPathInAlternateTpgALUA(
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForDsmPolicyAdjustment(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_In_ IN ULONGLONG PreferredPath
);
NTSTATUS
DsmpSetLBForVidPidPolicyAdjustment(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PWSTR TargetHardwareId,
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_In_ IN ULONGLONG PreferredPath
);
NTSTATUS
DsmpSetNewDefaultLBPolicy(
_In_ IN PDSM_CONTEXT DsmContext,
_In_opt_ IN PDSM_DEVICE_INFO NewDeviceInfo,
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathArrival(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO NewDeviceInfo,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathArrivalALUA(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO NewDeviceInfo,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathRemoval(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO RemovedDeviceInfo,
_In_opt_ IN OPTIONAL PDSM_GROUP_ENTRY Group,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathRemovalALUA(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO RemovedDeviceInfo,
_In_opt_ IN OPTIONAL PDSM_GROUP_ENTRY Group,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathFailing(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO FailingDeviceInfo,
_In_ IN BOOLEAN MarkDevInfoFailed,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetLBForPathFailingALUA(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO FailingDeviceInfo,
_In_ IN BOOLEAN MarkDevInfoFailed,
_In_ IN ULONG SpecialHandlingFlag
);
NTSTATUS
DsmpSetPathForIoRetryALUA(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO FailingDeviceInfo,
_In_ IN BOOLEAN TPGException,
_In_ IN BOOLEAN DeviceInfoException
);
PDSM_FAIL_PATH_PROCESSING_LIST_ENTRY
DsmpFindFailPathDevInfoEntry(
_In_ IN PDSM_CONTEXT Context,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_DEVICE_INFO FailingDevInfo
);
PDSM_FAIL_PATH_PROCESSING_LIST_ENTRY
DsmpBuildFailPathDevInfoEntry(
_In_ IN PDSM_CONTEXT Context,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_DEVICE_INFO FailingDevInfo,
_In_ IN PDSM_DEVICE_INFO AlternateDevInfo
);
IO_COMPLETION_ROUTINE DsmpPhase1ProcessPathFailingALUA;
NTSTATUS
DsmpRemoveFailPathDevInfoEntry(
_In_ IN PDSM_CONTEXT Context,
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN PDSM_FAIL_PATH_PROCESSING_LIST_ENTRY FailPathDevInfoEntry
);
IO_COMPLETION_ROUTINE DsmpPhase2ProcessPathFailingALUA;
NTSTATUS
DsmpPersistentReserveOut(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PKEVENT Event
);
__inline
BOOLEAN
DsmpIsPersistentReservationKeyZeroKey(
_In_ ULONG KeyLength,
_In_reads_bytes_(KeyLength) PUCHAR Key
)
{
BOOLEAN zeroKey = FALSE;
NT_ASSERT(KeyLength == 8);
if ((KeyLength) == 8 &&
(Key[0] == 0 && Key[1] == 0 && Key[2] == 0 && Key[3] == 0 &&
Key[4] == 0 && Key[5] == 0 && Key[6] == 0 && Key[7] == 0)) {
zeroKey = TRUE;
}
return zeroKey;
}
NTSTATUS
DsmpPersistentReserveIn(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN PSCSI_REQUEST_BLOCK Srb,
_In_ IN PKEVENT Event
);
IO_COMPLETION_ROUTINE DsmpPersistentReserveCompletion;
//
// Function prototypes for functions in utils.c
//
_Success_(return != NULL)
__drv_allocatesMem(Mem)
_When_(((PoolType&0x1))!=0, _IRQL_requires_max_(APC_LEVEL))
_When_(((PoolType&0x1))==0, _IRQL_requires_max_(DISPATCH_LEVEL))
_When_(((PoolType&0x2))!=0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
_When_(((PoolType&(0x2|POOL_RAISE_IF_ALLOCATION_FAILURE)))==0,
_Post_maybenull_ _Must_inspect_result_)
_When_(((PoolType&(0x2|POOL_RAISE_IF_ALLOCATION_FAILURE)))!=0,
_Post_notnull_)
_When_((PoolType&NonPagedPoolMustSucceed)!=0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
_Post_writable_byte_size_(NumberOfBytes)
PVOID
DsmpAllocatePool(
_In_ _Strict_type_match_ IN POOL_TYPE PoolType,
_In_ IN SIZE_T NumberOfBytes,
_In_ IN ULONG Tag
);
_Success_(return != NULL)
_Post_maybenull_
_Must_inspect_result_
__drv_allocatesMem(Mem)
_Post_writable_byte_size_(*BytesAllocated)
_When_(((PoolType&0x1))!=0, _IRQL_requires_max_(APC_LEVEL))
_When_(((PoolType&0x1))==0, _IRQL_requires_max_(DISPATCH_LEVEL))
_When_((PoolType&NonPagedPoolMustSucceed)!=0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
PVOID
DsmpAllocateAlignedPool(
_In_ IN POOL_TYPE PoolType,
_In_ IN SIZE_T NumberOfBytes,
_In_ IN ULONG AlignmentMask,
_In_ IN ULONG Tag,
_Out_ OUT SIZE_T *BytesAllocated
);
_IRQL_requires_max_(DISPATCH_LEVEL)
VOID
DsmpFreePool(
_In_opt_ __drv_freesMem(Mem) IN PVOID Block
);
NTSTATUS
DsmpGetStatsGatheringChoice(
_In_ IN PDSM_CONTEXT Context,
_Out_ OUT PULONG StatsGatherChoice
);
NTSTATUS
DsmpSetStatsGatheringChoice(
_In_ IN PDSM_CONTEXT Context,
_In_ IN ULONG StatsGatherChoice
);
NTSTATUS
DsmpGetDeviceList(
_In_ IN PDSM_CONTEXT Context
);
_Success_(return==0)
NTSTATUS
DsmpGetStandardInquiryData(
_In_ IN PDEVICE_OBJECT DeviceObject,
_Out_ OUT PINQUIRYDATA InquiryData
);
BOOLEAN
DsmpCheckScsiCompliance(
_In_ IN PDEVICE_OBJECT DeviceObject,
_In_ IN PINQUIRYDATA InquiryData,
_In_ IN PSTORAGE_DEVICE_DESCRIPTOR Descriptor,
_In_ IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceIdList
);
BOOLEAN
DsmpDeviceSupported(
_In_ IN PDSM_CONTEXT Context,
_In_ IN PCSTR VendorId,
_In_ IN PCSTR ProductId
);
BOOLEAN
DsmpFindSupportedDevice(
_In_ IN PUNICODE_STRING DeviceName,
_In_ IN PUNICODE_STRING SupportedDevices
);
_Success_(return!=0)
PVOID
DsmpParseDeviceID (
_In_ IN PSTORAGE_DEVICE_ID_DESCRIPTOR DeviceID,
_In_ IN DSM_DEVID_TYPE DeviceIdType,
_In_opt_ IN PULONG IdNumber,
_Out_opt_ PSTORAGE_IDENTIFIER_CODE_SET CodeSet,
_In_ IN BOOLEAN Legacy
);
PUCHAR
DsmpBinaryToAscii(
_In_reads_(Length) IN PUCHAR HexBuffer,
_In_ IN ULONG Length,
_Inout_ IN OUT PULONG UpdateLength,
_In_ IN BOOLEAN Legacy
);
PSTR
DsmpGetSerialNumber(
_In_ IN PDEVICE_OBJECT DeviceObject
);
NTSTATUS
DsmpDisableImplicitStateTransition(
_In_ IN PDEVICE_OBJECT DeviceObject,
_Out_ OUT PBOOLEAN DisableImplicit
);
PWSTR
DsmpBuildHardwareId(
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
PWSTR
DsmpBuildDeviceNameLegacyPage0x80(
_In_ IN PDSM_DEVICE_INFO DeviceInfo
);
PWSTR
DsmpBuildDeviceName(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_reads_(SerialNumberLength) IN PSTR SerialNumber,
_In_ IN SIZE_T SerialNumberLength
);
NTSTATUS
DsmpApplyDeviceNameCorrection(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_reads_(DeviceNameLegacyLen) PWSTR DeviceNameLegacy,
_In_ IN SIZE_T DeviceNameLegacyLen,
_In_reads_(DeviceNameLen) PWSTR DeviceName,
_In_ IN SIZE_T DeviceNameLen
);
NTSTATUS
DsmpQueryDeviceLBPolicyFromRegistry(
_In_ PDSM_DEVICE_INFO DeviceInfo,
_In_ PWSTR RegistryKeyName,
_Inout_ PDSM_LOAD_BALANCE_TYPE LoadBalanceType,
_Inout_ PULONGLONG PreferredPath,
_Inout_ PUCHAR ExplicitlySet
);
NTSTATUS
DsmpQueryTargetLBPolicyFromRegistry(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_Out_ OUT PDSM_LOAD_BALANCE_TYPE LoadBalanceType,
_Out_ OUT PULONGLONG PreferredPath
);
NTSTATUS
DsmpQueryDsmLBPolicyFromRegistry(
_Out_ OUT PDSM_LOAD_BALANCE_TYPE LoadBalanceType,
_Out_ OUT PULONGLONG PreferredPath
);
NTSTATUS
DsmpSetDsmLBPolicyInRegistry(
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_In_ IN ULONGLONG PreferredPath
);
NTSTATUS
DsmpSetVidPidLBPolicyInRegistry(
_In_ IN PWSTR TargetHardwareId,
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_In_ IN ULONGLONG PreferredPath
);
NTSTATUS
DsmpOpenLoadBalanceSettingsKey(
_In_ IN ACCESS_MASK AccessMask,
_Out_ OUT PHANDLE LoadBalanceSettingsKey
);
NTSTATUS
DsmpOpenTargetsLoadBalanceSettingKey(
_In_ IN ACCESS_MASK AccessMask,
_Out_ OUT PHANDLE TargetsLoadBalanceSettingKey
);
NTSTATUS
DsmpOpenDsmServicesParametersKey(
_In_ IN ACCESS_MASK AccessMask,
_Out_ OUT PHANDLE ParametersSettingsKey
);
IO_COMPLETION_ROUTINE DsmpReportTargetPortGroupsSyncCompletion;
_Success_(return==0)
NTSTATUS
DsmpReportTargetPortGroups(
_In_ PDEVICE_OBJECT DeviceObject,
_Outptr_result_buffer_maybenull_(*TargetPortGroupsInfoLength) PUCHAR *TargetPortGroupsInfo,
_Out_ PULONG TargetPortGroupsInfoLength
);
NTSTATUS
DsmpReportTargetPortGroupsAsync(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN PIO_COMPLETION_ROUTINE CompletionRoutine,
_Inout_ __drv_aliasesMem IN PDSM_TPG_COMPLETION_CONTEXT CompletionContext,
_In_ IN ULONG TargetPortGroupsInfoLength,
_Inout_ __drv_aliasesMem IN OUT PUCHAR TargetPortGroupsInfo
);
NTSTATUS
DsmpQueryLBPolicyForDevice(
_In_ IN PWSTR RegistryKeyName,
_In_ IN ULONGLONG PathId,
_In_ IN DSM_LOAD_BALANCE_TYPE LoadBalanceType,
_Out_ OUT PULONG PrimaryPath,
_Out_ OUT PULONG OptimizedPath,
_Out_ OUT PULONG PathWeight
);
VOID
DsmpGetDSMPathKeyName(
_In_ ULONGLONG DSMPathId,
_Out_writes_(DsmPathKeyNameSize) PWCHAR DsmPathKeyName,
_In_ ULONG DsmPathKeyNameSize
);
UCHAR
DsmpGetAsciiForBinary(
_In_ UCHAR BinaryChar
);
NTSTATUS
DsmpGetDeviceIdList (
_In_ IN PDEVICE_OBJECT DeviceObject,
_Out_ OUT PSTORAGE_DESCRIPTOR_HEADER *Descriptor
);
NTSTATUS
DsmpSetTargetPortGroups(
_In_ IN PDEVICE_OBJECT DeviceObject,
_In_reads_bytes_(TargetPortGroupsInfoLength) IN PUCHAR TargetPortGroupsInfo,
_In_ IN ULONG TargetPortGroupsInfoLength
);
NTSTATUS
DsmpSetTargetPortGroupsAsync(
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN PIO_COMPLETION_ROUTINE CompletionRoutine,
_In_ __drv_aliasesMem IN PDSM_TPG_COMPLETION_CONTEXT CompletionContext,
_In_ IN ULONG TargetPortGroupsInfoLength,
_In_ __drv_aliasesMem IN PUCHAR TargetPortGroupsInfo
);
PDSM_LOAD_BALANCE_POLICY_SETTINGS
DsmpCopyLoadBalancePolicies(
_In_ IN PDSM_GROUP_ENTRY GroupEntry,
_In_ IN ULONG DsmWmiVersion,
_In_ IN PVOID SupportedLBPolicies
);
NTSTATUS
DsmpPersistLBSettings(
_In_ IN PDSM_LOAD_BALANCE_POLICY_SETTINGS LoadBalanceSettings
);
NTSTATUS
DsmpSetDeviceALUAState(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_ IN DSM_DEVICE_STATE DevState
);
NTSTATUS
DsmpGetDeviceALUAState(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_DEVICE_INFO DeviceInfo,
_In_opt_ IN PDSM_DEVICE_STATE DevState
);
NTSTATUS
DsmpAdjustDeviceStatesALUA(
_In_ IN PDSM_GROUP_ENTRY Group,
_In_opt_ IN PDSM_DEVICE_INFO PreferredActiveDeviceInfo,
_In_ IN ULONG SpecialHandlingFlag
);
PDSM_WORKITEM
DsmpAllocateWorkItem(
_In_ IN PDEVICE_OBJECT DeviceObject,
_In_ IN PVOID Context
);
VOID
DsmpFreeWorkItem(
_In_ IN PDSM_WORKITEM DsmWorkItem
);
VOID
DsmpFreeZombieGroupList(
_In_ IN PDSM_FAILOVER_GROUP FailGroup
);
NTSTATUS
DsmpRegCopyTree(
_In_ IN HANDLE SourceKey,
_In_ IN HANDLE DestKey
);
NTSTATUS
DsmpRegDeleteTree(
_In_ IN HANDLE KeyRoot
);
#if defined (_WIN64)
VOID
DsmpPassThroughPathTranslate32To64(
_In_ IN PMPIO_PASS_THROUGH_PATH32 MpioPassThroughPath32,
_Inout_ IN OUT PMPIO_PASS_THROUGH_PATH MpioPassThroughPath64
);
VOID
DsmpPassThroughPathTranslate64To32(
_In_ IN PMPIO_PASS_THROUGH_PATH MpioPassThroughPath64,
_Inout_ IN OUT PMPIO_PASS_THROUGH_PATH32 MpioPassThroughPath32
);
#endif
NTSTATUS
DsmpGetMaxPRRetryTime(
_In_ IN PDSM_CONTEXT Context,
_Out_ OUT PULONG RetryTime
);
NTSTATUS
DsmpQueryCacheInformationFromRegistry(
_In_ IN PDSM_CONTEXT DsmContext,
_Out_ OUT PBOOLEAN UseCacheForLeastBlocks,
_Out_ OUT PULONGLONG CacheSizeForLeastBlocks
);
BOOLEAN
DsmpConvertSharedSpinLockToExclusive(
_Inout_ _Requires_lock_held_(*_Curr_) PEX_SPIN_LOCK SpinLock
);
//
// Function prototypes for functions in wmi.c
//
VOID
DsmpDsmWmiInitialize(
_In_ IN PDSM_WMILIB_CONTEXT WmiGlobalInfo,
_In_ IN PUNICODE_STRING RegistryPath
);
NTSTATUS
DsmGlobalQueryData(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN ULONG GuidIndex,
_In_ IN ULONG InstanceIndex,
_In_ IN ULONG InstanceCount,
_Inout_ IN OUT PULONG InstanceLengthArray,
_In_ IN ULONG BufferAvail,
_Out_writes_to_(BufferAvail, *DataLength) OUT PUCHAR Buffer,
_Out_ OUT PULONG DataLength,
...
);
NTSTATUS
DsmGlobalSetData(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN ULONG GuidIndex,
_In_ IN ULONG InstanceIndex,
_In_ IN ULONG BufferAvail,
_In_reads_bytes_(BufferAvail) IN PUCHAR Buffer,
...
);
VOID
DsmpWmiInitialize(
_In_ IN PDSM_WMILIB_CONTEXT WmiInfo,
_In_ IN PUNICODE_STRING RegistryPath
);
NTSTATUS
DsmQueryData(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN ULONG GuidIndex,
_In_ IN ULONG InstanceIndex,
_In_ IN ULONG InstanceCount,
_Inout_ IN OUT PULONG InstanceLengthArray,
_In_ IN ULONG BufferAvail,
_When_(GuidIndex == 0 || GuidIndex == 7, _Pre_notnull_ _Const_)
_When_(!(GuidIndex == 0 || GuidIndex == 7), _Out_writes_to_(BufferAvail, *DataLength))
OUT PUCHAR Buffer,
_Out_ OUT PULONG DataLength,
...
);
NTSTATUS
DsmpQueryLoadBalancePolicy(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN ULONG DsmWmiVersion,
_In_ IN ULONG InBufferSize,
_In_ IN PULONG OutBufferSize,
_Out_writes_bytes_(*OutBufferSize) OUT PVOID Buffer
);
NTSTATUS
DsmpQuerySupportedLBPolicies(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN ULONG BufferAvail,
_In_ IN ULONG DsmWmiVersion,
_Out_ OUT PULONG OutBufferSize,
_Out_writes_to_(BufferAvail, *OutBufferSize) OUT PUCHAR Buffer
);
NTSTATUS
DsmExecuteMethod(
_In_ IN PVOID DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN PIRP Irp,
_In_ IN ULONG GuidIndex,
_In_ IN ULONG InstanceIndex,
_In_ IN ULONG MethodId,
_In_ IN ULONG InBufferSize,
_In_ IN PULONG OutBufferSize,
_Inout_ IN OUT PUCHAR Buffer,
...
);
NTSTATUS
DsmpClearLoadBalancePolicy(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds
);
NTSTATUS
DsmpSetLoadBalancePolicy(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN ULONG DsmWmiVersion,
_In_ IN ULONG InBufferSize,
_In_ IN PULONG OutBufferSize,
_In_ IN PVOID Buffer
);
NTSTATUS
DsmpValidateSetLBPolicyInput(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds,
_In_ IN ULONG DsmWmiVersion,
_In_ IN PVOID SetLoadBalancePolicyIN,
_In_ IN ULONG InBufferSize
);
VOID
DsmpSaveDeviceState(
_In_ IN PVOID SupportedLBPolicies,
_In_ IN ULONG DsmWmiVersion
);
VOID
DsmpRestorePreviousDeviceState(
_In_ IN PVOID SupportedLBPolicies,
_In_ IN ULONG DsmWmiVersion
);
VOID
DsmpUpdateDesiredStateAndWeight(
_In_ IN PDSM_GROUP_ENTRY Group,
_In_ IN ULONG DsmWmiVersion,
_In_ IN PVOID SupportedLBPolicies
);
NTSTATUS
DsmpQueryDevicePerf(
_In_ PDSM_CONTEXT DsmContext,
_In_ PDSM_IDS DsmIds,
_In_ ULONG InBufferSize,
_Inout_ PULONG OutBufferSize,
_Out_writes_to_(*OutBufferSize, *OutBufferSize) PUCHAR Buffer
);
NTSTATUS
DsmpClearPerfCounters(
_In_ IN PDSM_CONTEXT DsmContext,
_In_ IN PDSM_IDS DsmIds
);
NTSTATUS
DsmpQuerySupportedDevicesList(
_In_ PDSM_CONTEXT DsmContext,
_In_ ULONG InBufferSize,
_Inout_ PULONG OutBufferSize,
_Out_writes_to_(*OutBufferSize, *OutBufferSize) PUCHAR Buffer
);
NTSTATUS
DsmpQueryTargetsDefaultPolicy(
_In_ PDSM_CONTEXT DsmContext,
_In_ ULONG InBufferSize,
_Inout_ PULONG OutBufferSize,
_Out_writes_to_(*OutBufferSize, *OutBufferSize) PUCHAR Buffer
);
NTSTATUS
DsmpQueryDsmDefaultPolicy(
_In_ PDSM_CONTEXT DsmContext,
_In_ ULONG InBufferSize,
_Inout_ PULONG OutBufferSize,
_Out_writes_to_(*OutBufferSize, *OutBufferSize) PUCHAR Buffer
);
//
// Function prototypes for functions in debug.c
//
VOID
DsmpDebugPrint(
_In_ ULONG DebugPrintLevel,
_In_ PCCHAR DebugMessage,
...
);
//
// SRB Helpers not found in srbhelper.h
//
_Success_(return != 0)
__drv_allocatesMem(mem)
_When_(((PoolType&0x1))!=0, _IRQL_requires_max_(APC_LEVEL))
_When_(((PoolType&0x1))==0, _IRQL_requires_max_(DISPATCH_LEVEL))
_When_(((PoolType&0x2))!=0,
__drv_reportError("Must succeed pool allocations are forbidden. "
"Allocation failures cause a system crash"))
_When_(((PoolType&(0x2|POOL_RAISE_IF_ALLOCATION_FAILURE)))==0,
_Post_maybenull_ _Must_inspect_result_)
_When_(((PoolType&(0x2|POOL_RAISE_IF_ALLOCATION_FAILURE)))!=0,
_Post_notnull_ )
__inline PSTORAGE_REQUEST_BLOCK_HEADER
SrbAllocateCopy(
_Inout_ PVOID Srb,
_In_ _Strict_type_match_ POOL_TYPE PoolType,
_In_ ULONG Tag
)
/*
Description:
This function returns an allocated copy of the given SRB. The memory is
allocated using DsmpAllocatePool().
***It is up to the caller to free the memory returned by this function.***
Arguments:
Srb - A pointer to either a STORAGE_REQUEST_BLOCK or a SCSI_REQUEST_BLOCK.
PoolType - The pool type to use. See documentation for ExAllocatePoolZero().
Tag - The allocation tag to use. See documentation for ExAllocatePoolZero().
Returns:
NULL, if the copy could not be allocated; or
A pointer to either a STORAGE_REQUEST_BLOCK or a SCSI_REQUEST_BLOCK that is
direct copy of the given SRB.
*/
{
PSTORAGE_REQUEST_BLOCK srb = (PSTORAGE_REQUEST_BLOCK)Srb;
PSTORAGE_REQUEST_BLOCK_HEADER srbCopy = NULL;
ULONG allocationSize = 0;
if (srb->Function == SRB_FUNCTION_STORAGE_REQUEST_BLOCK)
{
allocationSize = srb->SrbLength;
NT_ASSERT(allocationSize >= (sizeof(STORAGE_REQUEST_BLOCK) + sizeof(STOR_ADDR_BTL8)));
}
else
{
allocationSize = SCSI_REQUEST_BLOCK_SIZE;
NT_ASSERT(allocationSize >= sizeof(SCSI_REQUEST_BLOCK));
}
#pragma warning(suppress: 28160 28118) // False-positive; PoolType is simply passed through
srbCopy = (PSTORAGE_REQUEST_BLOCK_HEADER)DsmpAllocatePool(PoolType, allocationSize, Tag);
if (srbCopy != NULL)
{
RtlCopyMemory(srbCopy, Srb, allocationSize);
}
return srbCopy;
}
__inline
BOOLEAN DsmpIsMPIOPassThroughEx(
ULONG ControlCode
)
//
// Returns TRUE if the given passthrough IOCTL's control code indicates it is
// an "extended" passthrough. Returns FALSE otherwise.
//
{
if (ControlCode == IOCTL_MPIO_PASS_THROUGH_PATH_EX ||
ControlCode == IOCTL_MPIO_PASS_THROUGH_PATH_DIRECT_EX) {
return TRUE;
} else {
return FALSE;
}
}
__inline
UCHAR DsmpNtStatusToSrbStatus(
_In_ NTSTATUS Status
)
/*++
Routine Description:
Translate an NT status value into a SCSI Srb status code.
Arguments:
Status - Supplies the NT status code to translate.
Return Value:
SRB status code.
--*/
{
switch (Status) {
case STATUS_DEVICE_BUSY:
return SRB_STATUS_BUSY;
case STATUS_INVALID_DEVICE_REQUEST:
return SRB_STATUS_BAD_FUNCTION;
case STATUS_INSUFFICIENT_RESOURCES:
return SRB_STATUS_INTERNAL_ERROR;
case STATUS_INVALID_PARAMETER:
return SRB_STATUS_INVALID_REQUEST;
default:
if (NT_SUCCESS (Status)) {
return SRB_STATUS_SUCCESS;
} else {
return SRB_STATUS_ERROR;
}
}
}
#endif // _PROTOTYPES_H_
|