Im facing a problem with file stream read/write for a usb device. The code works fine on XP (32 bit). but fails to work on Windows 7 (64 bit).
<br/>
Im successfully past problem of getting the device to enumarate and getting the file handle
<br/>
However the fileStream Read/Write doesnt work
I used the managed file stream method i.e first create a handle via native call in overlapped mode. Then use the handle to get a FileStream object and perform read/write using it. On XP 32 bit it works great but on Windows 7 the FileStream.Write throws a
null reference exception.
Then on Windows 7 the approach I took was read/write using native calls (I abandoned the managed FileStream class approach). For this I used WriteFile, ReadFile, GetOverlappedResult APIs with OVERLAPPED structure etc. I have also pinned the data buffers.
But ReadFile (or WriteFile) returns 997 i.e ERROR_IO_PENDING and subsequent call to GetOverlappedResult returns 1 ie. ERROR_INVALID_FUNCTION. Then NumberOfBytesRead is always 0.
Im not sure what am I doing wrong!!!.
Following is a code snippet containing the Read API from my code.
Thanks In advance for all the help.
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; byte[] Read()
{
OVERLAPPED ovlpd = <span style="color:Blue; new OVERLAPPED();
<span style="color:Blue; byte [] buffer = <span style="color:Blue; new <span style="color:Blue; byte[512];
<span style="color:Blue; int ErrorCode = 0;
<span style="color:Blue; uint NumberOfBytesRead = 0;
<span style="color:Blue; const <span style="color:Blue; uint ERROR_IO_PENDING = 997;
GCHandle PinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
ovlpd.Offset = 0;
ovlpd.OffsetHigh = 0;
ovlpd.EventHandle = ewhRead.SafeWaitHandle.DangerousGetHandle();
ovlpd.Internal = UIntPtr.Zero;
ovlpd.InternalHigh = UIntPtr.Zero;
GCHandle PinnedOvlpd = GCHandle.Alloc(ovlpd, GCHandleType.Pinned);
<span style="color:Green; // ewhRead is declared and instantiate outside
<span style="color:Green; // EventWaitHandle ewhRead = new EventWaitHandle(false, EventResetMode.ManualReset);
ewhRead.Reset();
<span style="color:Blue; if(ReadFile(m_hDevFsHandle,
PinnedBuffer.AddrOfPinnedObject(),
(<span style="color:Blue; uint) 512,
<span style="color:Blue; out NumberOfBytesRead,
PinnedOvlpd.AddrOfPinnedObject()))
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "Read Success: {0}", ErrorCode);
}
<span style="color:Blue; else
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "Read Error: {0}", ErrorCode);
<span style="color:Blue; if (ErrorCode == ERROR_IO_PENDING)
{
<span style="color:Blue; if (!ewhRead.WaitOne(5000))
{
Dbg.WriteLine(<span style="color:#A31515; "Wait Timed out");
}
<span style="color:Blue; if (0 != GetOverlappedResult(m_hDevFsHandle,
PinnedOvlpd.AddrOfPinnedObject(),
<span style="color:Blue; out NumberOfBytesRead,
1))
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "GetOverlappedResult Success: {0}", ErrorCode);
}
<span style="color:Blue; else
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "GetOverlappedResult Error: {0}", ErrorCode);
}
}
<span style="color:Blue; else
{
CancelIo(m_hDevFsHandle);
}
Dbg.WriteLine(<span style="color:#A31515; "Read {0}", NumberOfBytesRead);
}
PinnedBuffer.Free();
PinnedOvlpd.Free();
<span style="color:Blue; return buffer;
}
[/code]
View the full article
<br/>
Im successfully past problem of getting the device to enumarate and getting the file handle
<br/>
However the fileStream Read/Write doesnt work
I used the managed file stream method i.e first create a handle via native call in overlapped mode. Then use the handle to get a FileStream object and perform read/write using it. On XP 32 bit it works great but on Windows 7 the FileStream.Write throws a
null reference exception.
Then on Windows 7 the approach I took was read/write using native calls (I abandoned the managed FileStream class approach). For this I used WriteFile, ReadFile, GetOverlappedResult APIs with OVERLAPPED structure etc. I have also pinned the data buffers.
But ReadFile (or WriteFile) returns 997 i.e ERROR_IO_PENDING and subsequent call to GetOverlappedResult returns 1 ie. ERROR_INVALID_FUNCTION. Then NumberOfBytesRead is always 0.
Im not sure what am I doing wrong!!!.
Following is a code snippet containing the Read API from my code.
Thanks In advance for all the help.
<div style="color:Black;background-color:White; <pre>
<span style="color:Blue; public <span style="color:Blue; byte[] Read()
{
OVERLAPPED ovlpd = <span style="color:Blue; new OVERLAPPED();
<span style="color:Blue; byte [] buffer = <span style="color:Blue; new <span style="color:Blue; byte[512];
<span style="color:Blue; int ErrorCode = 0;
<span style="color:Blue; uint NumberOfBytesRead = 0;
<span style="color:Blue; const <span style="color:Blue; uint ERROR_IO_PENDING = 997;
GCHandle PinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
ovlpd.Offset = 0;
ovlpd.OffsetHigh = 0;
ovlpd.EventHandle = ewhRead.SafeWaitHandle.DangerousGetHandle();
ovlpd.Internal = UIntPtr.Zero;
ovlpd.InternalHigh = UIntPtr.Zero;
GCHandle PinnedOvlpd = GCHandle.Alloc(ovlpd, GCHandleType.Pinned);
<span style="color:Green; // ewhRead is declared and instantiate outside
<span style="color:Green; // EventWaitHandle ewhRead = new EventWaitHandle(false, EventResetMode.ManualReset);
ewhRead.Reset();
<span style="color:Blue; if(ReadFile(m_hDevFsHandle,
PinnedBuffer.AddrOfPinnedObject(),
(<span style="color:Blue; uint) 512,
<span style="color:Blue; out NumberOfBytesRead,
PinnedOvlpd.AddrOfPinnedObject()))
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "Read Success: {0}", ErrorCode);
}
<span style="color:Blue; else
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "Read Error: {0}", ErrorCode);
<span style="color:Blue; if (ErrorCode == ERROR_IO_PENDING)
{
<span style="color:Blue; if (!ewhRead.WaitOne(5000))
{
Dbg.WriteLine(<span style="color:#A31515; "Wait Timed out");
}
<span style="color:Blue; if (0 != GetOverlappedResult(m_hDevFsHandle,
PinnedOvlpd.AddrOfPinnedObject(),
<span style="color:Blue; out NumberOfBytesRead,
1))
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "GetOverlappedResult Success: {0}", ErrorCode);
}
<span style="color:Blue; else
{
ErrorCode = Marshal.GetLastWin32Error();
Dbg.WriteLine(<span style="color:#A31515; "GetOverlappedResult Error: {0}", ErrorCode);
}
}
<span style="color:Blue; else
{
CancelIo(m_hDevFsHandle);
}
Dbg.WriteLine(<span style="color:#A31515; "Read {0}", NumberOfBytesRead);
}
PinnedBuffer.Free();
PinnedOvlpd.Free();
<span style="color:Blue; return buffer;
}
[/code]
View the full article