Mercurial > hg > ucis.core
comparison USBLib/Communication/VBoxUSB.cs @ 60:3424fa5a12c9
Updated Windows USB enumeration classes and VBoxUSB backend
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Sat, 12 Oct 2013 16:35:24 +0200 |
parents | b1efeada517e |
children | 99ed461509fe |
comparison
equal
deleted
inserted
replaced
59:4e1a5dec786a | 60:3424fa5a12c9 |
---|---|
236 public UIntPtr len; | 236 public UIntPtr len; |
237 public void* buf; | 237 public void* buf; |
238 public UInt32 numIsoPkts; | 238 public UInt32 numIsoPkts; |
239 public fixed byte aIsoPkts[8 * 8]; | 239 public fixed byte aIsoPkts[8 * 8]; |
240 } | 240 } |
241 class USBRegistry : WindowsUsbDeviceRegistry, IUsbDeviceRegistry { | 241 class USBRegistry : IUsbDeviceRegistry { |
242 public DeviceNode DeviceNode { get; private set; } | |
243 public String DevicePath { get; private set; } | |
244 public String DeviceID { get; private set; } | |
245 public String SymbolicName { get { return DevicePath; } } | |
246 private UCIS.HWLib.Windows.USB.UsbDevice usbdev = null; | |
247 private Boolean hasDeviceDescriptor = false; | |
248 private UCIS.USBLib.Descriptor.UsbDeviceDescriptor deviceDescriptor; | |
249 private IDictionary<string, object> mDeviceProperties; | |
250 public UCIS.HWLib.Windows.USB.UsbDevice USBDevice { | |
251 get { | |
252 if (usbdev == null) usbdev = UCIS.HWLib.Windows.USB.UsbDevice.GetUsbDevice(DeviceNode); | |
253 return usbdev; | |
254 } | |
255 } | |
256 public UCIS.USBLib.Descriptor.UsbDeviceDescriptor DeviceDescriptor { | |
257 get { | |
258 if (!hasDeviceDescriptor) deviceDescriptor = UCIS.USBLib.Descriptor.UsbDeviceDescriptor.FromDevice(USBDevice); | |
259 return deviceDescriptor; | |
260 } | |
261 } | |
262 public IDictionary<string, object> DeviceProperties { | |
263 get { | |
264 if (mDeviceProperties == null) mDeviceProperties = SetupApi.GetSPDRPProperties(DeviceNode); | |
265 return mDeviceProperties; | |
266 } | |
267 } | |
268 | |
269 internal USBRegistry(DeviceNode device, String interfacepath) { | |
270 DeviceNode = device; | |
271 DeviceID = device.DeviceID; | |
272 DevicePath = interfacepath; | |
273 } | |
274 | |
275 public int Vid { get { return DeviceDescriptor.VendorID; } } | |
276 public int Pid { get { return DeviceDescriptor.ProductID; } } | |
277 public byte InterfaceID { get { return 0; } } | |
278 | |
279 public string Name { get { return DeviceNode.GetPropertyString(CMRDP.DEVICEDESC); } } | |
280 public string Manufacturer { get { return DeviceNode.GetPropertyString(CMRDP.MFG); } } | |
281 public string FullName { | |
282 get { | |
283 String desc = Name; | |
284 String mfg = Manufacturer; | |
285 if (mfg == null) return desc; | |
286 if (desc == null) return mfg; | |
287 return mfg + " - " + desc; | |
288 } | |
289 } | |
290 | |
242 public IUsbDevice Open() { return new VBoxUSB(this); } | 291 public IUsbDevice Open() { return new VBoxUSB(this); } |
243 public USBRegistry(DeviceNode devnode, String intf) : base(devnode, intf) { } | |
244 } | 292 } |
245 | 293 |
246 public class VBoxUSB : UsbInterface, IUsbDevice { | 294 public class VBoxUSB : UsbInterface, IUsbDevice { |
247 const int FILE_DEVICE_UNKNOWN = 0x00000022; | 295 const int FILE_DEVICE_UNKNOWN = 0x00000022; |
248 const int METHOD_BUFFERED = 0; | 296 const int METHOD_BUFFERED = 0; |
267 const UInt32 USBMON_MINOR_VERSION = 0; | 315 const UInt32 USBMON_MINOR_VERSION = 0; |
268 | 316 |
269 static SafeFileHandle hMonitor = null; | 317 static SafeFileHandle hMonitor = null; |
270 const String USBMON_DEVICE_NAME = "\\\\.\\VBoxUSBMon"; | 318 const String USBMON_DEVICE_NAME = "\\\\.\\VBoxUSBMon"; |
271 | 319 |
320 static unsafe int SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize, Boolean throwError) { | |
321 Int32 pBytesReturned = 0; | |
322 if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null)) return 0; | |
323 int ret = Marshal.GetLastWin32Error(); | |
324 if (throwError) throw new Win32Exception(ret); | |
325 return ret; | |
326 } | |
272 static unsafe void SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize) { | 327 static unsafe void SyncIoControl(SafeHandle hDevice, int IoControlCode, void* InBuffer, int nInBufferSize, void* OutBuffer, int nOutBufferSize) { |
273 Int32 pBytesReturned = 0; | 328 SyncIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, true); |
274 if (!Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null)) | |
275 throw new Win32Exception(Marshal.GetLastWin32Error()); | |
276 } | 329 } |
277 | 330 |
278 unsafe static void InitMonitor() { | 331 unsafe static void InitMonitor() { |
279 if (hMonitor != null && !hMonitor.IsClosed && !hMonitor.IsInvalid) return; | 332 if (hMonitor != null && !hMonitor.IsClosed && !hMonitor.IsInvalid) return; |
280 hMonitor = Kernel32.CreateFile(USBMON_DEVICE_NAME, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, Kernel32.FILE_ATTRIBUTE_SYSTEM, IntPtr.Zero); | 333 hMonitor = Kernel32.CreateFile(USBMON_DEVICE_NAME, Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE, Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE, IntPtr.Zero, Kernel32.OPEN_EXISTING, Kernel32.FILE_ATTRIBUTE_SYSTEM, IntPtr.Zero); |
324 InitMonitor(); | 377 InitMonitor(); |
325 USBFILTER Filter = new USBFILTER(USBFILTERTYPE.USBFILTERTYPE_ONESHOT_CAPTURE); | 378 USBFILTER Filter = new USBFILTER(USBFILTERTYPE.USBFILTERTYPE_ONESHOT_CAPTURE); |
326 initFilterFromDevice(ref Filter, aDevice); | 379 initFilterFromDevice(ref Filter, aDevice); |
327 IntPtr pvId = USBLibAddFilter(ref Filter); | 380 IntPtr pvId = USBLibAddFilter(ref Filter); |
328 if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); | 381 if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); |
329 //USBLibRunFilters(); | 382 USBLibRunFilters(); |
330 aDevice.Reenumerate(0); | 383 //aDevice.Reenumerate(0); |
331 } | 384 } |
332 public unsafe static void Release(DeviceNode aDevice) { | 385 public unsafe static void Release(DeviceNode aDevice) { |
333 InitMonitor(); | 386 InitMonitor(); |
334 USBFILTER Filter = new USBFILTER(USBFILTERTYPE.USBFILTERTYPE_ONESHOT_IGNORE); | 387 USBFILTER Filter = new USBFILTER(USBFILTERTYPE.USBFILTERTYPE_ONESHOT_IGNORE); |
335 initFilterFromDevice(ref Filter, aDevice); | 388 initFilterFromDevice(ref Filter, aDevice); |
336 IntPtr pvId = USBLibAddFilter(ref Filter); | 389 IntPtr pvId = USBLibAddFilter(ref Filter); |
337 if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); | 390 if (pvId == IntPtr.Zero) throw new Exception("Add one-shot Filter failed"); |
338 //USBLibRunFilters(); | 391 USBLibRunFilters(); |
339 aDevice.Reenumerate(0); | 392 //aDevice.Reenumerate(0); |
340 } | 393 } |
341 public static IUsbDeviceRegistry GetDeviceForDeviceNode(DeviceNode device) { | 394 public static IUsbDeviceRegistry GetDeviceForDeviceNode(DeviceNode device) { |
342 String[] intfpath = device.GetInterfaces(new Guid(0x873fdf, 0xCAFE, 0x80EE, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0xb)); | 395 String[] intfpath = device.GetInterfaces(new Guid(0x873fdf, 0xCAFE, 0x80EE, 0xaa, 0x5e, 0x0, 0xc0, 0x4f, 0xb1, 0x72, 0xb)); |
343 if (intfpath == null || intfpath.Length == 0) return null; | 396 if (intfpath == null || intfpath.Length == 0) return null; |
344 return new USBRegistry(device, intfpath[0]); | 397 return new USBRegistry(device, intfpath[0]); |
366 } | 419 } |
367 } | 420 } |
368 public unsafe override void Close() { | 421 public unsafe override void Close() { |
369 if (!hDev.IsInvalid && !hDev.IsClosed) { | 422 if (!hDev.IsInvalid && !hDev.IsClosed) { |
370 USBSUP_CLAIMDEV release = new USBSUP_CLAIMDEV() { bInterfaceNumber = bInterfaceNumber }; | 423 USBSUP_CLAIMDEV release = new USBSUP_CLAIMDEV() { bInterfaceNumber = bInterfaceNumber }; |
371 SyncIoControl(hDev, SUPUSB_IOCTL_USB_RELEASE_DEVICE, &release, sizeof(USBSUP_CLAIMDEV), null, 0); | 424 SyncIoControl(hDev, SUPUSB_IOCTL_USB_RELEASE_DEVICE, &release, sizeof(USBSUP_CLAIMDEV), null, 0, false); |
372 } | 425 } |
373 hDev.Close(); | 426 hDev.Close(); |
374 } | 427 } |
375 | 428 |
376 public unsafe override void BulkReset(byte endpoint) { | 429 public unsafe override void BulkReset(byte endpoint) { |
407 throw new Win32Exception(Marshal.GetLastWin32Error()); | 460 throw new Win32Exception(Marshal.GetLastWin32Error()); |
408 } | 461 } |
409 } | 462 } |
410 | 463 |
411 private unsafe int BlockTransfer(USBSUP_TRANSFER_TYPE type, USBSUP_DIRECTION dir, USBSUP_XFER_FLAG flags, UInt32 ep, Byte[] buffer, int offset, int length) { | 464 private unsafe int BlockTransfer(USBSUP_TRANSFER_TYPE type, USBSUP_DIRECTION dir, USBSUP_XFER_FLAG flags, UInt32 ep, Byte[] buffer, int offset, int length) { |
465 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); | |
412 fixed (Byte* ptr = buffer) { | 466 fixed (Byte* ptr = buffer) { |
413 USBSUP_URB urb = new USBSUP_URB(); | 467 USBSUP_URB urb = new USBSUP_URB(); |
414 urb.type = type; | 468 urb.type = type; |
415 urb.dir = dir; | 469 urb.dir = dir; |
416 urb.flags = flags; | 470 urb.flags = flags; |
417 urb.ep = ep; | 471 urb.ep = ep; |
418 urb.len = (UIntPtr)length; | 472 urb.len = (UIntPtr)length; |
419 urb.buf = ptr; | 473 urb.buf = ptr + offset; |
420 HandleURB(&urb); | 474 HandleURB(&urb); |
421 return (int)urb.len; | 475 return (int)urb.len; |
422 } | 476 } |
423 } | 477 } |
424 | 478 |