This is primarily Node.js question but it likely requires to be familiar with Win32 API and named pipes.
Node.js supports Windows named pipes for IPC connections. Here's an example:
// server.js
const server = require('net').createServer((socket) => {
socket.write('test\n');
socket.on('end', () => {
server.close();
});
});
server.listen('\\\\.\\\pipe\\\WinUAE');
It doesn't work when named pipe is connected by third-party client written in C++, this results in ERROR_INVALID_PARAMETER (code 87) error:
Connected to '\.\pipe\WinUAE'
SetNamedPipeHandleState failed err=87
And the snippet that causes the problem:
mode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(p, &mode, NULL, NULL)) {
printf("SetNamedPipeHandleState failed err=%d\n", GetLastError());
return 0;
}
Client binary can be downloaded here, and the mirror in case of hosting problems.
I assume the problem is that Node.js doesn't fully support Windows named pipes and cannot be used for IPC in cases that demand first-class support like this one.
Is Node.js not suitable for IPC with such process? What is going on here under the hood?
This is primarily Node.js question
No, I can reproduce it with C++, creating namepipe with PIPE_TYPE_BYTE
type(this is the default type).
As @RbMm pointed out, according to the SetNamedPipeHandleState
:
PIPE_READMODE_MESSAGE: Data is read from the pipe as a stream of messages. The function fails if this flag is specified for a byte-type pipe.
This is because the type modes must be the same for all instances of a pipe, but PIPE_TYPE_BYTE
do not support PIPE_READMODE_MESSAGE
mode.
CreateNamedPipe
:
dwPipeMode
The same type mode must be specified for each instance of the pipe.
PIPE_TYPE_BYTE: Data is written to the pipe as a stream of bytes. This mode cannot be used with
PIPE_READMODE_MESSAGE
. The pipe does not distinguish bytes written during different write operations.PIPE_READMODE_MESSAGE: Data is read from the pipe as a stream of messages. This mode can be only used if
PIPE_TYPE_MESSAGE
is also specified.
As the document Named Pipe Type, Read, and Wait Modes:
To create a byte-type pipe, specify PIPE_TYPE_BYTE or use the default value. The data is written to the pipe as a stream of bytes, and the system does not differentiate between the bytes written in different write operations.
To create a message-type pipe, specify PIPE_TYPE_MESSAGE. The system treats the bytes written in each write operation to the pipe as a message unit. The system always performs write operations on message-type pipes as if write-through mode were enabled.
When specified as PIPE_TYPE_BYTE
, the system does not differentiate between the bytes written in different write operations, so the message unit in each write operation is also not able to be differentiated.