PythonForWindows icon indicating copy to clipboard operation
PythonForWindows copied to clipboard

Reading from Pipe can't be blocked

Open prprDog opened this issue 2 years ago • 1 comments

Using Api ReadFile() can't be blocked before server writes data. Client, python ver.

pipe_name = "dotnetest_py"
pipe_full_name = windows.pipe.full_pipe_address(pipe_name)
pipe_handle = windows.winproxy.CreateFileA(pipe_full_name,
                            dwDesiredAccess=gdef.GENERIC_READ | gdef.GENERIC_WRITE,
                             dwShareMode=gdef.FILE_SHARE_WRITE | gdef.FILE_SHARE_READ)

bool_receive = ctypes.create_string_buffer(ctypes.sizeof(ctypes.c_bool))
windows.winproxy.ReadFile(pipe_handle, bool_receive)
test1= ctypes.c_bool.from_buffer(bool_receive).value
# print True
print(test1)
if test1:
  windows.winproxy.ReadFile(pipe_handle, bool_receive)
  test2 = ctypes.c_bool.from_buffer(bool_receive).value
 # print False
  print(test2)

Server, c++ ver.

TCHAR pipeName[255] = "\\\\.\\pipe\\dotnetest_py";

pipehandle=CreateNamedPipeW(pipename, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 255,256*1024, 16, INFINITE, NULL);
BOOL result = true;
ULONG byteswritten;
// write twice
WriteFile(pipehandle, &result, sizeof(result), &byteswritten, NULL);
WriteFile(pipehandle, &result, sizeof(result), &byteswritten, NULL);

I try write client with c++, It's ok, the client would be blocked, and when I try to debug the python program, I found it can't be blocked. What is the problem? I am new to python. I think the pipe is something like system mechanics and it couldn't be wrong. Is there something miss in my code?

prprDog avatar Aug 09 '22 07:08 prprDog

Hi,

I tried to reproduce your code the best I can in Python for both side in an interactive shell with something like:

server:

>>> windows.winproxy.CreateNamedPipeW("\\\\.\\pipe\\dotnetest_py", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 255,256*1024, 16, INFINITE, None)
784
>>> x = _
>>> windows.winproxy.WriteFile(x, "testing_string")
1

client:

>>> pipehandle = winproxy.CreateFileA("\\\\.\\pipe\\dotnetest_py", gdef.GENERIC_READ | gdef.GENERIC_WRITE, 0, None, gdef.OPEN_EXISTING, 0, None)
>>> buffer = ctypes.create_string_buffer(100)
>>> windows.winproxy.ReadFile(pipehandle, buffer)
1
>>> buffer.value
'testing_string'

If each line is entered at the correct time (server-create / client-connect / client-read / server-write), I have the expected waiting behavior client-side.

But, in the server, if you write to the pipe before the client is connected, I have the following error:

>>> windows.winproxy.WriteFile(x, "testing_string")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\apis\kernel32.py", line 489, in WriteFile
    return WriteFile.ctypes_function(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped)
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\apiproxy.py", line 99, in perform_call
    return self._cprototyped(*args)
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\error.py", line 49, in fail_on_zero
    raise WinproxyError(func_name)
windows.winproxy.error.WinproxyError: WriteFile: [Error 536] Waiting for a process to open the other end of the pipe.

I see that you don't have any check on the WriteFile returned values in your server. Are you sure the data are indeed written to the pipe ?

hakril avatar Aug 11 '22 16:08 hakril

Hi,

I tried to reproduce your code the best I can in Python for both side in an interactive shell with something like:

server:

>>> windows.winproxy.CreateNamedPipeW("\\\\.\\pipe\\dotnetest_py", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 255,256*1024, 16, INFINITE, None)
784
>>> x = _
>>> windows.winproxy.WriteFile(x, "testing_string")
1

client:

>>> pipehandle = winproxy.CreateFileA("\\\\.\\pipe\\dotnetest_py", gdef.GENERIC_READ | gdef.GENERIC_WRITE, 0, None, gdef.OPEN_EXISTING, 0, None)
>>> buffer = ctypes.create_string_buffer(100)
>>> windows.winproxy.ReadFile(pipehandle, buffer)
1
>>> buffer.value
'testing_string'

If each line is entered at the correct time (server-create / client-connect / client-read / server-write), I have the expected waiting behavior client-side.

But, in the server, if you write to the pipe before the client is connected, I have the following error:

>>> windows.winproxy.WriteFile(x, "testing_string")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\apis\kernel32.py", line 489, in WriteFile
    return WriteFile.ctypes_function(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped)
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\apiproxy.py", line 99, in perform_call
    return self._cprototyped(*args)
  File "c:\users\hakril\documents\projets\pythonforwindows\windows\winproxy\error.py", line 49, in fail_on_zero
    raise WinproxyError(func_name)
windows.winproxy.error.WinproxyError: WriteFile: [Error 536] Waiting for a process to open the other end of the pipe.

I see that you don't have any check on the WriteFile returned values in your server. Are you sure the data are indeed written to the pipe ?

Thanks for help, that is my mistake

prprDog avatar Aug 23 '22 06:08 prprDog