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);
        }
Пример #2
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);
        }