From 637f5ce0fecddfb14d8f0b6a12d791fac469ad84 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 28 Jul 2000 22:33:43 +0000 Subject: [PATCH] * 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_to_registry): Write cygdrive prefix to the appropriate registry hive. Overwrite in-memory copy of cygdrive, if appropriate. (mount_info::remove_cygdrive_info_from_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. --- winsup/cygwin/ChangeLog | 20 +++++ winsup/cygwin/dcrt0.cc | 1 + winsup/cygwin/external.cc | 15 ++++ winsup/cygwin/include/sys/cygwin.h | 3 +- winsup/cygwin/path.cc | 114 ++++++++++++++++++++++++++--- winsup/cygwin/registry.cc | 11 +++ winsup/cygwin/shared.h | 3 + 7 files changed, 155 insertions(+), 12 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index c44dcbef7..4785301cd 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +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_to_registry): Write cygdrive prefix to + the appropriate registry hive. Overwrite in-memory copy of cygdrive, + if appropriate. + (mount_info::remove_cygdrive_info_from_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 23:33:32 2000 Christopher Faylor * include/cygwin/version.h: Bump DLL minor version number to 4. diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 283c2f3f4..8a5240606 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -1217,6 +1217,7 @@ LoadDLLfunc (OpenProcessToken, 12, advapi32) 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) diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index e626cf5ef..f187d9779 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -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, ...) { @@ -107,6 +115,13 @@ cygwin_internal (cygwin_getinfo_types t, ...) 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; } diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index d2cf9482f..978e976d5 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -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 diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 7995747bf..a46ac4f41 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1497,17 +1497,39 @@ mount_info::del_reg_mount (const char * posix_path, unsigned flags) 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_registry () 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_registry (const char *cygdrive_prefix, unsign 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_from_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_from_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; diff --git a/winsup/cygwin/registry.cc b/winsup/cygwin/registry.cc index e4439663b..af543ba67 100644 --- a/winsup/cygwin/registry.cc +++ b/winsup/cygwin/registry.cc @@ -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) diff --git a/winsup/cygwin/shared.h b/winsup/cygwin/shared.h index d6e465544..fa14492cb 100644 --- a/winsup/cygwin/shared.h +++ b/winsup/cygwin/shared.h @@ -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_from_registry (const char *cygdrive_prefix, unsigned flags); + int get_cygdrive_prefixes (char *user, char *system); void import_v1_mounts ();