/* * Copyright (C) 2010-2016 JPEXS * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.jpexs.decompiler.flash.gui.pipes; import com.sun.jna.Platform; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; import java.io.IOException; import java.io.InputStream; /** * * @author JPEXS */ public class PipeInputStream extends InputStream { protected HANDLE pipe; private boolean closed = false; public PipeInputStream(String pipeName, boolean newpipe) throws IOException { if (!Platform.isWindows()) { throw new IOException("Cannot create Pipe on nonWindows OS"); } String fullPipePath = "\\\\.\\pipe\\" + pipeName; if (newpipe) { pipe = Kernel32.INSTANCE.CreateNamedPipe(fullPipePath, Kernel32.PIPE_ACCESS_INBOUND, Kernel32.PIPE_TYPE_BYTE, 1, 4096, 4096, 0, null); if (pipe == null || !Kernel32.INSTANCE.ConnectNamedPipe(pipe, null)) { throw new IOException("Cannot connect to the pipe"); } } else { pipe = Kernel32.INSTANCE.CreateFile(fullPipePath, Kernel32.GENERIC_READ, Kernel32.FILE_SHARE_READ, null, Kernel32.OPEN_EXISTING, Kernel32.FILE_ATTRIBUTE_NORMAL, null); } if (pipe == null) { throw new IOException("Cannot connect to the pipe"); } Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { try { close(); } catch (IOException ex) { //ignore } } }); } @Override public synchronized void close() throws IOException { if (!closed) { Kernel32.INSTANCE.CloseHandle(pipe); closed = true; } } @Override public synchronized int read() throws IOException { byte[] d = new byte[1]; if (readPipe(d) == 0) { return -1; } return d[0]; } private int readPipe(byte res[]) throws IOException { final IntByReference ibr = new IntByReference(); int read = 0; while (read < res.length) { byte[] data = new byte[res.length - read]; boolean result = Kernel32.INSTANCE.ReadFile(pipe, data, data.length, ibr, null); if (!result) { throw new IOException("Cannot read pipe. Error " + Kernel32.INSTANCE.GetLastError()); } int readNow = ibr.getValue(); System.arraycopy(data, 0, res, read, readNow); read += readNow; } return read; } }