private unsafe IAsyncResult BeginReadCore(byte[] array, int offset, int count, AsyncCallback userCallback, Object stateObject) { Debug.Assert(userCallback == null); Debug.Assert(stateObject == null); CheckParametersForBegin(array, offset, count); AsyncFileStream_AsyncResult asyncResult = new AsyncFileStream_AsyncResult(userCallback, stateObject, false); if (count == 0) { asyncResult.SignalCompleted( ); } else { // Keep the array in one location in memory until the OS writes the // relevant data into the array. Free GCHandle later. asyncResult.PinBuffer(array); int totalRead = 0; int availableToTransfer = 0; fixed(byte *dst = array) { // if we already have available data, then we need to use it lock ( syncRW ) { System.Diagnostics.Debug.Assert(count == m_bytesAvailable); if (m_bytesAvailable > 0) { // truncate availableToTransfer = Math.Min(count, ( int )m_bytesAvailable); // copy over to the application buffer Marshal.Copy(m_buffer, 0, new IntPtr(dst + offset), availableToTransfer); // update the available bytes count m_bytesAvailable -= ( uint )availableToTransfer; totalRead += availableToTransfer; // adjust the buffering if there is a left over // this will never happen if application call AvailableBytes and the reads them if (m_bytesAvailable > 0) { fixed(byte *copy = m_buffer) { Marshal.Copy(new IntPtr(copy), m_buffer, ( int )availableToTransfer, ( int )m_bytesAvailable); } } } } // if we need to read more, then we should go to the stream directly int remainder = count - availableToTransfer; if (remainder > 0) { byte[] byteArray = new byte[remainder]; Array.Clear(byteArray, 0, byteArray.Length); fixed(byte *p = byteArray) { uint numBytesRead = 0; var res = m_winUsbDevice.ReadPipe(Convert.ToByte(m_winUsbDevice.DeviceInfo.bulkInPipe) , byteArray , ( uint )remainder , ref numBytesRead , IntPtr.Zero ); if (!res) { if (HandleErrorSituation("BeginRead", false)) { asyncResult.SignalCompleted( ); } else { m_outstandingRequests.Add(asyncResult); } } else { Marshal.Copy(byteArray, 0, new IntPtr(dst + totalRead + offset), ( int )numBytesRead); totalRead += ( int )numBytesRead; } } } if (totalRead > 0) { asyncResult.m_numBytes = totalRead; asyncResult.SignalCompleted( ); } } } return(asyncResult); }