This is the mail archive of the cygwin-developers@sources.redhat.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]

[PATCH]: Cygdrive Path Prefix


On Tue, Jun 13, 2000 at 04:57:30PM -0400, Jason Tishler wrote:
> Following the recommendations from "Re: mount's --change-cygdrive-prefix
> option" I have implemented the following:
> 
> 1. Fixed mount's --change-cygdrive-prefix functionality to save the
> specified cygdrive path prefix to the user or system registry area as
> appropriate (ie, -s or -u).
> 
> 2. Enhanced umount by adding the corresponding --remove-cygdrive-prefix
> functionality.
> 
> Bob McGowan wrote:
> > It is useful to display the current state before trying to
> > modify it.  Maybe the mount command should have a specific option to do
> > so, perhaps "--show-cygdrive-prefix"?

I have finally finished the above and generated a patch against CVS.
Hopefully, (really) late is better than never.  See attached:

    cygdrive.diff:    patch
    ChangeLog-cygwin: cygwin/ChangeLog entry
    ChangeLog-utils:  utils/ChangeLog entry
    cygdrive.txt:     sample usage session

I'm not sure that I like the output from "mount --show-cygdrive-prefix" --
feedback is gladly accepted.

Thanks,
Jason

-- 
Jason Tishler
Director, Software Engineering       Phone: +1 (732) 264-8770 x235
Dot Hill Systems Corporation         Fax:   +1 (732) 264-8798
82 Bethany Road, Suite 7             Email: Jason.Tishler@dothill.com
Hazlet, NJ 07730 USA                 WWW:   http://www.dothill.com
Index: cygwin/dcrt0.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.37
diff -u -p -r1.37 dcrt0.cc
--- dcrt0.cc	2000/07/17 19:18:21	1.37
+++ dcrt0.cc	2000/07/28 02:09:06
@@ -1217,6 +1217,7 @@ LoadDLLfunc (OpenProcessToken, 12, advap
 LoadDLLfunc (RegCloseKey, 4, advapi32)
 LoadDLLfunc (RegCreateKeyExA, 36, advapi32)
 LoadDLLfunc (RegDeleteKeyA, 8, advapi32)
+LoadDLLfunc (RegDeleteValueA, 8, advapi32)
 LoadDLLfunc (RegLoadKeyA, 12, advapi32)
 LoadDLLfunc (RegEnumKeyExA, 32, advapi32)
 LoadDLLfunc (RegOpenKeyExA, 20, advapi32)
Index: cygwin/external.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/external.cc,v
retrieving revision 1.5
diff -u -p -r1.5 external.cc
--- external.cc	2000/07/09 05:29:51	1.5
+++ external.cc	2000/07/28 02:09:06
@@ -63,6 +63,14 @@ fillout_pinfo (DWORD pid)
   return &ep;
 }
 
+static DWORD
+get_cygdrive_prefixes (char *user, char *system)
+{
+  shared_info *info = cygwin_getshared();
+  int res = info->mount.get_cygdrive_prefixes(user, system);
+  return (res == ERROR_SUCCESS) ? 1 : 0;
+}
+
 extern "C" DWORD
 cygwin_internal (cygwin_getinfo_types t, ...)
 {
@@ -106,6 +114,13 @@ cygwin_internal (cygwin_getinfo_types t,
       case CW_PERFILE:
 	perfile_table = va_arg (arg, struct __cygwin_perfile *);
 	return 0;
+
+      case CW_GET_CYGDRIVE_PREFIXES:
+	{
+	  char *user = va_arg (arg, char *);
+	  char *system = va_arg (arg, char *);
+	  return get_cygdrive_prefixes (user, system);
+	}
 
       default:
 	return (DWORD) -1;
Index: cygwin/path.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/path.cc,v
retrieving revision 1.38
diff -u -p -r1.38 path.cc
--- path.cc	2000/07/19 20:14:24	1.38
+++ path.cc	2000/07/28 02:09:36
@@ -1497,17 +1497,39 @@ mount_info::del_reg_mount (const char * 
 void
 mount_info::read_cygdrive_info_from_registry ()
 {
-  /* reg_key for user mounts in HKEY_CURRENT_USER. */
+  /* reg_key for user path prefix in HKEY_CURRENT_USER. */
   reg_key r;
 
   if (r.get_string ("cygdrive prefix", cygdrive, sizeof (cygdrive), "") != 0)
     {
-      /* Didn't find it so write the default to the registry and use it. */
-      write_cygdrive_info_to_registry ("/cygdrive", MOUNT_AUTO);
+      /* Didn't find the user path prefix so check the system path prefix. */
+
+      /* reg_key for system path prefix in HKEY_LOCAL_MACHINE.  */
+      reg_key r2 (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",
+		 CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
+		 CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
+		 CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
+		 NULL);
+
+    if (r2.get_string ("cygdrive prefix", cygdrive, sizeof (cygdrive), "") != 0)
+      {
+        /* Didn't find either so write the default to the registry and use it.
+	   NOTE: We are writing and using the user path prefix.  */
+        write_cygdrive_info_to_registry ("/cygdrive", MOUNT_AUTO);
+      }
+    else
+      {
+        /* Fetch system cygdrive_flags from registry; returns MOUNT_AUTO on
+	   error. */
+        cygdrive_flags = r2.get_int ("cygdrive flags", MOUNT_AUTO);
+        slashify (cygdrive, cygdrive, 1);
+        cygdrive_len = strlen(cygdrive);
+      }
     }
   else
     {
-      /* Fetch cygdrive_flags from registry; returns MOUNT_AUTO on error. */
+      /* Fetch user cygdrive_flags from registry; returns MOUNT_AUTO on
+         error. */
       cygdrive_flags = r.get_int ("cygdrive flags", MOUNT_AUTO);
       slashify (cygdrive, cygdrive, 1);
       cygdrive_len = strlen(cygdrive);
@@ -1521,8 +1543,16 @@ mount_info::read_cygdrive_info_from_regi
 int
 mount_info::write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags)
 {
-  /* reg_key for user mounts in HKEY_CURRENT_USER. */
-  reg_key r;
+  /* Determine whether to modify user or system cygdrive path prefix. */
+  HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+
+  /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in
+     HKEY_LOCAL_MACHINE.  */
+  reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",
+	     CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
+	     CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
+	     CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
+	     NULL);
 
   /* Verify cygdrive prefix starts with a forward slash and if there's
      another character, it's not a slash. */
@@ -1541,14 +1571,64 @@ mount_info::write_cygdrive_info_to_regis
   r.set_string ("cygdrive prefix", hold_cygdrive_prefix);
   r.set_int ("cygdrive flags", flags);
 
-  /* This also needs to go in the in-memory copy of "cygdrive" */
-  slashify (cygdrive_prefix, cygwin_shared->mount.cygdrive, 1);
-  cygwin_shared->mount.cygdrive_flags = flags;
-  cygwin_shared->mount.cygdrive_len = strlen(cygwin_shared->mount.cygdrive);
+  /* This also needs to go in the in-memory copy of "cygdrive", but only if
+     appropriate:
+       1. setting user path prefix, or
+       2. overwriting (a previous) system path prefix */
+  if ((flags & MOUNT_SYSTEM) == 0 ||
+      (cygwin_shared->mount.cygdrive_flags & MOUNT_SYSTEM) != 0)
+    {
+      slashify (cygdrive_prefix, cygwin_shared->mount.cygdrive, 1);
+      cygwin_shared->mount.cygdrive_flags = flags;
+      cygwin_shared->mount.cygdrive_len = strlen(cygwin_shared->mount.cygdrive);
+    }
 
   return 0;
 }
 
+int
+mount_info::remove_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags)
+{
+  /* Determine whether to modify user or system cygdrive path prefix. */
+  HKEY top = (flags & MOUNT_SYSTEM) ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
+
+  /* reg_key for user path prefix in HKEY_CURRENT_USER or system path prefix in
+     HKEY_LOCAL_MACHINE.  */
+  reg_key r (top, KEY_ALL_ACCESS, "SOFTWARE",
+	     CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
+	     CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
+	     CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
+	     NULL);
+
+  /* Delete cygdrive prefix and flags. */
+  int res = r.killvalue ("cygdrive prefix");
+  int res2 = r.killvalue ("cygdrive flags");
+
+  /* Reinitialize the cygdrive path prefix to reflect to removal from the
+     registry. */
+  read_cygdrive_info_from_registry ();
+
+  return (res != ERROR_SUCCESS) ? res : res2;
+}
+
+int
+mount_info::get_cygdrive_prefixes (char *user, char *system)
+{
+  /* Get the user path prefix from HKEY_CURRENT_USER. */
+  reg_key r;
+  int res = r.get_string ("cygdrive prefix", user, MAX_PATH, "");
+
+  /* Get the system path prefix from HKEY_LOCAL_MACHINE. */
+  reg_key r2 (HKEY_LOCAL_MACHINE, KEY_ALL_ACCESS, "SOFTWARE",
+	      CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
+	      CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
+	      CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME,
+	      NULL);
+  int res2 = r2.get_string ("cygdrive prefix", system, MAX_PATH, "");
+
+  return (res != ERROR_SUCCESS) ? res : res2;
+}
+
 struct mntent *
 mount_info::getmntent (int x)
 {
@@ -1982,7 +2062,19 @@ extern "C"
 int
 cygwin_umount (const char *path, unsigned flags)
 {
-  int res = cygwin_shared->mount.del_item (path, flags, TRUE);
+  int res = -1;
+
+  if (flags & MOUNT_AUTO)
+    {
+      /* When flags include MOUNT_AUTO, take this to mean that we actually want
+         to remove the cygdrive prefix and flags without actually unmounting
+	 anything. */
+      res = cygwin_shared->mount.remove_cygdrive_info_to_registry (path, flags);
+    }
+  else
+    {
+      res = cygwin_shared->mount.del_item (path, flags, TRUE);
+    }
 
   syscall_printf ("%d = cygwin_umount (%s, %d)", res,  path, flags);
   return res;
Index: cygwin/registry.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/registry.cc,v
retrieving revision 1.5
diff -u -p -r1.5 registry.cc
--- registry.cc	2000/06/22 18:54:26	1.5
+++ registry.cc	2000/07/28 02:09:37
@@ -171,6 +171,17 @@ reg_key::kill (const char *name)
   return RegDeleteKeyA (key, name);
 }
 
+/* Delete the value specified by name of current key.  Returns the error code
+   from the RegDeleteValueA invocation. */
+
+int
+reg_key::killvalue (const char *name)
+{
+  if (key_is_invalid)
+    return key_is_invalid;
+  return RegDeleteValueA (key, name);
+}
+
 reg_key::~reg_key ()
 {
   if (!key_is_invalid)
Index: cygwin/shared.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/shared.h,v
retrieving revision 1.16
diff -u -p -r1.16 shared.h
--- shared.h	2000/07/19 20:14:24	1.16
+++ shared.h	2000/07/28 02:09:44
@@ -247,6 +247,7 @@ public:
   int error () {return key == (HKEY) INVALID_HANDLE_VALUE;}
 
   int kill (const char *child);
+  int killvalue (const char *name);
 
   HKEY get_key ();
   int get_int (const char *,int def);
@@ -336,6 +337,8 @@ public:
   struct mntent *getmntent (int x);
 
   int write_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
+  int remove_cygdrive_info_to_registry (const char *cygdrive_prefix, unsigned flags);
+  int get_cygdrive_prefixes (char *user, char *system);
 
   void import_v1_mounts ();
 
Index: cygwin/include/sys/cygwin.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/include/sys/cygwin.h,v
retrieving revision 1.12
diff -u -p -r1.12 cygwin.h
--- cygwin.h	2000/07/09 05:29:51	1.12
+++ cygwin.h	2000/07/28 02:09:48
@@ -59,7 +59,8 @@ typedef enum
     CW_GETVERSIONINFO,
     CW_READ_V1_MOUNT_TABLES,
     CW_USER_DATA,
-    CW_PERFILE
+    CW_PERFILE,
+	CW_GET_CYGDRIVE_PREFIXES
   } cygwin_getinfo_types;
 
 #define CW_NEXTPID 0x80000000	// or with pid to get next one
Index: utils/mount.cc
===================================================================
RCS file: /cvs/src/src/winsup/utils/mount.cc,v
retrieving revision 1.7
diff -u -p -r1.7 mount.cc
--- mount.cc	2000/07/13 21:49:36	1.7
+++ mount.cc	2000/07/28 02:09:54
@@ -22,6 +22,7 @@ details. */
 #include <errno.h>
 
 static void show_mounts (void);
+static void show_cygdrive_prefixes (void);
 static void change_cygdrive_prefix (const char *new_prefix, int flags);
 static int mount_already_exists (const char *posix_path, int flags);
 
@@ -96,6 +97,8 @@ usage (void)
 
 [-bs] --change-cygdrive-prefix <posixpath>
     change the cygdrive path prefix to <posixpath>
+--show-cygdrive-prefixes
+    show user and/or system cygdrive path prefixes
 --import-old-mounts
     copy old registry mount table mounts into the current mount areas
 ", progname);
@@ -136,6 +139,13 @@ main (int argc, const char **argv)
 	  cygwin_internal (CW_READ_V1_MOUNT_TABLES);
 	  exit (0);
 	}
+      else if (strcmp (argv[i], "--show-cygdrive-prefixes") == 0)
+	{
+	  if ((i + 1) != argc)
+	    usage ();
+
+	  show_cygdrive_prefixes ();
+	}
       else if (strcmp (argv[i], "-b") == 0)
 	flags |= MOUNT_BINARY;
       else if (strcmp (argv[i], "-t") == 0)
@@ -250,5 +260,26 @@ change_cygdrive_prefix (const char *new_
   if (mount (NULL, new_prefix, flags))
     error (new_prefix);
   
+  exit (0);
+}
+
+/* show_cygdrive_prefixes: Show the user and/or cygdrive path prefixes */
+static void
+show_cygdrive_prefixes ()
+{
+  /* Get the Cygdrive user and system path prefixes */
+  char user[MAX_PATH];
+  char system[MAX_PATH];
+  cygwin_internal (CW_GET_CYGDRIVE_PREFIXES, user, system);
+
+  /* Display the user and system cygdrive path prefixes, if necessary
+     (ie, not empty) */
+  const char *format = "%-18s  %-11s\n";
+  printf (format, "Prefix", "Type");
+  if (strlen (user) > 0)
+    printf (format, user, "user");
+  if (strlen (system) > 0)
+    printf (format, system, "system");
+
   exit (0);
 }
Index: utils/umount.cc
===================================================================
RCS file: /cvs/src/src/winsup/utils/umount.cc,v
retrieving revision 1.3
diff -u -p -r1.3 umount.cc
--- umount.cc	2000/06/08 12:54:12	1.3
+++ umount.cc	2000/07/28 02:09:57
@@ -19,6 +19,7 @@ static void remove_all_mounts ();
 static void remove_all_automounts ();
 static void remove_all_user_mounts ();
 static void remove_all_system_mounts ();
+static void remove_cygdrive_prefix (int flags);
 
 static const char *progname;
 
@@ -31,12 +32,13 @@ usage (void)
   fprintf (stderr, "--remove-all-mounts = remove all mounts\n");
   fprintf (stderr, "--remove-auto-mounts = remove all automatically mounted mounts\n");
   fprintf (stderr, "--remove-user-mounts = remove all mounts in the current user mount registry area, including auto mounts\n");
-  fprintf (stderr, "--remove-system-mounts = Remove all mounts in the system-wide mount registry area\n");
+  fprintf (stderr, "--remove-system-mounts = remove all mounts in the system-wide mount registry area\n");
+  fprintf (stderr, "[-s] --remove_cygdrive_prefix = remove cygdrive path prefix\n");
   exit (1);
 }
 
 static void
-error (char *path)
+error (const char *path)
 {
   fprintf (stderr, "%s: %s: %s\n", progname, path, strerror (errno));
   exit (1);
@@ -81,6 +83,11 @@ main (int argc, char **argv)
 	  remove_all_automounts ();
 	  exit (0);
 	}
+      else if (strcmp (argv[i], "--remove_cygdrive_prefix") == 0)
+	{
+	  remove_cygdrive_prefix (flags);
+	  exit (0);
+	}
       else
 	usage ();
     }
@@ -181,4 +188,13 @@ remove_all_system_mounts ()
     }
 
   endmntent (m);
+}
+
+/* remove_cygdrive_prefix: Remove cygdrive user or system path prefix. */
+static void
+remove_cygdrive_prefix (int flags)
+{
+  int res = cygwin_umount(NULL, flags | MOUNT_AUTO);
+  if (res)
+    error ("remove_cygdrive_prefix");
 }
Thu Jul 27 22:54:28 2000  Jason Tishler <jt@dothill.com>

	* dcrt0.cc (dummy_autoload) : Add load statement for RegDeleteValueA.
	* external.cc (get_cygdrive_prefixes): New function.
	(cygwin_internal): Add CW_GET_CYGDRIVE_PREFIXES case.
	* path.cc (mount_info::read_cygdrive_info_from_registry): Read system
	cygdrive prefix if user one is undefined.
	(mount_info::write_cygdrive_info_from_registry): Write cygdrive prefix
	to the appropriate registry hive.  Overwrite in-memory copy of
	cygdrive, if appropriate.
	(mount_info::remove_cygdrive_info_to_registry): New method.
	(mount_info::get_cygdrive_prefixes): New method.
	(cygwin_umount): Remove cygdrive prefix, if appropriate.
	* registry.cc (reg_key::killvalue): New method.
	* shared.h (class reg_key): Add killvalue,
	remove_cygdrive_info_to_registry, and get_cygdrive_prefixes
	declarations.
	* include/sys/cygwin.h (cygwin_getinfo_types): Add
	CW_GET_CYGDRIVE_PREFIXES.
Thu Jul 27 22:54:28 2000  Jason Tishler <jt@dothill.com>

	* utils/mount.cc (main): Add --show-cygdrive-prefixes option.
	(show_cygdrive_prefixes): New function.
	* utils/umount.cc (main): Add --remove_cygdrive_prefix option.
	(error): Change signature from 'char *' to 'const char *'.
	(remove_cygdrive_prefix): New function.
# Default cygdrive prefix behavior (user is defined, system is not defined)
$ mount --show-cygdrive-prefixes
Prefix              Type
/cygdrive           user

$ ls /cygdrive/c
AUTOEXEC.BAT      Oetc              cdrom             liprefs.js
..

# Change system cygdrive prefix
$ mount -b -s --change-cygdrive-prefix /mnt
$ mount --show-cygdrive-prefixes
Prefix              Type
/cygdrive           user
/mnt                system

# Since user cygdrive prefix is defined, system one is ignored
$ ls /cygdrive/c
AUTOEXEC.BAT      Oetc              cdrom             liprefs.js
..
$ ls /mnt/c
ls: /mnt/c: No such file or directory

# Remove user cygdrive prefix
$ umount --remove_cygdrive_prefix
$ mount --show-cygdrive-prefixes
Prefix              Type
/mnt                system

# Since user cygdrive prefix is not defined, system one is used
$ ls /cygdrive/c
ls: /cygdrive/c: No such file or directory
$ ls /mnt/c
AUTOEXEC.BAT      Oetc              cdrom             liprefs.js
..

# Remove system cydrive prefix
$ umount -s --remove_cygdrive_prefix
$ mount --show-cygdrive-prefixes
Prefix              Type
/cygdrive           user

$ ls /cygdrive/c
AUTOEXEC.BAT      Oetc              cdrom             liprefs.js
..

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