diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fileio.c | 15 | ||||
-rw-r--r-- | src/if_cscope.c | 15 | ||||
-rw-r--r-- | src/os_win32.c | 40 | ||||
-rw-r--r-- | src/proto/os_win32.pro | 1 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim.h | 6 |
6 files changed, 59 insertions, 20 deletions
diff --git a/src/fileio.c b/src/fileio.c index 62adf72dc..11b5045a4 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -6555,6 +6555,21 @@ vim_rename(from, to) use_tmp_file = TRUE; } #endif +#ifdef WIN3264 + { + BY_HANDLE_FILE_INFORMATION info1, info2; + + /* It's possible for the source and destination to be the same file. + * In that case go through a temp file name. This makes rename("foo", + * "./foo") a no-op (in a complicated way). */ + if (win32_fileinfo(from, &info1) == FILEINFO_OK + && win32_fileinfo(to, &info2) == FILEINFO_OK + && info1.dwVolumeSerialNumber == info2.dwVolumeSerialNumber + && info1.nFileIndexHigh == info2.nFileIndexHigh + && info1.nFileIndexLow == info2.nFileIndexLow) + use_tmp_file = TRUE; + } +#endif #if defined(UNIX) || defined(CASE_INSENSITIVE_FILENAME) if (use_tmp_file) diff --git a/src/if_cscope.c b/src/if_cscope.c index 82c517371..a96622684 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -1412,17 +1412,15 @@ cs_insert_filelist(fname, ppath, flags, sb) { short i, j; #ifndef UNIX - HANDLE hFile; BY_HANDLE_FILE_INFORMATION bhfi; - vim_memset(&bhfi, 0, sizeof(bhfi)); /* On windows 9x GetFileInformationByHandle doesn't work, so skip it */ if (!mch_windows95()) { - hFile = CreateFile(fname, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile == INVALID_HANDLE_VALUE) + switch (win32_fileinfo(fname, &bhfi)) { + case FILEINFO_ENC_FAIL: /* enc_to_utf16() failed */ + case FILEINFO_READ_FAIL: /* CreateFile() failed */ if (p_csverbose) { char *cant_msg = _("E625: cannot open cscope database: %s"); @@ -1438,15 +1436,12 @@ cs_insert_filelist(fname, ppath, flags, sb) (void)EMSG2(cant_msg, fname); } return -1; - } - if (!GetFileInformationByHandle(hFile, &bhfi)) - { - CloseHandle(hFile); + + case FILEINFO_INFO_FAIL: /* GetFileInformationByHandle() failed */ if (p_csverbose) (void)EMSG(_("E626: cannot get cscope database information")); return -1; } - CloseHandle(hFile); } #endif diff --git a/src/os_win32.c b/src/os_win32.c index 90664e626..bf51d2473 100644 --- a/src/os_win32.c +++ b/src/os_win32.c @@ -2645,25 +2645,44 @@ mch_isdir(char_u *name) int mch_is_linked(char_u *fname) { + BY_HANDLE_FILE_INFORMATION info; + + return win32_fileinfo(fname, &info) == FILEINFO_OK + && info.nNumberOfLinks > 1; +} + +/* + * Get the by-handle-file-information for "fname". + * Returns FILEINFO_OK when OK. + * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed. + * Returns FILEINFO_READ_FAIL when CreateFile() failed. + * Returns FILEINFO_INFO_FAIL when GetFileInformationByHandle() failed. + */ + int +win32_fileinfo(char_u *fname, BY_HANDLE_FILE_INFORMATION *info) +{ HANDLE hFile; - int res = 0; - BY_HANDLE_FILE_INFORMATION inf; + int res = FILEINFO_READ_FAIL; #ifdef FEAT_MBYTE WCHAR *wn = NULL; if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) + { wn = enc_to_utf16(fname, NULL); + if (wn == NULL) + res = FILEINFO_ENC_FAIL; + } if (wn != NULL) { hFile = CreateFileW(wn, /* file name */ GENERIC_READ, /* access mode */ - 0, /* share mode */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */ NULL, /* security descriptor */ OPEN_EXISTING, /* creation disposition */ - 0, /* file attributes */ + FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */ NULL); /* handle to template file */ if (hFile == INVALID_HANDLE_VALUE - && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) + && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) { /* Retry with non-wide function (for Windows 98). */ vim_free(wn); @@ -2674,17 +2693,18 @@ mch_is_linked(char_u *fname) #endif hFile = CreateFile(fname, /* file name */ GENERIC_READ, /* access mode */ - 0, /* share mode */ + FILE_SHARE_READ | FILE_SHARE_WRITE, /* share mode */ NULL, /* security descriptor */ OPEN_EXISTING, /* creation disposition */ - 0, /* file attributes */ + FILE_FLAG_BACKUP_SEMANTICS, /* file attributes */ NULL); /* handle to template file */ if (hFile != INVALID_HANDLE_VALUE) { - if (GetFileInformationByHandle(hFile, &inf) != 0 - && inf.nNumberOfLinks > 1) - res = 1; + if (GetFileInformationByHandle(hFile, info) != 0) + res = FILEINFO_OK; + else + res = FILEINFO_INFO_FAIL; CloseHandle(hFile); } diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro index 31aa269ae..a3f5b3ecd 100644 --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -21,6 +21,7 @@ int mch_setperm __ARGS((char_u *name, long perm)); void mch_hide __ARGS((char_u *name)); int mch_isdir __ARGS((char_u *name)); int mch_is_linked __ARGS((char_u *fname)); +int win32_fileinfo __ARGS((char_u *name, BY_HANDLE_FILE_INFORMATION *lpFileInfo)); int mch_writable __ARGS((char_u *name)); int mch_can_exe __ARGS((char_u *name)); int mch_nodetype __ARGS((char_u *name)); diff --git a/src/version.c b/src/version.c index b99456a53..d4edf67ce 100644 --- a/src/version.c +++ b/src/version.c @@ -715,6 +715,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 172, +/**/ 171, /**/ 170, @@ -2217,4 +2217,10 @@ typedef int VimClipboard; /* This is required for the prototypes. */ #define KEYLEN_PART_MAP -2 /* keylen value for incomplete mapping */ #define KEYLEN_REMOVED 9999 /* keylen value for removed sequence */ +/* Return values from win32_fileinfo(). */ +#define FILEINFO_OK 0 +#define FILEINFO_ENC_FAIL 1 /* enc_to_utf16() failed */ +#define FILEINFO_READ_FAIL 2 /* CreateFile() failed */ +#define FILEINFO_INFO_FAIL 3 /* GetFileInformationByHandle() failed */ + #endif /* VIM__H */ |