-
Notifications
You must be signed in to change notification settings - Fork 191
/
SetupAPI.DiFuncs2.cs
4985 lines (4897 loc) · 299 KB
/
SetupAPI.DiFuncs2.cs
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
using Microsoft.Win32.SafeHandles;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Security.AccessControl;
namespace Vanara.PInvoke;
/// <summary>Items from the SetupAPI.dll</summary>
public static partial class SetupAPI
{
/// <summary>
/// The <c>SetupDiGetClassProperty</c> function retrieves a device property that is set for a device setup class or a device
/// interface class.
/// </summary>
/// <param name="ClassGuid">
/// A pointer to a GUID that identifies the device setup class or device interface class for which to retrieve a device property
/// that is set for the device class. For information about specifying the class type, see the Flags parameter.
/// </param>
/// <param name="PropertyKey">
/// A pointer to a DEVPROPKEY structure that represents the device property key of the requested device class property.
/// </param>
/// <param name="PropertyType">
/// A pointer to a DEVPROPTYPE-typed variable that receives the property-data-type identifier of the requested device class
/// property, where the property-data-type identifier is the bitwise OR between a base-data-type identifier and, if the base data
/// type is modified, a property-data-type modifier.
/// </param>
/// <param name="PropertyBuffer">
/// A pointer to a buffer that receives the requested device class property. <c>SetupDiGetClassProperty</c> retrieves the requested
/// property value only if the buffer is large enough to hold all the property value data. The pointer can be <c>NULL</c>. If the
/// pointer is set to <c>NULL</c> and RequiredSize is supplied, <c>SetupDiGetClassProperty</c> returns the size of the device class
/// property, in bytes, in *RequiredSize.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to <c>NULL</c>, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="RequiredSize">
/// A pointer to a DWORD-typed variable that receives either the size, in bytes, of the device class property if the device class
/// property is retrieved or the required buffer size if the buffer is not large enough. This pointer can be set to <c>NULL</c>.
/// </param>
/// <param name="Flags">
/// <para>One of the following values, which specifies whether the class is a device setup class or a device interface class.</para>
/// <para>DICLASSPROP_INSTALLER</para>
/// <para>ClassGuid specifies a device setup class. This flag cannot be used with DICLASSPROP_INTERFACE.</para>
/// <para>DICLASSPROP_INTERFACE</para>
/// <para>ClassGuid specifies a device interface class. This flag cannot be used with DICLASSPROP_INSTALLER.</para>
/// </param>
/// <returns>
/// <para>
/// <c>SetupDiGetClassProperty</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged error
/// can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_CLASS</term>
/// <term>
/// The device setup class that is specified by ClassGuid is not valid. This error can occur only if the DICLASSPROP_INSTALLER flag
/// is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>An unspecified parameter is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REG_PROPERTY</term>
/// <term>The property key that is supplied by PropertyKey is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REFERENCE_STRING</term>
/// <term>The device interface reference string is not valid. This error can be returned if the DICLASSPROP_INTERFACE flag is specified.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified internal data value was not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyBuffer is NULL, and PropertyBufferSize is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_INTERFACE_CLASS</term>
/// <term>
/// The device interface class that is specified by ClassGuid does not exist. This error can occur only if the DICLASSPROP_INTERFACE
/// flag is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
/// <term>An internal data buffer that was passed to a system call was too small.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested device property does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetClassProperty</c> is part of the unified device property model.</para>
/// <para>SetupAPI supports only a Unicode version of <c>SetupDiGetClassProperty</c>.</para>
/// <para>A caller of <c>SetupDiGetClassProperty</c> must be a member of the Administrators group to set a device interface property.</para>
/// <para>
/// To obtain the device property keys that represent the device properties that are set for a device class on a local computer,
/// call SetupDiGetClassPropertyKeys.
/// </para>
/// <para>To retrieve a device class property on a remote computer, call SetupDiGetClassPropertyEx.</para>
/// <para>
/// To set a device class property on a local computer, call SetupDiSetClassProperty <c>,</c> and to set a device class property on
/// a remote computer, call SetupDiSetClassPropertyEx.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclasspropertyw WINSETUPAPI BOOL
// SetupDiGetClassPropertyW( const GUID *ClassGuid, const DEVPROPKEY *PropertyKey, DEVPROPTYPE *PropertyType, PBYTE PropertyBuffer,
// DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassPropertyW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetClassProperty(in Guid ClassGuid, in DEVPROPKEY PropertyKey, out DEVPROPTYPE PropertyType,
[Out, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, out uint RequiredSize, DICLASSPROP Flags);
/// <summary>
/// The <c>SetupDiGetClassPropertyEx</c> function retrieves a class property for a device setup class or a device interface class on
/// a local or remote computer.
/// </summary>
/// <param name="ClassGuid">
/// A pointer to a GUID that identifies the device setup class or device interface class for which to retrieve a device property for
/// the device class. For information about specifying the class type, see the Flags parameter.
/// </param>
/// <param name="PropertyKey">
/// A pointer to a DEVPROPKEY structure that represents the device property key of the requested device class property.
/// </param>
/// <param name="PropertyType">
/// A pointer to a DEVPROPTYPE-typed variable that receives the property-data-type identifier of the requested device class
/// property, where the property-data-type identifier is the bitwise OR between a base-data-type identifier and, if the base data
/// type is modified, a property-data-type modifier.
/// </param>
/// <param name="PropertyBuffer">
/// A pointer to a buffer that receives the requested device class property. <c>SetupDiGetClassPropertyEx</c> retrieves the
/// requested property value only if the buffer is large enough to hold all the property value data. The pointer can be <c>NULL</c>.
/// If the pointer is set to <c>NULL</c> and RequiredSize is supplied, <c>SetupDiGetClassPropertyEx</c> returns the size of the
/// device class property, in bytes, in *RequiredSize.
/// </param>
/// <param name="PropertyBufferSize">
/// The size, in bytes, of the PropertyBuffer buffer. If PropertyBuffer is set to <c>NULL</c>, PropertyBufferSize must be set to zero.
/// </param>
/// <param name="RequiredSize">
/// A pointer to a DWORD-typed variable that receives either the size, in bytes, of the device class property if the property is
/// retrieved or the required buffer size if the buffer is not large enough. This pointer can be set to <c>NULL</c>.
/// </param>
/// <param name="Flags">
/// <para>One of the following values, which specifies whether the class is a device setup class or a device interface class:</para>
/// <para>DICLASSPROP_INSTALLER</para>
/// <para>ClassGuid specifies a device setup class. This flag cannot be used with DICLASSPROP_INTERFACE.</para>
/// <para>DICLASSPROP_INTERFACE</para>
/// <para>ClassGuid specifies a device interface class. This flag cannot be used with DICLASSPROP_INSTALLER.</para>
/// </param>
/// <param name="MachineName">
/// A pointer to a NULL-terminated string that contains the UNC name, including the "\" prefix, of a computer. The pointer can be
/// set to <c>NULL</c>. If MachineName is <c>NULL</c>, <c>SetupDiGetClassPropertyEx</c> retrieves the requested device class
/// property from the local computer.
/// </param>
/// <param name="Reserved">This parameter must be set to <c>NULL</c>.</param>
/// <returns>
/// <para>
/// <c>SetupDiGetClassPropertyEx</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_CLASS</term>
/// <term>
/// The device setup class that is specified by ClassGuid is not valid. This error can occur only if the DICLASSPROP_INSTALLER flag
/// is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>An unspecified parameter is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REG_PROPERTY</term>
/// <term>The property key that is supplied by PropertyKey is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REFERENCE_STRING</term>
/// <term>The device interface reference string is not valid. This error can be returned if the DICLASSPROP_INTERFACE flag is specified.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified internal data value was not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyBuffer is NULL, and PropertyBufferSize is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_MACHINENAME</term>
/// <term>The computer name that is specified by MachineName is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_INTERFACE_CLASS</term>
/// <term>
/// The device interface class that is specified by ClassGuid does not exist. This error can occur only if the DICLASSPROP_INTERFACE
/// flag is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICIENT_BUFFER</term>
/// <term>An internal data buffer that was passed to a system call was too small.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_NOT_FOUND</term>
/// <term>The requested device property does not exist.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetClassPropertyEx</c> is part of the unified device property model.</para>
/// <para>SetupAPI supports only a Unicode version of <c>SetupDiGetClassPropertyEx</c>.</para>
/// <para>A caller of <c>SetupDiGetClassPropertyEx</c> must be a member of the Administrators group to set a device interface property.</para>
/// <para>
/// To obtain the device property keys that represent the device properties that are set for a device class on a remote computer,
/// call SetupDiGetClassPropertyKeysEx.
/// </para>
/// <para>To retrieve a device class property on a local computer, call SetupDiGetClassProperty.</para>
/// <para>
/// To set a device class property on a local computer, call SetupDiSetClassProperty <c>,</c> and to set a device class property on
/// a remote computer, call SetupDiSetClassPropertyEx.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclasspropertyexw WINSETUPAPI BOOL
// SetupDiGetClassPropertyExW( const GUID *ClassGuid, const DEVPROPKEY *PropertyKey, DEVPROPTYPE *PropertyType, PBYTE
// PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize, DWORD Flags, PCWSTR MachineName, PVOID Reserved );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassPropertyExW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetClassPropertyEx(in Guid ClassGuid, in DEVPROPKEY PropertyKey, out DEVPROPTYPE PropertyType,
[Out, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, out uint RequiredSize, DICLASSPROP Flags,
[Optional, MarshalAs(UnmanagedType.LPWStr)] string? MachineName, [In, Optional] IntPtr Reserved);
/// <summary>
/// The <c>SetupDiGetClassPropertyKeys</c> function retrieves an array of the device property keys that represent the device
/// properties that are set for a device setup class or a device interface class.
/// </summary>
/// <param name="ClassGuid">
/// A pointer to a GUID that represents a device setup class or a device interface class. <c>SetupDiGetClassPropertyKeys</c>
/// retrieves an array of the device property keys that represent device properties that are set for the specified class. For
/// information about specifying the class type, see the Flags parameter.
/// </param>
/// <param name="PropertyKeyArray">
/// A pointer to a buffer that receives an array of DEVPROPKEY-typed values, where each value is a device property key that
/// represents a device property that is set for the device class. The pointer is optional and can be <c>NULL</c>. For more
/// information, see the <c>Remarks</c> section later in this topic.
/// </param>
/// <param name="PropertyKeyCount">
/// The size, in DEVPROPKEY-typed values, of the PropertyKeyArray buffer. If PropertyKeyArray is set to <c>NULL</c>,
/// PropertyKeyCount must be set to zero.
/// </param>
/// <param name="RequiredPropertyKeyCount">
/// A pointer to a DWORD-typed variable that receives the number of requested property keys. The parameter is optional and can be
/// set to <c>NULL</c>.
/// </param>
/// <param name="Flags">
/// <para>
/// One of the following values, which specifies whether to retrieve property keys for a device setup class or for a device
/// interface class:
/// </para>
/// <para>DICLASSPROP_INSTALLER</para>
/// <para>ClassGuid specifies a device setup class. This flag cannot be used with DICLASSPROP_INTERFACE.</para>
/// <para>DICLASSPROP_INTERFACE</para>
/// <para>ClassGuid specifies a device interface class. This flag cannot be used with DICLASSPROP_INSTALLER.</para>
/// </param>
/// <returns>
/// <para>
/// <c>SetupDiGetClassPropertyKeys</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_CLASS</term>
/// <term>
/// If the DICLASSPROP_INSTALLER flag is specified, this error code indicates that the device setup class that is specified by
/// ClassGuid does not exist.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REFERENCE_STRING</term>
/// <term>
/// The reference string for the device interface that is specified by ClassGuild is not valid. This error can be returned if the
/// DICLASSPROP_INTERFACE flag is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified data value is not valid. One possibility is that the ClassGuid value is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>An unspecified parameter is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyKeyArray is NULL, and PropertKeyCount is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_INTERFACE_CLASS</term>
/// <term>
/// If the DICLASSPROP_INTERFACE flag is specified, this error code indicates that the device interface class that is specified by
/// ClassGuid does not exist.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICENT_BUFFER</term>
/// <term>
/// The PropertyKeyArray buffer is not large enough to hold all the property keys, or an internal data buffer that was passed to a
/// system call was too small.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetClassPropertyKeys</c> is part of the unified device property model.</para>
/// <para>
/// A caller of <c>SetupDiGetClassPropertyKeys</c> must be a member of the Administrators group to retrieve device property keys for
/// a device class.
/// </para>
/// <para>
/// If the PropertyKeyArray buffer is not large enough to hold all the requested property keys, <c>SetupDiGetClassPropertyKeys</c>
/// does not retrieve any property keys and returns ERROR_INSUFFICIENT_BUFFER. If the caller supplied a RequiredPropertyKeyCount
/// pointer, <c>SetupDiGetClassPropertyKeys</c> sets the value of *RequiredPropertyKeyCount to the required size, in
/// DEVPROPKEY-typed values, of the PropertyKeyArray buffer.
/// </para>
/// <para>
/// To retrieve a device class property on a local computer, call SetupDiGetClassProperty. To set a device class property on a local
/// computer, call SetupDiSetClassProperty.
/// </para>
/// <para>To retrieve the property keys for a device setup class or device interface class on a remote computer, call SetupDiGetClassPropertyKeysEx.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclasspropertykeys WINSETUPAPI BOOL
// SetupDiGetClassPropertyKeys( const GUID *ClassGuid, DEVPROPKEY *PropertyKeyArray, DWORD PropertyKeyCount, PDWORD
// RequiredPropertyKeyCount, DWORD Flags );
[DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassPropertyKeys")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetClassPropertyKeys(in Guid ClassGuid,
[Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] DEVPROPKEY[]? PropertyKeyArray, uint PropertyKeyCount,
out uint RequiredPropertyKeyCount, DICLASSPROP Flags);
/// <summary>
/// The <c>SetupDiGetClassPropertyKeysEx</c> function retrieves an array of the device property keys that represent the device
/// properties that are set for a device setup class or a device interface class on a local or a remote computer.
/// </summary>
/// <param name="ClassGuid">
/// A pointer to a GUID that represents a device setup class or a device interface class. <c>SetupDiGetClassPropertyKeysEx</c>
/// retrieves an array of the device property keys that represent device properties that are set for the specified class. For
/// information about specifying the class type, see the Flags parameter.
/// </param>
/// <param name="PropertyKeyArray">
/// A pointer to a buffer that receives an array of DEVPROPKEY-typed values, where each value is a device property key that
/// represents a device property that is set for the device setup class. The pointer is optional and can be <c>NULL</c>. For more
/// information, see the <c>Remarks</c> section later in this topic.
/// </param>
/// <param name="PropertyKeyCount">
/// The size, in DEVPROPKEY-type values, of the PropertyKeyArray buffer. If PropertyKeyArray is set to <c>NULL</c>, PropertyKeyCount
/// must be set to zero.
/// </param>
/// <param name="RequiredPropertyKeyCount">
/// A pointer to a DWORD-typed variable that receives the number of requested property keys. The pointer is optional and can be set
/// to <c>NULL</c>.
/// </param>
/// <param name="Flags">
/// <para>
/// One of the following values, which specifies whether to retrieve class property keys for a device setup class or for a device
/// interface class.
/// </para>
/// <para>DICLASSPROP_INSTALLER</para>
/// <para>ClassGuid specifies a device setup class. This flag cannot be used with DICLASSPROP_INTERFACE.</para>
/// <para>DICLASSPROP_INTERFACE</para>
/// <para>ClassGuid specifies a device interface class. This flag cannot be used with DICLASSPROP_INSTALLER.</para>
/// </param>
/// <param name="MachineName">
/// A pointer to a NULL-terminated string that contains the UNC name, including the "\" prefix, of a computer. The pointer can be
/// <c>NULL</c>. If the pointer is <c>NULL</c>, <c>SetupDiGetClassPropertyKeysEx</c> retrieves the requested information from the
/// local computer.
/// </param>
/// <param name="Reserved">This parameter must be set to <c>NULL</c>.</param>
/// <returns>
/// <para>
/// <c>SetupDiGetClassPropertyKeysEx</c> returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c>, and the logged
/// error can be retrieved by calling GetLastError.
/// </para>
/// <para>The following table includes some of the more common error codes that this function might log.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_FLAGS</term>
/// <term>The value of Flags is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_CLASS</term>
/// <term>
/// If the DICLASSPROP_INSTALLER flag is specified, this error code indicates that the device setup class that is specified by
/// ClassGuid does not exist.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_REFERENCE_STRING</term>
/// <term>
/// The reference string for the device interface that is specified by ClassGuild is not valid. This error might be returned when
/// the DICLASSPROP_INTERFACE flag is specified.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_DATA</term>
/// <term>An unspecified data value is not valid. One possibility is that the ClassGuid value is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>An unspecified parameter is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>A user buffer is not valid. One possibility is that PropertyKeyArray is NULL, and PropertKeyCount is not zero.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_MACHINENAME</term>
/// <term>The computer name that is specified by MachineName is not valid.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_INTERFACE_CLASS</term>
/// <term>
/// If the DICLASSPROP_INTERFACE flag is specified, this error code indicates that the device interface class that is specified by
/// ClassGuid does not exist.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_INSUFFICENT_BUFFER</term>
/// <term>
/// The PropertyKeyArray buffer is not large enough to hold all the property keys, or an internal data buffer that was passed to a
/// system call was too small.
/// </term>
/// </item>
/// <item>
/// <term>ERROR_NOT_ENOUGH_MEMORY</term>
/// <term>There was not enough system memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>ERROR_ACCESS_DENIED</term>
/// <term>The caller does not have Administrator privileges.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>SetupDiGetClassPropertyKeysEx</c> is part of the unified device property model.</para>
/// <para>
/// A caller of <c>SetupDiGetClassPropertyKeysEx</c> must be a member of the Administrators group to retrieve device property keys
/// for a device class.
/// </para>
/// <para>
/// If the PropertyKeyArray buffer is not large enough to hold all the requested property keys, <c>SetupDiGetClassPropertyKeysEx</c>
/// does not retrieve any property keys and returns ERROR_INSUFFICIENT_BUFFER. If the caller supplied a RequiredPropertyKeyCount
/// pointer, <c>SetupDiGetClassPropertyKeysEx</c> sets the value of *RequiredPropertyKeyCount to the required size, in
/// DEVPROPKEY-typed values, of the PropertyKeyArray buffer.
/// </para>
/// <para>
/// To retrieve a device class property on a remote computer, call SetupDiGetClassPropertyEx, and to set a device class property on
/// a remote computer, call SetupDiSetClassPropertyEx.
/// </para>
/// <para>To retrieve the property keys for a device setup class or device interface class on a local computer, call SetupDiGetClassPropertyKeys.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclasspropertykeysexw WINSETUPAPI BOOL
// SetupDiGetClassPropertyKeysExW( const GUID *ClassGuid, DEVPROPKEY *PropertyKeyArray, DWORD PropertyKeyCount, PDWORD
// RequiredPropertyKeyCount, DWORD Flags, PCWSTR MachineName, PVOID Reserved );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Unicode)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassPropertyKeysExW")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetClassPropertyKeysEx(in Guid ClassGuid,
[Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] DEVPROPKEY[]? PropertyKeyArray, uint PropertyKeyCount,
out uint RequiredPropertyKeyCount, DICLASSPROP Flags, [Optional, MarshalAs(UnmanagedType.LPWStr)] string? MachineName,
[In, Optional] IntPtr Reserved);
/// <summary>
/// The <c>SetupDiGetClassRegistryProperty</c> function retrieves a property for a specified device setup class from the registry.
/// </summary>
/// <param name="ClassGuid">A pointer to a GUID representing the device setup class for which a property is to be retrieved.</param>
/// <param name="Property">
/// <para>A value that identifies the property to be retrieved. This must be one of the following values:</para>
/// <para>SPCRP_CHARACTERISTICS</para>
/// <para>
/// The function returns flags indicating device characteristics for the class. For a list of characteristics flags, see the
/// DeviceCharacteristics parameter to IoCreateDevice.
/// </para>
/// <para>SPCRP_DEVTYPE</para>
/// <para>
/// The function returns a DWORD value that represents the device type for the class. For more information, see Specifying Device Types.
/// </para>
/// <para>SPCRP_EXCLUSIVE</para>
/// <para>
/// The function returns a DWORD value indicating whether users can obtain exclusive access to devices for this class. The returned
/// value is one if exclusive access is allowed, or zero otherwise.
/// </para>
/// <para>SPCRP_LOWERFILTERS</para>
/// <para>
/// (Windows Vista and later) The function returns a REG_MULTI_SZ list of the service names of the lower filter drivers that are
/// installed for the device setup class.
/// </para>
/// <para>SPCRP_SECURITY</para>
/// <para>
/// The function returns the device's security descriptor as a SECURITY_DESCRIPTOR structure in self-relative format (described in
/// the Microsoft Windows SDK documentation).
/// </para>
/// <para>SPCRP_SECURITY_SDS</para>
/// <para>
/// The function returns the device's security descriptor as a text string. For information about security descriptor strings, see
/// Security Descriptor Definition Language (Windows). For information about the format of security descriptor strings, see Security
/// Descriptor Definition Language (Windows).
/// </para>
/// <para>SPCRP_UPPERFILTERS</para>
/// <para>
/// (Windows Vista and later) The function returns a REG_MULTI_SZ list of the service names of the upper filter drivers that are
/// installed for the device setup class.
/// </para>
/// </param>
/// <param name="PropertyRegDataType">
/// A pointer to a variable of type DWORD that receives the property data type as one of the REG_-prefixed registry data types. This
/// parameter is optional and can be <c>NULL</c>. If this parameter is <c>NULL</c>, S <c>etupDiGetClassRegistryProperty</c> does not
/// return the data type.
/// </param>
/// <param name="PropertyBuffer">A pointer to a buffer that receives the requested property.</param>
/// <param name="PropertyBufferSize">The size, in bytes, of the PropertyBuffer buffer.</param>
/// <param name="RequiredSize">
/// A pointer to a variable of type DWORD that receives the required size, in bytes, of the PropertyBuffer buffer. If the
/// PropertyBuffer buffer is too small, and RequiredSize is not <c>NULL</c>, the function sets RequiredSize to the minimum buffer
/// size that is required to receive the requested property.
/// </param>
/// <param name="MachineName">
/// A pointer to a NULL-terminated string that contains the name of a remote system from which to retrieve the specified device
/// class property. This parameter is optional and can be <c>NULL</c>. If this parameter is <c>NULL</c>, the property is retrieved
/// from the local system.
/// </param>
/// <param name="Reserved">Reserved, must be <c>NULL</c>.</param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// with a call to GetLastError.
/// </returns>
/// <remarks/>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetclassregistrypropertya WINSETUPAPI BOOL
// SetupDiGetClassRegistryPropertyA( const GUID *ClassGuid, DWORD Property, PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD
// PropertyBufferSize, PDWORD RequiredSize, PCSTR MachineName, PVOID Reserved );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetClassRegistryPropertyA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetClassRegistryProperty(in Guid ClassGuid, SPCRP Property, out REG_VALUE_TYPE PropertyRegDataType,
[Out, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, out uint RequiredSize,
[Optional, MarshalAs(UnmanagedType.LPTStr)] string? MachineName, [In, Optional] IntPtr Reserved);
/// <summary>The <c>SetupDiGetCustomDeviceProperty</c> function retrieves a specified custom device property from the registry.</summary>
/// <param name="DeviceInfoSet">
/// A handle to the device information set that contains a device information element that represents the device for which to
/// retrieve a custom device property.
/// </param>
/// <param name="DeviceInfoData">A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet.</param>
/// <param name="CustomPropertyName">A registry value name representing a custom property.</param>
/// <param name="Flags">
/// <para>A flag value that indicates how the requested information should be returned. The flag can be zero or one of the following:</para>
/// <para>DICUSTOMDEVPROP_MERGE_MULTISZ</para>
/// <para>
/// If set, the function retrieves both device instance-specific property values and hardware ID-specific property values,
/// concatenated as a REG_MULTI_SZ-typed string. (For more information, see the <c>Remarks</c> section on this reference page.)
/// </para>
/// </param>
/// <param name="PropertyRegDataType">
/// A pointer to a variable of type DWORD that receives the data type of the retrieved property. The data type is specified as one
/// of the REG_-prefixed constants that represents registry data types. This parameter is optional and can be <c>NULL</c>.
/// </param>
/// <param name="PropertyBuffer">A pointer to a buffer that receives requested property information.</param>
/// <param name="PropertyBufferSize">The size, in bytes, of the PropertyBuffer buffer.</param>
/// <param name="RequiredSize">
/// A pointer to a variable of type DWORD that receives the buffer size, in bytes, that is required to receive the requested
/// information. This parameter is optional and can be <c>NULL</c>. If this parameter is specified,
/// <c>SetupDiGetCustomDeviceProperty</c> returns the required size, regardless of whether the PropertyBuffer buffer is large enough
/// to receive the requested information.
/// </param>
/// <returns>
/// If the operation succeeds, <c>SetupDiGetCustomDeviceProperty</c> returns <c>TRUE</c>. Otherwise, the function returns
/// <c>FALSE</c> and the logged error can be retrieved with a call to GetLastError. If the PropertyBuffer buffer is not large enough
/// to receive the requested information, <c>SetupDiGetCustomDeviceProperty</c> returns <c>FALSE</c> and a subsequent call to
/// GetLastError will return ERROR_INSUFFICIENT_BUFFER.
/// </returns>
/// <remarks>
/// <para>
/// <c>SetupDiGetCustomDeviceProperty</c> retrieves device properties that are associated with a single device instance or with all
/// devices matching a certain hardware ID. (For information about hardware IDs, see Device Identification Strings).
/// </para>
/// <para>
/// Vendors can set properties for a device instance by using INF AddReg directives in INF DDInstall.HW sections and specifying the
/// <c>HKR</c> registry root.
/// </para>
/// <para>Only the system can set properties for hardware IDs. The system supplies an "Icon" property for some hardware IDs.</para>
/// <para>
/// The function first checks to see if the specified property exists for the specified device instance. If so, the property's value
/// is returned. If not, the function checks to see if the property exists for all devices matching the hardware ID of the specified
/// device instance. If so, the property's value is returned. If DICUSTOMDEVPROP_MERGE_MULTISZ is set in Flags, the function returns
/// the property values associated with both the device instance and the hardware ID, if they both exist.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetcustomdevicepropertya WINSETUPAPI BOOL
// SetupDiGetCustomDevicePropertyA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PCSTR CustomPropertyName, DWORD Flags,
// PDWORD PropertyRegDataType, PBYTE PropertyBuffer, DWORD PropertyBufferSize, PDWORD RequiredSize );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetCustomDevicePropertyA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetCustomDeviceProperty(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData,
[MarshalAs(UnmanagedType.LPTStr)] string CustomPropertyName, DICUSTOMDEVPROP Flags, out REG_VALUE_TYPE PropertyRegDataType,
[Out, Optional] IntPtr PropertyBuffer, uint PropertyBufferSize, out uint RequiredSize);
/// <summary>
/// The <c>SetupDiGetDeviceInfoListClass</c> function retrieves the GUID for the device setup class associated with a device
/// information set if the set has an associated class.
/// </summary>
/// <param name="DeviceInfoSet">A handle to the device information set to query.</param>
/// <param name="ClassGuid">A pointer to variable of type GUID that receives the GUID for the associated class.</param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// with a call to GetLastError.
/// </returns>
/// <remarks>
/// <para>
/// If the specified device information set does not have an associated class because a class GUID was not specified when the set
/// was created with SetupDiCreateDeviceInfoList, the function fails. In this case, a call to GetLastError returns ERROR_NO_ASSOCIATED_CLASS.
/// </para>
/// <para>
/// If a device information set is for a remote computer, use SetupDiGetDeviceInfoListDetail to get the associated remote computer
/// handle and computer name.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinfolistclass WINSETUPAPI BOOL
// SetupDiGetDeviceInfoListClass( HDEVINFO DeviceInfoSet, LPGUID ClassGuid );
[DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInfoListClass")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInfoListClass(HDEVINFO DeviceInfoSet, out Guid ClassGuid);
/// <summary>
/// The <c>SetupDiGetDeviceInfoListDetail</c> function retrieves information associated with a device information set including the
/// class GUID, remote computer handle, and remote computer name.
/// </summary>
/// <param name="DeviceInfoSet">A handle to the device information set for which to retrieve information.</param>
/// <param name="DeviceInfoSetDetailData">
/// A pointer to a caller-initialized SP_DEVINFO_LIST_DETAIL_DATA structure that receives the device information set information.
/// For more information about this structure, see the following <c>Remarks</c> section.
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// by making a call to GetLastError.
/// </returns>
/// <remarks>
/// <para>
/// If the parameters are valid, <c>SetupDiGetDeviceInfoListDetail</c> sets values in the DeviceInfoSetDetailData structure (except
/// for the <c>cbSize</c> field) and returns status NO_ERROR.
/// </para>
/// <para>
/// A caller of <c>SetupDiGetDeviceInfoListDetail</c> must set DeviceInfoSetDetailData. <c>cbSize</c> to
/// <c>sizeof</c>(SP_DEVINFO_LIST_DETAIL_DATA) or the function will fail and the call to GetLastError will return ERROR_INVALID_USER_BUFFER.
/// </para>
/// <para>
/// If <c>SetupDiGetDeviceInfoListDetail</c> completes successfully, DeviceInfoSetDetailData. <c>ClassGuid</c> contains the class
/// GUID associated with the device information set or a GUID_NULL structure.
/// </para>
/// <para>
/// If <c>SetupDiGetDeviceInfoListDetail</c> completes successfully and the device information set is for a remote system,
/// DeviceInfoSetDetailData. <c>RemoteMachineHandle</c> contains the ConfigMgr32 system handle for accessing the remote system and
/// DeviceInfoSetDetailData. <c>RemoteMachineName</c> contains the name of the remote system. If there is a remote handle for the
/// device information set, it must be used when calling <c>CM_</c> Xxx <c>_Ex</c> functions because the DevInst handles are
/// relative to the remote handle.
/// </para>
/// <para>
/// If the device information set is for the local computer, DeviceInfoSetDetailData. <c>RemoteMachineHandle</c> is <c>NULL</c> and
/// DeviceInfoSetDetailData. <c>RemoteMachineName</c> is an empty string.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinfolistdetaila WINSETUPAPI BOOL
// SetupDiGetDeviceInfoListDetailA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_LIST_DETAIL_DATA_A DeviceInfoSetDetailData );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInfoListDetailA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInfoListDetail(HDEVINFO DeviceInfoSet, ref SP_DEVINFO_LIST_DETAIL_DATA DeviceInfoSetDetailData);
/// <summary>
/// The <c>SetupDiGetDeviceInstallParams</c> function retrieves device installation parameters for a device information set or a
/// particular device information element.
/// </summary>
/// <param name="DeviceInfoSet">A handle to the device information set that contains the device installation parameters to retrieve.</param>
/// <param name="DeviceInfoData">
/// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is
/// optional and can be <c>NULL</c>. If this parameter is specified, <c>SetupDiGetDeviceInstallParams</c> retrieves the installation
/// parameters for the specified device. If this parameter is <c>NULL</c>, the function retrieves the global device installation
/// parameters that are associated with DeviceInfoSet.
/// </param>
/// <param name="DeviceInstallParams">
/// A pointer to an SP_DEVINSTALL_PARAMS structure that receives the device install parameters. DeviceInstallParams. <c>cbSize</c>
/// must be set to the size, in bytes, of the structure before calling this function.
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// by making a call to GetLastError.
/// </returns>
/// <remarks/>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinstallparamsa WINSETUPAPI BOOL
// SetupDiGetDeviceInstallParamsA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A
// DeviceInstallParams );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInstallParamsA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInstallParams(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData, ref SP_DEVINSTALL_PARAMS DeviceInstallParams);
/// <summary>
/// The <c>SetupDiGetDeviceInstallParams</c> function retrieves device installation parameters for a device information set or a
/// particular device information element.
/// </summary>
/// <param name="DeviceInfoSet">A handle to the device information set that contains the device installation parameters to retrieve.</param>
/// <param name="DeviceInfoData">
/// A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet. This parameter is
/// optional and can be <c>NULL</c>. If this parameter is specified, <c>SetupDiGetDeviceInstallParams</c> retrieves the installation
/// parameters for the specified device. If this parameter is <c>NULL</c>, the function retrieves the global device installation
/// parameters that are associated with DeviceInfoSet.
/// </param>
/// <param name="DeviceInstallParams">
/// A pointer to an SP_DEVINSTALL_PARAMS structure that receives the device install parameters. DeviceInstallParams. <c>cbSize</c>
/// must be set to the size, in bytes, of the structure before calling this function.
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// by making a call to GetLastError.
/// </returns>
/// <remarks/>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinstallparamsa WINSETUPAPI BOOL
// SetupDiGetDeviceInstallParamsA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSP_DEVINSTALL_PARAMS_A
// DeviceInstallParams );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInstallParamsA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInstallParams(HDEVINFO DeviceInfoSet, [In, Optional] IntPtr DeviceInfoData, ref SP_DEVINSTALL_PARAMS DeviceInstallParams);
/// <summary>
/// The <c>SetupDiGetDeviceInstanceId</c> function retrieves the device instance ID that is associated with a device information element.
/// </summary>
/// <param name="DeviceInfoSet">
/// A handle to the device information set that contains the device information element that represents the device for which to
/// retrieve a device instance ID.
/// </param>
/// <param name="DeviceInfoData">A pointer to an SP_DEVINFO_DATA structure that specifies the device information element in DeviceInfoSet.</param>
/// <param name="DeviceInstanceId">
/// A pointer to the character buffer that will receive the NULL-terminated device instance ID for the specified device information
/// element. For information about device instance IDs, see Device Identification Strings.
/// </param>
/// <param name="DeviceInstanceIdSize">The size, in characters, of the DeviceInstanceId buffer.</param>
/// <param name="RequiredSize">
/// A pointer to the variable that receives the number of characters required to store the device instance ID.
/// </param>
/// <returns>
/// The function returns <c>TRUE</c> if it is successful. Otherwise, it returns <c>FALSE</c> and the logged error can be retrieved
/// by making a call to GetLastError.
/// </returns>
/// <remarks/>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinstanceida WINSETUPAPI BOOL
// SetupDiGetDeviceInstanceIdA( HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, PSTR DeviceInstanceId, DWORD
// DeviceInstanceIdSize, PDWORD RequiredSize );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInstanceIdA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInstanceId(HDEVINFO DeviceInfoSet, in SP_DEVINFO_DATA DeviceInfoData,
[Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder DeviceInstanceId, uint DeviceInstanceIdSize, out uint RequiredSize);
/// <summary>The <c>SetupDiGetDeviceInterfaceAlias</c> function returns an alias of a specified device interface.</summary>
/// <param name="DeviceInfoSet">
/// A pointer to the device information set that contains the device interface for which to retrieve an alias. This handle is
/// typically returned by SetupDiGetClassDevs.
/// </param>
/// <param name="DeviceInterfaceData">
/// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the device interface in DeviceInfoSet for which to retrieve an
/// alias. This pointer is typically returned by SetupDiEnumDeviceInterfaces.
/// </param>
/// <param name="AliasInterfaceClassGuid">A pointer to a GUID that specifies the interface class of the alias to retrieve.</param>
/// <param name="AliasDeviceInterfaceData">
/// A pointer to a caller-allocated buffer that contains, on successful return, a completed SP_DEVICE_INTERFACE_DATA structure that
/// identifies the requested alias. The caller must set AliasDeviceInterfaceData <c>.cbSize</c> to
/// <c>sizeof</c>(SP_DEVICE_INTERFACE_DATA) before calling this function.
/// </param>
/// <returns>
/// <para>
/// <c>SetupDiGetDeviceInterfaceAlias</c> returns <c>TRUE</c> if the function completed without error. If the function completed
/// with an error, <c>FALSE</c> is returned and the error code for the failure can be retrieved by calling GetLastError.
/// </para>
/// <para>Possible errors returned by GetLastError are listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>ERROR_INVALID_PARAMETER</term>
/// <term>Invalid DeviceInfoSet or invalid DeviceInterfaceData parameter.</term>
/// </item>
/// <item>
/// <term>ERROR_NO_SUCH_INTERFACE_DEVICE</term>
/// <term>There is no alias of class AliasInterfaceClassGuid for the specified device interface.</term>
/// </item>
/// <item>
/// <term>ERROR_INVALID_USER_BUFFER</term>
/// <term>Invalid AliasDeviceInterfaceData buffer.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// Device interfaces are considered aliases if they are of different interface classes but are supported by the same device and
/// have identical reference strings.
/// </para>
/// <para>
/// <c>SetupDiGetDeviceInterfaceAlias</c> can be used to locate a device that exposes more than one interface. For example, consider
/// a disk that can be part of a fault-tolerant volume and can contain encrypted data. The function driver for the disk device could
/// register a fault-tolerant-volume interface and an encrypted-volume interface. These interfaces are device interface aliases if
/// the function driver registers them with identical reference strings and they refer to the same device. (The reference strings
/// will likely be <c>NULL</c> and therefore are equal.)
/// </para>
/// <para>
/// To locate such a multi-interface device, first locate all available devices that expose one of the interfaces, such as the
/// fault-tolerant-volume interface, using SetupDiGetClassDevs and SetupDiEnumDeviceInterfaces. Then, pass a device with the first
/// interface (fault-tolerant-volume) to <c>SetupDiGetDeviceInterfaceAlias</c> and request an alias of the other interface class (encrypted-volume).
/// </para>
/// <para>
/// If the requested alias exists but the caller-supplied AliasDeviceInterfaceData buffer is invalid, this function successfully
/// adds the device interface element to DevInfoSet but returns <c>FALSE</c> for the return value. In this case, GetLastError
/// returns ERROR_INVALID_USER_BUFFER.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinterfacealias WINSETUPAPI BOOL
// SetupDiGetDeviceInterfaceAlias( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, const GUID
// *AliasInterfaceClassGuid, PSP_DEVICE_INTERFACE_DATA AliasDeviceInterfaceData );
[DllImport(Lib_SetupAPI, SetLastError = true, ExactSpelling = true)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInterfaceAlias")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInterfaceAlias(HDEVINFO DeviceInfoSet, in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
in Guid AliasInterfaceClassGuid, ref SP_DEVICE_INTERFACE_DATA AliasDeviceInterfaceData);
/// <summary>The <c>SetupDiGetDeviceInterfaceDetail</c> function returns details about a device interface.</summary>
/// <param name="DeviceInfoSet">
/// A pointer to the device information set that contains the interface for which to retrieve details. This handle is typically
/// returned by SetupDiGetClassDevs.
/// </param>
/// <param name="DeviceInterfaceData">
/// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the interface in DeviceInfoSet for which to retrieve details.
/// A pointer of this type is typically returned by SetupDiEnumDeviceInterfaces.
/// </param>
/// <param name="DeviceInterfaceDetailData">
/// A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information about the specified interface. This parameter
/// is optional and can be <c>NULL</c>. This parameter must be <c>NULL</c> if DeviceInterfaceDetailSize is zero. If this parameter
/// is specified, the caller must set DeviceInterfaceDetailData <c>.cbSize</c> to <c>sizeof</c>(SP_DEVICE_INTERFACE_DETAIL_DATA)
/// before calling this function. The <c>cbSize</c> member always contains the size of the fixed part of the data structure, not a
/// size reflecting the variable-length string at the end.
/// </param>
/// <param name="DeviceInterfaceDetailDataSize">
/// <para>
/// The size of the DeviceInterfaceDetailData buffer. The buffer must be at least ( <c>offsetof</c>(SP_DEVICE_INTERFACE_DETAIL_DATA,
/// <c>DevicePath</c>) + <c>sizeof</c>(TCHAR)) bytes, to contain the fixed part of the structure and a single <c>NULL</c> to
/// terminate an empty MULTI_SZ string.
/// </para>
/// <para>This parameter must be zero if DeviceInterfaceDetailData is <c>NULL</c>.</para>
/// </param>
/// <param name="RequiredSize">
/// A pointer to a variable of type DWORD that receives the required size of the DeviceInterfaceDetailData buffer. This size
/// includes the size of the fixed part of the structure plus the number of bytes required for the variable-length device path
/// string. This parameter is optional and can be <c>NULL</c>.
/// </param>
/// <param name="DeviceInfoData">
/// A pointer to a buffer that receives information about the device that supports the requested interface. The caller must set
/// DeviceInfoData <c>.cbSize</c> to <c>sizeof</c>(SP_DEVINFO_DATA). This parameter is optional and can be <c>NULL</c>.
/// </param>
/// <returns>
/// <c>SetupDiGetDeviceInterfaceDetail</c> returns <c>TRUE</c> if the function completed without error. If the function completed
/// with an error, <c>FALSE</c> is returned and the error code for the failure can be retrieved by calling GetLastError.
/// </returns>
/// <remarks>
/// <para>Using this function to get details about an interface is typically a two-step process:</para>
/// <list type="number">
/// <item>
/// <term>
/// Get the required buffer size. Call <c>SetupDiGetDeviceInterfaceDetail</c> with a <c>NULL</c> DeviceInterfaceDetailData pointer,
/// a DeviceInterfaceDetailDataSize of zero, and a valid RequiredSize variable. In response to such a call, this function returns
/// the required buffer size at RequiredSize and fails with GetLastError returning ERROR_INSUFFICIENT_BUFFER.
/// </term>
/// </item>
/// <item>
/// <term>Allocate an appropriately sized buffer and call the function again to get the interface details.</term>
/// </item>
/// </list>
/// <para>
/// The interface detail returned by this function consists of a device path that can be passed to Win32 functions such as
/// CreateFile. Do not attempt to parse the device path symbolic name. The device path can be reused across system starts.
/// </para>
/// <para>
/// <c>SetupDiGetDeviceInterfaceDetail</c> can be used to get just the DeviceInfoData. If the interface exists but
/// DeviceInterfaceDetailData is <c>NULL</c>, this function fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, and the
/// DeviceInfoData structure is filled with information about the device that exposes the interface.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/setupapi/nf-setupapi-setupdigetdeviceinterfacedetaila WINSETUPAPI BOOL
// SetupDiGetDeviceInterfaceDetailA( HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
// PSP_DEVICE_INTERFACE_DETAIL_DATA_A DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize,
// PSP_DEVINFO_DATA DeviceInfoData );
[DllImport(Lib_SetupAPI, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("setupapi.h", MSDNShortId = "NF:setupapi.SetupDiGetDeviceInterfaceDetailA")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetupDiGetDeviceInterfaceDetail(HDEVINFO DeviceInfoSet, in SP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
[Out, Optional] IntPtr DeviceInterfaceDetailData, uint DeviceInterfaceDetailDataSize, out uint RequiredSize, ref SP_DEVINFO_DATA DeviceInfoData);
/// <summary>The <c>SetupDiGetDeviceInterfaceDetail</c> function returns details about a device interface.</summary>
/// <param name="DeviceInfoSet">
/// A pointer to the device information set that contains the interface for which to retrieve details. This handle is typically
/// returned by SetupDiGetClassDevs.
/// </param>
/// <param name="DeviceInterfaceData">
/// A pointer to an SP_DEVICE_INTERFACE_DATA structure that specifies the interface in DeviceInfoSet for which to retrieve details.
/// A pointer of this type is typically returned by SetupDiEnumDeviceInterfaces.
/// </param>
/// <param name="DeviceInterfaceDetailData">
/// A pointer to an SP_DEVICE_INTERFACE_DETAIL_DATA structure to receive information about the specified interface. This parameter
/// is optional and can be <c>NULL</c>. This parameter must be <c>NULL</c> if DeviceInterfaceDetailSize is zero. If this parameter
/// is specified, the caller must set DeviceInterfaceDetailData <c>.cbSize</c> to <c>sizeof</c>(SP_DEVICE_INTERFACE_DETAIL_DATA)
/// before calling this function. The <c>cbSize</c> member always contains the size of the fixed part of the data structure, not a
/// size reflecting the variable-length string at the end.
/// </param>
/// <param name="DeviceInterfaceDetailDataSize">
/// <para>
/// The size of the DeviceInterfaceDetailData buffer. The buffer must be at least ( <c>offsetof</c>(SP_DEVICE_INTERFACE_DETAIL_DATA,
/// <c>DevicePath</c>) + <c>sizeof</c>(TCHAR)) bytes, to contain the fixed part of the structure and a single <c>NULL</c> to
/// terminate an empty MULTI_SZ string.
/// </para>
/// <para>This parameter must be zero if DeviceInterfaceDetailData is <c>NULL</c>.</para>
/// </param>
/// <param name="RequiredSize">
/// A pointer to a variable of type DWORD that receives the required size of the DeviceInterfaceDetailData buffer. This size
/// includes the size of the fixed part of the structure plus the number of bytes required for the variable-length device path
/// string. This parameter is optional and can be <c>NULL</c>.
/// </param>
/// <param name="DeviceInfoData">