This is the mail archive of the cygwin-developers@cygwin.com mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [stefan.schuerger: Path problems with trailing dot]


On May 15 23:52, Christopher Faylor wrote:
> As the above email illustrates, we are specifically treating a foo.\bar
> as invalid in path_conv.  I don't remember the rationale for doing this.
> It seems inconsistent to do this given the above example.
> 
> The patch below reverts this behavior on non-NT systems but it is
> obviously not the right behavior for NT due to the fact that NtCreateFile
> doesn't consider "foo." == "foo".  Do either of you remember why
> we (i.e., I) did things this way?

Not exactly.  My guess is that this approach was just simpler.  It would be
more correct to ignore trailing dots and spaces in every path component.

However, I think we should change the whole approach.  We shouldn't remove
any trailing dots and spaces in path_conv::check.  Instead, we should change
fhandler_base::open and path_conv::get_nt_native_path to do just the
"right thing"(tm).  Instead of taking the half-hearted approach to convert
the path to NT speak ourselves (curtesy myself), Cygwin should call
RtlDosPathNameToNtPathName_U to do the job and don't suffer anymore.

RtlDosPathNameToNtPathName_U also takes the DOS device names (aux:, prn:)
into account automagically, so there's no need anymore to check for dos
devices at the beginning of fhandler_base::open and redirect to open_9x.

Preliminary patch see below.


Corinna

	* autoload.cc  (RtlDosPathNameToNtPathName_U): Import.
	(RtlCreateUnicodeStringFromAsciiz): Import.
	(RtlFreeUnicodeString): Import.
	* fhandler.cc (fhandler_base::open): Drop wpath since
	path_conv::get_nt_native_path now allocates the upath Buffer.
	Remove call to RtlIsDosDeviceName_U.  Free upath.Buffer on
	return.
	* ntdll.h (RtlDosPathNameToNtPathName_U): Declare.
	(RtlCreateUnicodeStringFromAsciiz): Declare.
	(RtlFreeUnicodeString): Declare.
	* path.cc: Include ntdll.h.
	(path_conv::get_nt_native_path): Call RtlDosPathNameToNtPathName_U
	to generate the correct NT path.  Use RtlCreateUnicodeStringFromAsciiz
	to allocate Buffer in case of incoming NT paths.
	(path_conv::check): Drop trailing dot and space handling entirely.

Index: autoload.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/autoload.cc,v
retrieving revision 1.102
diff -u -p -r1.102 autoload.cc
--- autoload.cc	13 May 2005 20:20:02 -0000	1.102
+++ autoload.cc	16 May 2005 10:52:55 -0000
@@ -404,6 +404,9 @@ LoadDLLfuncEx (NtUnmapViewOfSection, 8, 
 LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
 LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
 LoadDLLfuncEx (RtlIsDosDeviceName_U, 4, ntdll, 1)
+LoadDLLfuncEx (RtlDosPathNameToNtPathName_U, 16, ntdll, 1)
+LoadDLLfuncEx (RtlCreateUnicodeStringFromAsciiz, 8, ntdll, 1)
+LoadDLLfuncEx (RtlFreeUnicodeString, 4, ntdll, 1)
 
 LoadDLLfuncEx (EnumProcessModules, 16, psapi, 1)
 LoadDLLfuncEx (GetModuleFileNameExA, 16, psapi, 1)
Index: fhandler.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/fhandler.cc,v
retrieving revision 1.233
diff -u -p -r1.233 fhandler.cc
--- fhandler.cc	28 Apr 2005 03:41:09 -0000	1.233
+++ fhandler.cc	16 May 2005 10:52:55 -0000
@@ -555,12 +555,13 @@ fhandler_base::open (int flags, mode_t m
   if (!wincap.is_winnt ())
     return fhandler_base::open_9x (flags, mode);
 
-  WCHAR wpath[CYG_MAX_PATH + 10];
-  UNICODE_STRING upath = {0, sizeof (wpath), wpath};
-  pc.get_nt_native_path (upath);
-
-  if (RtlIsDosDeviceName_U (upath.Buffer))
-    return fhandler_base::open_9x (flags, mode);
+  UNICODE_STRING upath;
+  if (!pc.get_nt_native_path (upath))
+    {
+      syscall_printf ("0 = fhandler_base::open (%s, %p)",
+		      get_win32_name (), flags);
+      return 0;
+    }
 
   int res = 0;
   HANDLE x;
@@ -681,6 +682,7 @@ done:
 
   syscall_printf ("%d = fhandler_base::open (%s, %p)", res, get_win32_name (),
 		  flags);
+  RtlFreeUnicodeString (&upath);
   return res;
 }
 
Index: ntdll.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/ntdll.h,v
retrieving revision 1.28
diff -u -p -r1.28 ntdll.h
--- ntdll.h	2 May 2005 03:50:07 -0000	1.28
+++ ntdll.h	16 May 2005 10:52:55 -0000
@@ -507,4 +507,8 @@ extern "C"
   VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
   ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
   ULONG WINAPI RtlIsDosDeviceName_U (PCWSTR);
+  ULONG WINAPI RtlDosPathNameToNtPathName_U (PCWSTR, PUNICODE_STRING,
+					     PCWSTR *, PUNICODE_STRING);
+  ULONG WINAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR);
+  ULONG WINAPI RtlFreeUnicodeString (PUNICODE_STRING);
 }
Index: path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.374
diff -u -p -r1.374 path.cc
--- path.cc	13 May 2005 21:05:46 -0000	1.374
+++ path.cc	16 May 2005 10:52:56 -0000
@@ -75,6 +75,7 @@ details. */
 #include "shared_info.h"
 #include "registry.h"
 #include "cygtls.h"
+#include "ntdll.h"
 #include <assert.h>
 
 static int normalize_win32_path (const char *, char *, char *&);
@@ -482,25 +483,29 @@ path_conv::set_normalized_path (const ch
 PUNICODE_STRING
 path_conv::get_nt_native_path (UNICODE_STRING &upath)
 {
-  if (path[0] != '\\')			/* X:\...  or NUL, etc. */
+  if (path[0] == '\\' && path[1] != '\\')
     {
-      str2uni_cat (upath, "\\??\\");
-      str2uni_cat (upath, path);
+      /* This handles all paths already given in NT speak.  On writing this
+         comment, these are the raw device paths. */
+      if (RtlCreateUnicodeStringFromAsciiz (&upath, path))
+	return &upath;
     }
-  else if (path[1] != '\\')		/* \Device\... */
-    str2uni_cat (upath, path);
-  else if (path[2] != '.'
-	   || path[3] != '\\')		/* \\server\share\... */
-    {
-      str2uni_cat (upath, "\\??\\UNC\\");
-      str2uni_cat (upath, path + 2);
-    }
-  else					/* \\.\device */
+  else
     {
-      str2uni_cat (upath, "\\??\\");
-      str2uni_cat (upath, path + 4);
+      wchar_t wc_path[CYG_MAX_PATH];
+      sys_mbstowcs (wc_path, path, CYG_MAX_PATH);
+      if (RtlDosPathNameToNtPathName_U (wc_path, &upath, NULL, NULL))
+	{
+#ifdef DEBUGGING
+	  char nt_path[CYG_MAX_PATH + 5];
+	  sys_wcstombs (nt_path, upath.Buffer, CYG_MAX_PATH);
+	  debug_printf ("DOS: <%s> NT: <%s>", path, nt_path);
+#endif
+	  return &upath;
+	}
     }
-  return &upath;
+  set_errno (ENOMEM);
+  return NULL;
 }
 
 /* Convert an arbitrary path SRC to a pure Win32 path, suitable for
@@ -902,35 +907,6 @@ out:
 
   if (dev.isfs ())
     {
-      if (strncmp (path, "\\\\.\\", 4))
-	{
-	  /* Windows ignores trailing dots and spaces */
-	  char *tail = NULL;
-	  for (char *p = path; *p; p++)
-	    if (*p != '.' && *p != ' ')
-	      tail = NULL;
-	    else if (p[1] == '\\')
-	      {
-		error = ENOENT;
-		return;
-	      }
-	    else if (!tail)
-	      tail = p;
-
-	  if (!tail)
-	    /* nothing */;
-	  else if (tail[-1] != '\\')
-	    {
-	      *tail = '\0';
-	      strip_tail = true;
-	    }
-	  else
-	    {
-	      error = ENOENT;
-	      return;
-	    }
-	}
-
       if (fs.update (path))
 	{
 	  debug_printf ("this->path(%s), has_acls(%d)", path, fs.has_acls ());

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          mailto:cygwin@cygwin.com
Red Hat, Inc.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]