To: vim-dev@vim.org Subject: Patch 6.2.456 (extra) Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.456 (extra) Problem: Win32: Editing a file by its Unicode name (dropping it on Vim or using the file selection dialog) doesn't work. (Yakov Lerner, Alex Jakushev) Solution: Use wide character functions when file names are involved and convert from/to 'encoding' where needed. Files: src/gui_w48.c, src/macros.h, src/memfile.c, src/memline.c, src/os_mswin.c, src/os_win32.c *** ../vim-6.2.455/src/gui_w48.c Tue Mar 30 22:11:17 2004 --- src/gui_w48.c Tue Mar 30 22:09:17 2004 *************** *** 288,295 **** #ifdef FEAT_BEVAL /* balloon-eval WM_NOTIFY_HANDLER */ ! void Handle_WM_Notify __ARGS((HWND hwnd, LPNMHDR pnmh)); ! void TrackUserActivity __ARGS((UINT uMsg)); #endif /* --- 288,295 ---- #ifdef FEAT_BEVAL /* balloon-eval WM_NOTIFY_HANDLER */ ! static void Handle_WM_Notify __ARGS((HWND hwnd, LPNMHDR pnmh)); ! static void TrackUserActivity __ARGS((UINT uMsg)); #endif /* *************** *** 2628,2635 **** char_u *icon) { #ifdef FEAT_MBYTE ! if (title != NULL && has_mbyte ! && (enc_codepage == 0 || enc_codepage != (int)GetACP())) { WCHAR *wbuf; --- 2628,2634 ---- char_u *icon) { #ifdef FEAT_MBYTE ! if (title != NULL && enc_codepage != (int)GetACP()) { WCHAR *wbuf; *************** *** 2715,2734 **** * the \t and \n delimeters with \0. * Returns the converted string in allocated memory. */ static char_u * convert_filter(char_u *s) { char_u *res; unsigned s_len = (unsigned)STRLEN(s); unsigned i; res = alloc(s_len + 3); if (res != NULL) { - STRCPY(res, s); for (i = 0; i < s_len; ++i) ! if ((res[i] == '\t') || (res[i] == '\n')) res[i] = '\0'; /* Add two extra NULs to make sure it's properly terminated. */ res[s_len + 1] = NUL; res[s_len + 2] = NUL; --- 2714,2747 ---- * the \t and \n delimeters with \0. * Returns the converted string in allocated memory. */ + # ifdef FEAT_MBYTE + static WCHAR * + # else static char_u * + # endif convert_filter(char_u *s) { + # ifdef FEAT_MBYTE + WCHAR *res; + # else char_u *res; + # endif unsigned s_len = (unsigned)STRLEN(s); unsigned i; + # ifdef FEAT_MBYTE + res = (WCHAR *)alloc((s_len + 3) * 2); + # else res = alloc(s_len + 3); + # endif if (res != NULL) { for (i = 0; i < s_len; ++i) ! if (s[i] == '\t' || s[i] == '\n') res[i] = '\0'; + else + res[i] = s[i]; + res[s_len] = NUL; /* Add two extra NULs to make sure it's properly terminated. */ res[s_len + 1] = NUL; res[s_len + 2] = NUL; *************** *** 2755,2799 **** char_u *initdir, char_u *filter) { OPENFILENAME fileStruct; ! char_u fileBuf[MAXPATHL], *p; ! char_u dirBuf[MAXPATHL]; if (dflt == NULL) ! fileBuf[0] = '\0'; else { STRNCPY(fileBuf, dflt, MAXPATHL - 1); fileBuf[MAXPATHL - 1] = NUL; } /* Convert the filter to Windows format. */ ! filter = convert_filter(filter); memset(&fileStruct, 0, sizeof(OPENFILENAME)); ! fileStruct.lStructSize = sizeof(OPENFILENAME); ! fileStruct.lpstrFilter = filter; ! fileStruct.lpstrFile = fileBuf; ! fileStruct.nMaxFile = MAXPATHL; fileStruct.lpstrTitle = title; fileStruct.lpstrDefExt = ext; fileStruct.hwndOwner = s_hwnd; /* main Vim window is owner*/ /* has an initial dir been specified? */ if (initdir != NULL && *initdir != NUL) { /* Must have backslashes here, no matter what 'shellslash' says */ - STRNCPY(dirBuf, initdir, MAXPATHL - 1); - dirBuf[MAXPATHL - 1] = NUL; - for (p = dirBuf; *p != NUL; ++p) - { - if (*p == '/') - *p = '\\'; #ifdef FEAT_MBYTE ! if (has_mbyte) ! p += (*mb_ptr2len_check)(p) - 1; ! #endif } ! fileStruct.lpstrInitialDir = dirBuf; } /* --- 2768,2865 ---- char_u *initdir, char_u *filter) { + #ifdef FEAT_MBYTE + /* We always use the wide function. This means enc_to_ucs2() must work, + * otherwise it fails miserably! */ + OPENFILENAMEW fileStruct; + WCHAR fileBuf[MAXPATHL]; + WCHAR *wp; + int i; + WCHAR *titlep = NULL; + WCHAR *extp = NULL; + WCHAR *initdirp = NULL; + WCHAR *filterp; + #else OPENFILENAME fileStruct; ! char_u fileBuf[MAXPATHL]; ! char_u *initdirp = NULL; ! char_u *filterp; ! #endif ! char_u *p; if (dflt == NULL) ! fileBuf[0] = NUL; else { + #ifdef FEAT_MBYTE + wp = enc_to_ucs2(dflt, NULL); + if (wp == NULL) + fileBuf[0] = NUL; + else + { + for (i = 0; wp[i] != NUL && i < MAXPATHL - 1; ++i) + fileBuf[i] = wp[i]; + fileBuf[i] = NUL; + vim_free(wp); + } + #else STRNCPY(fileBuf, dflt, MAXPATHL - 1); fileBuf[MAXPATHL - 1] = NUL; + #endif } /* Convert the filter to Windows format. */ ! filterp = convert_filter(filter); memset(&fileStruct, 0, sizeof(OPENFILENAME)); ! #ifdef OPENFILENAME_SIZE_VERSION_400 ! /* be compatible with Windows NT 4.0 */ ! /* TODO: what when using OPENFILENAMEW??? */ ! fileStruct.lStructSize = sizeof(OPENFILENAME_SIZE_VERSION_400); ! #else ! fileStruct.lStructSize = sizeof(fileStruct); ! #endif ! ! #ifdef FEAT_MBYTE ! if (title != NULL) ! titlep = enc_to_ucs2(title, NULL); ! fileStruct.lpstrTitle = titlep; ! #else fileStruct.lpstrTitle = title; + #endif + + #ifdef FEAT_MBYTE + if (ext != NULL) + extp = enc_to_ucs2(ext, NULL); + fileStruct.lpstrDefExt = extp; + #else fileStruct.lpstrDefExt = ext; + #endif + + fileStruct.lpstrFile = fileBuf; + fileStruct.nMaxFile = MAXPATHL; + fileStruct.lpstrFilter = filterp; fileStruct.hwndOwner = s_hwnd; /* main Vim window is owner*/ /* has an initial dir been specified? */ if (initdir != NULL && *initdir != NUL) { /* Must have backslashes here, no matter what 'shellslash' says */ #ifdef FEAT_MBYTE ! initdirp = enc_to_ucs2(initdir, NULL); ! if (initdirp != NULL) ! { ! for (wp = initdirp; *wp != NUL; ++wp) ! if (*wp == '/') ! *wp = '\\'; } ! #else ! initdirp = vim_strsave(initdir); ! if (initdirp != NULL) ! for (p = initdirp; *p != NUL; ++p) ! if (*p == '/') ! *p = '\\'; ! #endif ! fileStruct.lpstrInitialDir = initdirp; } /* *************** *** 2811,2832 **** #endif if (saving) { if (!GetSaveFileName(&fileStruct)) return NULL; } else { if (!GetOpenFileName(&fileStruct)) return NULL; } ! vim_free(filter); /* Shorten the file name if possible */ mch_dirname(IObuff, IOSIZE); ! p = shorten_fname(fileBuf, IObuff); if (p == NULL) ! p = fileBuf; return vim_strsave(p); } #endif /* FEAT_BROWSE */ --- 2877,2922 ---- #endif if (saving) { + #ifdef FEAT_MBYTE + if (!GetSaveFileNameW(&fileStruct)) + #else if (!GetSaveFileName(&fileStruct)) + #endif return NULL; } else { + #ifdef FEAT_MBYTE + if (!GetOpenFileNameW(&fileStruct)) + #else if (!GetOpenFileName(&fileStruct)) + #endif return NULL; } ! vim_free(filterp); ! vim_free(initdirp); ! #ifdef FEAT_MBYTE ! vim_free(titlep); ! vim_free(extp); ! #endif ! ! #ifdef FEAT_MBYTE ! /* Convert from UCS2 to 'encoding'. */ ! p = ucs2_to_enc(fileBuf, NULL); ! if (p != NULL) /* when out of memory we get garbage... */ ! STRCPY(fileBuf, p); ! vim_free(p); ! #endif ! ! /* Give focus back to main window (when using MDI). */ ! SetFocus(s_hwnd); /* Shorten the file name if possible */ mch_dirname(IObuff, IOSIZE); ! p = shorten_fname((char_u *)fileBuf, IObuff); if (p == NULL) ! p = (char_u *)fileBuf; return vim_strsave(p); } #endif /* FEAT_BROWSE */ *************** *** 2844,2851 **** # define BUFPATHLEN MAXPATHL # define DRAGQVAL 0xFFFF #endif char szFile[BUFPATHLEN]; ! UINT cFiles = DragQueryFile(hDrop, DRAGQVAL, szFile, BUFPATHLEN); UINT i; char_u **fnames; POINT pt; --- 2934,2945 ---- # define BUFPATHLEN MAXPATHL # define DRAGQVAL 0xFFFF #endif + #ifdef FEAT_MBYTE + WCHAR szFile[BUFPATHLEN]; + #else char szFile[BUFPATHLEN]; ! #endif ! UINT cFiles = DragQueryFile(hDrop, DRAGQVAL, NULL, 0); UINT i; char_u **fnames; POINT pt; *************** *** 2866,2873 **** --- 2960,2972 ---- if (fnames != NULL) for (i = 0; i < cFiles; ++i) { + #ifdef FEAT_MBYTE + DragQueryFileW(hDrop, i, szFile, BUFPATHLEN); + fnames[i] = ucs2_to_enc(szFile, NULL); + #else DragQueryFile(hDrop, i, szFile, BUFPATHLEN); fnames[i] = vim_strsave(szFile); + #endif } DragFinish(hDrop); *** ../vim-6.2.455/src/macros.h Sun Jan 25 20:28:03 2004 --- src/macros.h Tue Mar 16 14:54:11 2004 *************** *** 149,155 **** # ifndef WIN32 # define mch_access(n, p) access((n), (p)) # endif ! # define mch_fopen(n, p) fopen((n), (p)) # define mch_fstat(n, p) fstat((n), (p)) # define mch_lstat(n, p) lstat((n), (p)) # ifdef MSWIN /* has it's own mch_stat() function */ --- 149,157 ---- # ifndef WIN32 # define mch_access(n, p) access((n), (p)) # endif ! # if !(defined(FEAT_MBYTE) && defined(WIN3264)) ! # define mch_fopen(n, p) fopen((n), (p)) ! # endif # define mch_fstat(n, p) fstat((n), (p)) # define mch_lstat(n, p) lstat((n), (p)) # ifdef MSWIN /* has it's own mch_stat() function */ *************** *** 177,183 **** */ # define mch_open(n, m, p) open(vms_fixfilename(n), (m), (p)) # else ! # define mch_open(n, m, p) open((n), (m), (p)) # endif #endif --- 179,198 ---- */ # define mch_open(n, m, p) open(vms_fixfilename(n), (m), (p)) # else ! # if !(defined(FEAT_MBYTE) && defined(WIN3264)) ! # define mch_open(n, m, p) open((n), (m), (p)) ! # endif ! # endif ! #endif ! ! /* mch_open_rw(): invoke mch_open() with third argument for user R/W. */ ! #if defined(UNIX) || defined(VMS) /* open in rw------- mode */ ! # define mch_open_rw(n, f) mch_open((n), (f), (mode_t)0600) ! #else ! # if defined(MSDOS) || defined(MSWIN) || defined(OS2) /* open read/write */ ! # define mch_open_rw(n, f) mch_open((n), (f), S_IREAD | S_IWRITE) ! # else ! # define mch_open_rw(n, f) mch_open((n), (f), 0) # endif #endif *** ../vim-6.2.455/src/memfile.c Sun Oct 12 17:25:14 2003 --- src/memfile.c Mon Mar 15 22:28:37 2004 *************** *** 1268,1298 **** } else #endif ! ! /* ! * try to open the file ! */ ! mfp->mf_fd = open( ! #ifdef VMS ! vms_fixfilename(mfp->mf_fname), ! #else ! (char *)mfp->mf_fname, ! #endif ! flags | O_EXTRA #ifdef WIN32 /* Prevent handle inheritance that cause problems with Cscope * (swap file may not be deleted if cscope connection was open after ! * the file) ! */ ! |O_NOINHERIT ! #endif ! #if defined(UNIX) || defined(RISCOS) || defined(VMS) ! , (mode_t)0600 /* open in rw------- mode */ ! #endif ! #if defined(MSDOS) || defined(MSWIN) || defined(__EMX__) ! , S_IREAD | S_IWRITE /* open read/write */ #endif ! ); /* * If the file cannot be opened, use memory only --- 1268,1286 ---- } else #endif ! { ! /* ! * try to open the file ! */ ! flags |= O_EXTRA; #ifdef WIN32 /* Prevent handle inheritance that cause problems with Cscope * (swap file may not be deleted if cscope connection was open after ! * the file) */ ! flags |= O_NOINHERIT; #endif ! mfp->mf_fd = mch_open_rw((char *)mfp->mf_fname, flags); ! } /* * If the file cannot be opened, use memory only *** ../vim-6.2.455/src/memline.c Sun Jan 25 19:45:13 2004 --- src/memline.c Mon Mar 15 22:29:48 2004 *************** *** 3468,3487 **** f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); if (f1 < 0) { ! f1 = open( ! #ifdef VMS ! vms_fixfilename((char *)fname), ! #else ! (char *)fname, ! #endif ! O_RDWR|O_CREAT|O_EXCL|O_EXTRA ! #if defined(UNIX) || defined(VMS) /* open in rw------- mode */ ! , (mode_t)0600 ! #endif ! #if defined(MSDOS) || defined(MSWIN) || defined(OS2) /* open read/write */ ! , S_IREAD | S_IWRITE ! #endif ! ); #if defined(OS2) if (f1 < 0 && errno == ENOENT) same = TRUE; --- 3468,3475 ---- f1 = mch_open((char *)fname, O_RDONLY | O_EXTRA, 0); if (f1 < 0) { ! f1 = mch_open_rw((char *)fname, ! O_RDWR|O_CREAT|O_EXCL|O_EXTRA); #if defined(OS2) if (f1 < 0 && errno == ENOENT) same = TRUE; *************** *** 3493,3512 **** f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0); if (f2 < 0) { ! f2 = open( ! #ifdef VMS ! vms_fixfilename((char *)fname2), ! #else ! (char *)fname2, ! #endif ! O_RDWR|O_CREAT|O_EXCL|O_EXTRA ! #if defined(UNIX) || defined(VMS) /* open in rw------- mode */ ! , (mode_t)0600 ! #endif ! #if defined(MSDOS) || defined(MSWIN) || defined(OS2) /* open read/write */ ! , S_IREAD | S_IWRITE ! #endif ! ); created2 = TRUE; } if (f2 >= 0) --- 3481,3488 ---- f2 = mch_open((char *)fname2, O_RDONLY | O_EXTRA, 0); if (f2 < 0) { ! f2 = mch_open_rw((char *)fname2, ! O_RDWR|O_CREAT|O_EXCL|O_EXTRA); created2 = TRUE; } if (f2 >= 0) *** ../vim-6.2.455/src/os_mswin.c Fri Apr 2 11:36:09 2004 --- src/os_mswin.c Thu Apr 1 22:43:35 2004 *************** *** 450,455 **** --- 450,469 ---- --p; if (p > buf && (*p == '\\' || *p == '/') && p[-1] != ':') *p = NUL; + #ifdef FEAT_MBYTE + if ((int)GetACP() != enc_codepage) + { + WCHAR *wp = enc_to_ucs2(buf, NULL); + int n; + + if (wp != NULL) + { + n = _wstat(wp, (struct _stat *)stp); + vim_free(wp); + return n; + } + } + #endif return stat(buf, stp); } *** ../vim-6.2.455/src/os_win32.c Tue Mar 23 21:23:28 2004 --- src/os_win32.c Tue Apr 6 21:25:50 2004 *************** *** 2361,2366 **** --- 2361,2380 ---- mch_getperm( char_u *name) { + #ifdef FEAT_MBYTE + if ((int)GetACP() != enc_codepage) + { + WCHAR *p = enc_to_ucs2(name, NULL); + long n; + + if (p != NULL) + { + n = (long)GetFileAttributesW(p); + vim_free(p); + return n; + } + } + #endif return (long)GetFileAttributes((char *)name); } *************** *** 2374,2379 **** --- 2388,2407 ---- long perm) { perm |= FILE_ATTRIBUTE_ARCHIVE; /* file has changed, set archive bit */ + #ifdef FEAT_MBYTE + if ((int)GetACP() != enc_codepage) + { + WCHAR *p = enc_to_ucs2(name, NULL); + long n; + + if (p != NULL) + { + n = (long)SetFileAttributesW(p, perm); + vim_free(p); + return n ? OK : FAIL; + } + } + #endif return SetFileAttributes((char *)name, perm) ? OK : FAIL; } *************** *** 2383,2396 **** void mch_hide(char_u *name) { ! int perm; ! perm = GetFileAttributes((char *)name); if (perm >= 0) { perm |= FILE_ATTRIBUTE_HIDDEN; ! SetFileAttributes((char *)name, perm); } } /* --- 2411,2443 ---- void mch_hide(char_u *name) { ! int perm; ! #ifdef FEAT_MBYTE ! WCHAR *p = NULL; ! ! if ((int)GetACP() != enc_codepage) ! p = enc_to_ucs2(name, NULL); ! #endif ! #ifdef FEAT_MBYTE ! if (p != NULL) ! perm = GetFileAttributesW(p); ! else ! #endif ! perm = GetFileAttributes((char *)name); if (perm >= 0) { perm |= FILE_ATTRIBUTE_HIDDEN; ! #ifdef FEAT_MBYTE ! if (p != NULL) ! SetFileAttributesW(p, perm); ! else ! #endif ! SetFileAttributes((char *)name, perm); } + #ifdef FEAT_MBYTE + vim_free(p); + #endif } /* *************** *** 3959,3964 **** --- 4006,4027 ---- int mch_remove(char_u *name) { + #ifdef FEAT_MBYTE + WCHAR *wn = NULL; + int n; + + if ((int)GetACP() != enc_codepage) + { + wn = enc_to_ucs2(name, NULL); + if (wn != NULL) + { + SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL); + n = DeleteFileW(wn) ? 0 : -1; + vim_free(wn); + return n; + } + } + #endif SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL); return DeleteFile(name) ? 0 : -1; } *************** *** 3995,4000 **** --- 4058,4122 ---- return (long_u) (ms.dwAvailPhys + ms.dwAvailPageFile); } + #ifdef FEAT_MBYTE + /* + * Same code as below, but with wide functions and no comments. + * Return 0 for success, non-zero for failure. + */ + int + mch_wrename(WCHAR *wold, WCHAR *wnew) + { + WCHAR *p; + int i; + WCHAR szTempFile[_MAX_PATH + 1]; + WCHAR szNewPath[_MAX_PATH + 1]; + HANDLE hf; + + if (!mch_windows95()) + { + p = wold; + for (i = 0; wold[i] != NUL; ++i) + if ((wold[i] == '/' || wold[i] == '\\' || wold[i] == ':') + && wold[i + 1] != 0) + p = wold + i + 1; + if ((int)(wold + i - p) < 8 || p[6] != '~') + return (MoveFileW(wold, wnew) == 0); + } + + if (GetFullPathNameW(wnew, _MAX_PATH, szNewPath, &p) == 0 || p == NULL) + return -1; + *p = NUL; + + if (GetTempFileNameW(szNewPath, L"VIM", 0, szTempFile) == 0) + return -2; + + if (!DeleteFileW(szTempFile)) + return -3; + + if (!MoveFileW(wold, szTempFile)) + return -4; + + if ((hf = CreateFileW(wold, GENERIC_WRITE, 0, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) + return -5; + if (!CloseHandle(hf)) + return -6; + + if (!MoveFileW(szTempFile, wnew)) + { + (void)MoveFileW(szTempFile, wold); + return -7; + } + + DeleteFileW(szTempFile); + + if (!DeleteFileW(wold)) + return -8; + + return 0; + } + #endif + /* * mch_rename() works around a bug in rename (aka MoveFile) in *************** *** 4024,4029 **** --- 4146,4171 ---- char szNewPath[_MAX_PATH+1]; char *pszFilePart; HANDLE hf; + #ifdef FEAT_MBYTE + WCHAR *wold = NULL; + WCHAR *wnew = NULL; + int retval = 0; + + if ((int)GetACP() != enc_codepage) + { + wold = enc_to_ucs2((char_u *)pszOldFile, NULL); + wnew = enc_to_ucs2((char_u *)pszNewFile, NULL); + if (wold != NULL && wnew != NULL) + { + retval = mch_wrename(wold, wnew); + vim_free(wold); + vim_free(wnew); + return retval; + } + vim_free(wold); + vim_free(wnew); + } + #endif /* * No need to play tricks if not running Windows 95, unless the file name *************** *** 4116,4147 **** int mch_access(char *n, int p) { ! HANDLE hFile; ! DWORD am; if (mch_isdir(n)) { char TempName[_MAX_PATH + 16] = ""; if (p & R_OK) { /* Read check is performed by seeing if we can do a find file on ! * the directory for any file ! */ ! char *pch; ! WIN32_FIND_DATA d; ! STRNCPY(TempName, n, _MAX_PATH); ! pch = TempName + STRLEN(TempName) - 1; ! if (*pch != '\\' && *pch != '/') ! *pch++ = '\\'; ! *pch++ = '*'; ! *pch = NUL; ! ! hFile = FindFirstFile(TempName, &d); ! if (hFile == INVALID_HANDLE_VALUE) ! return -1; ! (void)FindClose(hFile); } if (p & W_OK) --- 4258,4320 ---- int mch_access(char *n, int p) { ! HANDLE hFile; ! DWORD am; ! int retval = -1; /* default: fail */ ! #ifdef FEAT_MBYTE ! WCHAR *wn = NULL; ! ! if ((int)GetACP() != enc_codepage) ! wn = enc_to_ucs2(n, NULL); ! #endif if (mch_isdir(n)) { char TempName[_MAX_PATH + 16] = ""; + #ifdef FEAT_MBYTE + WCHAR TempNameW[_MAX_PATH + 16] = L""; + #endif if (p & R_OK) { /* Read check is performed by seeing if we can do a find file on ! * the directory for any file. */ ! #ifdef FEAT_MBYTE ! if (wn != NULL) ! { ! int i; ! WIN32_FIND_DATAW d; ! for (i = 0; i < _MAX_PATH && wn[i] != 0; ++i) ! TempNameW[i] = wn[i]; ! if (TempNameW[i - 1] != '\\' && TempNameW[i - 1] != '/') ! TempNameW[i++] = '\\'; ! TempNameW[i++] = '*'; ! TempNameW[i++] = 0; ! ! hFile = FindFirstFileW(TempNameW, &d); ! if (hFile == INVALID_HANDLE_VALUE) ! goto getout; ! (void)FindClose(hFile); ! } ! else ! #endif ! { ! char *pch; ! WIN32_FIND_DATA d; ! ! STRNCPY(TempName, n, _MAX_PATH); ! pch = TempName + STRLEN(TempName) - 1; ! if (*pch != '\\' && *pch != '/') ! *++pch = '\\'; ! *++pch = '*'; ! *++pch = NUL; ! ! hFile = FindFirstFile(TempName, &d); ! if (hFile == INVALID_HANDLE_VALUE) ! goto getout; ! (void)FindClose(hFile); ! } } if (p & W_OK) *************** *** 4149,4176 **** /* Trying to create a temporary file in the directory should catch * directories on read-only network shares. However, in * directories whose ACL allows writes but denies deletes will end ! * up keeping the temporary file :-( ! */ ! if (!GetTempFileName(n, "VIM", 0, TempName)) ! return -1; ! mch_remove((char_u *)TempName); } } else { /* Trying to open the file for the required access does ACL, read-only ! * network share, and file attribute checks. ! */ am = ((p & W_OK) ? GENERIC_WRITE : 0) | ((p & R_OK) ? GENERIC_READ : 0); ! hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) ! return -1; CloseHandle(hFile); } ! return 0; } /* * SUB STREAM: * --- 4322,4419 ---- /* Trying to create a temporary file in the directory should catch * directories on read-only network shares. However, in * directories whose ACL allows writes but denies deletes will end ! * up keeping the temporary file :-(. */ ! #ifdef FEAT_MBYTE ! if (wn != NULL) ! { ! if (!GetTempFileNameW(wn, L"VIM", 0, TempNameW)) ! goto getout; ! DeleteFileW(TempNameW); ! } ! else ! #endif ! { ! if (!GetTempFileName(n, "VIM", 0, TempName)) ! goto getout; ! mch_remove((char_u *)TempName); ! } } } else { /* Trying to open the file for the required access does ACL, read-only ! * network share, and file attribute checks. */ am = ((p & W_OK) ? GENERIC_WRITE : 0) | ((p & R_OK) ? GENERIC_READ : 0); ! #ifdef FEAT_MBYTE ! if (wn != NULL) ! hFile = CreateFileW(wn, am, 0, NULL, OPEN_EXISTING, 0, NULL); ! else ! #endif ! hFile = CreateFile(n, am, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) ! goto getout; CloseHandle(hFile); } ! ! retval = 0; /* success */ ! getout: ! #ifdef FEAT_MBYTE ! vim_free(wn); ! #endif ! return retval; } + #if defined(FEAT_MBYTE) || defined(PROTO) + /* + * Version of open() that may use ucs2 file name. + */ + int + mch_open(char *name, int flags, int mode) + { + WCHAR *wn; + int f; + + if ((int)GetACP() != enc_codepage) + { + wn = enc_to_ucs2(name, NULL); + if (wn != NULL) + { + f = _wopen(wn, flags, mode); + vim_free(wn); + return f; + } + } + + return open(name, flags, mode); + } + + /* + * Version of fopen() that may use ucs2 file name. + */ + FILE * + mch_fopen(char *name, char *mode) + { + WCHAR *wn, *wm; + FILE *f; + + if ((int)GetACP() != enc_codepage) + { + wn = enc_to_ucs2(name, NULL); + wm = enc_to_ucs2(mode, NULL); + if (wn != NULL && wm != NULL) + { + f = _wfopen(wn, wm); + return f; + } + vim_free(wn); + vim_free(wm); + } + + return fopen(name, mode); + } + #endif + /* * SUB STREAM: * *** ../vim-6.2.455/src/version.c Tue Apr 6 20:19:26 2004 --- src/version.c Tue Apr 6 21:28:09 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 456, /**/ -- "Intelligence has much less practical application than you'd think." -- Scott Adams, Dilbert. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///