Created
November 22, 2011 18:59
-
-
Save igorzi/1386547 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 33604b4f22879e3617a358ef944d5442c241b6bc Mon Sep 17 00:00:00 2001 | |
From: Igor Zinkovsky <igorzi@microsoft.com> | |
Date: Tue, 22 Nov 2011 00:38:29 -0800 | |
Subject: [PATCH] windows: enables uv_fs_open and uv_fs_stat to work with long paths | |
--- | |
src/win/fs.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- | |
1 files changed, 49 insertions(+), 4 deletions(-) | |
diff --git a/src/win/fs.c b/src/win/fs.c | |
index c6d86b0..da089ca 100644 | |
--- a/src/win/fs.c | |
+++ b/src/win/fs.c | |
@@ -492,7 +492,12 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) { | |
void fs__stat(uv_fs_t* req, const wchar_t* path) { | |
int result; | |
- result = _wstati64(path, &req->stat); | |
+ fs__open(req, path, _O_RDONLY, 0); | |
+ if (req->result == -1) { | |
+ return; | |
+ } | |
+ | |
+ result = _fstati64(req->result, &req->stat); | |
if (result == -1) { | |
req->ptr = NULL; | |
} else { | |
@@ -500,6 +505,8 @@ void fs__stat(uv_fs_t* req, const wchar_t* path) { | |
} | |
SET_REQ_RESULT(req, result); | |
+ | |
+ _close(req->result); | |
} | |
@@ -905,10 +912,47 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) { | |
int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, | |
int mode, uv_fs_cb cb) { | |
wchar_t* pathw; | |
- int size; | |
+ const wchar_t lfs_ext_len_prefix[] = L"\\\\?\\"; | |
+ const wchar_t unc_ext_len_prefix[] = L"\\\\?\\UNC\\"; | |
+ int size, offset = 0; | |
+ int convert_lfs_to_ext_len = 0, convert_unc_to_ext_len = 0; | |
+ | |
+ size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(wchar_t); | |
+ | |
+ if (size >= 3) { | |
+ if (isalpha(path[0]) && path[1] == ':' && path[2] == '\\') { | |
+ /* | |
+ * path is local filesystem path, which needs to be converted | |
+ * to long UNC path. | |
+ */ | |
+ convert_lfs_to_ext_len = 1; | |
+ offset = COUNTOF(lfs_ext_len_prefix); | |
+ } else if (memcmp(path, "\\\\", 2) == 0 && | |
+ (size < 4 || memcmp(path + 2, "?\\", 2) != 0)) { | |
+ /* | |
+ * path is network UNC path, which needs to be converted | |
+ * to long UNC path. | |
+ */ | |
+ convert_unc_to_ext_len = 1; | |
+ offset = COUNTOF(unc_ext_len_prefix); | |
+ } | |
+ } | |
- /* Convert to UTF16. */ | |
- UTF8_TO_UTF16(path, pathw); | |
+ pathw = (wchar_t*)malloc(size + offset); | |
+ if (!pathw) { | |
+ uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); | |
+ } | |
+ | |
+ if (!uv_utf8_to_utf16(path, pathw + offset, size / sizeof(wchar_t))) { | |
+ uv__set_sys_error(loop, GetLastError()); | |
+ return -1; | |
+ } | |
+ | |
+ if (convert_lfs_to_ext_len) { | |
+ memcpy(pathw, lfs_ext_len_prefix, sizeof(lfs_ext_len_prefix)); | |
+ } else if (convert_unc_to_ext_len) { | |
+ memcpy(pathw, unc_ext_len_prefix, sizeof(unc_ext_len_prefix)); | |
+ } | |
if (cb) { | |
uv_fs_req_init_async(loop, req, UV_FS_OPEN, path, pathw, cb); | |
@@ -1517,3 +1561,4 @@ void uv_fs_req_cleanup(uv_fs_t* req) { | |
req->flags |= UV_FS_CLEANEDUP; | |
} | |
+ | |
-- | |
1.7.4.msysgit.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment