Java WINAPI Anonymous Pipe Invalid/Not Found?

279 Views Asked by At

Java seems unable to inherit anonymous pipes from the WinAPI, I am using my own library and can not figure out what the issue is.

Library source on the current commit.

The anon test:

package net.gudenau.lib.pipes.test;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import net.gudenau.lib.pipes.AnonymousPipeHandle;
import net.gudenau.lib.pipes.PipeHandle;
import net.gudenau.lib.pipes.Pipes;

public class AnonymousPipe{
    public static void main(String[] args){
        try(PipeHandle client = Pipes.findPipe()){
            InputStream inputStream = client.getInputStream();
            OutputStream outputStream = client.getOutputStream();

            byte[] data = "This is from the anon pipe!".getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);
            data = new byte[inputStream.read()];
            inputStream.read(data);
            System.out.printf("Server says: %s\n", new String(data, StandardCharsets.UTF_16));
        }catch(IOException e){
            e.printStackTrace();
            System.exit(0);
        }
    }

    static void test(){
        File path = new File(System.getProperty("java.home") + File.separator + "bin");
        File executable;
        if(System.getProperty("os.name").toLowerCase().contains("windows")){
            executable = new File(path, "javaw.exe");
        }else{
            executable = new File(path, "java");
        }

        ProcessBuilder processBuilder = new ProcessBuilder(
            executable.getAbsolutePath(),
            "-Dfile.encoding=UTF-8",
            "-classpath",
            System.getProperty("java.class.path"),
            "net.gudenau.lib.pipes.test.AnonymousPipe"
        );
        processBuilder.inheritIO();

        try(AnonymousPipeHandle pipe = Pipes.createPipe()){
            pipe.setupHandleShare(processBuilder);
            Process process = processBuilder.start();
            pipe.clientConnected();

            InputStream inputStream = pipe.getInputStream();
            OutputStream outputStream = pipe.getOutputStream();

            byte[] data = new byte[inputStream.read()];
            inputStream.read(data);
            String message = new String(data, StandardCharsets.UTF_16);
            System.out.printf("Client says: %s\n", new String(data, StandardCharsets.UTF_16));
            data = message.toUpperCase().getBytes(StandardCharsets.UTF_16);
            outputStream.write(data.length);
            outputStream.write(data);

            try{
                process.waitFor();
            }catch(InterruptedException ignored){}
        }catch(IOException e){
            e.printStackTrace();
            System.exit(-1);
        }
    }
}

As far as I can tell I am doing all of this correctly.

I am creating the anon pipe with CreatePipe using a SECURITY_ATTRIBUTES with bInheritHandle set to true.

Then after the client side is created I close the "client" side handles.

What am I missing?

Edit: I spaced and missed the errors. The test method throws The specified procedure could not be found., at least according to Windows which makes no sense to me.

The other process throws The handle is invalid., again according to Windows.

Output:

Client says: the quick brown fox jumps over the lazy dog
Server says: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
java.io.IOException: The specified procedure could not be found.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:34)
    at java.base/java.io.InputStream.read(InputStream.java:106)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeInputStream.read(WindowsPipeInputStream.java:16)
    at net.gudenau.lib.pipes.test.AnonymousPipe.test(AnonymousPipe.java:57)
    at net.gudenau.lib.pipes.test.PipeTest.main(PipeTest.java:6)
java.io.IOException: The handle is invalid.

    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:35)
    at java.base/java.io.OutputStream.write(OutputStream.java:77)
    at net.gudenau.lib.pipes.impl.windows.WindowsPipeOutputStream.write(WindowsPipeOutputStream.java:15)
    at net.gudenau.lib.pipes.test.AnonymousPipe.main(AnonymousPipe.java:19)

Process finished with exit code -1
1

There are 1 best solutions below

5
On

I remember reading here that handles from one process are invalid in another process and that Java windows anonymous pipes only worked between threads. That would explain an invalid handle.