dll_list: Store dll file name as full NT path.
Store loaded dll's file name as full NT path. * dll_init.h (struct dll): Rename member variable name to ntname. (struct dll_list): Declare private static member variable nt_max_path_buffer. Declare public static methods form_ntname, form_shortname. Define public static methods nt_max_path_buf, buffered_shortname. (dll_list::operator []): Use PCWCHAR rather than const PWCHAR. (dll_list::find_by_modname): Ditto. * dll_init.cc (in_load_after_fork): Define earlier in file. (struct dll_list): Rename member variable name to ntname. Define nt_max_path_buffer variable. Implement static methods form_ntname, form_shortname. (dll_list::operator []): Use PCWCHAR rather than const PWCHAR. (dll_list::find_by_modname): Ditto. (reserve_at): Ditto. (release_at): Ditto. (dll_list::alloc): Use nt_max_path_buf method instead of local buffer. Store module file name as full NT path, convert using the form_ntname static method. (dll_list::load_after_fork): Call load_after_fork_impl only when reload_on_fork is set. * fork.cc (frok::child): Call dlls.load_after_fork even without need to dynamically load dlls. (frok::parent): Move syscall_printf into the retry loop.
This commit is contained in:
parent
9fa22dba55
commit
2678c4efe1
@ -30,10 +30,129 @@ extern void __stdcall check_sanity_and_sync (per_process *);
|
|||||||
|
|
||||||
dll_list dlls;
|
dll_list dlls;
|
||||||
|
|
||||||
|
WCHAR NO_COPY dll_list::nt_max_path_buffer[NT_MAX_PATH];
|
||||||
|
|
||||||
muto dll_list::protect;
|
muto dll_list::protect;
|
||||||
|
|
||||||
static bool dll_global_dtors_recorded;
|
static bool dll_global_dtors_recorded;
|
||||||
|
|
||||||
|
/* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork
|
||||||
|
time if this is a linked DLL or a dynamically loaded DLL. In either case,
|
||||||
|
both, cygwin_finished_initializing and in_forkee are true, so they are not
|
||||||
|
sufficient to discern the situation. */
|
||||||
|
static bool NO_COPY in_load_after_fork;
|
||||||
|
|
||||||
|
/* Into ntbuf with ntbufsize, prints name prefixed with "\\??\\"
|
||||||
|
or "\\??\\UNC" as necessary to form the native NT path name.
|
||||||
|
Returns the end of the resulting string in ntbuf.
|
||||||
|
Supports using (a substring of) ntbuf as name argument. */
|
||||||
|
PWCHAR dll_list::form_ntname (PWCHAR ntbuf, size_t ntbufsize, PCWCHAR name)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
/* avoid using path_conv here: cygheap might not be
|
||||||
|
initialized when started from non-cygwin process,
|
||||||
|
or still might be frozen in_forkee */
|
||||||
|
if (name[0] == L'\0' || ntbufsize < 8)
|
||||||
|
break;
|
||||||
|
if (name[1] == L':') /* short Win32 drive letter path name */
|
||||||
|
{
|
||||||
|
int winlen = min (ntbufsize - 5, wcslen (name));
|
||||||
|
if (ntbuf + 4 != name)
|
||||||
|
memmove (ntbuf + 4, name, sizeof (*ntbuf) * winlen);
|
||||||
|
wcsncpy (ntbuf, L"\\??\\", 4);
|
||||||
|
ntbuf += 4 + winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!wcsncmp (name, L"\\\\?\\", 4)) /* long Win32 path name */
|
||||||
|
{
|
||||||
|
int winlen = min (ntbufsize - 1, wcslen (name));
|
||||||
|
if (ntbuf != name)
|
||||||
|
memmove (ntbuf, name, sizeof (*ntbuf) * winlen);
|
||||||
|
ntbuf[1] = L'?';
|
||||||
|
ntbuf += winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!wcsncmp (name, L"\\\\", 2)) /* short Win32 UNC path name */
|
||||||
|
{
|
||||||
|
name += 1; /* skip first backslash */
|
||||||
|
int winlen = min (ntbufsize - 8, wcslen (name));
|
||||||
|
if (ntbuf + 7 != name)
|
||||||
|
memmove (ntbuf + 7, name, sizeof (*ntbuf) * winlen);
|
||||||
|
wcsncpy (ntbuf, L"\\??\\UNC", 7);
|
||||||
|
ntbuf += 7 + winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!wcsncmp (name, L"\\??\\", 4)) /* already a long NT path name */
|
||||||
|
{
|
||||||
|
int winlen = min (ntbufsize - 1, wcslen (name));
|
||||||
|
if (ntbuf != name)
|
||||||
|
memmove (ntbuf, name, sizeof (*ntbuf) * winlen);
|
||||||
|
ntbuf += winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
system_printf ("WARNING: invalid path name '%W'", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ntbufsize)
|
||||||
|
*ntbuf = L'\0';
|
||||||
|
return ntbuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Into shortbuf with shortbufsize, prints name with "\\??\\"
|
||||||
|
or "\\??\\UNC" prefix removed/modified as necessary to form
|
||||||
|
the short Win32 path name.
|
||||||
|
Returns the end of the resulting string in shortbuf.
|
||||||
|
Supports using (a substring of) shortbuf as name argument. */
|
||||||
|
PWCHAR
|
||||||
|
dll_list::form_shortname (PWCHAR shortbuf, size_t shortbufsize, PCWCHAR name)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
/* avoid using path_conv here: cygheap might not be
|
||||||
|
initialized when started from non-cygwin process,
|
||||||
|
or still might be frozen in_forkee */
|
||||||
|
if (name[0] == L'\0' || shortbufsize < 2)
|
||||||
|
break;
|
||||||
|
if (name[0] == L'\\' &&
|
||||||
|
(name[1] == L'\\' || name[1] == L'?') &&
|
||||||
|
name[2] == L'?' &&
|
||||||
|
name[3] == L'\\') /* long Win32 or NT path name */
|
||||||
|
name += 4;
|
||||||
|
if (name[1] == L':') /* short Win32 drive letter path name */
|
||||||
|
{
|
||||||
|
int ntlen = min (shortbufsize - 1, wcslen (name));
|
||||||
|
if (shortbuf != name)
|
||||||
|
memmove (shortbuf, name, sizeof (*shortbuf) * ntlen);
|
||||||
|
shortbuf += ntlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!wcsncmp (name, L"UNC\\", 4)) /* UNC path name */
|
||||||
|
{
|
||||||
|
name += 3; /* skip "UNC" */
|
||||||
|
int winlen = min (shortbufsize - 2, wcslen (name));
|
||||||
|
if (shortbuf + 1 != name)
|
||||||
|
memmove (shortbuf + 1, name, sizeof (*shortbuf) * winlen);
|
||||||
|
shortbuf[0] = L'\\';
|
||||||
|
shortbuf += 1 + winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!wcsncmp (name, L"\\\\", 2)) /* already a short Win32 UNC path name */
|
||||||
|
{
|
||||||
|
int winlen = min (shortbufsize - 1, wcslen (name));
|
||||||
|
if (shortbuf != name)
|
||||||
|
memmove (shortbuf, name, sizeof (*shortbuf) * winlen);
|
||||||
|
shortbuf += winlen;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
system_printf ("WARNING: invalid path name '%W'", name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (shortbufsize)
|
||||||
|
*shortbuf = L'\0';
|
||||||
|
return shortbuf;
|
||||||
|
}
|
||||||
|
|
||||||
/* Run destructors for all DLLs on exit. */
|
/* Run destructors for all DLLs on exit. */
|
||||||
void
|
void
|
||||||
dll_global_dtors ()
|
dll_global_dtors ()
|
||||||
@ -148,11 +267,11 @@ dll::init ()
|
|||||||
of dll_list::alloc, as well as the comment preceeding the definition of
|
of dll_list::alloc, as well as the comment preceeding the definition of
|
||||||
the in_load_after_fork bool later in the file. */
|
the in_load_after_fork bool later in the file. */
|
||||||
dll *
|
dll *
|
||||||
dll_list::operator[] (const PWCHAR name)
|
dll_list::operator[] (PCWCHAR ntname)
|
||||||
{
|
{
|
||||||
dll *d = &start;
|
dll *d = &start;
|
||||||
while ((d = d->next) != NULL)
|
while ((d = d->next) != NULL)
|
||||||
if (!wcscasecmp (name, d->name))
|
if (!wcscasecmp (ntname, d->ntname))
|
||||||
return d;
|
return d;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -160,7 +279,7 @@ dll_list::operator[] (const PWCHAR name)
|
|||||||
|
|
||||||
/* Look for a dll based on the basename. */
|
/* Look for a dll based on the basename. */
|
||||||
dll *
|
dll *
|
||||||
dll_list::find_by_modname (const PWCHAR modname)
|
dll_list::find_by_modname (PCWCHAR modname)
|
||||||
{
|
{
|
||||||
dll *d = &start;
|
dll *d = &start;
|
||||||
while ((d = d->next) != NULL)
|
while ((d = d->next) != NULL)
|
||||||
@ -177,58 +296,47 @@ dll *
|
|||||||
dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
dll_list::alloc (HINSTANCE h, per_process *p, dll_type type)
|
||||||
{
|
{
|
||||||
/* Called under loader lock conditions so this function can't be called
|
/* Called under loader lock conditions so this function can't be called
|
||||||
multiple times in parallel. A static buffer is safe. */
|
multiple times in parallel. The static buffer is safe. */
|
||||||
static WCHAR buf[NT_MAX_PATH];
|
PWCHAR ntname = nt_max_path_buf ();
|
||||||
GetModuleFileNameW (h, buf, NT_MAX_PATH);
|
GetModuleFileNameW (h, ntname, NT_MAX_PATH);
|
||||||
PWCHAR name = buf;
|
PWCHAR modname = form_ntname (ntname, NT_MAX_PATH, ntname);
|
||||||
if (!wcsncmp (name, L"\\\\?\\", 4))
|
while (modname > ntname && *(modname - 1) != L'\\')
|
||||||
{
|
--modname;
|
||||||
name += 4;
|
|
||||||
if (!wcsncmp (name, L"UNC\\", 4))
|
|
||||||
{
|
|
||||||
name += 2;
|
|
||||||
*name = L'\\';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DWORD namelen = wcslen (name);
|
|
||||||
PWCHAR modname = wcsrchr (name, L'\\') + 1;
|
|
||||||
|
|
||||||
guard (true);
|
guard (true);
|
||||||
/* Already loaded? For linked DLLs, only compare the basenames. Linked
|
/* Already loaded? For linked DLLs, only compare the basenames. Linked
|
||||||
DLLs are loaded using just the basename and the default DLL search path.
|
DLLs are loaded using just the basename and the default DLL search path.
|
||||||
The Windows loader picks up the first one it finds. */
|
The Windows loader picks up the first one it finds. */
|
||||||
dll *d = (type == DLL_LINK) ? dlls.find_by_modname (modname) : dlls[name];
|
dll *d = (type == DLL_LINK) ? dlls.find_by_modname (modname) : dlls[ntname];
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
/* We only get here in the forkee. */
|
/* We only get here in the forkee. */
|
||||||
if (d->handle != h)
|
if (d->handle != h)
|
||||||
fabort ("%W: Loaded to different address: parent(%p) != child(%p)",
|
fabort ("%W: Loaded to different address: parent(%p) != child(%p)",
|
||||||
name, d->handle, h);
|
ntname, d->handle, h);
|
||||||
/* If this DLL has been linked against, and the full path differs, try
|
/* If this DLL has been linked against, and the full path differs, try
|
||||||
to sanity check if this is the same DLL, just in another path. */
|
to sanity check if this is the same DLL, just in another path. */
|
||||||
else if (type == DLL_LINK && wcscasecmp (name, d->name)
|
else if (type == DLL_LINK && wcscasecmp (ntname, d->ntname)
|
||||||
&& (d->p.data_start != p->data_start
|
&& (d->p.data_start != p->data_start
|
||||||
|| d->p.data_start != p->data_start
|
|| d->p.data_start != p->data_start
|
||||||
|| d->p.bss_start != p->bss_start
|
|| d->p.bss_start != p->bss_start
|
||||||
|| d->p.bss_end != p->bss_end
|
|| d->p.bss_end != p->bss_end
|
||||||
|| d->p.ctors != p->ctors
|
|| d->p.ctors != p->ctors
|
||||||
|| d->p.dtors != p->dtors))
|
|| d->p.dtors != p->dtors))
|
||||||
fabort ("\nLoaded different DLL with same basename in forked child,\n"
|
fabort ("\nLoaded different DLL with same basename in forked child,\n"
|
||||||
"parent loaded: %W\n"
|
"parent loaded: %W\n"
|
||||||
" child loaded: %W\n"
|
" child loaded: %W\n"
|
||||||
"The DLLs differ, so it's not safe to run the forked child.\n"
|
"The DLLs differ, so it's not safe to run the forked child.\n"
|
||||||
"Make sure to remove the offending DLL before trying again.",
|
"Make sure to remove the offending DLL before trying again.",
|
||||||
d->name, name);
|
d->ntname, ntname);
|
||||||
d->p = p;
|
d->p = p;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d = (dll *) cmalloc (HEAP_2_DLL,
|
|
||||||
sizeof (*d) + (namelen * sizeof (*name)));
|
|
||||||
/* Now we've allocated a block of information. Fill it in with the
|
/* Now we've allocated a block of information. Fill it in with the
|
||||||
supplied info about this DLL. */
|
supplied info about this DLL. */
|
||||||
wcscpy (d->name, name);
|
wcscpy (d->ntname, ntname);
|
||||||
d->modname = d->name + (modname - name);
|
d->modname = d->ntname + (modname - ntname);
|
||||||
d->handle = h;
|
d->handle = h;
|
||||||
d->count = 0; /* Reference counting performed in dlopen/dlclose. */
|
d->count = 0; /* Reference counting performed in dlopen/dlclose. */
|
||||||
d->has_dtors = true;
|
d->has_dtors = true;
|
||||||
@ -473,7 +581,7 @@ dll_list::init ()
|
|||||||
to clobber the dll's target address range because it often overlaps.
|
to clobber the dll's target address range because it often overlaps.
|
||||||
*/
|
*/
|
||||||
static PVOID
|
static PVOID
|
||||||
reserve_at (const PWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size)
|
reserve_at (PCWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size)
|
||||||
{
|
{
|
||||||
DWORD size;
|
DWORD size;
|
||||||
MEMORY_BASIC_INFORMATION mb;
|
MEMORY_BASIC_INFORMATION mb;
|
||||||
@ -502,7 +610,7 @@ reserve_at (const PWCHAR name, PVOID here, PVOID dll_base, DWORD dll_size)
|
|||||||
|
|
||||||
/* Release the memory previously allocated by "reserve_at" above. */
|
/* Release the memory previously allocated by "reserve_at" above. */
|
||||||
static void
|
static void
|
||||||
release_at (const PWCHAR name, PVOID here)
|
release_at (PCWCHAR name, PVOID here)
|
||||||
{
|
{
|
||||||
if (!VirtualFree (here, 0, MEM_RELEASE))
|
if (!VirtualFree (here, 0, MEM_RELEASE))
|
||||||
fabort ("couldn't release memory %p for '%W' alignment, %E\n",
|
fabort ("couldn't release memory %p for '%W' alignment, %E\n",
|
||||||
@ -527,12 +635,6 @@ dll_list::reserve_space ()
|
|||||||
d->modname, d->handle);
|
d->modname, d->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need the in_load_after_fork flag so dll_dllcrt0_1 can decide at fork
|
|
||||||
time if this is a linked DLL or a dynamically loaded DLL. In either case,
|
|
||||||
both, cygwin_finished_initializing and in_forkee are true, so they are not
|
|
||||||
sufficient to discern the situation. */
|
|
||||||
static bool NO_COPY in_load_after_fork;
|
|
||||||
|
|
||||||
/* Reload DLLs after a fork. Iterates over the list of dynamically loaded
|
/* Reload DLLs after a fork. Iterates over the list of dynamically loaded
|
||||||
DLLs and attempts to load them in the same place as they were loaded in the
|
DLLs and attempts to load them in the same place as they were loaded in the
|
||||||
parent. */
|
parent. */
|
||||||
@ -543,7 +645,8 @@ dll_list::load_after_fork (HANDLE parent)
|
|||||||
// dll_list::reserve_space();
|
// dll_list::reserve_space();
|
||||||
|
|
||||||
in_load_after_fork = true;
|
in_load_after_fork = true;
|
||||||
load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0);
|
if (reload_on_fork)
|
||||||
|
load_after_fork_impl (parent, dlls.istart (DLL_LOAD), 0);
|
||||||
in_load_after_fork = false;
|
in_load_after_fork = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,33 +679,34 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
dll's protective reservation from step 1
|
dll's protective reservation from step 1
|
||||||
*/
|
*/
|
||||||
if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
|
if (!retries && !VirtualFree (d->handle, 0, MEM_RELEASE))
|
||||||
fabort ("unable to release protective reservation for %W (%p), %E",
|
fabort ("unable to release protective reservation (%p) for %W, %E",
|
||||||
d->modname, d->handle);
|
d->handle, d->ntname);
|
||||||
|
|
||||||
HMODULE h = LoadLibraryExW (d->name, NULL, DONT_RESOLVE_DLL_REFERENCES);
|
HMODULE h = LoadLibraryExW (buffered_shortname (d->ntname),
|
||||||
|
NULL, DONT_RESOLVE_DLL_REFERENCES);
|
||||||
if (!h)
|
if (!h)
|
||||||
fabort ("unable to create interim mapping for %W, %E", d->name);
|
fabort ("unable to create interim mapping for %W, %E", d->ntname);
|
||||||
if (h != d->handle)
|
if (h != d->handle)
|
||||||
{
|
{
|
||||||
sigproc_printf ("%W loaded in wrong place: %p != %p",
|
sigproc_printf ("%W loaded in wrong place: %p != %p",
|
||||||
d->modname, h, d->handle);
|
d->ntname, h, d->handle);
|
||||||
FreeLibrary (h);
|
FreeLibrary (h);
|
||||||
PVOID reservation = reserve_at (d->modname, h,
|
PVOID reservation = reserve_at (d->ntname, h,
|
||||||
d->handle, d->image_size);
|
d->handle, d->image_size);
|
||||||
if (!reservation)
|
if (!reservation)
|
||||||
fabort ("unable to block off %p to prevent %W from loading there",
|
fabort ("unable to block off %p to prevent %W from loading there",
|
||||||
h, d->modname);
|
h, d->ntname);
|
||||||
|
|
||||||
if (retries < DLL_RETRY_MAX)
|
if (retries < DLL_RETRY_MAX)
|
||||||
load_after_fork_impl (parent, d, retries+1);
|
load_after_fork_impl (parent, d, retries+1);
|
||||||
else
|
else
|
||||||
fabort ("unable to remap %W to same address as parent (%p) - try running rebaseall",
|
fabort ("unable to remap %W to same address as parent (%p) - try running rebaseall",
|
||||||
d->modname, d->handle);
|
d->ntname, d->handle);
|
||||||
|
|
||||||
/* once the above returns all the dlls are mapped; release
|
/* once the above returns all the dlls are mapped; release
|
||||||
the reservation and continue unwinding */
|
the reservation and continue unwinding */
|
||||||
sigproc_printf ("releasing blocked space at %p", reservation);
|
sigproc_printf ("releasing blocked space at %p", reservation);
|
||||||
release_at (d->modname, reservation);
|
release_at (d->ntname, reservation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,7 +722,7 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
{
|
{
|
||||||
if (!VirtualFree (d->handle, 0, MEM_RELEASE))
|
if (!VirtualFree (d->handle, 0, MEM_RELEASE))
|
||||||
fabort ("unable to release protective reservation for %W (%p), %E",
|
fabort ("unable to release protective reservation for %W (%p), %E",
|
||||||
d->modname, d->handle);
|
d->ntname, d->handle);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -626,17 +730,19 @@ void dll_list::load_after_fork_impl (HANDLE parent, dll* d, int retries)
|
|||||||
to ours or we wouldn't have gotten this far */
|
to ours or we wouldn't have gotten this far */
|
||||||
if (!FreeLibrary (d->handle))
|
if (!FreeLibrary (d->handle))
|
||||||
fabort ("unable to unload interim mapping of %W, %E",
|
fabort ("unable to unload interim mapping of %W, %E",
|
||||||
d->modname);
|
d->ntname);
|
||||||
}
|
}
|
||||||
HMODULE h = LoadLibraryW (d->name);
|
/* cygwin1.dll - as linked dependency - may reuse the shortname
|
||||||
|
buffer, even in case of failure: don't reuse shortname later */
|
||||||
|
HMODULE h = LoadLibraryW (buffered_shortname (d->ntname));
|
||||||
if (!h)
|
if (!h)
|
||||||
fabort ("unable to map %W, %E", d->name);
|
fabort ("unable to map %W, %E", d->ntname);
|
||||||
if (h != d->handle)
|
if (h != d->handle)
|
||||||
fabort ("unable to map %W to same address as parent: %p != %p",
|
fabort ("unable to map %W to same address as parent: %p != %p",
|
||||||
d->modname, d->handle, h);
|
d->ntname, d->handle, h);
|
||||||
/* Fix OS reference count. */
|
/* Fix OS reference count. */
|
||||||
for (int cnt = 1; cnt < d->count; ++cnt)
|
for (int cnt = 1; cnt < d->count; ++cnt)
|
||||||
LoadLibraryW (d->name);
|
LoadLibraryW (buffered_shortname (d->ntname));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ struct dll
|
|||||||
DWORD image_size;
|
DWORD image_size;
|
||||||
void* preferred_base;
|
void* preferred_base;
|
||||||
PWCHAR modname;
|
PWCHAR modname;
|
||||||
WCHAR name[1];
|
WCHAR ntname[1]; /* must be the last data member */
|
||||||
void detach ();
|
void detach ();
|
||||||
int init ();
|
int init ();
|
||||||
void run_dtors ()
|
void run_dtors ()
|
||||||
@ -79,11 +79,25 @@ class dll_list
|
|||||||
dll *hold;
|
dll *hold;
|
||||||
dll_type hold_type;
|
dll_type hold_type;
|
||||||
static muto protect;
|
static muto protect;
|
||||||
|
/* Use this buffer under loader lock conditions only. */
|
||||||
|
static WCHAR NO_COPY nt_max_path_buffer[NT_MAX_PATH];
|
||||||
public:
|
public:
|
||||||
|
static PWCHAR form_ntname (PWCHAR ntbuf, size_t bufsize, PCWCHAR name);
|
||||||
|
static PWCHAR form_shortname (PWCHAR shortbuf, size_t bufsize, PCWCHAR name);
|
||||||
|
static PWCHAR nt_max_path_buf ()
|
||||||
|
{
|
||||||
|
return nt_max_path_buffer;
|
||||||
|
}
|
||||||
|
static PCWCHAR buffered_shortname (PCWCHAR name)
|
||||||
|
{
|
||||||
|
form_shortname (nt_max_path_buffer, NT_MAX_PATH, name);
|
||||||
|
return nt_max_path_buffer;
|
||||||
|
}
|
||||||
|
|
||||||
dll start;
|
dll start;
|
||||||
int loaded_dlls;
|
int loaded_dlls;
|
||||||
int reload_on_fork;
|
int reload_on_fork;
|
||||||
dll *operator [] (const PWCHAR name);
|
dll *operator [] (PCWCHAR ntname);
|
||||||
dll *alloc (HINSTANCE, per_process *, dll_type);
|
dll *alloc (HINSTANCE, per_process *, dll_type);
|
||||||
dll *find (void *);
|
dll *find (void *);
|
||||||
void detach (void *);
|
void detach (void *);
|
||||||
@ -91,7 +105,7 @@ public:
|
|||||||
void load_after_fork (HANDLE);
|
void load_after_fork (HANDLE);
|
||||||
void reserve_space ();
|
void reserve_space ();
|
||||||
void load_after_fork_impl (HANDLE, dll* which, int retries);
|
void load_after_fork_impl (HANDLE, dll* which, int retries);
|
||||||
dll *find_by_modname (const PWCHAR name);
|
dll *find_by_modname (PCWCHAR modname);
|
||||||
void populate_deps (dll* d);
|
void populate_deps (dll* d);
|
||||||
void topsort ();
|
void topsort ();
|
||||||
void topsort_visit (dll* d, bool goto_tail);
|
void topsort_visit (dll* d, bool goto_tail);
|
||||||
|
@ -175,21 +175,18 @@ frok::child (volatile char * volatile here)
|
|||||||
if (fixup_shms_after_fork ())
|
if (fixup_shms_after_fork ())
|
||||||
api_fatal ("recreate_shm areas after fork failed");
|
api_fatal ("recreate_shm areas after fork failed");
|
||||||
|
|
||||||
/* If we haven't dynamically loaded any dlls, just signal
|
/* load dynamic dlls, if any */
|
||||||
the parent. Otherwise, load all the dlls, tell the parent
|
dlls.load_after_fork (hParent);
|
||||||
that we're done, and wait for the parent to fill in the.
|
|
||||||
loaded dlls' data/bss. */
|
cygheap->fdtab.fixup_after_fork (hParent);
|
||||||
|
|
||||||
|
/* If we haven't dynamically loaded any dlls, just signal the parent.
|
||||||
|
Otherwise, tell the parent that we've loaded all the dlls
|
||||||
|
and wait for the parent to fill in the loaded dlls' data/bss. */
|
||||||
if (!load_dlls)
|
if (!load_dlls)
|
||||||
{
|
sync_with_parent ("performed fork fixup", false);
|
||||||
cygheap->fdtab.fixup_after_fork (hParent);
|
|
||||||
sync_with_parent ("performed fork fixup", false);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
sync_with_parent ("loaded dlls", true);
|
||||||
dlls.load_after_fork (hParent);
|
|
||||||
cygheap->fdtab.fixup_after_fork (hParent);
|
|
||||||
sync_with_parent ("loaded dlls", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
init_console_handler (myself->ctty > 0);
|
init_console_handler (myself->ctty > 0);
|
||||||
ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
ForceCloseHandle1 (fork_info->forker_finished, forker_finished);
|
||||||
@ -303,8 +300,6 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
si.lpReserved2 = (LPBYTE) &ch;
|
si.lpReserved2 = (LPBYTE) &ch;
|
||||||
si.cbReserved2 = sizeof (ch);
|
si.cbReserved2 = sizeof (ch);
|
||||||
|
|
||||||
syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
|
|
||||||
myself->progname, myself->progname, c_flags, &si, &pi);
|
|
||||||
bool locked = __malloc_lock ();
|
bool locked = __malloc_lock ();
|
||||||
|
|
||||||
/* Remove impersonation */
|
/* Remove impersonation */
|
||||||
@ -315,6 +310,9 @@ frok::parent (volatile char * volatile stack_here)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
syscall_printf ("CreateProcessW (%W, %W, 0, 0, 1, %y, 0, 0, %p, %p)",
|
||||||
|
myself->progname, myself->progname, c_flags, &si, &pi);
|
||||||
|
|
||||||
hchild = NULL;
|
hchild = NULL;
|
||||||
rc = CreateProcessW (myself->progname, /* image to run */
|
rc = CreateProcessW (myself->progname, /* image to run */
|
||||||
GetCommandLineW (), /* Take same space for command
|
GetCommandLineW (), /* Take same space for command
|
||||||
|
Loading…
x
Reference in New Issue
Block a user