public static void ChangeDeviceEnabledState( DeviceInfoListHandle deviceInfoList, ref SP_DEVINFO_DATA deviceInfoData, DiClassInstallState state, DiClassInstallScope scope, DiClassInstallFunction installFunction ) { var pcp = new SP_PROPCHANGE_PARAMS(); pcp.Header.cbSize = (uint)Marshal.SizeOf(pcp.Header.GetType()); pcp.Header.InstallFunction = installFunction; pcp.StateChange = state; pcp.Scope = scope; pcp.HwProfile = 0; SetupDiSetClassInstallParams(deviceInfoList, ref deviceInfoData, pcp); if (!SetupDiCallClassInstaller( installFunction, deviceInfoList.DangerousGetHandle(), ref deviceInfoData )) { var error = Marshal.GetLastWin32Error(); if (error != 0) { throw new Win32Exception(error); } else { throw new Exception("Failed to change device enabled state"); } } }
public static unsafe void SetupDiSetClassInstallParams <TParams> (DeviceInfoListHandle deviceList, ref SP_DEVINFO_DATA deviceInfoData, TParams parms) where TParams : class { var pinned = GCHandle.Alloc(parms, GCHandleType.Pinned); try { if (!_SetupDiSetClassInstallParams( deviceList.DangerousGetHandle(), ref deviceInfoData, pinned.AddrOfPinnedObject(), (UInt32)Marshal.SizeOf(parms) )) { var error = Marshal.GetLastWin32Error(); if (error != 0) { throw new Win32Exception(error); } } } finally { pinned.Free(); } }
public static unsafe void EnumerateDevices <TContext> ( string machine, DiGetClassFlags flags, string[] deviceClassNames, EnumerateDevicesFunc <TContext> callback, TContext context ) where TContext : class { DeviceInfoListHandle devs = null; var devInfo = new SP_DEVINFO_DATA(); var devInfoListDetail = new SP_DEVINFO_LIST_DETAIL_DATA(); Guid[] deviceClassGuids; try { int numClasses = 0; if (deviceClassNames != null) { deviceClassGuids = new Guid[deviceClassNames.Length]; foreach (var className in deviceClassNames) { UInt32 numResults; if ( !SetupDiClassGuidsFromNameEx( className, out deviceClassGuids[numClasses], 1, out numResults, machine, IntPtr.Zero ) && (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) ) { throw new Exception("Unable to resolve class name '" + className + "'"); } numClasses += 1; } var newClassGuids = new Guid[numClasses]; Array.Copy(deviceClassGuids, newClassGuids, numClasses); deviceClassGuids = newClassGuids; } else { deviceClassGuids = new Guid[0]; } if (deviceClassGuids.Length > 0) { for (int i = 0; i < deviceClassGuids.Length; i++) { fixed(Guid *pGuid = &(deviceClassGuids[i])) { var existingPtr = IntPtr.Zero; if (devs != null) { existingPtr = devs.DangerousGetHandle(); } var result = SetupDiGetClassDevsEx( new IntPtr(pGuid), null, IntPtr.Zero, flags, existingPtr, machine, IntPtr.Zero ); var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } if (devs == null) { devs = new DeviceInfoListHandle(result, true); } } } } else { devs = new DeviceInfoListHandle( SetupDiGetClassDevsEx( IntPtr.Zero, null, IntPtr.Zero, flags | DiGetClassFlags.DIGCF_ALLCLASSES, IntPtr.Zero, machine, IntPtr.Zero ), true ); var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } } if (devs.IsInvalid) { throw new Exception("Failed to create device info list"); } devInfoListDetail.cbSize = (UInt32)Marshal.SizeOf(devInfoListDetail.GetType()); if (!SetupDiGetDeviceInfoListDetail(devs.DangerousGetHandle(), ref devInfoListDetail)) { var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } return; } devInfo.cbSize = (UInt32)Marshal.SizeOf(devInfo.GetType()); for (UInt32 devIndex = 0; SetupDiEnumDeviceInfo(devs.DangerousGetHandle(), devIndex, ref devInfo); devIndex++) { callback(devs, ref devInfo, GetDeviceId(ref devInfo), context); } { var lastError = Marshal.GetLastWin32Error(); if ((lastError != 0) && (lastError != ERROR_NO_MORE_ITEMS)) { throw new Win32Exception(lastError); } } } finally { if (devs != null && !devs.IsClosed) { devs.Close(); } } }
public static unsafe void EnumerateDeviceInterfaces <TContext> ( DeviceInfoListHandle devs, ref SP_DEVINFO_DATA devInfo, ref Guid interfaceGuid, EnumerateDeviceInterfacesFunc <TContext> callback, TContext context ) where TContext : class { try { var deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA(); deviceInterfaceData.cbSize = (uint)Marshal.SizeOf(deviceInterfaceData.GetType()); for ( UInt32 memberIndex = 0; SetupDiEnumDeviceInterfaces( devs.DangerousGetHandle(), ref devInfo, ref interfaceGuid, memberIndex, ref deviceInterfaceData ); memberIndex++ ) { uint requiredSize; // We can't use a struct for this because the CLR's interpretation of // alignment is different from Win32's on x64 :( var buffer = new byte[1024 + 4]; fixed(byte *pBuffer = buffer) { // Account for differences in alignment strategy if (Environment.Is64BitProcess) { *(UInt32 *)pBuffer = 8; } else { *(UInt32 *)pBuffer = (uint)(4 + Marshal.SystemDefaultCharSize); } SetupDiGetDeviceInterfaceDetail( devs.DangerousGetHandle(), ref deviceInterfaceData, new IntPtr(pBuffer), (UInt32)buffer.Length, out requiredSize, ref devInfo ); var lastError = Marshal.GetLastWin32Error(); if (lastError != 0) { throw new Win32Exception(lastError); } var devicePath = new String( (char *)(pBuffer + 4) ); callback( devs, ref devInfo, ref deviceInterfaceData, devicePath, context ); } } { var lastError = Marshal.GetLastWin32Error(); if ((lastError != 0) && (lastError != ERROR_NO_MORE_ITEMS)) { throw new Win32Exception(lastError); } } } finally { } }