/// <summary> /// Creates an event object for the overlapped structure used with /// ReadFile. Called before the first call to ReadFile. /// </summary> /// /// <param name="hidOverlapped"> the overlapped structure </param> /// <param name="eventObject"> the event object </param> public void PrepareForOverlappedTransfer(ref FileIO.OVERLAPPED hidOverlapped, ref SafeWaitHandle eventObject) { try { // *** // API function: CreateEvent // Purpose: Creates an event object for the overlapped structure used with ReadFile. // Accepts: // A security attributes structure. // Manual Reset = False (The system automatically resets the state to nonsignaled // after a waiting thread has been released.) // Initial state = True (signaled) // An event object name (optional) // Returns: a handle to the event object // *** eventObject = FileIO.CreateEvent(null, System.Convert.ToInt32(false), System.Convert.ToInt32(true), ""); // Debug.WriteLine(MyDebugging.ResultOfAPICall("CreateEvent")) // Set the members of the overlapped structure. hidOverlapped.Offset = 0; hidOverlapped.OffsetHigh = 0; hidOverlapped.hEvent = eventObject; readyForOverlappedTransfer = true; } catch (Exception ex) { DisplayException(MODULE_NAME, ex); } }
/// <summary> /// reads an Input report from the device using interrupt transfers. /// </summary> /// /// <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param> /// <param name="readHandle"> the handle for reading Input reports from the device. </param> /// <param name="writeHandle"> the handle for writing Output reports to the device. </param> /// <param name="myDeviceDetected"> tells whether the device is currently attached. </param> /// <param name="inputReportBuffer"> contains the requested report. </param> /// <param name="success"> read success </param> public override void Read(SafeFileHandle hidHandle, SafeFileHandle readHandle, SafeFileHandle writeHandle, ref Boolean myDeviceDetected, ref Byte[] inputReportBuffer, ref Boolean success) { SafeWaitHandle eventObject = null; FileIO.OVERLAPPED HidOverlapped = new FileIO.OVERLAPPED(); Int32 numberOfBytesRead = 0; Int32 result = 0; try { // If it's the first attempt to read, set up the overlapped structure for ReadFile. if (readyForOverlappedTransfer == false) { PrepareForOverlappedTransfer(ref HidOverlapped, ref eventObject); } // *** // API function: ReadFile // Purpose: Attempts to read an Input report from the device. // Accepts: // A device handle returned by CreateFile // (for overlapped I/O, CreateFile must have been called with FILE_FLAG_OVERLAPPED), // A pointer to a buffer for storing the report. // The Input report length in bytes returned by HidP_GetCaps, // A pointer to a variable that will hold the number of bytes read. // An overlapped structure whose hEvent member is set to an event object. // Returns: the report in ReadBuffer. // The overlapped call returns immediately, even if the data hasn't been received yet. // To read multiple reports with one ReadFile, increase the size of ReadBuffer // and use NumberOfBytesRead to determine how many reports were returned. // Use a larger buffer if the application can't keep up with reading each report // individually. // *** result = FileIO.ReadFile(readHandle, inputReportBuffer, inputReportBuffer.Length, ref numberOfBytesRead, HidOverlapped); Debug.WriteLine("waiting for ReadFile"); // API function: WaitForSingleObject // Purpose: waits for at least one report or a timeout. // Used with overlapped ReadFile. // Accepts: // An event object created with CreateEvent // A timeout value in milliseconds. // Returns: A result code. result = FileIO.WaitForSingleObject(eventObject, 3000); // Find out if ReadFile completed or timeout. switch (result) { case (System.Int32)FileIO.WAIT_OBJECT_0: // ReadFile has completed success = true; Debug.WriteLine("ReadFile completed successfully."); break; case FileIO.WAIT_TIMEOUT: // Cancel the operation on timeout CancelTransfer(hidHandle, readHandle, writeHandle); Debug.WriteLine("Readfile timeout"); success = false; myDeviceDetected = false; break; default: // Cancel the operation on other error. CancelTransfer(hidHandle, readHandle, writeHandle); Debug.WriteLine("Readfile undefined error"); success = false; myDeviceDetected = false; break; } if (result == 0) { success = true; } else { success = false; } } catch (Exception ex) { DisplayException(MODULE_NAME, ex); } }
/// <summary> /// reads an Input report from the device using interrupt transfers. /// </summary> /// /// <param name="hidHandle"> the handle for learning about the device and exchanging Feature reports. </param> /// <param name="readHandle"> the handle for reading Input reports from the device. </param> /// <param name="writeHandle"> the handle for writing Output reports to the device. </param> /// <param name="myDeviceDetected"> tells whether the device is currently attached. </param> /// <param name="inputReportBuffer"> contains the requested report. </param> /// <param name="success"> read success </param> public override void Read(SafeFileHandle hidHandle, SafeFileHandle readHandle, SafeFileHandle writeHandle, ref Boolean myDeviceDetected, ref Byte[] inputReportBuffer, ref Boolean success) { SafeWaitHandle eventObject = null; FileIO.OVERLAPPED HidOverlapped = new FileIO.OVERLAPPED(); Int32 numberOfBytesRead = 0; Int32 result = 0; try { // If it's the first attempt to read, set up the overlapped structure for ReadFile. if ( readyForOverlappedTransfer == false ) { PrepareForOverlappedTransfer( ref HidOverlapped, ref eventObject ); } // *** // API function: ReadFile // Purpose: Attempts to read an Input report from the device. // Accepts: // A device handle returned by CreateFile // (for overlapped I/O, CreateFile must have been called with FILE_FLAG_OVERLAPPED), // A pointer to a buffer for storing the report. // The Input report length in bytes returned by HidP_GetCaps, // A pointer to a variable that will hold the number of bytes read. // An overlapped structure whose hEvent member is set to an event object. // Returns: the report in ReadBuffer. // The overlapped call returns immediately, even if the data hasn't been received yet. // To read multiple reports with one ReadFile, increase the size of ReadBuffer // and use NumberOfBytesRead to determine how many reports were returned. // Use a larger buffer if the application can't keep up with reading each report // individually. // *** result = FileIO.ReadFile(readHandle, inputReportBuffer, inputReportBuffer.Length, ref numberOfBytesRead, HidOverlapped); Debug.WriteLine( "waiting for ReadFile" ); // API function: WaitForSingleObject // Purpose: waits for at least one report or a timeout. // Used with overlapped ReadFile. // Accepts: // An event object created with CreateEvent // A timeout value in milliseconds. // Returns: A result code. result = FileIO.WaitForSingleObject(eventObject, 3000); // Find out if ReadFile completed or timeout. switch ( result ) { case (System.Int32)FileIO.WAIT_OBJECT_0: // ReadFile has completed success = true; Debug.WriteLine( "ReadFile completed successfully." ); break; case FileIO.WAIT_TIMEOUT: // Cancel the operation on timeout CancelTransfer( hidHandle, readHandle, writeHandle ); Debug.WriteLine( "Readfile timeout" ); success = false; myDeviceDetected = false; break; default: // Cancel the operation on other error. CancelTransfer( hidHandle, readHandle, writeHandle ); Debug.WriteLine( "Readfile undefined error" ); success = false; myDeviceDetected = false; break; } if ( result == 0 ) { success = true; } else { success = false; } } catch ( Exception ex ) { DisplayException( MODULE_NAME, ex ); throw ; } }