private bool WriteData(byte[] data, int timeout)
{
if (_deviceCapabilities.OutputReportByteLength <= 0)
{
return(false);
}
uint bytesWritten = 0;
// Optimization: Don't create a new buffer & copy if given data array is of sufficient size.
byte[] buffer;
if (data.Length == _deviceCapabilities.OutputReportByteLength)
{
buffer = data;
}
else
{
buffer = CreateOutputBuffer();
Array.Copy(data, 0, buffer, 0, Math.Min(data.Length, _deviceCapabilities.OutputReportByteLength));
}
// TODO: Do that thing that tells the CLR not to move the 'byte[] data' object around in memory.
// As there may be a race condition if the location moves during the Write() Win32 call.
if (_deviceWriteMode == 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), "");
try
{
NativeMethods.WriteFile(Handle, buffer, (uint)buffer.Length, out bytesWritten, ref overlapped);
}
catch { return(false); }
var result = NativeMethods.WaitForSingleObject(overlapped.EventHandle, overlapTimeout);
switch (result)
{
case NativeMethods.WAIT_OBJECT_0:
NativeMethods.CloseHandle(overlapped.EventHandle);
return(true);
case NativeMethods.WAIT_TIMEOUT:
return(false);
case NativeMethods.WAIT_FAILED:
return(false);
default:
return(false);
}
}
else
{
try
{
var overlapped = new NativeOverlapped();
return(NativeMethods.WriteFile(Handle, buffer, (uint)buffer.Length, out bytesWritten, ref overlapped));
}
catch { return(false); }
}
}