comparison USBLib/Windows/Devices/DeviceNode.cs @ 50:556b4fb511bd

Added HWLib and USBLib functions to support USB Driver Installer
author Ivo Smits <Ivo@UCIS.nl>
date Mon, 30 Sep 2013 19:23:09 +0200
parents dcfec2be27c9
children d4778c3232ad
comparison
equal deleted inserted replaced
47:15ddb1e0e2a5 50:556b4fb511bd
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
3 using System.ComponentModel; 3 using System.ComponentModel;
4 using System.Reflection;
4 using System.Runtime.InteropServices; 5 using System.Runtime.InteropServices;
5 using System.Text; 6 using System.Text;
6 using Microsoft.Win32; 7 using Microsoft.Win32;
8 using Microsoft.Win32.SafeHandles;
7 using UCIS.USBLib.Internal.Windows; 9 using UCIS.USBLib.Internal.Windows;
8 10
9 namespace UCIS.HWLib.Windows.Devices { 11 namespace UCIS.HWLib.Windows.Devices {
10 public class CMException : Exception { 12 public class CMException : Exception {
11 internal CMException(CR result, String method) 13 internal CMException(CR result, String method)
50 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(ref classGuid, null, IntPtr.Zero, DICFG.PRESENT | DICFG.DEVICEINTERFACE)) { 52 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(ref classGuid, null, IntPtr.Zero, DICFG.PRESENT | DICFG.DEVICEINTERFACE)) {
51 return GetDevicesInSet(dis); 53 return GetDevicesInSet(dis);
52 } 54 }
53 } 55 }
54 public static IList<DeviceNode> GetDevices(String enumerator) { 56 public static IList<DeviceNode> GetDevices(String enumerator) {
55 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, DICFG.PRESENT | DICFG.ALLCLASSES)) { 57 return GetDevices(enumerator, true);
58 }
59 public static IList<DeviceNode> GetDevices(String enumerator, Boolean present) {
60 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, (present ? DICFG.PRESENT : 0) | DICFG.ALLCLASSES)) {
56 //using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, DICFG.ALLCLASSES | DICFG.DEVICEINTERFACE)) { 61 //using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, enumerator, IntPtr.Zero, DICFG.ALLCLASSES | DICFG.DEVICEINTERFACE)) {
57 return GetDevicesInSet(dis); 62 return GetDevicesInSet(dis);
58 } 63 }
59 } 64 }
60 65
124 Byte[] buffer = GetProperty(property); 129 Byte[] buffer = GetProperty(property);
125 if (buffer == null) return null; 130 if (buffer == null) return null;
126 return SetupApi.GetAsStringArray(buffer, buffer.Length); 131 return SetupApi.GetAsStringArray(buffer, buffer.Length);
127 } 132 }
128 133
134 public void SetProperty(SPDRP property, Byte[] value) {
135 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) {
136 if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
137 SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true);
138 if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd))
139 throw new Win32Exception(Marshal.GetLastWin32Error());
140 if (!SetupApi.SetupDiSetDeviceRegistryProperty(dis, ref dd, property, value, (uint)value.Length))
141 throw new Win32Exception(Marshal.GetLastWin32Error());
142 }
143 }
144
129 public Byte[] GetCustomProperty(String name) { 145 public Byte[] GetCustomProperty(String name) {
130 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) { 146 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) {
131 if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error()); 147 if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
132 SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true); 148 SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true);
133 if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd)) 149 if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd))
154 } 170 }
155 public String[] GetCustomPropertyStringArray(String name) { 171 public String[] GetCustomPropertyStringArray(String name) {
156 Byte[] buffer = GetCustomProperty(name); 172 Byte[] buffer = GetCustomProperty(name);
157 if (buffer == null) return null; 173 if (buffer == null) return null;
158 return SetupApi.GetAsStringArray(buffer, buffer.Length); 174 return SetupApi.GetAsStringArray(buffer, buffer.Length);
175 }
176
177 public RegistryKey OpenRegistryKey(UInt32 scope, UInt32 hwProfile, UInt32 keyType, UInt32 samDesired) {
178 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) {
179 if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
180 SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true);
181 if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd))
182 return null;
183 IntPtr handle = SetupApi.SetupDiOpenDevRegKey(dis, ref dd, scope, hwProfile, keyType, samDesired);
184 if (handle == (IntPtr)(-1)) return null;
185 return RegistryKeyFromHandle(handle, true, (samDesired & (0x00000002 | 0x00000004 | 0x00000020)) != 0);
186 }
187 }
188
189 private RegistryKey RegistryKeyFromHandle(IntPtr hKey, bool writable, bool ownsHandle) {
190 BindingFlags privateConstructors = BindingFlags.Instance | BindingFlags.NonPublic;
191 Type safeRegistryHandleType = typeof(SafeHandleZeroOrMinusOneIsInvalid).Assembly.GetType("Microsoft.Win32.SafeHandles.SafeRegistryHandle");
192 Type[] safeRegistryHandleCtorTypes = new Type[] { typeof(IntPtr), typeof(bool) };
193 ConstructorInfo safeRegistryHandleCtorInfo = safeRegistryHandleType.GetConstructor(privateConstructors, null, safeRegistryHandleCtorTypes, null);
194 Object safeHandle = safeRegistryHandleCtorInfo.Invoke(new Object[] { hKey, ownsHandle });
195 Type registryKeyType = typeof(RegistryKey);
196 Type[] registryKeyConstructorTypes = new Type[] { safeRegistryHandleType, typeof(bool) };
197 ConstructorInfo registryKeyCtorInfo = registryKeyType.GetConstructor(privateConstructors, null, registryKeyConstructorTypes, null);
198 RegistryKey resultKey = (RegistryKey)registryKeyCtorInfo.Invoke(new Object[] { safeHandle, writable });
199 return resultKey;
200 }
201
202 public Byte[] GetDeviceProperty(Guid fmtid, UInt32 pid) {
203 using (SafeDeviceInfoSetHandle dis = SetupApi.SetupDiGetClassDevsA(IntPtr.Zero, DeviceID, IntPtr.Zero, DICFG.DEVICEINTERFACE | DICFG.ALLCLASSES)) {
204 if (dis.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
205 SP_DEVINFO_DATA dd = new SP_DEVINFO_DATA(true);
206 if (!SetupApi.SetupDiEnumDeviceInfo(dis, 0, ref dd))
207 return null;
208 byte[] propBuffer = new byte[256];
209 UInt32 requiredSize;
210 UInt32 propertyType;
211 DEVPROPKEY propertyKey = new DEVPROPKEY() { fmtid = fmtid, pid = pid };
212 if (!SetupApi.SetupDiGetDeviceProperty(dis, ref dd, ref propertyKey, out propertyType, propBuffer, (uint)propBuffer.Length, out requiredSize, 0))
213 return null;
214 if (requiredSize > propBuffer.Length) {
215 propBuffer = new Byte[requiredSize];
216 if (!SetupApi.SetupDiGetDeviceProperty(dis, ref dd, ref propertyKey, out propertyType, propBuffer, (uint)propBuffer.Length, out requiredSize, 0))
217 throw new Win32Exception(Marshal.GetLastWin32Error());
218 }
219 if (requiredSize < propBuffer.Length) Array.Resize(ref propBuffer, (int)requiredSize);
220 return propBuffer;
221 }
222 }
223 public String GetDevicePropertyString(Guid fmtid, UInt32 pid) {
224 Byte[] buffer = GetDeviceProperty(fmtid, pid);
225 if (buffer == null) return null;
226 return SetupApi.GetAsString(buffer, buffer.Length);
227 }
228
229 public void Reenumerate(UInt32 flags) {
230 CR ret = SetupApi.CM_Reenumerate_DevNode(DevInst, flags);
231 CMException.Throw(ret, "CM_Reenumerate_DevNode");
159 } 232 }
160 233
161 public String DeviceDescription { get { return GetPropertyString(CMRDP.DEVICEDESC); } } 234 public String DeviceDescription { get { return GetPropertyString(CMRDP.DEVICEDESC); } }
162 public String[] HardwareID { get { return GetPropertyStringArray(CMRDP.HARDWAREID); } } 235 public String[] HardwareID { get { return GetPropertyStringArray(CMRDP.HARDWAREID); } }
163 public String[] CompatibleIDs { get { return GetPropertyStringArray(CMRDP.COMPATIBLEIDS); } } 236 public String[] CompatibleIDs { get { return GetPropertyStringArray(CMRDP.COMPATIBLEIDS); } }