summaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-08-26 08:11:33 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-08-26 08:11:33 +0000
commit8e6259e0d91f83439802f0d0fa1f4c56c2999f96 (patch)
treec143768b4687fd92580aabd1bc42253108f85983 /win32
parentdd67521bd1a1c98b2591f2a5b8bca32bc1ff1705 (diff)
win32.c: find by final path
* win32/win32.c (open_dir_handle): find by final path name. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51689 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'win32')
-rw-r--r--win32/win32.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/win32/win32.c b/win32/win32.c
index a9598e1a94..157d43e97e 100644
--- a/win32/win32.c
+++ b/win32/win32.c
@@ -1822,6 +1822,21 @@ w32_cmdvector(const WCHAR *cmd, char ***vec, UINT cp, rb_encoding *enc)
// UNIX compatible directory access functions for NT
//
+static DWORD
+get_final_path(HANDLE f, WCHAR *buf, DWORD len, DWORD flag)
+{
+ typedef DWORD (WINAPI *get_final_path_func)(HANDLE, WCHAR*, DWORD, DWORD);
+ static get_final_path_func func = (get_final_path_func)-1;
+
+ if (func == (get_final_path_func)-1) {
+ func = (get_final_path_func)
+ get_proc_address("kernel32", "GetFinalPathNameByHandleW", NULL);
+ }
+
+ if (!func) return 0;
+ return func(f, buf, len, flag);
+}
+
//
// The idea here is to read all the directory names into a string table
// (separated by nulls) and when one of the other dir functions is called
@@ -1842,6 +1857,7 @@ open_dir_handle(const WCHAR *filename, WIN32_FIND_DATAW *fd)
{
HANDLE fh;
static const WCHAR wildcard[] = L"\\*";
+ WCHAR fullname[MAX_PATH];
WCHAR *scanname;
WCHAR *p;
int len;
@@ -1850,7 +1866,17 @@ open_dir_handle(const WCHAR *filename, WIN32_FIND_DATAW *fd)
//
// Create the search pattern
//
- len = lstrlenW(filename);
+
+ fh = CreateFileW(filename, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh != INVALID_HANDLE_VALUE) {
+ len = get_final_path(fh, fullname, numberof(fullname), 0);
+ CloseHandle(fh);
+ filename = fullname;
+ }
+ else {
+ len = lstrlenW(filename);
+ }
scanname = ALLOCV_N(WCHAR, v, len + numberof(wildcard));
lstrcpyW(scanname, filename);
p = CharPrevW(scanname, scanname + len);
@@ -5325,22 +5351,13 @@ winnt_stat(const WCHAR *path, struct stati64 *st)
{
HANDLE f;
- typedef DWORD (WINAPI *get_final_path_func)(HANDLE, WCHAR*, DWORD, DWORD);
- static get_final_path_func get_final_path = (get_final_path_func)-1;
-
- if (get_final_path == (get_final_path_func)-1) {
- get_final_path = (get_final_path_func)
- get_proc_address("kernel32", "GetFinalPathNameByHandleW", NULL);
- }
-
memset(st, 0, sizeof(*st));
f = CreateFileW(path, 0, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (f != INVALID_HANDLE_VALUE) {
WCHAR finalname[MAX_PATH];
const DWORD attr = stati64_handle(f, st);
- const DWORD len = get_final_path ?
- get_final_path(f, finalname, numberof(finalname), 0) : 0;
+ const DWORD len = get_final_path(f, finalname, numberof(finalname), 0);
CloseHandle(f);
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
if (check_valid_dir(path)) return -1;