/// <summary> /// return a unique device number for the given device path /// </summary> /// <param name="devicePath">Device path</param> /// <returns>Device number</returns> static int GetDeviceNumber(string devicePath) { int ans = -1; IntPtr h = CreateFile(devicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero); if (h == INVALID_HANDLE_VALUE) { return(ans); } StorageDeviceNumber sdn = new StorageDeviceNumber(); int nBytes = Marshal.SizeOf(sdn); IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes); if (DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out _, IntPtr.Zero)) { sdn = (StorageDeviceNumber)Marshal.PtrToStructure(ptrSdn, typeof(StorageDeviceNumber)); // just my way of combining the relevant parts of the // STORAGE_DEVICE_NUMBER into a single number ans = (sdn.DeviceType << 8) + sdn.DeviceNumber; } Marshal.FreeHGlobal(ptrSdn); CloseHandle(h); return(ans); }
internal static extern bool DeviceIoControlGetDeviceNumber(SafeFileHandle hDevice, WindowsIoctl ioControlCode, IntPtr inBuffer, uint nInBufferSize, ref StorageDeviceNumber outBuffer, uint nOutBufferSize, ref uint pBytesReturned, IntPtr overlapped);
/// <summary> /// Gets the device number for a specified handle /// </summary> /// <param name="deviceHandle">Device handle</param> /// <returns>Device number</returns> static uint GetDeviceNumber(SafeFileHandle deviceHandle) { StorageDeviceNumber sdn = new StorageDeviceNumber { deviceNumber = -1 }; uint k = 0; if (!Extern.DeviceIoControlGetDeviceNumber(deviceHandle, WindowsIoctl.IoctlStorageGetDeviceNumber, IntPtr.Zero, 0, ref sdn, (uint)Marshal.SizeOf(sdn), ref k, IntPtr.Zero)) { return(uint.MaxValue); } return((uint)sdn.deviceNumber); }