Exemplo n.º 1
0
        private static NativeMethods.SP_DEVICE_INTERFACE_DATA CreateDeviceInterfaceDataInstance()
        {
            var did = new NativeMethods.SP_DEVICE_INTERFACE_DATA();

            did.cbSize = (uint)Marshal.SizeOf(did);

            return(did);
        }
Exemplo n.º 2
0
        internal static IEnumerable <DeviceInfo> EnumerateDevicesCore(string hostName, DeviceGuid deviceGuid, bool getAllProperties)
        {
            if (Utils.IsNullOrWhiteSpace(hostName))
            {
                hostName = Environment.MachineName;
            }


            // CM_Connect_Machine()
            // MSDN Note: Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed.
            // You cannot access remote machines when running on these versions of Windows.
            // http://msdn.microsoft.com/en-us/library/windows/hardware/ff537948%28v=vs.85%29.aspx


            SafeCmConnectMachineHandle safeMachineHandle;

            var lastError = NativeMethods.CM_Connect_Machine(Host.GetUncName(hostName), out safeMachineHandle);

            NativeMethods.IsValidHandle(safeMachineHandle, lastError);


            var classGuid = new Guid(Utils.GetEnumDescription(deviceGuid));


            // Start at the "Root" of the device tree of the specified machine.

            using (safeMachineHandle)
                using (var safeHandle = NativeMethods.SetupDiGetClassDevsEx(ref classGuid, IntPtr.Zero, IntPtr.Zero, NativeMethods.SetupDiGetClassDevsExFlags.Present | NativeMethods.SetupDiGetClassDevsExFlags.DeviceInterface, IntPtr.Zero, hostName, IntPtr.Zero))
                {
                    NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error());

                    uint memberInterfaceIndex = 0;
                    var  interfaceStructSize  = (uint)Marshal.SizeOf(typeof(NativeMethods.SP_DEVICE_INTERFACE_DATA));
                    var  dataStructSize       = (uint)Marshal.SizeOf(typeof(NativeMethods.SP_DEVINFO_DATA));


                    // Start enumerating device interfaces.

                    while (true)
                    {
                        var interfaceData = new NativeMethods.SP_DEVICE_INTERFACE_DATA {
                            cbSize = interfaceStructSize
                        };

                        var success = NativeMethods.SetupDiEnumDeviceInterfaces(safeHandle, IntPtr.Zero, ref classGuid, memberInterfaceIndex++, ref interfaceData);

                        lastError = Marshal.GetLastWin32Error();

                        if (!success)
                        {
                            if (lastError != Win32Errors.NO_ERROR && lastError != Win32Errors.ERROR_NO_MORE_ITEMS)
                            {
                                NativeError.ThrowException(lastError, hostName);
                            }

                            break;
                        }


                        // Create DeviceInfo instance.

                        var diData = new NativeMethods.SP_DEVINFO_DATA {
                            cbSize = dataStructSize
                        };

                        var deviceInfo = new DeviceInfo(hostName)
                        {
                            DevicePath = GetDeviceInterfaceDetail(safeHandle, ref interfaceData, ref diData).DevicePath
                        };


                        if (getAllProperties)
                        {
                            deviceInfo.InstanceId = GetDeviceInstanceId(safeMachineHandle, hostName, diData);

                            SetDeviceProperties(safeHandle, deviceInfo, diData);
                        }

                        else
                        {
                            SetMinimalDeviceProperties(safeHandle, deviceInfo, diData);
                        }


                        yield return(deviceInfo);
                    }
                }
        }
Exemplo n.º 3
0
        private static NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA GetDeviceInterfaceDetail(SafeHandle safeHandle, ref NativeMethods.SP_DEVICE_INTERFACE_DATA interfaceData, ref NativeMethods.SP_DEVINFO_DATA infoData)
        {
            var didd = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA {
                cbSize = (uint)(IntPtr.Size == 4 ? 6 : 8)
            };

            var success = NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref interfaceData, ref didd, (uint)Marshal.SizeOf(didd), IntPtr.Zero, ref infoData);

            var lastError = Marshal.GetLastWin32Error();

            if (!success)
            {
                NativeError.ThrowException(lastError);
            }

            return(didd);
        }
Exemplo n.º 4
0
        internal static IEnumerable <DeviceInfo> EnumerateDevicesCore(SafeHandle safeHandle, string hostName, DeviceGuid deviceInterfaceGuid)
        {
            bool callerHandle = safeHandle != null;
            var  deviceGuid   = new Guid(Utils.GetEnumDescription(deviceInterfaceGuid));


            // CM_Connect_Machine()
            // MSDN Note: Beginning in Windows 8 and Windows Server 2012 functionality to access remote machines has been removed.
            // You cannot access remote machines when running on these versions of Windows.
            // http://msdn.microsoft.com/en-us/library/windows/hardware/ff537948%28v=vs.85%29.aspx

            SafeCmConnectMachineHandle safeMachineHandle;
            int lastError = NativeMethods.CM_Connect_Machine(Path.LocalToUncCore(Host.GetUncName(hostName), false, false, false), out safeMachineHandle);

            if (safeMachineHandle.IsInvalid)
            {
                safeMachineHandle.Close();
                NativeError.ThrowException(lastError, Resources.Handle_Is_Invalid);
            }

            using (safeMachineHandle)
            {
                // Start at the "Root" of the device tree of the specified machine.
                if (!callerHandle)
                {
                    safeHandle = NativeMethods.SetupDiGetClassDevsEx(ref deviceGuid, IntPtr.Zero, IntPtr.Zero,
                                                                     NativeMethods.SetupDiGetClassDevsExFlags.Present |
                                                                     NativeMethods.SetupDiGetClassDevsExFlags.DeviceInterface,
                                                                     IntPtr.Zero, hostName, IntPtr.Zero);
                }

                if (safeHandle.IsInvalid)
                {
                    safeHandle.Close();
                    NativeError.ThrowException(Marshal.GetLastWin32Error(), Resources.Handle_Is_Invalid);
                }


                try
                {
                    uint memberInterfaceIndex = 0;
                    NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData = CreateDeviceInterfaceDataInstance();

                    // Start enumerating Device Interfaces.
                    while (NativeMethods.SetupDiEnumDeviceInterfaces(safeHandle, IntPtr.Zero, ref deviceGuid, memberInterfaceIndex++, ref deviceInterfaceData))
                    {
                        lastError = Marshal.GetLastWin32Error();
                        if (lastError != Win32Errors.NO_ERROR)
                        {
                            NativeError.ThrowException(lastError, hostName);
                        }


                        NativeMethods.SP_DEVINFO_DATA deviceInfoData = CreateDeviceInfoDataInstance();
                        NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = GetDeviceInterfaceDetailDataInstance(safeHandle, deviceInterfaceData, deviceInfoData);

                        // Get device interace details.
                        if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref deviceInterfaceData, ref deviceInterfaceDetailData, NativeMethods.DefaultFileBufferSize, IntPtr.Zero, ref deviceInfoData))
                        {
                            lastError = Marshal.GetLastWin32Error();
                            if (lastError != Win32Errors.NO_ERROR)
                            {
                                NativeError.ThrowException(lastError, hostName);
                            }
                        }

                        // Create DeviceInfo instance.
                        // Set DevicePath property of DeviceInfo instance.
                        var deviceInfo = new DeviceInfo(hostName)
                        {
                            DevicePath = deviceInterfaceDetailData.DevicePath
                        };


                        // Current InstanceId is at the "USBSTOR" level, so we
                        // need up "move up" one level to get to the "USB" level.
                        uint ptrPrevious;

                        // CM_Get_Parent_Ex()
                        // Note: Using this function to access remote machines is not supported
                        // beginning with Windows 8 and Windows Server 2012, as this functionality has been removed.
                        // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538615%28v=vs.85%29.aspx

                        lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, deviceInfoData.DevInst, 0, safeMachineHandle);
                        if (lastError != Win32Errors.CR_SUCCESS)
                        {
                            NativeError.ThrowException(lastError, hostName);
                        }


                        // Now we get the InstanceID of the USB level device.
                        using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize))
                        {
                            // CM_Get_Device_ID_Ex()
                            // Note: Using this function to access remote machines is not supported beginning with Windows 8 and Windows Server 2012,
                            // as this functionality has been removed.
                            // http://msdn.microsoft.com/en-us/library/windows/hardware/ff538411%28v=vs.85%29.aspx

                            lastError = NativeMethods.CM_Get_Device_ID_Ex(deviceInfoData.DevInst, safeBuffer, (uint)safeBuffer.Capacity, 0, safeMachineHandle);
                            if (lastError != Win32Errors.CR_SUCCESS)
                            {
                                NativeError.ThrowException(lastError, hostName);
                            }

                            // Add to instance.
                            deviceInfo.InstanceId = safeBuffer.PtrToStringUni();
                        }

                        #region Get Registry Properties

                        using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize))
                        {
                            uint   regType;
                            string dataString;
                            uint   safeBufferCapacity = (uint)safeBuffer.Capacity;


                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.BaseContainerId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                dataString = safeBuffer.PtrToStringUni();
                                if (!Utils.IsNullOrWhiteSpace(dataString))
                                {
                                    deviceInfo.BaseContainerId = new Guid(dataString);
                                }
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.ClassGuid, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                dataString = safeBuffer.PtrToStringUni();
                                if (!Utils.IsNullOrWhiteSpace(dataString))
                                {
                                    deviceInfo.ClassGuid = new Guid(dataString);
                                }
                            }


                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Class, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.Class = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.CompatibleIds, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.CompatibleIds = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.DeviceDescription, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.DeviceDescription = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Driver, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.Driver = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.EnumeratorName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.EnumeratorName = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.FriendlyName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.FriendlyName = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.HardwareId, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.HardwareId = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationInformation, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.LocationInformation = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.LocationPaths, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.LocationPaths = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Manufacturer, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.Manufacturer = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.PhysicalDeviceObjectName, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.PhysicalDeviceObjectName = safeBuffer.PtrToStringUni();
                            }

                            if (NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref deviceInfoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum.Service, out regType, safeBuffer, safeBufferCapacity, IntPtr.Zero))
                            {
                                deviceInfo.Service = safeBuffer.PtrToStringUni();
                            }
                        }

                        #endregion // Get Registry Properties

                        yield return(deviceInfo);

                        // Get new structure instance.
                        deviceInterfaceData = CreateDeviceInterfaceDataInstance();
                    }
                }
                finally
                {
                    // Handle is ours, dispose.
                    if (!callerHandle && safeHandle != null)
                    {
                        safeHandle.Close();
                    }
                }
            }
        }
Exemplo n.º 5
0
        private static NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA GetDeviceInterfaceDetailDataInstance(SafeHandle safeHandle, NativeMethods.SP_DEVICE_INTERFACE_DATA deviceInterfaceData, NativeMethods.SP_DEVINFO_DATA deviceInfoData)
        {
            // Build a Device Interface Detail Data structure.
            var didd = new NativeMethods.SP_DEVICE_INTERFACE_DETAIL_DATA
            {
                cbSize = (IntPtr.Size == 4) ? (uint)(Marshal.SystemDefaultCharSize + 4) : 8
            };

            // Get device interace details.
            if (!NativeMethods.SetupDiGetDeviceInterfaceDetail(safeHandle, ref deviceInterfaceData, ref didd, NativeMethods.DefaultFileBufferSize, IntPtr.Zero, ref deviceInfoData))
            {
                int lastError = Marshal.GetLastWin32Error();
                if (lastError != Win32Errors.NO_ERROR)
                {
                    NativeError.ThrowException(lastError);
                }
            }

            return(didd);
        }