Karsten Hopp 78d140
To: vim_dev@googlegroups.com
Karsten Hopp 78d140
Subject: Patch 7.3.1182
Karsten Hopp 78d140
Fcc: outbox
Karsten Hopp 78d140
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 78d140
Mime-Version: 1.0
Karsten Hopp 78d140
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 78d140
Content-Transfer-Encoding: 8bit
Karsten Hopp 78d140
------------
Karsten Hopp 78d140
Karsten Hopp 78d140
Patch 7.3.1182
Karsten Hopp 78d140
Problem:    'backupcopy' default on MS-Windows does not work for hard and soft
Karsten Hopp 78d140
	    links.
Karsten Hopp 78d140
Solution:   Check for links. (David Pope, Ken Takata)
Karsten Hopp 78d140
Files:	    src/fileio.c, src/os_win32.c, src/proto/os_win32.pro
Karsten Hopp 78d140
Karsten Hopp 78d140
Karsten Hopp 78d140
*** ../vim-7.3.1181/src/fileio.c	2013-06-12 19:52:11.000000000 +0200
Karsten Hopp 78d140
--- src/fileio.c	2013-06-12 22:31:34.000000000 +0200
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 3780,3791 ****
Karsten Hopp 78d140
  	    }
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
  
Karsten Hopp 78d140
- # ifdef UNIX
Karsten Hopp 78d140
  	/*
Karsten Hopp 78d140
  	 * Break symlinks and/or hardlinks if we've been asked to.
Karsten Hopp 78d140
  	 */
Karsten Hopp 78d140
  	if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK))
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
  	    int	lstat_res;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  	    lstat_res = mch_lstat((char *)fname, &st);
Karsten Hopp 78d140
--- 3780,3791 ----
Karsten Hopp 78d140
  	    }
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  	/*
Karsten Hopp 78d140
  	 * Break symlinks and/or hardlinks if we've been asked to.
Karsten Hopp 78d140
  	 */
Karsten Hopp 78d140
  	if ((bkc_flags & BKC_BREAKSYMLINK) || (bkc_flags & BKC_BREAKHARDLINK))
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
+ # ifdef UNIX
Karsten Hopp 78d140
  	    int	lstat_res;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  	    lstat_res = mch_lstat((char *)fname, &st);
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 3801,3808 ****
Karsten Hopp 78d140
  		    && st_old.st_nlink > 1
Karsten Hopp 78d140
  		    && (lstat_res != 0 || st.st_ino == st_old.st_ino))
Karsten Hopp 78d140
  		backup_copy = FALSE;
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
- #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
--- 3801,3818 ----
Karsten Hopp 78d140
  		    && st_old.st_nlink > 1
Karsten Hopp 78d140
  		    && (lstat_res != 0 || st.st_ino == st_old.st_ino))
Karsten Hopp 78d140
  		backup_copy = FALSE;
Karsten Hopp 78d140
+ # else
Karsten Hopp 78d140
+ #  if defined(WIN32)
Karsten Hopp 78d140
+ 	    /* Symlinks. */
Karsten Hopp 78d140
+ 	    if ((bkc_flags & BKC_BREAKSYMLINK) && mch_is_symbolic_link(fname))
Karsten Hopp 78d140
+ 		backup_copy = FALSE;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ 	    /* Hardlinks. */
Karsten Hopp 78d140
+ 	    if ((bkc_flags & BKC_BREAKHARDLINK) && mch_is_hard_link(fname))
Karsten Hopp 78d140
+ 		backup_copy = FALSE;
Karsten Hopp 78d140
+ #  endif
Karsten Hopp 78d140
+ # endif
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
*** ../vim-7.3.1181/src/os_win32.c	2013-06-07 19:17:12.000000000 +0200
Karsten Hopp 78d140
--- src/os_win32.c	2013-06-12 22:39:53.000000000 +0200
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 78,83 ****
Karsten Hopp 78d140
--- 78,93 ----
Karsten Hopp 78d140
  # endif
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
+  * Reparse Point
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+ #ifndef FILE_ATTRIBUTE_REPARSE_POINT
Karsten Hopp 78d140
+ # define FILE_ATTRIBUTE_REPARSE_POINT	0x00000400
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+ #ifndef IO_REPARSE_TAG_SYMLINK
Karsten Hopp 78d140
+ # define IO_REPARSE_TAG_SYMLINK		0xA000000C
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
  /* Record all output and all keyboard & mouse input */
Karsten Hopp 78d140
  /* #define MCH_WRITE_DUMP */
Karsten Hopp 78d140
  
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 219,224 ****
Karsten Hopp 78d140
--- 229,238 ----
Karsten Hopp 78d140
  static char *vimrun_path = "vimrun ";
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
+ static int win32_getattrs(char_u *name);
Karsten Hopp 78d140
+ static int win32_setattrs(char_u *name, int attrs);
Karsten Hopp 78d140
+ static int win32_set_archive(char_u *name);
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
  #ifndef FEAT_GUI_W32
Karsten Hopp 78d140
  static int suppress_winsize = 1;	/* don't fiddle with console */
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2623,2679 ****
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
   * get file permissions for `name'
Karsten Hopp 78d140
   * -1 : error
Karsten Hopp 78d140
!  * else FILE_ATTRIBUTE_* defined in winnt.h
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      long
Karsten Hopp 78d140
  mch_getperm(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
! #ifdef FEAT_MBYTE
Karsten Hopp 78d140
!     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
!     {
Karsten Hopp 78d140
! 	WCHAR	*p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
! 	long	n;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
! 	if (p != NULL)
Karsten Hopp 78d140
! 	{
Karsten Hopp 78d140
! 	    n = (long)GetFileAttributesW(p);
Karsten Hopp 78d140
! 	    vim_free(p);
Karsten Hopp 78d140
! 	    if (n >= 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
! 		return n;
Karsten Hopp 78d140
! 	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
! 	}
Karsten Hopp 78d140
!     }
Karsten Hopp 78d140
! #endif
Karsten Hopp 78d140
!     return (long)GetFileAttributes((char *)name);
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
   * set file permission for `name' to `perm'
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_setperm(
Karsten Hopp 78d140
      char_u  *name,
Karsten Hopp 78d140
      long    perm)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     perm |= FILE_ATTRIBUTE_ARCHIVE;	/* file has changed, set archive bit */
Karsten Hopp 78d140
  #ifdef FEAT_MBYTE
Karsten Hopp 78d140
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
      {
Karsten Hopp 78d140
! 	WCHAR	*p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
! 	long	n;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  	if (p != NULL)
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
! 	    n = (long)SetFileAttributesW(p, perm);
Karsten Hopp 78d140
  	    vim_free(p);
Karsten Hopp 78d140
! 	    if (n || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
! 		return n ? OK : FAIL;
Karsten Hopp 78d140
  	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
      }
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
!     return SetFileAttributes((char *)name, perm) ? OK : FAIL;
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
--- 2637,2690 ----
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
   * get file permissions for `name'
Karsten Hopp 78d140
   * -1 : error
Karsten Hopp 78d140
!  * else mode_t
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      long
Karsten Hopp 78d140
  mch_getperm(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     struct stat st;
Karsten Hopp 78d140
!     int n;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
!     n = mch_stat(name, &st);
Karsten Hopp 78d140
!     return n == 0 ? (int)st.st_mode : -1;
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
   * set file permission for `name' to `perm'
Karsten Hopp 78d140
+  *
Karsten Hopp 78d140
+  * return FAIL for failure, OK otherwise
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_setperm(
Karsten Hopp 78d140
      char_u  *name,
Karsten Hopp 78d140
      long    perm)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     long	n;
Karsten Hopp 78d140
  #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     WCHAR *p;
Karsten Hopp 78d140
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
      {
Karsten Hopp 78d140
! 	p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  	if (p != NULL)
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
! 	    n = _wchmod(p, perm);
Karsten Hopp 78d140
  	    vim_free(p);
Karsten Hopp 78d140
! 	    if (n == -1 && GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
! 		return FAIL;
Karsten Hopp 78d140
  	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
      }
Karsten Hopp 78d140
+     if (p == NULL)
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
! 	n = _chmod(name, perm);
Karsten Hopp 78d140
!     if (n == -1)
Karsten Hopp 78d140
! 	return FAIL;
Karsten Hopp 78d140
! 
Karsten Hopp 78d140
!     win32_set_archive(name);
Karsten Hopp 78d140
! 
Karsten Hopp 78d140
!     return OK;
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2682,2730 ****
Karsten Hopp 78d140
      void
Karsten Hopp 78d140
  mch_hide(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int		perm;
Karsten Hopp 78d140
! #ifdef FEAT_MBYTE
Karsten Hopp 78d140
!     WCHAR	*p = NULL;
Karsten Hopp 78d140
! 
Karsten Hopp 78d140
!     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
! 	p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
! #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
! #ifdef FEAT_MBYTE
Karsten Hopp 78d140
!     if (p != NULL)
Karsten Hopp 78d140
!     {
Karsten Hopp 78d140
! 	perm = GetFileAttributesW(p);
Karsten Hopp 78d140
! 	if (perm < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
! 	{
Karsten Hopp 78d140
! 	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
! 	    vim_free(p);
Karsten Hopp 78d140
! 	    p = NULL;
Karsten Hopp 78d140
! 	}
Karsten Hopp 78d140
!     }
Karsten Hopp 78d140
!     if (p == NULL)
Karsten Hopp 78d140
! #endif
Karsten Hopp 78d140
! 	perm = GetFileAttributes((char *)name);
Karsten Hopp 78d140
!     if (perm >= 0)
Karsten Hopp 78d140
!     {
Karsten Hopp 78d140
! 	perm |= FILE_ATTRIBUTE_HIDDEN;
Karsten Hopp 78d140
! #ifdef FEAT_MBYTE
Karsten Hopp 78d140
! 	if (p != NULL)
Karsten Hopp 78d140
! 	{
Karsten Hopp 78d140
! 	    if (SetFileAttributesW(p, perm) == 0
Karsten Hopp 78d140
! 		    && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
! 	    {
Karsten Hopp 78d140
! 		/* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
! 		vim_free(p);
Karsten Hopp 78d140
! 		p = NULL;
Karsten Hopp 78d140
! 	    }
Karsten Hopp 78d140
! 	}
Karsten Hopp 78d140
! 	if (p == NULL)
Karsten Hopp 78d140
! #endif
Karsten Hopp 78d140
! 	    SetFileAttributes((char *)name, perm);
Karsten Hopp 78d140
!     }
Karsten Hopp 78d140
! #ifdef FEAT_MBYTE
Karsten Hopp 78d140
!     vim_free(p);
Karsten Hopp 78d140
! #endif
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
--- 2693,2704 ----
Karsten Hopp 78d140
      void
Karsten Hopp 78d140
  mch_hide(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int attrs = win32_getattrs(name);
Karsten Hopp 78d140
!     if (attrs == -1)
Karsten Hopp 78d140
! 	return;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
!     attrs |= FILE_ATTRIBUTE_HIDDEN;
Karsten Hopp 78d140
!     win32_setattrs(name, attrs);
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2734,2740 ****
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_isdir(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int f = mch_getperm(name);
Karsten Hopp 78d140
  
Karsten Hopp 78d140
      if (f == -1)
Karsten Hopp 78d140
  	return FALSE;		    /* file does not exist at all */
Karsten Hopp 78d140
--- 2708,2714 ----
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_isdir(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int f = win32_getattrs(name);
Karsten Hopp 78d140
  
Karsten Hopp 78d140
      if (f == -1)
Karsten Hopp 78d140
  	return FALSE;		    /* file does not exist at all */
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2770,2776 ****
Karsten Hopp 78d140
   * Return TRUE if file "fname" has more than one link.
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
! mch_is_linked(char_u *fname)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
      BY_HANDLE_FILE_INFORMATION info;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
--- 2744,2750 ----
Karsten Hopp 78d140
   * Return TRUE if file "fname" has more than one link.
Karsten Hopp 78d140
   */
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
! mch_is_hard_link(char_u *fname)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
      BY_HANDLE_FILE_INFORMATION info;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2779,2784 ****
Karsten Hopp 78d140
--- 2753,2826 ----
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
+  * Return TRUE if file "fname" is a symbolic link.
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+     int
Karsten Hopp 78d140
+ mch_is_symbolic_link(char_u *fname)
Karsten Hopp 78d140
+ {
Karsten Hopp 78d140
+     HANDLE		hFind;
Karsten Hopp 78d140
+     int			res = FALSE;
Karsten Hopp 78d140
+     WIN32_FIND_DATAA	findDataA;
Karsten Hopp 78d140
+     DWORD		fileFlags = 0, reparseTag = 0;
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     WCHAR		*wn = NULL;
Karsten Hopp 78d140
+     WIN32_FIND_DATAW	findDataW;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
+ 	wn = enc_to_utf16(fname, NULL);
Karsten Hopp 78d140
+     if (wn != NULL)
Karsten Hopp 78d140
+     {
Karsten Hopp 78d140
+ 	hFind = FindFirstFileW(wn, &findDataW);
Karsten Hopp 78d140
+ 	vim_free(wn);
Karsten Hopp 78d140
+ 	if (hFind == INVALID_HANDLE_VALUE
Karsten Hopp 78d140
+ 		&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
+ 	{
Karsten Hopp 78d140
+ 	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
+ 	    hFind = FindFirstFile(fname, &findDataA);
Karsten Hopp 78d140
+ 	    if (hFind != INVALID_HANDLE_VALUE)
Karsten Hopp 78d140
+ 	    {
Karsten Hopp 78d140
+ 		fileFlags = findDataA.dwFileAttributes;
Karsten Hopp 78d140
+ 		reparseTag = findDataA.dwReserved0;
Karsten Hopp 78d140
+ 	    }
Karsten Hopp 78d140
+ 	}
Karsten Hopp 78d140
+ 	else
Karsten Hopp 78d140
+ 	{
Karsten Hopp 78d140
+ 	    fileFlags = findDataW.dwFileAttributes;
Karsten Hopp 78d140
+ 	    reparseTag = findDataW.dwReserved0;
Karsten Hopp 78d140
+ 	}
Karsten Hopp 78d140
+     }
Karsten Hopp 78d140
+ #else
Karsten Hopp 78d140
+     hFind = FindFirstFile(fname, &findDataA);
Karsten Hopp 78d140
+     if (hFind != INVALID_HANDLE_VALUE)
Karsten Hopp 78d140
+     {
Karsten Hopp 78d140
+ 	fileFlags = findDataA.dwFileAttributes;
Karsten Hopp 78d140
+ 	reparseTag = findDataA.dwReserved0;
Karsten Hopp 78d140
+     }
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (hFind != INVALID_HANDLE_VALUE)
Karsten Hopp 78d140
+ 	FindClose(hFind);
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT)
Karsten Hopp 78d140
+ 	    && reparseTag == IO_REPARSE_TAG_SYMLINK)
Karsten Hopp 78d140
+ 	res = TRUE;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     return res;
Karsten Hopp 78d140
+ }
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
+  * Return TRUE if file "fname" has more than one link or if it is a symbolic
Karsten Hopp 78d140
+  * link.
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+     int
Karsten Hopp 78d140
+ mch_is_linked(char_u *fname)
Karsten Hopp 78d140
+ {
Karsten Hopp 78d140
+     if (mch_is_hard_link(fname) || mch_is_symbolic_link(fname))
Karsten Hopp 78d140
+ 	return TRUE;
Karsten Hopp 78d140
+     return FALSE;
Karsten Hopp 78d140
+ }
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
   * Get the by-handle-file-information for "fname".
Karsten Hopp 78d140
   * Returns FILEINFO_OK when OK.
Karsten Hopp 78d140
   * returns FILEINFO_ENC_FAIL when enc_to_utf16() failed.
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2842,2847 ****
Karsten Hopp 78d140
--- 2884,2975 ----
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
+  * get file attributes for `name'
Karsten Hopp 78d140
+  * -1 : error
Karsten Hopp 78d140
+  * else FILE_ATTRIBUTE_* defined in winnt.h
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+     static
Karsten Hopp 78d140
+     int
Karsten Hopp 78d140
+ win32_getattrs(char_u *name)
Karsten Hopp 78d140
+ {
Karsten Hopp 78d140
+     int		attr;
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     WCHAR	*p = NULL;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
+ 	p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (p != NULL)
Karsten Hopp 78d140
+     {
Karsten Hopp 78d140
+ 	attr = GetFileAttributesW(p);
Karsten Hopp 78d140
+ 	if (attr < 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
+ 	{
Karsten Hopp 78d140
+ 	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
+ 	    vim_free(p);
Karsten Hopp 78d140
+ 	    p = NULL;
Karsten Hopp 78d140
+ 	}
Karsten Hopp 78d140
+     }
Karsten Hopp 78d140
+     if (p == NULL)
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+ 	attr = GetFileAttributes((char *)name);
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     vim_free(p);
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+     return attr;
Karsten Hopp 78d140
+ }
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
+  * set file attributes for `name' to `attrs'
Karsten Hopp 78d140
+  *
Karsten Hopp 78d140
+  * return -1 for failure, 0 otherwise
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+     static
Karsten Hopp 78d140
+     int
Karsten Hopp 78d140
+ win32_setattrs(char_u *name, int attrs)
Karsten Hopp 78d140
+ {
Karsten Hopp 78d140
+     int res;
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     WCHAR	*p = NULL;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
+ 	p = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     if (p != NULL)
Karsten Hopp 78d140
+     {
Karsten Hopp 78d140
+ 	res = SetFileAttributesW(p, attrs);
Karsten Hopp 78d140
+ 	if (res == FALSE
Karsten Hopp 78d140
+ 	    && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
+ 	{
Karsten Hopp 78d140
+ 	    /* Retry with non-wide function (for Windows 98). */
Karsten Hopp 78d140
+ 	    vim_free(p);
Karsten Hopp 78d140
+ 	    p = NULL;
Karsten Hopp 78d140
+ 	}
Karsten Hopp 78d140
+     }
Karsten Hopp 78d140
+     if (p == NULL)
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+ 	res = SetFileAttributes((char *)name, attrs);
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
+     vim_free(p);
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
+     return res ? 0 : -1;
Karsten Hopp 78d140
+ }
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
+  * Set archive flag for "name".
Karsten Hopp 78d140
+  */
Karsten Hopp 78d140
+     static
Karsten Hopp 78d140
+     int
Karsten Hopp 78d140
+ win32_set_archive(char_u *name)
Karsten Hopp 78d140
+ {
Karsten Hopp 78d140
+     int attrs = win32_getattrs(name);
Karsten Hopp 78d140
+     if (attrs == -1)
Karsten Hopp 78d140
+ 	return -1;
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+     attrs |= FILE_ATTRIBUTE_ARCHIVE;
Karsten Hopp 78d140
+     return win32_setattrs(name, attrs);
Karsten Hopp 78d140
+ }
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ /*
Karsten Hopp 78d140
   * Return TRUE if file or directory "name" is writable (not readonly).
Karsten Hopp 78d140
   * Strange semantics of Win32: a readonly directory is writable, but you can't
Karsten Hopp 78d140
   * delete a file.  Let's say this means it is writable.
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 2849,2858 ****
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_writable(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int perm = mch_getperm(name);
Karsten Hopp 78d140
  
Karsten Hopp 78d140
!     return (perm != -1 && (!(perm & FILE_ATTRIBUTE_READONLY)
Karsten Hopp 78d140
! 				       || (perm & FILE_ATTRIBUTE_DIRECTORY)));
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
--- 2977,2986 ----
Karsten Hopp 78d140
      int
Karsten Hopp 78d140
  mch_writable(char_u *name)
Karsten Hopp 78d140
  {
Karsten Hopp 78d140
!     int attrs = win32_getattrs(name);
Karsten Hopp 78d140
  
Karsten Hopp 78d140
!     return (attrs != -1 && (!(attrs & FILE_ATTRIBUTE_READONLY)
Karsten Hopp 78d140
! 			  || (attrs & FILE_ATTRIBUTE_DIRECTORY)));
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
  /*
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 5012,5024 ****
Karsten Hopp 78d140
  #ifdef FEAT_MBYTE
Karsten Hopp 78d140
      WCHAR	*wn = NULL;
Karsten Hopp 78d140
      int		n;
Karsten Hopp 78d140
  
Karsten Hopp 78d140
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
      {
Karsten Hopp 78d140
  	wn = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
  	if (wn != NULL)
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
- 	    SetFileAttributesW(wn, FILE_ATTRIBUTE_NORMAL);
Karsten Hopp 78d140
  	    n = DeleteFileW(wn) ? 0 : -1;
Karsten Hopp 78d140
  	    vim_free(wn);
Karsten Hopp 78d140
  	    if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
--- 5140,5155 ----
Karsten Hopp 78d140
  #ifdef FEAT_MBYTE
Karsten Hopp 78d140
      WCHAR	*wn = NULL;
Karsten Hopp 78d140
      int		n;
Karsten Hopp 78d140
+ #endif
Karsten Hopp 78d140
  
Karsten Hopp 78d140
+     win32_setattrs(name, FILE_ATTRIBUTE_NORMAL);
Karsten Hopp 78d140
+ 
Karsten Hopp 78d140
+ #ifdef FEAT_MBYTE
Karsten Hopp 78d140
      if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
Karsten Hopp 78d140
      {
Karsten Hopp 78d140
  	wn = enc_to_utf16(name, NULL);
Karsten Hopp 78d140
  	if (wn != NULL)
Karsten Hopp 78d140
  	{
Karsten Hopp 78d140
  	    n = DeleteFileW(wn) ? 0 : -1;
Karsten Hopp 78d140
  	    vim_free(wn);
Karsten Hopp 78d140
  	    if (n == 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 5027,5033 ****
Karsten Hopp 78d140
  	}
Karsten Hopp 78d140
      }
Karsten Hopp 78d140
  #endif
Karsten Hopp 78d140
-     SetFileAttributes(name, FILE_ATTRIBUTE_NORMAL);
Karsten Hopp 78d140
      return DeleteFile(name) ? 0 : -1;
Karsten Hopp 78d140
  }
Karsten Hopp 78d140
  
Karsten Hopp 78d140
--- 5158,5163 ----
Karsten Hopp 78d140
*** ../vim-7.3.1181/src/proto/os_win32.pro	2012-11-20 16:56:49.000000000 +0100
Karsten Hopp 78d140
--- src/proto/os_win32.pro	2013-06-12 22:29:53.000000000 +0200
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 21,26 ****
Karsten Hopp 78d140
--- 21,28 ----
Karsten Hopp 78d140
  void mch_hide __ARGS((char_u *name));
Karsten Hopp 78d140
  int mch_isdir __ARGS((char_u *name));
Karsten Hopp 78d140
  int mch_mkdir __ARGS((char_u *name));
Karsten Hopp 78d140
+ int mch_is_hard_link __ARGS((char_u *fname));
Karsten Hopp 78d140
+ int mch_is_symbolic_link __ARGS((char_u *fname));
Karsten Hopp 78d140
  int mch_is_linked __ARGS((char_u *fname));
Karsten Hopp 78d140
  int win32_fileinfo __ARGS((char_u *fname, BY_HANDLE_FILE_INFORMATION *info));
Karsten Hopp 78d140
  int mch_writable __ARGS((char_u *name));
Karsten Hopp 78d140
*** ../vim-7.3.1181/src/version.c	2013-06-12 22:08:54.000000000 +0200
Karsten Hopp 78d140
--- src/version.c	2013-06-12 22:40:29.000000000 +0200
Karsten Hopp 78d140
***************
Karsten Hopp 78d140
*** 730,731 ****
Karsten Hopp 78d140
--- 730,733 ----
Karsten Hopp 78d140
  {   /* Add new patch number below this line */
Karsten Hopp 78d140
+ /**/
Karsten Hopp 78d140
+     1182,
Karsten Hopp 78d140
  /**/
Karsten Hopp 78d140
Karsten Hopp 78d140
-- 
Karsten Hopp 78d140
If Microsoft would build a car...
Karsten Hopp 78d140
... You'd have to press the "Start" button to turn the engine off.
Karsten Hopp 78d140
Karsten Hopp 78d140
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 78d140
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 78d140
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 78d140
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///