* cygheap.h (struct cwdstuff): Add dir member to store cwd handle.
(cwdstuff::get_handle): New method. * path.cc (cwdstuff::set): When doit is true, always try to get directory handle. Fail if duplicating handle fails. Store handle in dir. Fix potential SEGV when setting drive_length.
This commit is contained in:
		
							parent
							
								
									3fbb5e3d80
								
							
						
					
					
						commit
						8e87af7ed0
					
				|  | @ -1,3 +1,11 @@ | ||||||
|  | 2008-01-31  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  | 
 | ||||||
|  | 	* cygheap.h (struct cwdstuff): Add dir member to store cwd handle. | ||||||
|  | 	(cwdstuff::get_handle): New method. | ||||||
|  | 	* path.cc (cwdstuff::set): When doit is true, always try to get | ||||||
|  | 	directory handle.  Fail if duplicating handle fails.  Store handle | ||||||
|  | 	in dir.  Fix potential SEGV when setting drive_length.  | ||||||
|  | 
 | ||||||
| 2008-01-28  Corinna Vinschen  <corinna@vinschen.de> | 2008-01-28  Corinna Vinschen  <corinna@vinschen.de> | ||||||
| 
 | 
 | ||||||
| 	* path.cc: Fix Samba version in comment. | 	* path.cc: Fix Samba version in comment. | ||||||
|  |  | ||||||
|  | @ -223,9 +223,11 @@ struct cwdstuff | ||||||
| { | { | ||||||
|   char *posix; |   char *posix; | ||||||
|   UNICODE_STRING win32; |   UNICODE_STRING win32; | ||||||
|  |   HANDLE dir; | ||||||
|   DWORD drive_length; |   DWORD drive_length; | ||||||
|   static muto cwd_lock; |   static muto cwd_lock; | ||||||
|   char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH); |   char *get (char *, int = 1, int = 0, unsigned = CYG_MAX_PATH); | ||||||
|  |   HANDLE get_handle () { return dir; } | ||||||
|   DWORD get_drive (char * dst) |   DWORD get_drive (char * dst) | ||||||
|   { |   { | ||||||
|     cwd_lock.acquire (); |     cwd_lock.acquire (); | ||||||
|  |  | ||||||
|  | @ -4431,7 +4431,7 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit) | ||||||
| 	 - Unlinking a cwd fails because SetCurrentDirectory seems to | 	 - Unlinking a cwd fails because SetCurrentDirectory seems to | ||||||
| 	   open directories so that deleting the directory is disallowed. | 	   open directories so that deleting the directory is disallowed. | ||||||
| 	   The below code opens with *all* sharing flags set. */ | 	   The below code opens with *all* sharing flags set. */ | ||||||
|       HANDLE h; |       HANDLE h, h_copy; | ||||||
|       NTSTATUS status; |       NTSTATUS status; | ||||||
|       IO_STATUS_BLOCK io; |       IO_STATUS_BLOCK io; | ||||||
|       OBJECT_ATTRIBUTES attr; |       OBJECT_ATTRIBUTES attr; | ||||||
|  | @ -4441,18 +4441,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit) | ||||||
|       phdl = &get_user_proc_parms ()->CurrentDirectoryHandle; |       phdl = &get_user_proc_parms ()->CurrentDirectoryHandle; | ||||||
|       if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */ |       if (!nat_cwd) /* On init, just reopen CWD with desired access flags. */ | ||||||
| 	RtlInitUnicodeString (&upath, L""); | 	RtlInitUnicodeString (&upath, L""); | ||||||
|       else |  | ||||||
| 	{ |  | ||||||
| 	  /* TODO:
 |  | ||||||
| 	     Check the length of the new CWD.  Windows can only handle |  | ||||||
| 	     CWDs of up to MAX_PATH length, including a trailing backslash. |  | ||||||
| 	     If the path is longer, it's not an error condition for Cygwin, |  | ||||||
| 	     so we don't fail.  Windows on the other hand has a problem now. |  | ||||||
| 	     For now, we just don't store the path in the PEB and proceed as |  | ||||||
| 	     usual. */ |  | ||||||
| 	  if (len > MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2)) |  | ||||||
| 	    goto skip_peb_storing; |  | ||||||
| 	} |  | ||||||
|       InitializeObjectAttributes (&attr, &upath, |       InitializeObjectAttributes (&attr, &upath, | ||||||
| 				  OBJ_CASE_INSENSITIVE | OBJ_INHERIT, | 				  OBJ_CASE_INSENSITIVE | OBJ_INHERIT, | ||||||
| 				  nat_cwd ? NULL : *phdl, NULL); | 				  nat_cwd ? NULL : *phdl, NULL); | ||||||
|  | @ -4468,8 +4456,36 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit) | ||||||
| 	  res = -1; | 	  res = -1; | ||||||
| 	  goto out; | 	  goto out; | ||||||
| 	} | 	} | ||||||
|  |       /* Workaround a problem in Vista which fails in subsequent calls to
 | ||||||
|  | 	 CreateFile with ERROR_INVALID_HANDLE if the handle in | ||||||
|  | 	 CurrentDirectoryHandle changes without calling SetCurrentDirectory, | ||||||
|  | 	 and the filename given to CreateFile is a relative path.  It looks | ||||||
|  | 	 like Vista stores a copy of the CWD handle in some other undocumented | ||||||
|  | 	 place.  The NtClose/DuplicateHandle reuses the original handle for | ||||||
|  | 	 the copy of the new handle and the next CreateFile works. | ||||||
|  | 	 Note that this is not thread-safe (yet?) */ | ||||||
|  |       if (!DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (), | ||||||
|  | 			    &h_copy, 0, TRUE, DUPLICATE_SAME_ACCESS)) | ||||||
|  | 	{ | ||||||
|  | 	  RtlReleasePebLock (); | ||||||
|  | 	  __seterrno (); | ||||||
|  | 	  NtClose (h); | ||||||
|  | 	  res = -1; | ||||||
|  | 	  goto out; | ||||||
|  | 	} | ||||||
|  |       NtClose (*phdl); | ||||||
|  |       dir = *phdl = h; | ||||||
| 
 | 
 | ||||||
|       if (nat_cwd) /* No need to set path on init. */ |       /* No need to set path on init. */ | ||||||
|  |       if (nat_cwd | ||||||
|  | 	  /* TODO:
 | ||||||
|  | 	     Check the length of the new CWD.  Windows can only handle | ||||||
|  | 	     CWDs of up to MAX_PATH length, including a trailing backslash. | ||||||
|  | 	     If the path is longer, it's not an error condition for Cygwin, | ||||||
|  | 	     so we don't fail.  Windows on the other hand has a problem now. | ||||||
|  | 	     For now, we just don't store the path in the PEB and proceed as | ||||||
|  | 	     usual. */ | ||||||
|  | 	  && len <= MAX_PATH - (nat_cwd->Buffer[len - 1] == L'\\' ? 1 : 2)) | ||||||
|         { |         { | ||||||
| 	  /* Convert to a Win32 path. */ | 	  /* Convert to a Win32 path. */ | ||||||
| 	  upath.Buffer += upath.Length / sizeof (WCHAR) - len; | 	  upath.Buffer += upath.Length / sizeof (WCHAR) - len; | ||||||
|  | @ -4485,22 +4501,6 @@ cwdstuff::set (PUNICODE_STRING nat_cwd, const char *posix_cwd, bool doit) | ||||||
| 	  RtlCopyUnicodeString (&get_user_proc_parms ()->CurrentDirectoryName, | 	  RtlCopyUnicodeString (&get_user_proc_parms ()->CurrentDirectoryName, | ||||||
| 				&upath); | 				&upath); | ||||||
| 	} | 	} | ||||||
|       NtClose (*phdl); |  | ||||||
|       /* Workaround a problem in Vista which fails in subsequent calls to
 |  | ||||||
| 	 CreateFile with ERROR_INVALID_HANDLE if the handle in |  | ||||||
| 	 CurrentDirectoryHandle changes without calling SetCurrentDirectory, |  | ||||||
| 	 and the filename given to CreateFile is a relative path.  It looks |  | ||||||
| 	 like Vista stores a copy of the CWD handle in some other undocumented |  | ||||||
| 	 place.  The NtClose/DuplicateHandle reuses the original handle for |  | ||||||
| 	 the copy of the new handle and the next CreateFile works. |  | ||||||
| 	 Note that this is not thread-safe (yet?) */ |  | ||||||
|       if (DuplicateHandle (GetCurrentProcess (), h, GetCurrentProcess (), phdl, |  | ||||||
| 			   0, TRUE, DUPLICATE_SAME_ACCESS)) |  | ||||||
| 	NtClose (h); |  | ||||||
|       else |  | ||||||
| 	*phdl = h; |  | ||||||
| 
 |  | ||||||
| skip_peb_storing: |  | ||||||
| 
 | 
 | ||||||
|       RtlReleasePebLock (); |       RtlReleasePebLock (); | ||||||
|     } |     } | ||||||
|  | @ -4552,7 +4552,7 @@ skip_peb_storing: | ||||||
|       else if (win32.Buffer[1] == L'\\') |       else if (win32.Buffer[1] == L'\\') | ||||||
| 	{ | 	{ | ||||||
| 	  PWCHAR ptr = wcschr (win32.Buffer + 2, L'\\'); | 	  PWCHAR ptr = wcschr (win32.Buffer + 2, L'\\'); | ||||||
| 	  if (*ptr) | 	  if (ptr) | ||||||
| 	    ptr = wcschr (ptr + 1, L'\\'); | 	    ptr = wcschr (ptr + 1, L'\\'); | ||||||
| 	  if (ptr) | 	  if (ptr) | ||||||
| 	    drive_length = ptr - win32.Buffer; | 	    drive_length = ptr - win32.Buffer; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue