예제 #1
0
            /// <summary>
            /// Creates an event object for the overlapped structure used with ReadFile.
            /// Called before the first call to ReadFile.
            /// </summary>
            /// <param name="hidOverlapped"></param>
            /// <param name="eventObject"></param>
            internal void PrepareForOverlappedTransfer(ref FileIOApiDeclarations.OVERLAPPED hidOverlapped, ref int eventObject)
            {
                FileIOApiDeclarations.SECURITY_ATTRIBUTES Security = new FileIOApiDeclarations.SECURITY_ATTRIBUTES();

                try
                {
                    // Values for the SECURITY_ATTRIBUTES structure:
                    Security.lpSecurityDescriptor = 0;
                    Security.bInheritHandle       = Convert.ToInt32(true);
                    Security.nLength = Marshal.SizeOf(Security);

                    // ***
                    // 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 =
                        FileIOApiDeclarations.CreateEvent(ref Security, Convert.ToInt32(false), Convert.ToInt32(true), "");
                    if (Settings.Instance.ExtensiveLogging)
                    {
                        Log.Debug(Debugging.ResultOfAPICall("CreateEvent"));
                        Log.Debug("");
                    }
                    // Set the members of the overlapped structure.
                    hidOverlapped.Offset       = 0;
                    hidOverlapped.OffsetHigh   = 0;
                    hidOverlapped.hEvent       = eventObject;
                    ReadyForOverlappedTransfer = true;
                }
                catch (Exception ex)
                {
                    HandleException(ModuleName + ":" + MethodBase.GetCurrentMethod(), ex);
                }
            }
예제 #2
0
            /// <summary>
            /// reads an Input report from the device using interrupt transfers.
            /// </summary>
            /// <param name="readHandle">the handle for reading from the device.</param>
            /// <param name="hidHandle">the handle for other device communications.</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>
            protected override void ProtectedRead(int readHandle, int hidHandle, ref bool myDeviceDetected,
                                                  ref byte[] inputReportBuffer, ref bool success)
            {
                int EventObject = 0;

                FileIOApiDeclarations.OVERLAPPED HIDOverlapped = new FileIOApiDeclarations.OVERLAPPED();
                int NumberOfBytesRead = 0;

                try
                {
                    // If it's the first attempt to read, set up the overlapped structure for ReadFile.
                    if (!ReadyForOverlappedTransfer)
                    {
                        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.
                    // ***
                    if (Settings.Instance.ExtensiveLogging)
                    {
                        Log.Debug("input report length = " + inputReportBuffer.Length);
                    }

                    FileIOApiDeclarations.ReadFile(readHandle, ref inputReportBuffer[0], inputReportBuffer.Length,
                                                   ref NumberOfBytesRead, ref HIDOverlapped);
                    if (Settings.Instance.ExtensiveLogging)
                    {
                        Log.Debug(Debugging.ResultOfAPICall("ReadFile"));
                        Log.Debug("");
                        Log.Debug("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 = FileIOApiDeclarations.WaitForSingleObject(EventObject, 3000);
                    if (Settings.Instance.ExtensiveLogging)
                    {
                        Log.Debug(Debugging.ResultOfAPICall("WaitForSingleObject"));
                        Log.Debug("");
                    }

                    // Find out if ReadFile completed or timeout.
                    switch (Result)
                    {
                    case FileIOApiDeclarations.WAIT_OBJECT_0:
                        // ReadFile has completed
                        success = true;
                        if (Settings.Instance.ExtensiveLogging)
                        {
                            Log.Debug("ReadFile completed successfully.");
                        }
                        break;

                    case FileIOApiDeclarations.WAIT_TIMEOUT:
                        // Cancel the operation on timeout
                        CancelTransfer(readHandle, hidHandle);
                        if (Settings.Instance.ExtensiveLogging)
                        {
                            Log.Debug("Readfile timeout");
                        }
                        success          = false;
                        myDeviceDetected = false;
                        break;

                    default:
                        // Cancel the operation on other error.
                        CancelTransfer(readHandle, hidHandle);
                        if (Settings.Instance.ExtensiveLogging)
                        {
                            Log.Debug("Readfile undefined error");
                        }
                        success          = false;
                        myDeviceDetected = false;
                        break;
                    }

                    success = (Result == 0) ? true : false;
                }
                catch (Exception ex)
                {
                    HandleException(ModuleName + ":" + MethodBase.GetCurrentMethod(), ex);
                }
            }