protected HidDeviceData ReadData(int timeout)
{
var buffer = new byte[] { };
var status = HidDeviceData.ReadStatus.NoDataRead;
IntPtr nonManagedBuffer;
if (_deviceCapabilities.InputReportByteLength > 0)
{
uint bytesRead = 0;
buffer = CreateInputBuffer();
nonManagedBuffer = Marshal.AllocHGlobal(buffer.Length);
if (_deviceReadMode == DeviceMode.Overlapped)
{
var security = new NativeMethods.SECURITY_ATTRIBUTES();
var overlapped = new NativeOverlapped();
var overlapTimeout = timeout <= 0 ? NativeMethods.WAIT_INFINITE : timeout;
security.lpSecurityDescriptor = IntPtr.Zero;
security.bInheritHandle = true;
security.nLength = Marshal.SizeOf(security);
overlapped.OffsetLow = 0;
overlapped.OffsetHigh = 0;
overlapped.EventHandle = NativeMethods.CreateEvent(ref security, Convert.ToInt32(false), Convert.ToInt32(true), string.Empty);
try
{
var success = NativeMethods.ReadFile(Handle, nonManagedBuffer, (uint)buffer.Length, out bytesRead, ref overlapped);
if (success)
{
status = HidDeviceData.ReadStatus.Success; // No check here to see if bytesRead > 0 . Perhaps not necessary?
}
else
{
var result = NativeMethods.WaitForSingleObject(overlapped.EventHandle, overlapTimeout);
switch (result)
{
case NativeMethods.WAIT_OBJECT_0:
status = HidDeviceData.ReadStatus.Success;
NativeMethods.GetOverlappedResult(Handle, ref overlapped, out bytesRead, false);
break;
case NativeMethods.WAIT_TIMEOUT:
status = HidDeviceData.ReadStatus.WaitTimedOut;
NativeMethods.CancelIo(Handle);
buffer = new byte[] { };
break;
case NativeMethods.WAIT_FAILED:
status = HidDeviceData.ReadStatus.WaitFail;
buffer = new byte[] { };
break;
default:
status = HidDeviceData.ReadStatus.NoDataRead;
buffer = new byte[] { };
break;
}
}
Marshal.Copy(nonManagedBuffer, buffer, 0, (int)bytesRead);
}
catch { status = HidDeviceData.ReadStatus.ReadError; }
finally {
CloseDeviceIO(overlapped.EventHandle);
Marshal.FreeHGlobal(nonManagedBuffer);
}
}
else
{
try
{
var overlapped = new NativeOverlapped();
NativeMethods.ReadFile(Handle, nonManagedBuffer, (uint)buffer.Length, out bytesRead, ref overlapped);
status = HidDeviceData.ReadStatus.Success;
Marshal.Copy(nonManagedBuffer, buffer, 0, (int)bytesRead);
}
catch { status = HidDeviceData.ReadStatus.ReadError; }
finally { Marshal.FreeHGlobal(nonManagedBuffer); }
}
}
return(new HidDeviceData(buffer, status));
}