public virtual int ReadRegion(FileStream hardwareFileStream, MemoryRegion region, Action <int, int> progress) { uint currentPacketLength; uint noTransferredBytes = region.Size; uint currentAddress = region.Address; while (noTransferredBytes > 0) { currentPacketLength = _bytesPerPacket < noTransferredBytes ? _bytesPerPacket : noTransferredBytes; hardwareFileStream.Write(GetDataReq.getCommandPacket(currentAddress, (byte)currentPacketLength), 0, 65); byte[] rawdata = new byte[65]; hardwareFileStream.Read(rawdata, 0, 65); GetDataResultsResp response = new GetDataResultsResp(rawdata); for (uint i = 0, j = currentAddress - region.Address; i < response.BytesPerPacket; i++, j++) { region.Data[j] = response.Data[i]; } progress((int)(region.Size - noTransferredBytes), (int)region.Size); noTransferredBytes -= response.BytesPerPacket; currentAddress += response.BytesPerPacket; } return(0); }
public int ReadRegion(string path, MemoryRegion region, Action <int, int> progress) { SafeFileHandle asyncWriteHandle = CreateFile(path, Win32HardwareIOSupport.GENERIC_WRITE | Win32HardwareIOSupport.GENERIC_READ, Win32HardwareIOSupport.FILE_SHARE_WRITE | Win32HardwareIOSupport.FILE_SHARE_READ, IntPtr.Zero, Win32HardwareIOSupport.OPEN_EXISTING, Win32HardwareIOSupport.FILE_FLAG_OVERLAPPED | Win32HardwareIOSupport.FILE_FLAG_NO_BUFFERING, IntPtr.Zero); if (asyncWriteHandle.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } SafeFileHandle asyncReadHandle = CreateFile(path, Win32HardwareIOSupport.GENERIC_READ | Win32HardwareIOSupport.GENERIC_WRITE, Win32HardwareIOSupport.FILE_SHARE_WRITE | Win32HardwareIOSupport.FILE_SHARE_READ, IntPtr.Zero, Win32HardwareIOSupport.OPEN_EXISTING, Win32HardwareIOSupport.FILE_FLAG_OVERLAPPED | Win32HardwareIOSupport.FILE_FLAG_NO_BUFFERING, IntPtr.Zero); if (asyncReadHandle.IsInvalid) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } int currentPacketLength = 0; uint trBytes; int pendingPackets = 0; int noRequestedBytes = (int)region.Size; int noReadedBytes = (int)region.Size; uint currentAddress = region.Address; byte lastError = 0; EventWaitHandle hWrite1Event = new EventWaitHandle(false, EventResetMode.AutoReset); EventWaitHandle hWrite2Event = new EventWaitHandle(false, EventResetMode.AutoReset); EventWaitHandle hReadEvent = new EventWaitHandle(false, EventResetMode.AutoReset); NativeOverlapped write1Over = new NativeOverlapped(); write1Over.OffsetHigh = 0; write1Over.OffsetLow = 0; write1Over.EventHandle = hWrite1Event.SafeWaitHandle.DangerousGetHandle(); NativeOverlapped write2Over = new NativeOverlapped(); write2Over.OffsetHigh = 0; write2Over.OffsetLow = 0; write2Over.EventHandle = hWrite2Event.SafeWaitHandle.DangerousGetHandle(); NativeOverlapped readOver = new NativeOverlapped(); readOver.OffsetHigh = 0; readOver.OffsetLow = 0; readOver.EventHandle = hReadEvent.SafeWaitHandle.DangerousGetHandle(); MemSafeHandle pWrite1 = new MemSafeHandle(Marshal.AllocHGlobal(65)); MemSafeHandle pWrite2 = new MemSafeHandle(Marshal.AllocHGlobal(65)); MemSafeHandle pRead = new MemSafeHandle(Marshal.AllocHGlobal(65)); currentPacketLength = (int)_bytesPerPacket < noRequestedBytes ? (int)_bytesPerPacket : noRequestedBytes; ArrayToMem(GetDataReq.getCommandPacket(currentAddress, (byte)currentPacketLength), pWrite1); if (!WriteFile(asyncWriteHandle, pWrite1.DangerousGetHandle(), 65, out trBytes, ref write1Over)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hWrite1Event.Set(); } pendingPackets++; noRequestedBytes -= currentPacketLength; currentAddress += (uint)currentPacketLength; if (noRequestedBytes > 0) { currentPacketLength = (int)_bytesPerPacket < noRequestedBytes ? (int)_bytesPerPacket : noRequestedBytes; ArrayToMem(GetDataReq.getCommandPacket(currentAddress, (byte)currentPacketLength), pWrite2); if (!WriteFile(asyncWriteHandle, pWrite2.DangerousGetHandle(), 65, out trBytes, ref write2Over)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hWrite2Event.Set(); } pendingPackets++; noRequestedBytes -= currentPacketLength; currentAddress += (uint)currentPacketLength; } byte[] rawdata = new byte[65]; if (!ReadFile(asyncReadHandle, pRead.DangerousGetHandle(), 65, out trBytes, ref readOver)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hReadEvent.Set(); } while (noReadedBytes > 0) { if (WaitHandle.WaitAny(new WaitHandle[] { hWrite1Event, hWrite2Event, hReadEvent }, 10000) == WaitHandle.WaitTimeout) { throw new Exception("Hardware doesn't answer. Read time out. no readed bytes:" + noReadedBytes.ToString() + " pending packets:" + pendingPackets.ToString() + " no requested bytes:" + noRequestedBytes.ToString() + " current addr:" + currentAddress.ToString()); } if ((write1Over.InternalLow.ToInt32() != 0x103) && (pendingPackets < 10) && (noRequestedBytes > 0)) { write1Over.OffsetHigh = 0; write1Over.OffsetLow = 0; write1Over.InternalLow = IntPtr.Zero; write1Over.InternalHigh = IntPtr.Zero; currentPacketLength = (int)_bytesPerPacket < noRequestedBytes ? (int)_bytesPerPacket : noRequestedBytes; ArrayToMem(GetDataReq.getCommandPacket(currentAddress, (byte)currentPacketLength), pWrite1); if (!WriteFile(asyncWriteHandle, pWrite1.DangerousGetHandle(), 65, out trBytes, ref write1Over)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hWrite1Event.Set(); } pendingPackets++; noRequestedBytes -= currentPacketLength; currentAddress += (uint)currentPacketLength; } if ((write2Over.InternalLow.ToInt32() != 0x103) && (pendingPackets < 10) && (noRequestedBytes > 0)) { write2Over.OffsetHigh = 0; write2Over.OffsetLow = 0; write2Over.InternalLow = IntPtr.Zero; write2Over.InternalHigh = IntPtr.Zero; currentPacketLength = (int)_bytesPerPacket < noRequestedBytes ? (int)_bytesPerPacket : noRequestedBytes; ArrayToMem(GetDataReq.getCommandPacket(currentAddress, (byte)currentPacketLength), pWrite2); if (!WriteFile(asyncWriteHandle, pWrite2.DangerousGetHandle(), 65, out trBytes, ref write2Over)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hWrite2Event.Set(); } pendingPackets++; noRequestedBytes -= currentPacketLength; currentAddress += (uint)currentPacketLength; } if ((readOver.InternalLow.ToInt32() != 0x103)) { MemToArray(pRead, rawdata); progress((int)(region.Size - noReadedBytes), (int)region.Size); if (pendingPackets > 0) { readOver.OffsetHigh = 0; readOver.OffsetLow = 0; readOver.InternalLow = IntPtr.Zero; readOver.InternalHigh = IntPtr.Zero; if (!ReadFile(asyncReadHandle, pRead.DangerousGetHandle(), 65, out trBytes, ref readOver)) { if (Marshal.GetLastWin32Error() != Win32HardwareIOSupport.ERROR_IO_PENDING) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } } else { hReadEvent.Set(); } } } } asyncWriteHandle.Close(); asyncReadHandle.Close(); if (lastError != 0) { string error = null; try { } catch (KeyNotFoundException) { error = "Unknown hardware error: " + lastError.ToString(); } throw new Exception(error); } return(0); }