Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Date: Fri, 28 Jul 2000 00:19:12 -0400 From: Jason Tishler To: cygwin-developers AT sources DOT redhat DOT com Subject: [PATCH]: Cygdrive Path Prefix Message-ID: <20000728001912.A1148@OLMY> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="WXEtizwpuPcl6rIh" Content-Disposition: inline User-Agent: Mutt/1.2.4i Organization: Dot Hill Systems Corp. --WXEtizwpuPcl6rIh Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 DOT Tishler AT dothill DOT com Hazlet, NJ 07730 USA WWW: http://www.dothill.com --WXEtizwpuPcl6rIh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cygdrive.diff" 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 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 change the cygdrive path prefix to +--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"); } --WXEtizwpuPcl6rIh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=ChangeLog-cygwin Thu Jul 27 22:54:28 2000 Jason Tishler * 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. --WXEtizwpuPcl6rIh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=ChangeLog-utils Thu Jul 27 22:54:28 2000 Jason Tishler * 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. --WXEtizwpuPcl6rIh Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="cygdrive.txt" # 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 .. --WXEtizwpuPcl6rIh--