STORAGE_DEVICE_NUMBER (Structures)
Last changed: -122.170.15.185

.
Summary
Used with IOCTL_STORAGE_GET_DEVICE_NUMBER to get a unique number of a storage device

C# Definition:

[StructLayout(LayoutKind.Sequential)]
struct STORAGE_DEVICE_NUMBER
{
   public int DeviceType;
   public int DeviceNumber;
   public int PartitionNumber;
}

VB Definition:

Structure STORAGE_DEVICE_NUMBER
   Public TODO
End Structure

User-Defined Field Types:

None.

Notes:

When used with a drive letter, the path should not have a trailing backslash ("\\.\C:")

Documentation

Example:

public const uint OPEN_EXISTING = 3;

public const uint INVALID_HANDLE_VALUE = 0;

public const int IOCTL_STORAGE_GET_DEVICE_NUMBER = 0x2D1080;

/// <summary>

/// Win32 CreateFile function, look for complete information at Platform SDK

/// </summary>

/// <param name="FileName">In order to read CD data FileName must be "\\.\\D:" where D is the CDROM drive letter</param>

/// <param name="DesiredAccess">Must be GENERIC_READ for CDROMs others access flags are not important in this case</param>

/// <param name="ShareMode">O means exlusive access, FILE_SHARE_READ allow open the CDROM</param>

/// <param name="lpSecurityAttributes">See Platform SDK documentation for details. NULL pointer could be enough</param>

/// <param name="CreationDisposition">Must be OPEN_EXISTING for CDROM drives</param>

/// <param name="dwFlagsAndAttributes">0 in fine for this case</param>

/// <param name="hTemplateFile">NULL handle in this case</param>

/// <returns>INVALID_HANDLE_VALUE on error or the handle to file if success</returns>

[System.Runtime.InteropServices.DllImport("Kernel32.dll", SetLastError = true)]

public extern static IntPtr CreateFile(string FileName, uint DesiredAccess,

    uint ShareMode, IntPtr lpSecurityAttributes,
    uint CreationDisposition, uint dwFlagsAndAttributes,
    IntPtr hTemplateFile);

/// <summary>

/// The CloseHandle function closes an open object handle.

/// </summary>

/// <param name="hObject">Handle to an open object.</param>

/// <returns>If the function succeeds, the return value is nonzero. If the function fails, the return value is zero. To get extended error information, call GetLastError.</returns>

[System.Runtime.InteropServices.DllImport("Kernel32.dll", SetLastError = true)]

public extern static int CloseHandle(IntPtr hObject);

[System.Runtime.InteropServices.DllImport("Kernel32.dll", SetLastError = true)]

public extern static bool DeviceIoControl(IntPtr hDevice, uint IoControlCode,

    IntPtr InMediaRemoval, uint InBufferSize,
    IntPtr OutBuffer, int OutBufferSize,
    out int BytesReturned,
    IntPtr Overlapped);

// return a unique device number for the given device path
int GetDeviceNumber(string DevicePath)
{
   int ans = -1;

   IntPtr h = CreateFile(DevicePath.TrimEnd('\\'), 0, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
   if (h.ToInt32() != INVALID_HANDLE_VALUE)
   {
     int requiredSize;
     STORAGE_DEVICE_NUMBER Sdn = new STORAGE_DEVICE_NUMBER();
     int nBytes = Marshal.SizeOf(Sdn);
     IntPtr ptrSdn = Marshal.AllocHGlobal(nBytes);

     if (DeviceIoControl(h, IOCTL_STORAGE_GET_DEVICE_NUMBER, IntPtr.Zero, 0, ptrSdn, nBytes, out requiredSize, IntPtr.Zero))
     {
       Sdn = (STORAGE_DEVICE_NUMBER)Marshal.PtrToStructure(ptrSdn, typeof(STORAGE_DEVICE_NUMBER));
       // 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;
}