summaryrefslogtreecommitdiffstats
path: root/Modules/getpath.c
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2023-12-13 23:41:43 (GMT)
committerGitHub <noreply@github.com>2023-12-13 23:41:43 (GMT)
commitfddc829236d7b29a522a2160e57b2d7ca23b9b95 (patch)
treeaaad0e053b6b2df28cbb56ce58138ffef6f6c41e /Modules/getpath.c
parent41c18aacc7a6082fbd9b08697c4d6180a9b62265 (diff)
downloadcpython-fddc829236d7b29a522a2160e57b2d7ca23b9b95.zip
cpython-fddc829236d7b29a522a2160e57b2d7ca23b9b95.tar.gz
cpython-fddc829236d7b29a522a2160e57b2d7ca23b9b95.tar.bz2
gh-86179: Implement realpath() on Windows for getpath.py calculations (GH-113033)
Diffstat (limited to 'Modules/getpath.c')
-rw-r--r--Modules/getpath.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/Modules/getpath.c b/Modules/getpath.c
index 6c1078b..422056b 100644
--- a/Modules/getpath.c
+++ b/Modules/getpath.c
@@ -502,6 +502,45 @@ done:
PyMem_Free((void *)path);
PyMem_Free((void *)narrow);
return r;
+#elif defined(MS_WINDOWS)
+ HANDLE hFile;
+ wchar_t resolved[MAXPATHLEN+1];
+ int len = 0, err;
+ PyObject *result;
+
+ wchar_t *path = PyUnicode_AsWideCharString(pathobj, NULL);
+ if (!path) {
+ return NULL;
+ }
+
+ Py_BEGIN_ALLOW_THREADS
+ hFile = CreateFileW(path, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (hFile != INVALID_HANDLE_VALUE) {
+ len = GetFinalPathNameByHandleW(hFile, resolved, MAXPATHLEN, VOLUME_NAME_DOS);
+ err = len ? 0 : GetLastError();
+ CloseHandle(hFile);
+ } else {
+ err = GetLastError();
+ }
+ Py_END_ALLOW_THREADS
+
+ if (err) {
+ PyErr_SetFromWindowsErr(err);
+ result = NULL;
+ } else if (len <= MAXPATHLEN) {
+ const wchar_t *p = resolved;
+ if (0 == wcsncmp(p, L"\\\\?\\", 4)) {
+ if (GetFileAttributesW(&p[4]) != INVALID_FILE_ATTRIBUTES) {
+ p += 4;
+ len -= 4;
+ }
+ }
+ result = PyUnicode_FromWideChar(p, len);
+ } else {
+ result = Py_NewRef(pathobj);
+ }
+ PyMem_Free(path);
+ return result;
#endif
return Py_NewRef(pathobj);