* cygprops.h: New file.
* dtable.cc (handle_to_fn): Add check for correct installation_key string in object name for pipes and ttys. * external.cc (cygwin_internal): Add CW_GET_INSTKEY to allow fetching the installation_key from cygserver. * fhandler_fifo.cc (fhandler_fifo::fifo_name): Add installation_key to fifo name. * globals.cc: Include cygprops.h. (_RDATA): Move slightly and add comment. (cygwin_props): Define. * mount.cc (mount_info::init): Accommodate the fact that installation_root is now a global variable in DLL common shared memory, rather than a member of cygwin_shared. * pipe.cc (fhandler_pipe::create_selectable): Add installation_key to pipe name. * shared.cc (installation_root): Define here for storage in DLL common shared memory. (installation_key): Ditto. (installation_key_buf): Ditto. (init_installation_root): Convert from shared_info method to ordinary function. Add initializing installation_key. Invalidate installation_key depending of value of disable_key property. Add comment to explain. (get_shared_parent_dir): Add installation_key to directory name. (get_session_parent_dir): Ditto. (shared_info::initialize): Move call to init_installation_root from here... (memory_init): ...to here. Add debug output to print installation root and installation key. Add comment to explain why. * shared_info.h (SHARED_INFO_CB): Recalculate. (CURR_SHARED_MAGIC): Ditto. (class shared_info): Remove definition of installation_root and declaration of init_installation_root. (init_installation_root): Declare. (installation_root): Declare. (installation_key): Declare. * uinfo.cc (pwdgrp::load): Accommodate the fact that installation_root is now a global variable in DLL common shared memory. * include/cygwin/version.h: Bump API minor number. (CYGWIN_INFO_INSTALLATIONS_NAME): Add. * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_GET_INSTKEY.
This commit is contained in:
@@ -26,12 +26,96 @@ details. */
|
||||
#include "ntdll.h"
|
||||
#include <alloca.h>
|
||||
#include <wchar.h>
|
||||
#include <wingdi.h>
|
||||
#include <winuser.h>
|
||||
|
||||
shared_info NO_COPY *cygwin_shared;
|
||||
user_info NO_COPY *user_shared;
|
||||
HANDLE NO_COPY cygwin_shared_h;
|
||||
HANDLE NO_COPY cygwin_user_h;
|
||||
|
||||
WCHAR installation_root[PATH_MAX] __attribute__((section (".cygwin_dll_common"), shared));
|
||||
UNICODE_STRING installation_key __attribute__((section (".cygwin_dll_common"), shared));
|
||||
WCHAR installation_key_buf[18] __attribute__((section (".cygwin_dll_common"), shared));
|
||||
|
||||
/* Use absolute path of cygwin1.dll to derive the Win32 dir which
|
||||
is our installation_root. Note that we can't handle Cygwin installation
|
||||
root dirs of more than 4K path length. I assume that's ok...
|
||||
|
||||
This function also generates the installation_key value. It's a 64 bit
|
||||
hash value based on the path of the Cygwin DLL itself. It's subsequently
|
||||
used when generating shared object names. Thus, different Cygwin
|
||||
installations generate different object names and so are isolated from
|
||||
each other.
|
||||
|
||||
Having this information, the installation key together with the
|
||||
installation root path is written to the registry. The idea is that
|
||||
cygcheck can print the paths into which the Cygwin DLL has been
|
||||
installed for debugging purposes.
|
||||
|
||||
Last but not least, the new cygwin properties datastrcuture is checked
|
||||
for the "disabled_key" value, which is used to determine whether the
|
||||
installation key is actually added to all object names or not. This is
|
||||
used as a last resort for debugging purposes, usually. However, there
|
||||
could be another good reason to re-enable object name collisions between
|
||||
multiple Cygwin DLLs, which we're just not aware of right now. Cygcheck
|
||||
can be used to change the value in an existing Cygwin DLL binary. */
|
||||
|
||||
void
|
||||
init_installation_root ()
|
||||
{
|
||||
if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX))
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"GetModuleFileNameW(%p, %p, %u), %E",
|
||||
cygwin_hmodule, installation_root, PATH_MAX);
|
||||
PWCHAR p = installation_root;
|
||||
if (wcsncmp (p, L"\\\\?\\", 4)) /* No long path prefix. */
|
||||
{
|
||||
if (!wcsncasecmp (p, L"\\\\", 2)) /* UNC */
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\UN");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 6);
|
||||
*p = L'C';
|
||||
}
|
||||
else
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4);
|
||||
}
|
||||
}
|
||||
installation_root[1] = L'?';
|
||||
|
||||
RtlInitEmptyUnicodeString (&installation_key, installation_key_buf,
|
||||
sizeof installation_key_buf);
|
||||
RtlInt64ToHexUnicodeString (hash_path_name (0, installation_root),
|
||||
&installation_key, FALSE);
|
||||
|
||||
PWCHAR w = wcsrchr (installation_root, L'\\');
|
||||
if (w)
|
||||
{
|
||||
*w = L'\0';
|
||||
w = wcsrchr (installation_root, L'\\');
|
||||
}
|
||||
if (!w)
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"Invalid DLL path");
|
||||
*w = L'\0';
|
||||
|
||||
for (int i = 1; i >= 0; --i)
|
||||
{
|
||||
reg_key r (i, KEY_WRITE, CYGWIN_INFO_INSTALLATIONS_NAME, NULL);
|
||||
if (r.set_string (installation_key_buf, installation_root)
|
||||
== ERROR_SUCCESS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (cygwin_props.disable_key)
|
||||
{
|
||||
installation_key.Length = 0;
|
||||
installation_key.Buffer[0] = L'\0';
|
||||
}
|
||||
}
|
||||
|
||||
/* This function returns a handle to the top-level directory in the global
|
||||
NT namespace used to implement global objects including shared memory. */
|
||||
|
||||
@@ -46,9 +130,10 @@ get_shared_parent_dir ()
|
||||
if (!dir)
|
||||
{
|
||||
WCHAR bnoname[MAX_PATH];
|
||||
__small_swprintf (bnoname, L"\\BaseNamedObjects\\%s%s",
|
||||
__small_swprintf (bnoname, L"\\BaseNamedObjects\\%s%s-%S",
|
||||
cygwin_version.shared_id,
|
||||
_cygwin_testing ? cygwin_version.dll_build_date : "");
|
||||
_cygwin_testing ? cygwin_version.dll_build_date : "",
|
||||
&installation_key);
|
||||
RtlInitUnicodeString (&uname, bnoname);
|
||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
|
||||
NULL, everyone_sd (CYG_SHARED_DIR_ACCESS));
|
||||
@@ -79,9 +164,10 @@ get_session_parent_dir ()
|
||||
{
|
||||
WCHAR bnoname[MAX_PATH];
|
||||
__small_swprintf (bnoname,
|
||||
L"\\Sessions\\BNOLINKS\\%d\\%s%s",
|
||||
L"\\Sessions\\BNOLINKS\\%d\\%s%s-%S",
|
||||
psi.SessionId, cygwin_version.shared_id,
|
||||
_cygwin_testing ? cygwin_version.dll_build_date : "");
|
||||
_cygwin_testing ? cygwin_version.dll_build_date : "",
|
||||
&installation_key);
|
||||
RtlInitUnicodeString (&uname, bnoname);
|
||||
InitializeObjectAttributes (&attr, &uname, OBJ_INHERIT | OBJ_OPENIF,
|
||||
NULL, everyone_sd(CYG_SHARED_DIR_ACCESS));
|
||||
@@ -270,46 +356,6 @@ shared_destroy ()
|
||||
UnmapViewOfFile (user_shared);
|
||||
}
|
||||
|
||||
/* Use absolute path of cygwin1.dll to derive the Win32 dir which
|
||||
is our installation root. Note that we can't handle Cygwin installation
|
||||
root dirs of more than 4K path length. I assume that's ok... */
|
||||
void
|
||||
shared_info::init_installation_root ()
|
||||
{
|
||||
if (!GetModuleFileNameW (cygwin_hmodule, installation_root, PATH_MAX))
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"GetModuleFileNameW(%p, %p, %u), %E",
|
||||
cygwin_hmodule, installation_root, PATH_MAX);
|
||||
PWCHAR p = installation_root;
|
||||
if (wcsncmp (p, L"\\\\?\\", 4)) /* No long path prefix. */
|
||||
{
|
||||
if (!wcsncasecmp (p, L"\\\\", 2)) /* UNC */
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\UN");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 6);
|
||||
*p = L'C';
|
||||
}
|
||||
else
|
||||
{
|
||||
p = wcpcpy (p, L"\\??\\");
|
||||
GetModuleFileNameW (cygwin_hmodule, p, PATH_MAX - 4);
|
||||
}
|
||||
}
|
||||
installation_root[1] = L'?';
|
||||
|
||||
PWCHAR w = wcsrchr (installation_root, L'\\');
|
||||
if (w)
|
||||
{
|
||||
*w = L'\0';
|
||||
w = wcsrchr (installation_root, L'\\');
|
||||
}
|
||||
if (!w)
|
||||
api_fatal ("Can't initialize Cygwin installation root dir.\n"
|
||||
"Invalid DLL path");
|
||||
|
||||
*w = L'\0';
|
||||
}
|
||||
|
||||
/* Initialize obcaseinsensitive. Default to case insensitive on pre-XP. */
|
||||
void
|
||||
shared_info::init_obcaseinsensitive ()
|
||||
@@ -349,7 +395,6 @@ shared_info::initialize ()
|
||||
|
||||
if (!sversion)
|
||||
{
|
||||
init_installation_root ();/* Initialize installation root dir. */
|
||||
init_obcaseinsensitive ();/* Initialize obcaseinsensitive. */
|
||||
tty.init (); /* Initialize tty table. */
|
||||
mt.initialize (); /* Initialize shared tape information. */
|
||||
@@ -373,6 +418,10 @@ memory_init (bool init_cygheap)
|
||||
cygheap->user.init ();
|
||||
}
|
||||
|
||||
/* Initialize installation root dir. */
|
||||
if (!installation_root[0])
|
||||
init_installation_root ();
|
||||
|
||||
/* Initialize general shared memory */
|
||||
shared_locations sh_cygwin_shared;
|
||||
cygwin_shared = (shared_info *) open_shared (L"shared",
|
||||
@@ -380,6 +429,11 @@ memory_init (bool init_cygheap)
|
||||
cygwin_shared_h,
|
||||
sizeof (*cygwin_shared),
|
||||
sh_cygwin_shared = SH_CYGWIN_SHARED);
|
||||
/* Defer debug output printing the installation root and installation key
|
||||
up to this point. Debug output except for system_printf requires
|
||||
the global shared memory to exist. */
|
||||
debug_printf ("Installation root: <%W> key: <%S>",
|
||||
installation_root, &installation_key);
|
||||
cygwin_shared->initialize ();
|
||||
user_shared_create (false);
|
||||
}
|
||||
|
Reference in New Issue
Block a user