[PATCH v59 0/1] MR10192: kernelbase: Handle extended length path prefix in GetLongPathNameW
``` Support the \\?\ prefix by skipping it during path resolution while preserving it in the output. Added specific handling for extended UNC paths (\\?\UNC\) to mirror standard UNC behavior, ensuring these paths are treated as network shares and not local devices. Some paths that use the extended length path were filtered out as UNC paths - but not all of them are UNC. There can be UNC path that use extended length path but not all extended length paths are UNC paths. ``` Signed-off-by: Vishnunithyasoundhar S svishnunithyasoundhar@gmail.com -- v59: kernelbase: Handle extended length path prefix in GetLongPathNameW https://gitlab.winehq.org/wine/wine/-/merge_requests/10192
From: Vishnunithyasoundhar S <svishnunithyasoundhar@gmail.com> Support the \\?\ prefix by skipping it during path resolution while preserving it in the output. Added specific handling for extended UNC paths (\\?\UNC\) to mirror standard UNC behavior, ensuring these paths are treated as network shares and not local devices. Some paths that use the extended length path were filtered out as UNC paths - but not all of them are UNC. There can be UNC path that use extended length path but not all extended length paths are UNC paths. Added test. Signed-off-by: Vishnunithyasoundhar S <svishnunithyasoundhar@gmail.com> --- dlls/kernel32/tests/path.c | 17 ++++++++++++++--- dlls/kernelbase/file.c | 26 +++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c index aa1833504d8..1b60de6d692 100644 --- a/dlls/kernel32/tests/path.c +++ b/dlls/kernel32/tests/path.c @@ -1255,6 +1255,8 @@ static void test_GetLongPathNameW(void) static const WCHAR prefix[] = { '\\','\\','?','\\', 0}; static const WCHAR backslash[] = { '\\', 0}; static const WCHAR letterX[] = { 'X', 0}; + WCHAR shortpath2[MAX_PATH]; + WCHAR longpath[MAX_PATH]; SetLastError(0xdeadbeef); length = GetLongPathNameW(NULL,NULL,0); @@ -1298,12 +1300,9 @@ static void test_GetLongPathNameW(void) /* With prefix */ SetLastError(0xdeadbeef); length = GetLongPathNameW(shortpath, NULL, 0); - todo_wine - { ok(length == 0, "Expected 0, got %ld\n", length); ok(GetLastError() == ERROR_FILE_NOT_FOUND, "Expected ERROR_PATH_NOT_FOUND, got %ld\n", GetLastError()); - } file = CreateFileW(shortpath, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); @@ -1327,6 +1326,18 @@ static void test_GetLongPathNameW(void) length = GetLongPathNameW(shortpath, NULL, 0); ok(length == expanded, "Expected %ld, got %ld\n", expanded, length); + /* Test that extended prefix is preserved in output when converting from + * short to long path */ + shortpath2[0] = 0; + length = GetShortPathNameW(dirpath, shortpath2, ARRAY_SIZE(shortpath2)); + ok(length > 0, "GetShortPathNameW failed: %lu\n", GetLastError()); + ok(lstrcmpiW(dirpath, shortpath2) != 0, "short path name isn't created, got %s\n", debugstr_w(shortpath2)); + + SetLastError(0xdeadbeef); + length = GetLongPathNameW(shortpath2, longpath, ARRAY_SIZE(longpath)); + ok(length > 0, "GetLongPathNameW failed: %lu\n", GetLastError()); + ok(lstrcmpiW(longpath, dirpath) == 0, "Expected path: %s, got: %s\n", wine_dbgstr_w(dirpath), wine_dbgstr_w(longpath)); + /* NULL buffer with length crashes on Windows */ if (0) GetLongPathNameW(shortpath, NULL, 20); diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 83977a2c40b..89bfe2160bd 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -2116,7 +2116,31 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetLongPathNameW( LPCWSTR shortpath, LPWSTR longp return 0; } - if (shortpath[0] == '\\' && shortpath[1] == '\\') + /* Handle \\?\ prefix (Extended Length Path) */ + if (lstrlenW(shortpath) >= 4 && shortpath[0] == '\\' && shortpath[1] == '\\' + && shortpath[2] == '?' && shortpath[3] == '\\') + { + if (wcsnicmp(shortpath + 4, L"UNC\\", 4) == 0) + { + FIXME("UNC Extended pathname %s\n", debugstr_w(shortpath)); + tmplen = lstrlenW(shortpath); + if (tmplen < longlen) + { + if (longpath != shortpath) lstrcpyW(longpath, shortpath); + return tmplen; + } + return tmplen + 1; + } + else if (((shortpath[4] | 0x20) >= 'a' && (shortpath[4] | 0x20) <= 'z') + && shortpath[5] == ':') + { + lstrcpynW(tmplongpath, shortpath, 7); + lp = 6; + sp = 6; + } + } + + if (sp == 0 && shortpath[0] == '\\' && shortpath[1] == '\\') { FIXME( "UNC pathname %s\n", debugstr_w(shortpath) ); tmplen = lstrlenW( shortpath ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10192
On Mon Apr 13 08:24:25 2026 +0000, Akihiro Sagawa wrote:
I'm a bit concerned about allocating 32KB on the stack, as that's quite large. Since adding proper length validation would make this patch more complex, I understand why you avoided it here. Would you leave the buffer size unchanged in this patch and create a follow-up patch that allocates the 32KB temporary buffer on the heap instead? That way we can avoid the stack usage issue without expanding the scope of this merge request. Noted. I have reverted it. I will push a follow up patch the way you mentioned
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_135935
On Mon Apr 13 07:12:36 2026 +0000, Vishnunithyasoundhar S wrote:
changed this line in [version 59 of the diff](/wine/wine/-/merge_requests/10192/diffs?diff_id=259903&start_sha=9e03caab2ecfe3baf857dbe0b52f957cff1b68a2#6c845445f68f8d3b54ba3798c9bb9e781b28b2ec_2134_2134) I have changed it to a direct comparison.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_135936
This merge request was approved by Akihiro Sagawa. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192
@sgwaki Hi just a clarification. After its approved, should I keep rebasing it ? Or should I just leave it as it is and the one who is merging would rebase it? I am trying to understand the general practice. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136232
On Wed Apr 15 11:53:21 2026 +0000, Vishnunithyasoundhar S wrote:
@sgwaki Hi just a clarification. After its approved, should I keep rebasing it ? Or should I just leave it as it is and the one who is merging would rebase it? I am trying to understand the general practice. Hi @svishnunithyasoundhar , whether it's approved or not, you don't need to rebase that often. In my case, unless there are conflicts, rebasing about once a week tends to be enough. The maintainer will rebase it when merging.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136280
On Wed Apr 15 16:45:48 2026 +0000, Akihiro Sagawa wrote:
Hi @svishnunithyasoundhar , whether it's approved or not, you don't need to rebase that often. In my case, unless there are conflicts, rebasing about once a week tends to be enough. The maintainer will rebase it when merging. I see. Thanks for the clarification
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136319
On Wed Apr 15 21:37:19 2026 +0000, Vishnunithyasoundhar S wrote:
I see. Thanks for the clarification I don't think there's any need to rebase ever unless there are conflicts?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136370
On Thu Apr 16 11:10:04 2026 +0000, Elizabeth Figura wrote:
I don't think there's any need to rebase ever unless there are conflicts? I see. Understood thanks
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136475
On Thu Apr 16 11:10:04 2026 +0000, Vishnunithyasoundhar S wrote:
I see. Understood thanks Ah, sorry -- I misunderstood that I should rebase once a week.
What I meant to say is the following part from the article at https://gitlab.winehq.org/wine/wine/-/wikis/Submitting-Patches#managing-your... :
If your merge request remains in the queue for several weeks without being committed and without feedback, improving it (perhaps by adding more tests) and resubmitting it (after rebasing to the current tip) may help.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10192#note_136477
participants (4)
-
Akihiro Sagawa (@sgwaki) -
Elizabeth Figura (@zfigura) -
Vishnunithyasoundhar S -
Vishnunithyasoundhar S (@svishnunithyasoundhar)