public static STORAGE_DEVICE_DESCRIPTOR GetDeviceDescriptor(SafeFileHandle hDevice) { const int StorageDeviceProperty = 0; const int PropertyStandardQuery = 0; uint dummy; STORAGE_PROPERTY_QUERY storagePropertyQuery = new STORAGE_PROPERTY_QUERY(); storagePropertyQuery.PropertyId = StorageDeviceProperty; storagePropertyQuery.QueryType = PropertyStandardQuery; IntPtr lpInBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(storagePropertyQuery)); Marshal.StructureToPtr(storagePropertyQuery, lpInBuffer, false); STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = new STORAGE_DESCRIPTOR_HEADER(); IntPtr lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(storageDescriptorHeader)); Marshal.StructureToPtr(storageDescriptorHeader, lpOutBuffer, false); bool success = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, lpInBuffer, (uint)Marshal.SizeOf(storagePropertyQuery), lpOutBuffer, (uint)Marshal.SizeOf(storageDescriptorHeader), out dummy, IntPtr.Zero); if (!success) { int errorCode = Marshal.GetLastWin32Error(); throw new IOException("Unable to retrieve device description header, Error: " + errorCode.ToString()); } storageDescriptorHeader = (STORAGE_DESCRIPTOR_HEADER)Marshal.PtrToStructure(lpOutBuffer, typeof(STORAGE_DESCRIPTOR_HEADER)); Marshal.FreeHGlobal(lpOutBuffer); if ((int)storageDescriptorHeader.Size < Marshal.SizeOf(typeof(STORAGE_DEVICE_DESCRIPTOR))) { // Observed when using Dataram RAMDisk v4.4.0 RC36 throw new InvalidDataException("Invalid STORAGE_DEVICE_DESCRIPTOR length"); } lpOutBuffer = Marshal.AllocHGlobal((int)storageDescriptorHeader.Size); success = DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, lpInBuffer, (uint)Marshal.SizeOf(storagePropertyQuery), lpOutBuffer, storageDescriptorHeader.Size, out dummy, IntPtr.Zero); if (!success) { int errorCode = Marshal.GetLastWin32Error(); throw new IOException("Unable to retrieve device description, Error: " + errorCode.ToString()); } STORAGE_DEVICE_DESCRIPTOR deviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR)Marshal.PtrToStructure(lpOutBuffer, typeof(STORAGE_DEVICE_DESCRIPTOR)); int rawDevicePropertiesOffset = Marshal.SizeOf(deviceDescriptor); int rawDevicePropertiesLength = (int)storageDescriptorHeader.Size - rawDevicePropertiesOffset; deviceDescriptor.RawDeviceProperties = new byte[rawDevicePropertiesLength]; Marshal.Copy(new IntPtr(lpOutBuffer.ToInt64() + rawDevicePropertiesOffset), deviceDescriptor.RawDeviceProperties, 0, rawDevicePropertiesLength); Marshal.FreeHGlobal(lpOutBuffer); Marshal.FreeHGlobal(lpInBuffer); return(deviceDescriptor); }
/// <summary> /// Returns the device serial number /// </summary> public static string GetDeviceSerialNumber(SafeFileHandle hDevice) { STORAGE_DEVICE_DESCRIPTOR deviceDescriptor = GetDeviceDescriptor(hDevice); // SerialNumberOffset = 0xFFFFFFFF means the device have no serial number if (deviceDescriptor.SerialNumberOffset > 0 && deviceDescriptor.SerialNumberOffset != 0xFFFFFFFF) { int offset = (int)deviceDescriptor.SerialNumberOffset - Marshal.SizeOf(deviceDescriptor); string serialNumber = ByteReader.ReadNullTerminatedAnsiString(deviceDescriptor.RawDeviceProperties, offset); return(DecodeDeviceSerialNumber(serialNumber.Trim())); } return(String.Empty); }
/// <summary> /// Returns the device product ID /// </summary> public static string GetDeviceDescription(SafeFileHandle hDevice) { STORAGE_DEVICE_DESCRIPTOR deviceDescriptor = GetDeviceDescriptor(hDevice); string description = String.Empty; if (deviceDescriptor.VendorIdOffset > 0) { int offset = (int)deviceDescriptor.VendorIdOffset - Marshal.SizeOf(deviceDescriptor); string vendor = ByteReader.ReadNullTerminatedAnsiString(deviceDescriptor.RawDeviceProperties, offset); while (vendor.EndsWith(" ")) // Remove multiple empty space { vendor = vendor.Remove(vendor.Length - 1); } description += vendor; } if (deviceDescriptor.ProductIdOffset > 0) { int offset = (int)deviceDescriptor.ProductIdOffset - Marshal.SizeOf(deviceDescriptor); string product = ByteReader.ReadNullTerminatedAnsiString(deviceDescriptor.RawDeviceProperties, offset); description += product.Trim(); } return(description); }