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)