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);
        }