* hookapi.cc (find_first_notloaded_dll): New function.
* pinfo.cc (status_exit): New function. Issue message when dll not found. Use find_first_notloaded_dll to find a nonexistent dll. (pinfo::maybe_set_exit_code_from_windows): Call status_exit when exit code >= 0xc0000000UL. * sigproc.cc (child_info::proc_retry): Return exit code when STATUS_DLL_NOT_FOUND. * spawn.cc (spawn_guts): Minor cleanup. * syscalls.cc (close_all_files): Don't actually close stderr filehandle. Just make it noninheritable. * winsup.h (find_first_notloaded_dll): Declare new function. * ntdll.h: Add several missing NTSTATUS defines.
This commit is contained in:
parent
73de02f44b
commit
93d606f60a
|
@ -1,3 +1,21 @@
|
|||
2008-03-26 Christopher Faylor <me+cygwin@cgf.cx>
|
||||
|
||||
* hookapi.cc (find_first_notloaded_dll): New function.
|
||||
* pinfo.cc (status_exit): New function. Issue message when dll not
|
||||
found. Use find_first_notloaded_dll to find a nonexistent dll.
|
||||
(pinfo::maybe_set_exit_code_from_windows): Call status_exit when exit
|
||||
code >= 0xc0000000UL.
|
||||
* sigproc.cc (child_info::proc_retry): Return exit code when
|
||||
STATUS_DLL_NOT_FOUND.
|
||||
* spawn.cc (spawn_guts): Minor cleanup.
|
||||
* syscalls.cc (close_all_files): Don't actually close stderr
|
||||
filehandle. Just make it noninheritable.
|
||||
* winsup.h (find_first_notloaded_dll): Declare new function.
|
||||
|
||||
2008-03-26 Brian Dessent <brian@dessent.net>
|
||||
|
||||
* ntdll.h: Add several missing NTSTATUS defines.
|
||||
|
||||
2008-03-24 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* flock.cc (inode_t::get_all_locks_list): Don't allow F_WAIT flag
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* dtable.h: fd table definition.
|
||||
|
||||
Copyright 2000, 2001, 2003, 2004, 2005 Red Hat, Inc.
|
||||
Copyright 2000, 2001, 2003, 2004, 2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
|
|
@ -153,7 +153,7 @@ open_stackdumpfile ()
|
|||
p, strlen (p)) * sizeof (WCHAR);
|
||||
RtlAppendUnicodeToString (&ucore, L".stackdump");
|
||||
/* Create an object attribute which refers to <progname>.stackdump
|
||||
in Cygwin's cwd. */
|
||||
in Cygwin's cwd. */
|
||||
InitializeObjectAttributes (&attr, &ucore, OBJ_CASE_INSENSITIVE,
|
||||
cygheap->cwd.get_handle (), NULL);
|
||||
HANDLE h;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* hookapi.cc
|
||||
|
||||
Copyright 2005, 2006 Red Hat, Inc.
|
||||
Copyright 2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -9,15 +9,17 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
|
|||
details. */
|
||||
|
||||
#include "winsup.h"
|
||||
#include <imagehlp.h>
|
||||
#include <stdlib.h>
|
||||
#include <alloca.h>
|
||||
#include "ntdll.h"
|
||||
#include "cygerrno.h"
|
||||
#include "security.h"
|
||||
#include "path.h"
|
||||
#include "fhandler.h"
|
||||
#include "dtable.h"
|
||||
#include "cygheap.h"
|
||||
#include <stdlib.h>
|
||||
#include <imagehlp.h>
|
||||
#include <alloca.h>
|
||||
#include "pinfo.h"
|
||||
|
||||
#define rva(coerce, base, addr) (coerce) ((char *) (base) + (addr))
|
||||
#define rvacyg(coerce, addr) rva (coerce, cygwin_hmodule, addr)
|
||||
|
@ -158,7 +160,74 @@ makename (const char *name, char *&buf, int& i, int inc)
|
|||
return name;
|
||||
}
|
||||
|
||||
// Top level routine to find the EXE's imports, and redirect them
|
||||
/* Find first missing dll in a given executable.
|
||||
FIXME: This is not foolproof since it doesn't look for dlls in the
|
||||
same directory as the given executable, like Windows. Instead it
|
||||
searches for dlls in the context of the current executable. */
|
||||
const char *
|
||||
find_first_notloaded_dll (path_conv& pc)
|
||||
{
|
||||
const char *res = "?";
|
||||
HANDLE hc = NULL;
|
||||
HMODULE hm = NULL;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
IO_STATUS_BLOCK io;
|
||||
HANDLE h;
|
||||
NTSTATUS status;
|
||||
|
||||
status = NtOpenFile (&h, SYNCHRONIZE | GENERIC_READ,
|
||||
pc.get_object_attr (attr, sec_none_nih),
|
||||
&io, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
FILE_SYNCHRONOUS_IO_NONALERT
|
||||
| FILE_OPEN_FOR_BACKUP_INTENT
|
||||
| FILE_NON_DIRECTORY_FILE);
|
||||
if (!NT_SUCCESS (status))
|
||||
goto out;
|
||||
|
||||
hc = CreateFileMapping (h, &sec_none_nih, PAGE_READONLY, 0, 0, NULL);
|
||||
NtClose (h);
|
||||
if (!hc)
|
||||
goto out;
|
||||
hm = (HMODULE) MapViewOfFile(hc, FILE_MAP_READ, 0, 0, 0);
|
||||
CloseHandle (hc);
|
||||
|
||||
PIMAGE_NT_HEADERS pExeNTHdr;
|
||||
pExeNTHdr = PEHeaderFromHModule (hm);
|
||||
|
||||
if (!pExeNTHdr)
|
||||
goto out;
|
||||
|
||||
DWORD importRVA;
|
||||
importRVA = pExeNTHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||
if (!importRVA)
|
||||
goto out;
|
||||
|
||||
long delta = rvadelta (pExeNTHdr, importRVA);
|
||||
|
||||
// Convert imports RVA to a usable pointer
|
||||
PIMAGE_IMPORT_DESCRIPTOR pdfirst;
|
||||
pdfirst = rva (PIMAGE_IMPORT_DESCRIPTOR, hm, importRVA - delta);
|
||||
|
||||
// Iterate through each import descriptor, and redirect if appropriate
|
||||
for (PIMAGE_IMPORT_DESCRIPTOR pd = pdfirst; pd->FirstThunk; pd++)
|
||||
{
|
||||
const char *lib = rva (PSTR, hm, pd->Name - delta);
|
||||
if (!LoadLibraryEx (lib, NULL, DONT_RESOLVE_DLL_REFERENCES
|
||||
| LOAD_LIBRARY_AS_DATAFILE))
|
||||
{
|
||||
static char buf[NT_MAX_PATH];
|
||||
res = strcpy (buf, lib);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (hm)
|
||||
UnmapViewOfFile (hm);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// Top level routine to find the EXE's imports and redirect them
|
||||
void *
|
||||
hook_or_detect_cygwin (const char *name, const void *fn, WORD& subsys)
|
||||
{
|
||||
|
|
|
@ -37,6 +37,12 @@
|
|||
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
|
||||
#define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005)
|
||||
#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006)
|
||||
#define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135)
|
||||
#define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139)
|
||||
#define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251)
|
||||
#define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269)
|
||||
|
||||
|
||||
#define PDI_MODULES 0x01
|
||||
#define PDI_HEAPS 0x04
|
||||
#define LDRP_IMAGE_DLL 0x00000004
|
||||
|
|
|
@ -104,6 +104,28 @@ pinfo_init (char **envp, int envc)
|
|||
debug_printf ("pid %d, pgid %d", myself->pid, myself->pgid);
|
||||
}
|
||||
|
||||
static DWORD
|
||||
status_exit (DWORD x)
|
||||
{
|
||||
const char *find_first_notloaded_dll (path_conv &);
|
||||
switch (x)
|
||||
{
|
||||
case STATUS_DLL_NOT_FOUND:
|
||||
{
|
||||
char posix_prog[NT_MAX_PATH];
|
||||
path_conv pc (myself->progname, PC_NOWARN);
|
||||
mount_table->conv_to_posix_path (pc.get_win32 (), posix_prog, 1);
|
||||
small_printf ("%s: error while loading shared libraries: %s: cannot open shared object file: No such file or directory\n",
|
||||
posix_prog, find_first_notloaded_dll (pc));
|
||||
x = 127;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
x = 127;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
# define self (*this)
|
||||
void
|
||||
pinfo::maybe_set_exit_code_from_windows ()
|
||||
|
@ -114,10 +136,12 @@ pinfo::maybe_set_exit_code_from_windows ()
|
|||
|
||||
if (hProcess && !(self->exitcode & EXITCODE_SET))
|
||||
{
|
||||
WaitForSingleObject (hProcess, INFINITE); // just to be safe, in case
|
||||
// process hasn't quite exited
|
||||
// after closing pipe
|
||||
WaitForSingleObject (hProcess, INFINITE); /* just to be safe, in case
|
||||
process hasn't quite exited
|
||||
after closing pipe */
|
||||
GetExitCodeProcess (hProcess, &x);
|
||||
if (x >= 0xc0000000UL)
|
||||
x = status_exit (x);
|
||||
self->exitcode = EXITCODE_SET | (sigExeced ?: (x & 0xff) << 8);
|
||||
}
|
||||
sigproc_printf ("pid %d, exit value - old %p, windows %p, cygwin %p",
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
pid_t pid;
|
||||
|
||||
/* Various flags indicating the state of the process. See PID_
|
||||
constants below. */
|
||||
constants in <sys/cygwin.h>. */
|
||||
DWORD process_state;
|
||||
|
||||
DWORD exitcode; /* set when process exits */
|
||||
|
|
|
@ -32,6 +32,7 @@ details. */
|
|||
#include "cygtls.h"
|
||||
#include "sigproc.h"
|
||||
#include "exceptions.h"
|
||||
#include "ntdll.h"
|
||||
|
||||
/*
|
||||
* Convenience defines
|
||||
|
@ -935,6 +936,8 @@ child_info::proc_retry (HANDLE h)
|
|||
case STILL_ACTIVE: /* shouldn't happen */
|
||||
sigproc_printf ("STILL_ACTIVE? How'd we get here?");
|
||||
break;
|
||||
case STATUS_DLL_NOT_FOUND:
|
||||
return exit_code;
|
||||
case STATUS_CONTROL_C_EXIT:
|
||||
if (saw_ctrl_c ())
|
||||
return EXITCODE_OK;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* spawn.cc
|
||||
|
||||
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
|
||||
2005, 2006, 2007 Red Hat, Inc.
|
||||
2005, 2006, 2007, 2008 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -265,7 +265,7 @@ do_cleanup (void *args)
|
|||
|
||||
|
||||
int __stdcall
|
||||
spawn_guts (const char * prog_arg, const char *const *argv,
|
||||
spawn_guts (const char *prog_arg, const char *const *argv,
|
||||
const char *const envp[], int mode, int __stdin, int __stdout)
|
||||
{
|
||||
bool rc;
|
||||
|
@ -745,8 +745,7 @@ loop:
|
|||
myself->wr_proc_pipe_owner = GetCurrentProcessId ();
|
||||
myself->wr_proc_pipe = orig_wr_proc_pipe;
|
||||
}
|
||||
DWORD res = ch.proc_retry (pi.hProcess);
|
||||
if (!res)
|
||||
if (!ch.proc_retry (pi.hProcess))
|
||||
{
|
||||
looped++;
|
||||
goto loop;
|
||||
|
|
|
@ -109,12 +109,17 @@ close_all_files (bool norelease)
|
|||
semaphore::terminate ();
|
||||
|
||||
fhandler_base *fh;
|
||||
HANDLE h = NULL;
|
||||
|
||||
for (int i = 0; i < (int) cygheap->fdtab.size; i++)
|
||||
if ((fh = cygheap->fdtab[i]) != NULL)
|
||||
{
|
||||
#ifdef DEBUGGING
|
||||
debug_printf ("closing fd %d", i);
|
||||
#endif
|
||||
if (i == 2)
|
||||
DuplicateHandle (GetCurrentProcess (), fh->get_output_handle (), GetCurrentProcess (), &h, 0, false,
|
||||
DUPLICATE_SAME_ACCESS);
|
||||
fh->close ();
|
||||
if (!norelease)
|
||||
cygheap->fdtab.release (i);
|
||||
|
@ -123,6 +128,8 @@ close_all_files (bool norelease)
|
|||
if (!hExeced && cygheap->ctty)
|
||||
cygheap->close_ctty ();
|
||||
|
||||
if (h)
|
||||
SetStdHandle (STD_ERROR_HANDLE, h);
|
||||
cygheap->fdtab.unlock ();
|
||||
}
|
||||
|
||||
|
|
|
@ -261,7 +261,8 @@ void __stdcall close_all_files (bool = false);
|
|||
extern "C" void error_start_init (const char*);
|
||||
extern "C" int try_to_debug (bool waitloop = 1);
|
||||
|
||||
extern void ld_preload ();
|
||||
void ld_preload ();
|
||||
const char *find_first_notloaded_dll (class path_conv &);
|
||||
|
||||
void set_file_api_mode (codepage_type);
|
||||
|
||||
|
|
Loading…
Reference in New Issue