Mercurial > vim
comparison src/os_win32.c @ 7657:9c5e8254ea6b v7.4.1128
commit https://github.com/vim/vim/commit/203258c3ad2966cc9d08b3805b103333988b30b7
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 17 22:15:16 2016 +0100
patch 7.4.1128
Problem: MS-Windows: delete() does not recognize junctions.
Solution: Add mch_isrealdir() for MS-Windows. Update mch_is_symbolic_link().
(Ken Takata)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 17 Jan 2016 22:30:05 +0100 |
parents | 6fed43c541c8 |
children | 21b0a39d13ed |
comparison
equal
deleted
inserted
replaced
7656:f165065a4300 | 7657:9c5e8254ea6b |
---|---|
3128 | 3128 |
3129 return (f & FILE_ATTRIBUTE_DIRECTORY) != 0; | 3129 return (f & FILE_ATTRIBUTE_DIRECTORY) != 0; |
3130 } | 3130 } |
3131 | 3131 |
3132 /* | 3132 /* |
3133 * return TRUE if "name" is a directory, NOT a symlink to a directory | |
3134 * return FALSE if "name" is not a directory | |
3135 * return FALSE for error | |
3136 */ | |
3137 int | |
3138 mch_isrealdir(char_u *name) | |
3139 { | |
3140 return mch_isdir(name) && !mch_is_symbolic_link(name); | |
3141 } | |
3142 | |
3143 /* | |
3133 * Create directory "name". | 3144 * Create directory "name". |
3134 * Return 0 on success, -1 on error. | 3145 * Return 0 on success, -1 on error. |
3135 */ | 3146 */ |
3136 int | 3147 int |
3137 mch_mkdir(char_u *name) | 3148 mch_mkdir(char_u *name) |
3188 return win32_fileinfo(fname, &info) == FILEINFO_OK | 3199 return win32_fileinfo(fname, &info) == FILEINFO_OK |
3189 && info.nNumberOfLinks > 1; | 3200 && info.nNumberOfLinks > 1; |
3190 } | 3201 } |
3191 | 3202 |
3192 /* | 3203 /* |
3193 * Return TRUE if file "fname" is a symbolic link. | 3204 * Return TRUE if "name" is a symbolic link (or a junction). |
3194 */ | 3205 */ |
3195 int | 3206 int |
3196 mch_is_symbolic_link(char_u *fname) | 3207 mch_is_symbolic_link(char_u *name) |
3197 { | 3208 { |
3198 HANDLE hFind; | 3209 HANDLE hFind; |
3199 int res = FALSE; | 3210 int res = FALSE; |
3200 WIN32_FIND_DATAA findDataA; | 3211 WIN32_FIND_DATAA findDataA; |
3201 DWORD fileFlags = 0, reparseTag = 0; | 3212 DWORD fileFlags = 0, reparseTag = 0; |
3202 #ifdef FEAT_MBYTE | 3213 #ifdef FEAT_MBYTE |
3203 WCHAR *wn = NULL; | 3214 WCHAR *wn = NULL; |
3204 WIN32_FIND_DATAW findDataW; | 3215 WIN32_FIND_DATAW findDataW; |
3205 | 3216 |
3206 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 3217 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) |
3207 wn = enc_to_utf16(fname, NULL); | 3218 wn = enc_to_utf16(name, NULL); |
3208 if (wn != NULL) | 3219 if (wn != NULL) |
3209 { | 3220 { |
3210 hFind = FindFirstFileW(wn, &findDataW); | 3221 hFind = FindFirstFileW(wn, &findDataW); |
3211 vim_free(wn); | 3222 vim_free(wn); |
3212 if (hFind == INVALID_HANDLE_VALUE | 3223 if (hFind == INVALID_HANDLE_VALUE |
3213 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) | 3224 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) |
3214 { | 3225 { |
3215 /* Retry with non-wide function (for Windows 98). */ | 3226 /* Retry with non-wide function (for Windows 98). */ |
3216 hFind = FindFirstFile(fname, &findDataA); | 3227 hFind = FindFirstFile(name, &findDataA); |
3217 if (hFind != INVALID_HANDLE_VALUE) | 3228 if (hFind != INVALID_HANDLE_VALUE) |
3218 { | 3229 { |
3219 fileFlags = findDataA.dwFileAttributes; | 3230 fileFlags = findDataA.dwFileAttributes; |
3220 reparseTag = findDataA.dwReserved0; | 3231 reparseTag = findDataA.dwReserved0; |
3221 } | 3232 } |
3227 } | 3238 } |
3228 } | 3239 } |
3229 else | 3240 else |
3230 #endif | 3241 #endif |
3231 { | 3242 { |
3232 hFind = FindFirstFile(fname, &findDataA); | 3243 hFind = FindFirstFile(name, &findDataA); |
3233 if (hFind != INVALID_HANDLE_VALUE) | 3244 if (hFind != INVALID_HANDLE_VALUE) |
3234 { | 3245 { |
3235 fileFlags = findDataA.dwFileAttributes; | 3246 fileFlags = findDataA.dwFileAttributes; |
3236 reparseTag = findDataA.dwReserved0; | 3247 reparseTag = findDataA.dwReserved0; |
3237 } | 3248 } |
3239 | 3250 |
3240 if (hFind != INVALID_HANDLE_VALUE) | 3251 if (hFind != INVALID_HANDLE_VALUE) |
3241 FindClose(hFind); | 3252 FindClose(hFind); |
3242 | 3253 |
3243 if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT) | 3254 if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT) |
3244 && reparseTag == IO_REPARSE_TAG_SYMLINK) | 3255 && (reparseTag == IO_REPARSE_TAG_SYMLINK |
3256 || reparseTag == IO_REPARSE_TAG_MOUNT_POINT)) | |
3245 res = TRUE; | 3257 res = TRUE; |
3246 | 3258 |
3247 return res; | 3259 return res; |
3248 } | 3260 } |
3249 | 3261 |
5837 #endif | 5849 #endif |
5838 } | 5850 } |
5839 | 5851 |
5840 | 5852 |
5841 /* | 5853 /* |
5842 * this version of remove is not scared by a readonly (backup) file | 5854 * This version of remove is not scared by a readonly (backup) file. |
5855 * This can also remove a symbolic link like Unix. | |
5843 * Return 0 for success, -1 for failure. | 5856 * Return 0 for success, -1 for failure. |
5844 */ | 5857 */ |
5845 int | 5858 int |
5846 mch_remove(char_u *name) | 5859 mch_remove(char_u *name) |
5847 { | 5860 { |
5848 #ifdef FEAT_MBYTE | 5861 #ifdef FEAT_MBYTE |
5849 WCHAR *wn = NULL; | 5862 WCHAR *wn = NULL; |
5850 int n; | 5863 int n; |
5851 #endif | 5864 #endif |
5865 | |
5866 /* | |
5867 * On Windows, deleting a directory's symbolic link is done by | |
5868 * RemoveDirectory(): mch_rmdir. It seems unnatural, but it is fact. | |
5869 */ | |
5870 if (mch_isdir(name) && mch_is_symbolic_link(name)) | |
5871 return mch_rmdir(name); | |
5852 | 5872 |
5853 win32_setattrs(name, FILE_ATTRIBUTE_NORMAL); | 5873 win32_setattrs(name, FILE_ATTRIBUTE_NORMAL); |
5854 | 5874 |
5855 #ifdef FEAT_MBYTE | 5875 #ifdef FEAT_MBYTE |
5856 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) | 5876 if (enc_codepage >= 0 && (int)GetACP() != enc_codepage) |