// Opens a handle to the devTH device attached the HIDUSB.SYS driver internal unsafe override bool Open(byte dev) { // If this object already has the driver open, close it. if (_hDevice != CyConst.INVALID_HANDLE) { Close(); } int Devices = DeviceCount; if (Devices == 0) { return(false); } if (dev > (Devices - 1)) { return(false); } _path = PInvoke.GetDevicePath(_drvGuid, dev); _hDevice = PInvoke.GetDeviceHandle(_path, false, ref _Access); if (_hDevice == CyConst.INVALID_HANDLE) { return(false); } _devNum = dev; PInvoke.HidD_GetPreparsedData(_hDevice, ref PreParsedData); PInvoke.HidD_GetAttributes(_hDevice, ref Attributes); PInvoke.HidP_GetCaps(PreParsedData, ref _Capabilities); _Inputs = new CyHidReport(HIDP_REPORT_TYPE.HidP_Input, _Capabilities, PreParsedData); _Outputs = new CyHidReport(HIDP_REPORT_TYPE.HidP_Output, _Capabilities, PreParsedData); _Features = new CyHidReport(HIDP_REPORT_TYPE.HidP_Feature, _Capabilities, PreParsedData); PInvoke.HidD_FreePreparsedData(PreParsedData); PreParsedData = null; byte[] buffer = new byte[512]; fixed(byte *buf = buffer) { char *sChars = (char *)buf; if (PInvoke.HidD_GetManufacturerString(_hDevice, buffer, 512)) { _manufacturer = new string(sChars); } if (PInvoke.HidD_GetProductString(_hDevice, buffer, 512)) { _product = new string(sChars); } if (PInvoke.HidD_GetSerialNumberString(_hDevice, buffer, 512)) { _serialNumber = new string(sChars); } } // Shortcut members. _vendorID = Attributes.VendorID; _productID = Attributes.ProductID; _Version = Attributes.VersionNumber; _Usage = _Capabilities.Usage; _UsagePage = _Capabilities.UsagePage; _driverName = "usbhid.sys"; return(true); }
private unsafe bool SendScsiCmd32(byte cmd, byte op, byte lun, byte dirIn, int bank, int lba, int bytes, byte[] data) { SCSI_PASS_THROUGH_WITH_BUFFERS32 sptB = new SCSI_PASS_THROUGH_WITH_BUFFERS32(); int len = Marshal.SizeOf(sptB) + bytes; // total size of buffer byte[] buffer = new byte[len]; fixed(byte *buf = buffer) { SCSI_PASS_THROUGH_WITH_BUFFERS32 *sptBuf = (SCSI_PASS_THROUGH_WITH_BUFFERS32 *)buf; SCSI_PASS_THROUGH32 *spt = (SCSI_PASS_THROUGH32 *)buf; CDB10 *cdb = (CDB10 *)&(spt->Cdb); bool bRetVal; sptBuf->totalSize = (uint)len; spt->Length = (ushort)Marshal.SizeOf(*spt); spt->Lun = lun; spt->CdbLength = 10; spt->SenseInfoLength = 18; spt->DataIn = dirIn; spt->DataTransferLength = (uint)bytes; spt->TimeOutValue = _TimeOut; spt->SenseInfoOffset = (uint)Marshal.SizeOf(*spt) + 4; spt->DataBufferOffset = (uint)Marshal.SizeOf(sptB); cdb->Cmd = cmd; cdb->OpCode = op; cdb->LBA = (uint)lba; cdb->Bank = (byte)bank; Util.ReverseBytes((byte *)&(cdb->LBA), 4); cdb->Blocks = (ushort)(bytes / _BlockSize); Util.ReverseBytes((byte *)&(cdb->Blocks), 2); if ((dirIn == 0) && (data != null)) { Marshal.Copy(data, 0, (IntPtr)(buf + Marshal.SizeOf(sptB)), bytes); } int[] BytesXfered = new int[1]; BytesXfered[0] = 0; fixed(byte *lpInBuffer = buffer) { fixed(byte *lpOutBuffer = buffer) { fixed(int *lpBytesXferred = BytesXfered) { bRetVal = PInvoke.DeviceIoControl(_hDevice, CyConst.IOCTL_SCSI_PASS_THROUGH, (IntPtr)lpInBuffer, len, (IntPtr)lpOutBuffer, len, (IntPtr)lpBytesXferred, (IntPtr)null); } } } int error = Marshal.GetLastWin32Error(); if (dirIn == 1) { Marshal.Copy((IntPtr)(buf + Marshal.SizeOf(sptB)), data, 0, bytes); } return(bRetVal); } }
internal unsafe CyHidReport(HIDP_REPORT_TYPE rType, HIDP_CAPS hidCaps, byte *PreparsedDta) { _rptType = rType; if (rType == HIDP_REPORT_TYPE.HidP_Input) { _RptByteLen = hidCaps.InputReportByteLength; _NumBtnCaps = hidCaps.NumberInputButtonCaps; _NumValCaps = hidCaps.NumberInputValueCaps; } else if (rType == HIDP_REPORT_TYPE.HidP_Output) { _RptByteLen = hidCaps.OutputReportByteLength; _NumBtnCaps = hidCaps.NumberOutputButtonCaps; _NumValCaps = hidCaps.NumberOutputValueCaps; } else { _RptByteLen = hidCaps.FeatureReportByteLength; _NumBtnCaps = hidCaps.NumberFeatureButtonCaps; _NumValCaps = hidCaps.NumberFeatureValueCaps; } // Big enough to hold the report ID and the report data if (_RptByteLen > 0) { DataBuf = new byte[_RptByteLen + 1]; } if (_NumBtnCaps > 0) { HIDP_BTN_VAL_CAPS ButtonCaps; Buttons = new CyHidButton[_NumBtnCaps]; HIDP_BTN_VAL_CAPS bc = new HIDP_BTN_VAL_CAPS(); byte[] buffer = new byte[_NumBtnCaps * Marshal.SizeOf(bc)]; fixed(byte *buf = buffer) { int numCaps = _NumBtnCaps; // // BUGFIX 3/07/2008 - HidP_GetButtonCaps will modify numCaps to the // "actual number of elements that the routine returns". // In the somewhat rare event that numcaps is < _NumBtnCaps // on return, the reference to bCaps[i] in the loop below // will throw an "Index Was Outside the Bounds of the Array" // Exception. This would occur for example when the // top-level HID report (being reported here) contains // a subset of the available buttons in the full HID interface. // PInvoke.HidP_GetButtonCaps(rType, buf, ref numCaps, PreparsedDta); // // Reset _NumBtnCaps to the actual returned value. // _NumBtnCaps = numCaps; HIDP_BTN_VAL_CAPS *bCaps = (HIDP_BTN_VAL_CAPS *)buf; for (int i = 0; i < _NumBtnCaps; i++) { // This assignment copies values from buf into ButtonCaps. ButtonCaps = bCaps[i]; // Note that you must pass ButtonCaps to the // below constructor and not bCaps[i] Buttons[i] = new CyHidButton(ButtonCaps); // Each button should have the same ReportID _ReportID = ButtonCaps.ReportID; } } } if (_NumValCaps > 0) { Values = new CyHidValue[_NumValCaps]; HIDP_BTN_VAL_CAPS vc = new HIDP_BTN_VAL_CAPS(); byte[] buffer = new byte[_NumValCaps * Marshal.SizeOf(vc)]; fixed(byte *buf = buffer) { int numCaps = _NumValCaps; PInvoke.HidP_GetValueCaps(rType, buf, ref numCaps, PreparsedDta); HIDP_BTN_VAL_CAPS *vCaps = (HIDP_BTN_VAL_CAPS *)buf; for (int i = 0; i < _NumValCaps; i++) { // This assignment copies values from buf into ValueCaps. HIDP_BTN_VAL_CAPS ValueCaps = vCaps[i]; // Note that you must pass ValueCaps[i] to the // below constructor and not vCaps[i] Values[i] = new CyHidValue(ValueCaps); // Each value should have the same ReportID _ReportID = ValueCaps.ReportID; } } } _NumValues = 0; for (int i = 0; i < _NumValCaps; i++) { //if (Values[i].IsRange) // _NumValues += Values[i].UsageMax - Values[i].Usage + 1; //else _NumValues++; } _NumItems = _NumBtnCaps + _NumValues; if (_NumItems > 0) { Items = new HID_DATA[_NumItems]; } //if ((ButtonCaps != null) && (Items != null)) if ((_NumBtnCaps > 0) && (Items != null)) { for (int i = 0; i < _NumBtnCaps; i++) { Items[i].IsButtonData = 1; Items[i].Status = CyConst.HIDP_STATUS_SUCCESS; Items[i].UsagePage = Buttons[i].UsagePage; if (Buttons[i].IsRange) { Items[i].Usage = Buttons[i].Usage; Items[i].UsageMax = Buttons[i].UsageMax; } else { Items[i].Usage = Items[i].UsageMax = Buttons[i].Usage; } Items[i].MaxUsageLength = PInvoke.HidP_MaxUsageListLength( rType, Buttons[i].UsagePage, PreparsedDta); Items[i].Usages = new ushort[Items[i].MaxUsageLength]; Items[i].ReportID = Buttons[i].ReportID; } } for (int i = 0; i < _NumValues; i++) { if (Values[i].IsRange) { for (ushort usage = Values[i].Usage; usage <= Values[i].UsageMax; usage++) { Items[i].IsButtonData = 0; Items[i].Status = CyConst.HIDP_STATUS_SUCCESS; Items[i].UsagePage = Values[i].UsagePage; Items[i].Usage = usage; Items[i].ReportID = Values[i].ReportID; } } else { Items[i].IsButtonData = 0; Items[i].Status = CyConst.HIDP_STATUS_SUCCESS; Items[i].UsagePage = Values[i].UsagePage; Items[i].Usage = Values[i].Usage; Items[i].ReportID = Values[i].ReportID; } } } // End of CyHidReport constructor
private string GetDevicePath(byte dev) { string dPath; byte dCnt = 0; //string s = "USBSTOR"; //byte[] sClass = new byte[s.Length+1]; //Encoding.ASCII.GetBytes(s,0,s.Length,sClass,0); //dPath = PInvoke.GetDevicePath(Guid.Empty,0,sClass); // First look for the devTH USBSTOR Disk byte i = 0; do { dPath = PInvoke.GetDevicePath(CyConst.DiskGuid, i); if (dPath.IndexOf("\\usbstor#") > -1) { if (dev == dCnt) { _drvGuid = CyConst.DiskGuid; return(dPath); } else { dCnt++; } } i++; }while (dPath.Length > 0); // Next look for the devTH USBSTOR CD i = 0; do { dPath = PInvoke.GetDevicePath(CyConst.CdGuid, i); if (dPath.IndexOf("\\usbstor#") > -1) { if (dev == dCnt) { _drvGuid = CyConst.CdGuid; return(dPath); } else { dCnt++; } } i++; }while (dPath.Length > 0); return(""); }
public USBDeviceList(byte DeviceMask, App_PnP_Callback fnCallBack) { Items = new ArrayList(); hDevNotifications = new ArrayList(); USBDriverGuids = new ArrayList(); EventCallBack = new App_PnP_Callback(PnP_Event_Handler); MsgWin.AppCallback = EventCallBack; AppCallBack = fnCallBack; // Get the HID GUID PInvoke.HidD_GetHidGuid(ref HidGuid); // Create list of driver GUIDs for this instance FillDriverGuids(DeviceMask); USBDevice tmpDev, tmp; int devs = 0; foreach (Guid guid in USBDriverGuids) { // tmpDev is just used for the DeviceCount functionality if (guid.Equals(CyConst.StorGuid)) { tmpDev = new CyUSBStorDevice(guid); } else if (guid.Equals(HidGuid)) { tmpDev = new CyHidDevice(HidGuid); } else { tmpDev = new CyFX2Device(guid); } // DeviceCount is IO intensive. Don't use it as for loop limit devs = tmpDev.DeviceCount; for (int d = 0; d < devs; d++) { // Create the new USBDevice objects of the correct type, based on guid if (guid.Equals(CyConst.StorGuid)) { tmp = new CyUSBStorDevice(guid); } else if (guid.Equals(HidGuid)) { tmp = new CyHidDevice(HidGuid); } else { tmp = new CyFX2Device(guid); if (tmp.Open((byte)d)) {// open handle to check device type CyUSBDevice t = tmp as CyUSBDevice; if (!t.CheckDeviceTypeFX3FX2()) {//FX3 tmp.Close(); tmp = new CyFX3Device(guid); } else { tmp.Close(); } } } if (tmp.Open((byte)d)) { Items.Add(tmp); // This creates new reference to tmp in Items tmp.RegisterForPnPEvents(MsgWin.Handle); } } if (guid.Equals(CyConst.StorGuid)) // We're not sure which drivers were identified, so setup PnP with both { RegisterForPnpEvents(MsgWin.Handle, CyConst.DiskGuid); RegisterForPnpEvents(MsgWin.Handle, CyConst.CdGuid); } else { RegisterForPnpEvents(MsgWin.Handle, guid); } } // foreach guid }