From: Jacek Caban Subject: [PATCH 1/2] ntdll: Fix handling \\.\CON path in RtlDosPathNameToNtPathName. Message-Id: <126a9774-9dca-841b-7069-cbd241d95aec@codeweavers.com> Date: Thu, 30 Dec 2021 15:49:38 +0100 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=32183 Signed-off-by: Jacek Caban --- It seems to be a special case, like in RtlIsDosDeviceName_U. dlls/ntdll/path.c | 4 +++- dlls/ntdll/tests/path.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c index 47196067cd4..cccd000a6c6 100644 --- a/dlls/ntdll/path.c +++ b/dlls/ntdll/path.c @@ -197,7 +197,8 @@ NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, U return STATUS_OBJECT_NAME_INVALID; if (!memcmp(dos_path, global_prefix, sizeof(global_prefix)) || - (!memcmp(dos_path, global_prefix2, sizeof(global_prefix2)) && dos_path[4])) + (!memcmp(dos_path, global_prefix2, sizeof(global_prefix2)) && dos_path[4]) || + !wcsicmp( dos_path, L"\\\\.\\CON" )) { ntpath->Length = wcslen(dos_path) * sizeof(WCHAR); ntpath->MaximumLength = ntpath->Length + sizeof(WCHAR); @@ -205,6 +206,7 @@ NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, U if (!ntpath->Buffer) return STATUS_NO_MEMORY; memcpy( ntpath->Buffer, dos_path, ntpath->MaximumLength ); ntpath->Buffer[1] = '?'; /* change \\?\ to \??\ */ + ntpath->Buffer[2] = '?'; if (file_part) { if ((ptr = wcsrchr( ntpath->Buffer, '\\' )) && ptr[1]) *file_part = ptr + 1; diff --git a/dlls/ntdll/tests/path.c b/dlls/ntdll/tests/path.c index dba889fdec7..e9cb0199876 100644 --- a/dlls/ntdll/tests/path.c +++ b/dlls/ntdll/tests/path.c @@ -120,6 +120,8 @@ static void test_RtlIsDosDeviceName_U(void) { "\\\\.\\CON", 8, 6, TRUE }, /* fails on win8 */ { "\\\\.\\con", 8, 6, TRUE }, /* fails on win8 */ { "\\\\.\\CON2", 0, 0 }, + { "\\\\.\\CONIN$", 0, 0 }, + { "\\\\.\\CONOUT$",0, 0 }, { "", 0, 0 }, { "\\\\foo\\nul", 0, 0 }, { "c:\\nul:", 6, 6 }, @@ -435,6 +437,7 @@ static void test_RtlDosPathNameToNtPathName_U(void) const WCHAR *nt; int file_offset; /* offset to file part */ const WCHAR *alt_nt; + BOOL may_fail; } tests[] = { @@ -558,6 +561,10 @@ static void test_RtlDosPathNameToNtPathName_U(void) {L"CONOUT$", L"\\??\\CONOUT$", -1, L"\\??\\C:\\windows\\CONOUT$" /* winxp */ }, {L"cOnOuT$", L"\\??\\cOnOuT$", -1, L"\\??\\C:\\windows\\cOnOuT$" /* winxp */ }, {L"CONERR$", L"\\??\\C:\\windows\\CONERR$", 15}, + {L"\\\\.\\foo", L"\\??\\foo", 4}, + {L"\\\\.\\CON", L"\\??\\CON", 4, NULL, TRUE}, /* broken on win7 */ + {L"\\\\.\\CONIN$", L"\\??\\CONIN$", 4}, + {L"\\\\.\\CONOUT$", L"\\??\\CONOUT$", 4}, }; static const WCHAR *error_paths[] = { NULL, L"", L" ", L"C:\\nonexistent\\nul", L"C:\\con\\con" @@ -586,6 +593,11 @@ static void test_RtlDosPathNameToNtPathName_U(void) for (i = 0; i < ARRAY_SIZE(tests); ++i) { ret = pRtlDosPathNameToNtPathName_U(tests[i].dos, &nameW, &file_part, NULL); + if (!ret && tests[i].may_fail) + { + win_skip("skipping broken %s\n", debugstr_w(tests[i].dos)); + continue; + } ok(ret == TRUE, "%s: Got %d.\n", debugstr_w(tests[i].dos), ret); if (pRtlDosPathNameToNtPathName_U_WithStatus)