Example #1
0
    public bool WriteUSB(byte[] buf)
    {
        for (int tries = 0; tries < 3; ++tries)
        {
            unsafe
            {
                // write the data - the file handle is in overlapped mode, so we have to do
                // this as an overlapped write with an OVERLAPPED structure and an event to
                // monitor for completion
                Overlapped        o    = new Overlapped(0, 0, evov.SafeWaitHandle.DangerousGetHandle(), null);
                NativeOverlapped *no   = o.Pack(null, null);
                IntPtr            hbuf = Marshal.AllocHGlobal(buf.Length);
                try
                {
                    Marshal.Copy(buf, 0, hbuf, buf.Length);
                    HIDImports.WriteFile(fp, hbuf, buf.Length, IntPtr.Zero, no);

                    // wait briefly for the write to complete
                    if (evov.WaitOne(250))
                    {
                        // successful completion - get the result
                        UInt32 actual;
                        int    result = HIDImports.GetOverlappedResult(fp, no, out actual, 0);

                        Overlapped.Unpack(no);
                        Overlapped.Free(no);

                        if (result == 0)
                        {
                            // the write failed - try re-opening the handle and go back
                            // for another try
                            TryReopenHandle();
                            continue;
                        }
                        else if (actual != buf.Length)
                        {
                            // length is wrong - the write failed
                            return(false);
                        }
                        else
                        {
                            // success
                            return(true);
                        }
                    }
                    else
                    {
                        // The write timed out.  Cancel the write and try reopening the handle.
                        HIDImports.CancelIo(fp);
                        Overlapped.Unpack(no);
                        Overlapped.Free(no);
                        if (TryReopenHandle())
                        {
                            continue;
                        }
                        return(false);
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(hbuf);
                }
            }
        }

        // maximum retries exceeded - return failure
        return(false);
    }