11using System ;
22using System . ComponentModel ;
33using System . IO ;
4+ using System . Runtime . CompilerServices ;
45using System . Runtime . InteropServices ;
56using System . Runtime . Versioning ;
67using Windows . Win32 . Storage . FileSystem ;
@@ -51,22 +52,18 @@ static unsafe uint GetBootDiskNumber()
5152 null
5253 ) ;
5354
54- if ( handle == null || handle . IsInvalid )
55+ if ( handle . IsInvalid )
5556 {
5657 throw new Win32Exception ( ) ;
5758 }
5859
5960 var extents = new VOLUME_DISK_EXTENTS ( ) ;
60- var bytesReturned = 0u ;
6161
6262 if ( ! DeviceIoControl (
6363 handle ,
6464 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS ,
6565 null ,
66- 0 ,
67- & extents ,
68- ( uint ) VOLUME_DISK_EXTENTS . SizeOf ( 1 ) ,
69- & bytesReturned , // If lpOverlapped is NULL, lpBytesReturned cannot be NULL
66+ new Span < byte > ( & extents , VOLUME_DISK_EXTENTS . SizeOf ( 1 ) ) ,
7067 null
7168 ) )
7269 {
@@ -94,7 +91,7 @@ static unsafe uint GetBootDiskNumber()
9491 null
9592 ) ;
9693
97- if ( handle == null || handle . IsInvalid )
94+ if ( handle . IsInvalid )
9895 {
9996 throw new Win32Exception ( ) ;
10097 }
@@ -104,21 +101,18 @@ static unsafe uint GetBootDiskNumber()
104101 PropertyId = STORAGE_PROPERTY_ID . StorageDeviceProperty ,
105102 QueryType = STORAGE_QUERY_TYPE . PropertyStandardQuery ,
106103 } ;
104+ var queryBuffer = new ReadOnlySpan < byte > ( & query , STORAGE_PROPERTY_QUERY . SizeOf ( 1 ) ) ;
107105
108106 // 1. Call DeviceIoControl(STORAGE_PROPERTY_QUERY, out STORAGE_DESCRIPTOR_HEADER) to figure out how many bytes
109107 // we need to allocate.
110108
111109 var header = new STORAGE_DESCRIPTOR_HEADER ( ) ;
112- var bytesReturned = 0u ;
113110
114111 if ( ! DeviceIoControl (
115112 handle ,
116113 IOCTL_STORAGE_QUERY_PROPERTY ,
117- & query ,
118- ( uint ) STORAGE_PROPERTY_QUERY . SizeOf ( 1 ) ,
119- & header ,
120- ( uint ) sizeof ( STORAGE_DESCRIPTOR_HEADER ) ,
121- & bytesReturned ,
114+ queryBuffer ,
115+ new Span < byte > ( & header , sizeof ( STORAGE_DESCRIPTOR_HEADER ) ) ,
122116 null
123117 ) )
124118 {
@@ -128,25 +122,25 @@ static unsafe uint GetBootDiskNumber()
128122 // 2. Call DeviceIOControl(STORAGE_PROPERTY_QUERY, STORAGE_DEVICE_DESCRIPTOR) to get a bunch of device info with a header
129123 // containing the offsets to each piece of information.
130124
131- var descriptorPtr = Marshal . AllocHGlobal ( ( int ) header . Size ) ;
125+ var descriptorSize = ( int ) header . Size ;
126+ var descriptorBuffer = NativeMemory . Alloc ( ( nuint ) descriptorSize ) ;
132127
133128 try
134129 {
130+ var descriptorSpan = new Span < byte > ( descriptorBuffer , descriptorSize ) ;
131+
135132 if ( ! DeviceIoControl (
136133 handle ,
137134 IOCTL_STORAGE_QUERY_PROPERTY ,
138- & query ,
139- ( uint ) STORAGE_PROPERTY_QUERY . SizeOf ( 1 ) ,
140- ( void * ) descriptorPtr ,
141- header . Size ,
142- & bytesReturned ,
135+ queryBuffer ,
136+ descriptorSpan ,
143137 null
144138 ) )
145139 {
146140 throw new Win32Exception ( ) ;
147141 }
148142
149- var descriptor = Marshal . PtrToStructure < STORAGE_DEVICE_DESCRIPTOR > ( descriptorPtr ) ;
143+ ref var descriptor = ref Unsafe . AsRef < STORAGE_DEVICE_DESCRIPTOR > ( descriptorBuffer ) ;
150144
151145 // 3. Figure out where in the blob the serial number is
152146 // and read it from there.
@@ -158,14 +152,14 @@ static unsafe uint GetBootDiskNumber()
158152 throw new InvalidOperationException ( "Serial number offset is zero." ) ;
159153 }
160154
161- var serialNumberPtr = IntPtr . Add ( descriptorPtr , ( int ) serialNumberOffset ) ;
155+ var serialNumberPtr = ( nint ) descriptorBuffer + ( int ) serialNumberOffset ;
162156
163157 var serialNumber = Marshal . PtrToStringAnsi ( serialNumberPtr ) ;
164158 return serialNumber ;
165159 }
166160 finally
167161 {
168- Marshal . FreeHGlobal ( descriptorPtr ) ;
162+ NativeMemory . Free ( descriptorBuffer ) ;
169163 }
170164 }
171165 }
0 commit comments