10000 gh-119690: Adds Unicode support for named pipes in _winapi (GH-119717) · python/cpython@78d697b · GitHub
[go: up one dir, main page]

Skip to content

Commit 78d697b

Browse files
authored
gh-119690: Adds Unicode support for named pipes in _winapi (GH-119717)
1 parent 34f9b3e commit 78d697b

File tree

6 files changed

+92
-29
lines changed

6 files changed

+92
-29
lines changed

Lib/test/audit-tests.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,17 @@ def hook(event, args):
556556
sys.monitoring.register_callback(1, 1, None)
557557

558558

559+
def test_winapi_createnamedpipe(pipe_name):
560+
import _winapi
561+
562+ 10000
def hook(event, args):
563+
if event == "_winapi.CreateNamedPipe":
564+
print(event, args)
565+
566+
sys.addaudithook(hook)
567+
_winapi.CreateNamedPipe(pipe_name, _winapi.PIPE_ACCESS_DUPLEX, 8, 2, 0, 0, 0, 0)
568+
569+
559570
if __name__ == "__main__":
560571
from test.support import suppress_msvcrt_asserts
561572

Lib/test/test_audit.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,20 @@ def test_sys_monitoring_register_callback(self):
291291

292292
self.assertEqual(actual, expected)
293293

294+
def test_winapi_createnamedpipe(self):
295+
winapi = import_helper.import_module("_winapi")
296+
297+
pipe_name = r"\\.\pipe\LOCAL\test_winapi_createnamed_pipe"
298+
returncode, events, stderr = self.run_python("test_winapi_createnamedpipe", pipe_name)
299+
if returncode:
300+
self.fail(stderr)
301+
302+
if support.verbose:
303+
print(*events, sep='\n')
304+
actual = [(ev[0], ev[2]) for ev in events]
305+
expected = [("_winapi.CreateNamedPipe", f"({pipe_name!r}, 3, 8)")]
306+
307+
self.assertEqual(actual, expected)
294308

295309
if __name__ == "__main__":
296310
unittest.main()

Lib/test/test_winapi.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import threading
88
import time
99
import unittest
10-
from test.support import import_helper
10+
from test.support import import_helper, os_helper
1111

1212
_winapi = import_helper.import_module('_winapi', required_on=['win'])
1313

@@ -127,3 +127,35 @@ def test_getshortpathname(self):
127127

128128
# Should contain "PROGRA~" but we can't predict the number
129129
self.assertIsNotNone(re.match(r".\:\\PROGRA~\d", actual.upper()), actual)
130+
131+
def test_namedpipe(self):
132+
pipe_name = rf"\\.\pipe\LOCAL\{os_helper.TESTFN}"
133+
134+
# Pipe does not exist, so this raises
135+
with self.assertRaises(FileNotFoundError):
136+
_winapi.WaitNamedPipe(pipe_name, 0)
137+
138+
pipe = _winapi.CreateNamedPipe(
139+
pipe_name,
140+
_winapi.PIPE_ACCESS_DUPLEX,
141+
8, # 8=PIPE_REJECT_REMOTE_CLIENTS
142+
2, # two instances available
143+
32, 32, 0, 0)
144+
self.addCleanup(_winapi.CloseHandle, pipe)
145+
146+
# Pipe instance is available, so this passes
147+
_winapi.WaitNamedPipe(pipe_name, 0)
148+
149+
with open(pipe_name, 'w+b') as pipe2:
150+
# No instances available, so this times out
151+
# (WinError 121 does not get mapped to TimeoutError)
152+
with self.assertRaises(OSError):
153+
_winapi.WaitNamedPipe(pipe_name, 0)
154+
155+
_winapi.WriteFile(pipe, b'testdata')
156+
self.assertEqual(b'testdata', pipe2.read(8))
157+
158+
self.assertEqual((b'', 0), _winapi.PeekNamedPipe(pipe, 8)[:2])
159+
pipe2.write(b'testdata')
160+
pipe2.flush()
161+
self.assertEqual((b'testdata', 8), _winapi.PeekNamedPipe(pipe, 8)[:2])
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds Unicode support and fixes audit events for ``_winapi.CreateNamedPipe``.

Modules/_winapi.c

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ create_converter('LPCVOID', '" F_POINTER "')
224224
225225
create_converter('BOOL', 'i') # F_BOOL used previously (always 'i')
226226
create_converter('DWORD', 'k') # F_DWORD is always "k" (which is much shorter)
227-
create_converter('LPCTSTR', 's')
228227
create_converter('UINT', 'I') # F_UINT used previously (always 'I')
229228
230229
class LPCWSTR_converter(Py_UNICODE_converter):
@@ -259,7 +258,7 @@ class LPVOID_return_converter(CReturnConverter):
259258
data.return_conversion.append(
260259
'return_value = HANDLE_TO_PYNUM(_return_value);\n')
261260
[python start generated code]*/
262-
/*[python end generated code: output=da39a3ee5e6b4b0d input=ef52a757a1830d92]*/
261+
/*[python end generated code: output=da39a3ee5e6b4b0d input=da0a4db751936ee7]*/
263262

264263
#include "clinic/_winapi.c.h"
265264

@@ -530,7 +529,7 @@ _winapi_CreateFile_impl(PyObject *module, LPCWSTR file_name,
530529
{
531530
HANDLE handle;
532531

533-
if (PySys_Audit("_winapi.CreateFile", "uIIII",
532+
if (PySys_Audit("_winapi.CreateFile", "ukkkk",
534533
file_name, desired_access, share_mode,
535534
creation_disposition, flags_and_attributes) < 0) {
536535
return INVALID_HANDLE_VALUE;
@@ -777,7 +776,7 @@ _winapi_CreateMutexW_impl(PyObject *module,
777776
/*[clinic input]
778777
_winapi.CreateNamedPipe -> HANDLE
779778
780-
name: LPCTSTR
779+
name: LPCWSTR
781780
open_mode: DWORD
782781
pipe_mode: DWORD
783782
max_instances: DWORD
@@ -789,25 +788,25 @@ _winapi.CreateNamedPipe -> HANDLE
789788
[clinic start generated code]*/
790789

791790
static HANDLE
792-
_winapi_CreateNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD open_mode,
791+
_winapi_CreateNamedPipe_impl(PyObject *module, LPCWSTR name, DWORD open_mode,
793792
DWORD pipe_mode, DWORD max_instances,
794793
DWORD out_buffer_size, DWORD in_buffer_size,
795794
DWORD default_timeout,
796795
LPSECURITY_ATTRIBUTES security_attributes)
797-
/*[clinic end generated code: output=80f8c07346a94fbc input=5a73530b84d8bc37]*/
796+
/*[clinic end generated code: output=7d6fde93227680ba input=5bd4e4a55639ee02]*/
798797
{
799798
HANDLE handle;
800799

801-
if (PySys_Audit("_winapi.CreateNamedPipe", "uII",
800+
if (PySys_Audit("_winapi.CreateNamedPipe", "ukk",
802801
name, open_mode, pipe_mode) < 0) {
803802
return INVALID_HANDLE_VALUE;
804803
}
805804

806805
Py_BEGIN_ALLOW_THREADS
807-
handle = CreateNamedPipe(name, open_mode, pipe_mode,
808-
max_instances, out_buffer_size,
809-
in_buffer_size, default_timeout,
810-
security_attributes);
806+
handle = CreateNamedPipeW(name, open_mode, pipe_mode,
807+
max_instances, out_buffer_size,
808+
in_buffer_size, default_timeout,
809+
security_attributes);
811810
Py_END_ALLOW_THREADS
812811

813812
if (handle == INVALID_HANDLE_VALUE)
@@ -1790,7 +1789,7 @@ _winapi_OpenEventW_impl(PyObject *module, DWORD desired_access,
17901789
{
17911790
HANDLE handle;
17921791

1793-
if (PySys_Audit("_winapi.OpenEventW", "Iu", desired_access, name) < 0) {
1792+
if (PySys_Audit("_winapi.OpenEventW", "ku", desired_access, name) < 0) {
17941793
return INVALID_HANDLE_VALUE;
17951794
}
17961795

@@ -1821,7 +1820,7 @@ _winapi_OpenMutexW_impl(PyObject *module, DWORD desired_access,
18211820
{
18221821
HANDLE handle;
18231822

1824-
if (PySys_Audit("_winapi.OpenMutexW", "Iu", desired_access, name) < 0) {
1823+
if (PySys_Audit("_winapi.OpenMutexW", "ku", desired_access, name) < 0) {
18251824
return INVALID_HANDLE_VALUE;
18261825
}
18271826

@@ -1882,7 +1881,7 @@ _winapi_OpenProcess_impl(PyObject *module, DWORD desired_access,
18821881
{
18831882
HANDLE handle;
18841883

1885-
if (PySys_Audit("_winapi.OpenProcess", "II",
1884+
if (PySys_Audit("_winapi.OpenProcess", "kk",
18861885
process_id, desired_access) < 0) {
18871886
return INVALID_HANDLE_VALUE;
18881887
}
@@ -2236,19 +2235,19 @@ _winapi_VirtualQuerySize_impl(PyObject *module, LPCVOID address)
22362235
/*[clinic input]
22372236
_winapi.WaitNamedPipe
22382237
2239-
name: LPCTSTR
2238+
name: LPCWSTR
22402239
timeout: DWORD
22412240
/
22422241
[clinic start generated code]*/
22432242

22442243
static PyObject *
2245-
_winapi_WaitNamedPipe_impl(PyObject *module, LPCTSTR name, DWORD timeout)
2246-
/*[clinic end generated code: output=c2866f4439b1fe38 input=36fc781291b1862c]*/
2244+
_winapi_WaitNamedPipe_impl(PyObject *module, LPCWSTR name, DWORD timeout)
2245+
/*[clinic end generated code: output=e161e2e630b3e9c2 input=099a4746544488fa]*/
22472246
{
22482247
BOOL success;
22492248

22502249
Py_BEGIN_ALLOW_THREADS
2251-
success = WaitNamedPipe(name, timeout);
2250+
success = WaitNamedPipeW(name, timeout);
22522251
Py_END_ALLOW_THREADS
22532252

22542253
if (!success)
@@ -2917,7 +2916,7 @@ _winapi_CopyFile2_impl(PyObject *module, LPCWSTR existing_file_name,
29172916
HRESULT hr;
29182917
COPYFILE2_EXTENDED_PARAMETERS params = { sizeof(COPYFILE2_EXTENDED_PARAMETERS) };
29192918

2920-
if (PySys_Audit("_winapi.CopyFile2", "uuI",
2919+
if (PySys_Audit("_winapi.CopyFile2", "uuk",
29212920
existing_file_name, new_file_name, flags) < 0) {
29222921
return NULL;
29232922
}

Modules/clinic/_winapi.c.h

Lines changed: 15 addi 3CE2 tions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
0