Beispiel #1
0
        public static List <StorageDeviceInfo> GetRemovableDriveDeviceIds(DriveType driveType, DeviceType deviceType)
        {
            List <StorageDeviceInfo> devices = new List <StorageDeviceInfo>();

            if (driveType == DriveType.Removable && deviceType == DeviceType.FILE_DEVICE_DISK)
            {
                var guid = Win32Constants.GUID_DEVINTERFACE_DISK;

                var setupInterfaceResult = NativeMethods.SetupDiGetClassDevs(
                    ref guid,
                    null,
                    IntPtr.Zero,
                    DiGetClassFlags.DIGCF_PRESENT | DiGetClassFlags.DIGCF_DEVICEINTERFACE);
                if (setupInterfaceResult == Win32Constants.INVALID_HANDLE_VALUE)
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                bool result = true;
                uint i      = 0;
                while (result)
                {
                    SP_DEVICE_INTERFACE_DATA dia = new SP_DEVICE_INTERFACE_DATA();
                    dia.cbSize = (uint)Marshal.SizeOf(dia);

                    result = NativeMethods.SetupDiEnumDeviceInterfaces(setupInterfaceResult, IntPtr.Zero, ref guid, i, out dia);
                    i++;

                    if (result)
                    {
                        SP_DEVINFO_DATA da = new SP_DEVINFO_DATA();
                        da.cbSize = (uint)Marshal.SizeOf(da);
                        var daPtr = Win32Utils.AllocateStructToPointer <SP_DEVINFO_DATA>(da).Item1;

                        SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
                        if (IntPtr.Size == 8)
                        {
                            didd.cbSize = 8;
                        }
                        else
                        {
                            didd.cbSize = (uint)(4 + Marshal.SystemDefaultCharSize);
                        }
                        var diddPtr = Win32Utils.AllocateStructToPointer(didd).Item1;

                        if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(
                                setupInterfaceResult,
                                ref dia,
                                diddPtr,
                                Win32Constants.SIZE_OUTPUT,
                                out uint requireSize,
                                daPtr))
                        {
                            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                        }

                        da   = Marshal.PtrToStructure <SP_DEVINFO_DATA>(daPtr);
                        didd = Marshal.PtrToStructure <SP_DEVICE_INTERFACE_DETAIL_DATA>(diddPtr);

                        string instanceID;
                        var    getParentResult = NativeMethods.CM_Get_Parent(out IntPtr ptrPrevious, da.devInst, 0);
                        if (getParentResult != Win32Constants.CR_SUCCESS)
                        {
                            instanceID = getParentResult.ToString();
                        }
                        else
                        {
                            IntPtr ptrInstanceBuf = Marshal.AllocHGlobal(Win32Constants.SIZE_OUTPUT);

                            var getDeviceIdResult = NativeMethods.CM_Get_Device_ID(ptrPrevious, ptrInstanceBuf, Win32Constants.SIZE_OUTPUT, 0);
                            if (getDeviceIdResult != Win32Constants.CR_SUCCESS)
                            {
                                instanceID = getDeviceIdResult.ToString();
                            }
                            else
                            {
                                instanceID = Marshal.PtrToStringAuto(ptrInstanceBuf);

                                using (SafeFileHandle handle = CreateDeviceNoRightsHandle(didd.DevicePath))
                                {
                                    var deviceNumber = Win32Utils.DeviceIoControlAction <STORAGE_DEVICE_NUMBER>(handle, DeviceControlCode.STORAGE_GET_DEVICE_NUMBER);

                                    StorageDeviceInfo info = new StorageDeviceInfo
                                    {
                                        StorageDeviceNumber    = deviceNumber.Item1,
                                        StorageDeviceNumberRaw = deviceNumber.Item2,
                                        InstanceID             = instanceID,
                                        DevicePath             = didd.DevicePath
                                    };

                                    devices.Add(info);
                                }
                            }

                            Marshal.FreeHGlobal(daPtr);
                            Marshal.FreeHGlobal(diddPtr);
                            Marshal.FreeHGlobal(ptrInstanceBuf);
                        }
                    }
                }

                if (!NativeMethods.SetupDiDestroyDeviceInfoList(setupInterfaceResult))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }
            }

            return(devices);
        }