@Override protected void _openMapping(long size) throws IOException { if (mapping != null) { throw new IllegalStateException("File is already mapped!"); } mapping = Kernel32.INSTANCE.CreateFileMapping( file, null, WinNT.PAGE_READWRITE, (int) (size >> 8 * 4), (int) (size & 0xFFFFFFFFL), null); if (mapping == null || WinNT.INVALID_HANDLE_VALUE.equals(mapping)) { throw new IOException("Unable to map file: " + getLastErrorAsString()); } else if (Kernel32.INSTANCE.GetLastError() == WinError.ERROR_ALREADY_EXISTS) { //File mapping already existing, TODO how to care about? throw new IOException("ERROR_ALREADY_EXISTS, don't know how to handle that!"); } }
@Override public void write(byte[] b, int off, int len) throws IOException { Pointer lpOverlapped = createOverlapped(writerWaitable).getPointer(); boolean immediate = api.WriteFile(pipeHandle, ByteBuffer.wrap(b, off, len), len, null, lpOverlapped); if (!immediate && api.GetLastError() != WinError.ERROR_IO_PENDING) { throw new IOException("WriteFile() failed. WinError: " + api.GetLastError()); } IntByReference written = new IntByReference(); // wait = true, blocked until data is written if (!api.GetOverlappedResult(pipeHandle, lpOverlapped, written, true)) { throw new IOException("GetOverlappedResult() failed for write operation"); } if (written.getValue() != len) { throw new IOException("WriteFile() wrote less bytes than requested"); } }
String getToken( final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) { final IntByReference attr = new IntByReference(); final SecBufferDesc token = new SecBufferDesc( Sspi.SECBUFFER_TOKEN, Sspi.MAX_TOKEN_SIZE); sspiContext = new CtxtHandle(); final int rc = Secur32.INSTANCE.InitializeSecurityContext(clientCred, continueCtx, targetName, Sspi.ISC_REQ_DELEGATE | Sspi.ISC_REQ_MUTUAL_AUTH, 0, Sspi.SECURITY_NATIVE_DREP, continueToken, 0, sspiContext, token, attr, null); switch (rc) { case WinError.SEC_I_CONTINUE_NEEDED: continueNeeded = true; break; case WinError.SEC_E_OK: dispose(); // Don't keep the context continueNeeded = false; break; default: dispose(); throw new Win32Exception(rc); } return Base64.encodeBase64String(token.getBytes()); }
@Override String getToken(final CtxtHandle continueCtx, final SecBufferDesc continueToken, final String targetName) { dispose(); /* We will rather throw SEC_E_TARGET_UNKNOWN because SEC_E_DOWNGRADE_DETECTED is not * available on Windows XP and this unit test always fails. */ throw new Win32Exception(WinError.SEC_E_TARGET_UNKNOWN); }
private static void waitForPipe(WinNT.HANDLE handle) throws IOException { WinNT.HANDLE connectEvent = KERNEL32.CreateEventA(null, true, false, null); WinBase.OVERLAPPED povl = new WinBase.OVERLAPPED(); povl.hEvent = connectEvent; boolean success = KERNEL32.ConnectNamedPipe(handle, povl); if (!success) { switch (KERNEL32.GetLastError()) { case WinError.ERROR_PIPE_CONNECTED: success = true; break; case WinError.ERROR_IO_PENDING: if (KERNEL32.WaitForSingleObject(connectEvent, CONNECT_PIPE_TIMEOUT) != WinBase.WAIT_OBJECT_0) { KERNEL32.CancelIo(handle); success = false; } else { success = true; } break; } } KERNEL32.CloseHandle(connectEvent); if (!success) throw new IOException("Cannot connect to a named pipe"); }
private static boolean isRunning() { if (Platform.isWindows()) { mutex = Kernel32.INSTANCE.CreateMutex(null, false, MUTEX_NAME); if (mutex == null) { return false; } int er = Kernel32.INSTANCE.GetLastError(); if (er == WinError.ERROR_ALREADY_EXISTS) { return true; } new Thread("OtherInstanceCommunicator") { @Override public void run() { while (true) { try (PipeInputStream pis = new PipeInputStream(PIPE_NAME, true)) { ObjectInputStream ois = new ObjectInputStream(pis); String app = ois.readUTF(); if (app.equals(PIPE_APP_CODE)) { int major = ois.readInt(); int minor = ois.readInt(); int release = ois.readInt(); int build = ois.readInt(); int pipeMajor = ois.readInt(); int pipeMinor = ois.readInt(); if (pipeMajor == PIPE_MAJOR) { String command = ois.readUTF(); switch (command) { case "open": int cnt = ois.readInt(); String[] fileNames = new String[cnt]; for (int i = 0; i < cnt; i++) { fileNames[i] = ois.readUTF(); } View.execInEventDispatch(() -> { for (int i = 0; i < cnt; i++) { Main.openFile(fileNames[i], null); } }); //no break - focus too case "focus": View.execInEventDispatch(new Runnable() { @Override public void run() { Window wnd = Main.getMainFrame().getWindow(); wnd.setAlwaysOnTop(true); wnd.toFront(); wnd.requestFocus(); wnd.setAlwaysOnTop(false); wnd.repaint(); } }); break; } } } } catch (IOException ex) { //ignore } } } }.start(); } return false; }