Moved 32-bit relay and snoop support to dlls/ntdll.
diff --git a/dlls/kernel/ne_module.c b/dlls/kernel/ne_module.c
index 74b53df..6b5ff07 100644
--- a/dlls/kernel/ne_module.c
+++ b/dlls/kernel/ne_module.c
@@ -44,7 +44,6 @@
#include "global.h"
#include "file.h"
#include "task.h"
-#include "snoop.h"
#include "builtin16.h"
#include "stackframe.h"
#include "excpt.h"
@@ -93,6 +92,8 @@
static const BUILTIN16_DESCRIPTOR *builtin_dlls[MAX_DLLS];
+extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR);
+extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16);
static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only );
static BOOL16 NE_FreeModule( HMODULE16 hModule, BOOL call_wep );
diff --git a/dlls/kernel/snoop16.c b/dlls/kernel/snoop16.c
index adcdc5b..e2e800a 100644
--- a/dlls/kernel/snoop16.c
+++ b/dlls/kernel/snoop16.c
@@ -31,10 +31,10 @@
#include "wine/winbase16.h"
#include "wine/library.h"
#include "global.h"
+#include "module.h"
#include "stackframe.h"
#include "builtin16.h"
#include "toolhelp.h"
-#include "snoop.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(snoop);
@@ -43,6 +43,8 @@
#include "pshpack1.h"
+extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname); /* FIXME */
+
void WINAPI SNOOP16_Entry(FARPROC proc, LPBYTE args, CONTEXT86 *context);
void WINAPI SNOOP16_Return(FARPROC proc, LPBYTE args, CONTEXT86 *context);
diff --git a/dlls/ntdll/Makefile.in b/dlls/ntdll/Makefile.in
index 2c0b5de..25f4277 100644
--- a/dlls/ntdll/Makefile.in
+++ b/dlls/ntdll/Makefile.in
@@ -27,8 +27,6 @@
$(TOPOBJDIR)/misc/registry.c \
$(TOPOBJDIR)/misc/version.c \
$(TOPOBJDIR)/msdos/dpmi.c \
- $(TOPOBJDIR)/relay32/relay386.c \
- $(TOPOBJDIR)/relay32/snoop.c \
$(TOPOBJDIR)/scheduler/handle.c \
$(TOPOBJDIR)/scheduler/process.c \
$(TOPOBJDIR)/scheduler/pthread.c \
@@ -51,6 +49,7 @@
path.c \
process.c \
reg.c \
+ relay.c \
resource.c \
rtl.c \
rtlbitmap.c \
@@ -81,7 +80,6 @@
$(TOPOBJDIR)/memory \
$(TOPOBJDIR)/misc \
$(TOPOBJDIR)/msdos \
- $(TOPOBJDIR)/relay32 \
$(TOPOBJDIR)/scheduler \
$(TOPOBJDIR)/win32
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 37c63e9..aad260b 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -44,7 +44,7 @@
DWORD exp_size, FARPROC proc, const char *user );
extern FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
FARPROC origfun, DWORD ordinal );
-extern void RELAY_SetupDLL( const char *module );
+extern void RELAY_SetupDLL( HMODULE hmod );
extern void SNOOP_SetupDLL( HMODULE hmod );
static inline HANDLE ntdll_get_process_heap(void)
diff --git a/relay32/relay386.c b/dlls/ntdll/relay.c
similarity index 62%
rename from relay32/relay386.c
rename to dlls/ntdll/relay.c
index f2a396d..631fdb6 100644
--- a/relay32/relay386.c
+++ b/dlls/ntdll/relay.c
@@ -1,7 +1,8 @@
/*
- * 386-specific Win32 relay functions
+ * Win32 relay and snoop functions
*
* Copyright 1997 Alexandre Julliard
+ * Copyright 1998 Marcus Meissner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,12 +31,15 @@
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
+#include "excpt.h"
+#include "wine/exception.h"
+#include "ntdll_misc.h"
#include "wine/unicode.h"
#include "wine/debug.h"
-#include "ntdll_misc.h"
WINE_DEFAULT_DEBUG_CHANNEL(relay);
WINE_DECLARE_DEBUG_CHANNEL(snoop);
+WINE_DECLARE_DEBUG_CHANNEL(seh);
const char **debug_relay_excludelist = NULL;
const char **debug_relay_includelist = NULL;
@@ -170,16 +174,77 @@
#ifdef __i386__
+#include "pshpack1.h"
+
typedef struct
{
- BYTE call; /* 0xe8 call callfrom32 (relative) */
- DWORD callfrom32 WINE_PACKED; /* RELAY_CallFrom32 relative addr */
- BYTE ret; /* 0xc2 ret $n or 0xc3 ret */
- WORD args; /* nb of args to remove from the stack */
- void *orig; /* original entry point */
- DWORD argtypes; /* argument types */
+ BYTE call; /* 0xe8 call callfrom32 (relative) */
+ DWORD callfrom32; /* RELAY_CallFrom32 relative addr */
+ BYTE ret; /* 0xc2 ret $n or 0xc3 ret */
+ WORD args; /* nb of args to remove from the stack */
+ void *orig; /* original entry point */
+ DWORD argtypes; /* argument types */
} DEBUG_ENTRY_POINT;
+typedef struct
+{
+ /* code part */
+ BYTE lcall; /* 0xe8 call snoopentry (relative) */
+ /* NOTE: If you move snoopentry OR nrofargs fix the relative offset
+ * calculation!
+ */
+ DWORD snoopentry; /* SNOOP_Entry relative */
+ /* unreached */
+ int nrofargs;
+ FARPROC origfun;
+ const char *name;
+} SNOOP_FUN;
+
+typedef struct tagSNOOP_DLL {
+ HMODULE hmod;
+ SNOOP_FUN *funs;
+ DWORD ordbase;
+ DWORD nrofordinals;
+ struct tagSNOOP_DLL *next;
+ char name[1];
+} SNOOP_DLL;
+
+typedef struct
+{
+ /* code part */
+ BYTE lcall; /* 0xe8 call snoopret relative*/
+ /* NOTE: If you move snoopret OR origreturn fix the relative offset
+ * calculation!
+ */
+ DWORD snoopret; /* SNOOP_Ret relative */
+ /* unreached */
+ FARPROC origreturn;
+ SNOOP_DLL *dll;
+ DWORD ordinal;
+ DWORD origESP;
+ DWORD *args; /* saved args across a stdcall */
+} SNOOP_RETURNENTRY;
+
+typedef struct tagSNOOP_RETURNENTRIES {
+ SNOOP_RETURNENTRY entry[4092/sizeof(SNOOP_RETURNENTRY)];
+ struct tagSNOOP_RETURNENTRIES *next;
+} SNOOP_RETURNENTRIES;
+
+#include "poppack.h"
+
+extern void WINAPI SNOOP_Entry();
+extern void WINAPI SNOOP_Return();
+
+static SNOOP_DLL *firstdll;
+static SNOOP_RETURNENTRIES *firstrets;
+
+static WINE_EXCEPTION_FILTER(page_fault)
+{
+ if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
+ GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
+ return EXCEPTION_EXECUTE_HANDLER;
+ return EXCEPTION_CONTINUE_SEARCH;
+}
/***********************************************************************
* check_relay_include
@@ -259,17 +324,17 @@
*
* Find the name of an exported function.
*/
-static const char *find_exported_name( const char *module,
+static const char *find_exported_name( HMODULE module,
IMAGE_EXPORT_DIRECTORY *exp, int ordinal )
{
int i;
const char *ret = NULL;
- WORD *ordptr = (WORD *)(module + exp->AddressOfNameOrdinals);
+ WORD *ordptr = (WORD *)((char *)module + exp->AddressOfNameOrdinals);
for (i = 0; i < exp->NumberOfNames; i++, ordptr++)
if (*ordptr + exp->Base == ordinal) break;
if (i < exp->NumberOfNames)
- ret = module + ((DWORD*)(module + exp->AddressOfNames))[i];
+ ret = (char *)module + ((DWORD*)((char *)module + exp->AddressOfNames))[i];
return ret;
}
@@ -283,7 +348,7 @@
{
IMAGE_EXPORT_DIRECTORY *exp = NULL;
DEBUG_ENTRY_POINT *debug;
- char *p, *base = NULL;
+ char *p;
const char *name;
int ordinal = 0;
PLIST_ENTRY mark, entry;
@@ -309,12 +374,11 @@
/* Now find the function */
- base = (char *)mod->BaseAddress;
- strcpy( buffer, base + exp->Name );
+ strcpy( buffer, (char *)mod->BaseAddress + exp->Name );
p = buffer + strlen(buffer);
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
- if ((name = find_exported_name( base, exp, ordinal + exp->Base )))
+ if ((name = find_exported_name( mod->BaseAddress, exp, ordinal + exp->Base )))
sprintf( p, ".%s", name );
else
sprintf( p, ".%ld", ordinal + exp->Base );
@@ -331,9 +395,9 @@
if ((typemask & 3) && HIWORD(*args))
{
if (typemask & 2)
- DPRINTF( "%08x %s", *args, debugstr_w((LPWSTR)*args) );
+ DPRINTF( "%08x %s", *args, debugstr_w((LPWSTR)*args) );
else
- DPRINTF( "%08x %s", *args, debugstr_a((LPCSTR)*args) );
+ DPRINTF( "%08x %s", *args, debugstr_a((LPCSTR)*args) );
}
else DPRINTF( "%08x", *args );
if (nb_args) DPRINTF( "," );
@@ -631,7 +695,7 @@
*
* Setup relay debugging for a built-in dll.
*/
-void RELAY_SetupDLL( const char *module )
+void RELAY_SetupDLL( HMODULE module )
{
IMAGE_EXPORT_DIRECTORY *exports;
DEBUG_ENTRY_POINT *debug;
@@ -641,12 +705,11 @@
char *p, dllname[80];
DWORD size;
- exports = RtlImageDirectoryEntryToData( (HMODULE)module, TRUE,
- IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
+ exports = RtlImageDirectoryEntryToData( module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
if (!exports) return;
debug = (DEBUG_ENTRY_POINT *)((char *)exports + size);
- funcs = (DWORD *)(module + exports->AddressOfFunctions);
- strcpy( dllname, module + exports->Name );
+ funcs = (DWORD *)((char *)module + exports->AddressOfFunctions);
+ strcpy( dllname, (char *)module + exports->Name );
p = dllname + strlen(dllname) - 4;
if (p > dllname && !strcasecmp( p, ".dll" )) *p = 0;
@@ -674,11 +737,355 @@
debug->callfrom32 = (char *)debug->orig - (char *)&debug->ret;
}
- debug->orig = (FARPROC)(module + (DWORD)*funcs);
- *funcs = (char *)debug - module;
+ debug->orig = (FARPROC)((char *)module + (DWORD)*funcs);
+ *funcs = (char *)debug - (char *)module;
}
}
+
+/***********************************************************************
+ * SNOOP_ShowDebugmsgSnoop
+ *
+ * Simple function to decide if a particular debugging message is
+ * wanted.
+ */
+int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) {
+
+ if(debug_snoop_excludelist || debug_snoop_includelist) {
+ const char **listitem;
+ char buf[80];
+ int len, len2, itemlen, show;
+
+ if(debug_snoop_excludelist) {
+ show = 1;
+ listitem = debug_snoop_excludelist;
+ } else {
+ show = 0;
+ listitem = debug_snoop_includelist;
+ }
+ len = strlen(dll);
+ assert(len < 64);
+ sprintf(buf, "%s.%d", dll, ord);
+ len2 = strlen(buf);
+ for(; *listitem; listitem++) {
+ itemlen = strlen(*listitem);
+ if((itemlen == len && !strncasecmp(*listitem, buf, len)) ||
+ (itemlen == len2 && !strncasecmp(*listitem, buf, len2)) ||
+ !strcasecmp(*listitem, fname)) {
+ show = !show;
+ break;
+ }
+ }
+ return show;
+ }
+ return 1;
+}
+
+
+/***********************************************************************
+ * SNOOP_SetupDLL
+ *
+ * Setup snoop debugging for a native dll.
+ */
+void SNOOP_SetupDLL(HMODULE hmod)
+{
+ SNOOP_DLL **dll = &firstdll;
+ char *p, *name;
+ void *addr;
+ SIZE_T size;
+ IMAGE_EXPORT_DIRECTORY *exports;
+
+ exports = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
+ if (!exports) return;
+ name = (char *)hmod + exports->Name;
+
+ TRACE("hmod=%p, name=%s\n", hmod, name);
+
+ while (*dll) {
+ if ((*dll)->hmod == hmod)
+ {
+ /* another dll, loaded at the same address */
+ addr = (*dll)->funs;
+ size = (*dll)->nrofordinals * sizeof(SNOOP_FUN);
+ NtFreeVirtualMemory(GetCurrentProcess(), &addr, &size, MEM_RELEASE);
+ break;
+ }
+ dll = &((*dll)->next);
+ }
+ *dll = RtlReAllocateHeap(ntdll_get_process_heap(),
+ HEAP_ZERO_MEMORY, *dll,
+ sizeof(SNOOP_DLL) + strlen(name));
+ (*dll)->hmod = hmod;
+ (*dll)->ordbase = exports->Base;
+ (*dll)->nrofordinals = exports->NumberOfFunctions;
+ strcpy( (*dll)->name, name );
+ p = (*dll)->name + strlen((*dll)->name) - 4;
+ if (p > (*dll)->name && !strcasecmp( p, ".dll" )) *p = 0;
+
+ size = exports->NumberOfFunctions * sizeof(SNOOP_FUN);
+ NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size,
+ MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
+ if (!addr) {
+ RtlFreeHeap(ntdll_get_process_heap(),0,*dll);
+ FIXME("out of memory\n");
+ return;
+ }
+ (*dll)->funs = addr;
+ memset((*dll)->funs,0,size);
+}
+
+
+/***********************************************************************
+ * SNOOP_GetProcAddress
+ *
+ * Return the proc address to use for a given function.
+ */
+FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports,
+ DWORD exp_size, FARPROC origfun, DWORD ordinal )
+{
+ int i;
+ const char *ename;
+ WORD *ordinals;
+ DWORD *names;
+ SNOOP_DLL *dll = firstdll;
+ SNOOP_FUN *fun;
+ IMAGE_SECTION_HEADER *sec;
+
+ if (!TRACE_ON(snoop)) return origfun;
+ if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
+ return origfun;
+
+ sec = RtlImageRvaToSection( RtlImageNtHeader(hmod), hmod, (char *)origfun - (char *)hmod );
+
+ if (!sec || !(sec->Characteristics & IMAGE_SCN_CNT_CODE))
+ return origfun; /* most likely a data reference */
+
+ while (dll) {
+ if (hmod == dll->hmod)
+ break;
+ dll=dll->next;
+ }
+ if (!dll) /* probably internal */
+ return origfun;
+
+ /* try to find a name for it */
+ ename = NULL;
+ names = (DWORD *)((char *)hmod + exports->AddressOfNames);
+ ordinals = (WORD *)((char *)hmod + exports->AddressOfNameOrdinals);
+ if (names) for (i = 0; i < exports->NumberOfNames; i++)
+ {
+ if (ordinals[i] == ordinal)
+ {
+ ename = (char *)hmod + names[i];
+ break;
+ }
+ }
+ if (!SNOOP_ShowDebugmsgSnoop(dll->name,ordinal,ename))
+ return origfun;
+ assert(ordinal < dll->nrofordinals);
+ fun = dll->funs+ordinal;
+ if (!fun->name)
+ {
+ fun->name = ename;
+ fun->lcall = 0xe8;
+ /* NOTE: origreturn struct member MUST come directly after snoopentry */
+ fun->snoopentry = (char*)SNOOP_Entry-((char*)(&fun->nrofargs));
+ fun->origfun = origfun;
+ fun->nrofargs = -1;
+ }
+ return (FARPROC)&(fun->lcall);
+}
+
+static void SNOOP_PrintArg(DWORD x)
+{
+ int i,nostring;
+
+ DPRINTF("%08lx",x);
+ if (!HIWORD(x) || TRACE_ON(seh)) return; /* trivial reject to avoid faults */
+ __TRY
+ {
+ LPBYTE s=(LPBYTE)x;
+ i=0;nostring=0;
+ while (i<80) {
+ if (s[i]==0) break;
+ if (s[i]<0x20) {nostring=1;break;}
+ if (s[i]>=0x80) {nostring=1;break;}
+ i++;
+ }
+ if (!nostring && i > 5)
+ DPRINTF(" %s",debugstr_an((LPSTR)x,i));
+ else /* try unicode */
+ {
+ LPWSTR s=(LPWSTR)x;
+ i=0;nostring=0;
+ while (i<80) {
+ if (s[i]==0) break;
+ if (s[i]<0x20) {nostring=1;break;}
+ if (s[i]>0x100) {nostring=1;break;}
+ i++;
+ }
+ if (!nostring && i > 5) DPRINTF(" %s",debugstr_wn((LPWSTR)x,i));
+ }
+ }
+ __EXCEPT(page_fault)
+ {
+ }
+ __ENDTRY
+}
+
+#define CALLER1REF (*(DWORD*)context->Esp)
+
+void WINAPI SNOOP_DoEntry( CONTEXT86 *context )
+{
+ DWORD ordinal=0,entry = context->Eip - 5;
+ SNOOP_DLL *dll = firstdll;
+ SNOOP_FUN *fun = NULL;
+ SNOOP_RETURNENTRIES **rets = &firstrets;
+ SNOOP_RETURNENTRY *ret;
+ int i=0, max;
+
+ while (dll) {
+ if ( ((char*)entry>=(char*)dll->funs) &&
+ ((char*)entry<=(char*)(dll->funs+dll->nrofordinals))
+ ) {
+ fun = (SNOOP_FUN*)entry;
+ ordinal = fun-dll->funs;
+ break;
+ }
+ dll=dll->next;
+ }
+ if (!dll) {
+ FIXME("entrypoint 0x%08lx not found\n",entry);
+ return; /* oops */
+ }
+ /* guess cdecl ... */
+ if (fun->nrofargs<0) {
+ /* Typical cdecl return frame is:
+ * add esp, xxxxxxxx
+ * which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
+ * (after that 81 C2 xx xx xx xx)
+ */
+ LPBYTE reteip = (LPBYTE)CALLER1REF;
+
+ if (reteip) {
+ if ((reteip[0]==0x83)&&(reteip[1]==0xc4))
+ fun->nrofargs=reteip[2]/4;
+ }
+ }
+
+
+ while (*rets) {
+ for (i=0;i<sizeof((*rets)->entry)/sizeof((*rets)->entry[0]);i++)
+ if (!(*rets)->entry[i].origreturn)
+ break;
+ if (i!=sizeof((*rets)->entry)/sizeof((*rets)->entry[0]))
+ break;
+ rets = &((*rets)->next);
+ }
+ if (!*rets) {
+ SIZE_T size = 4096;
+ VOID* addr;
+
+ NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size,
+ MEM_COMMIT | MEM_RESERVE,
+ PAGE_EXECUTE_READWRITE);
+ if (!addr) return;
+ *rets = addr;
+ memset(*rets,0,4096);
+ i = 0; /* entry 0 is free */
+ }
+ ret = &((*rets)->entry[i]);
+ ret->lcall = 0xe8;
+ /* NOTE: origreturn struct member MUST come directly after snoopret */
+ ret->snoopret = ((char*)SNOOP_Return)-(char*)(&ret->origreturn);
+ ret->origreturn = (FARPROC)CALLER1REF;
+ CALLER1REF = (DWORD)&ret->lcall;
+ ret->dll = dll;
+ ret->args = NULL;
+ ret->ordinal = ordinal;
+ ret->origESP = context->Esp;
+
+ context->Eip = (DWORD)fun->origfun;
+
+ if (fun->name) DPRINTF("%04lx:CALL %s.%s(",GetCurrentThreadId(),dll->name,fun->name);
+ else DPRINTF("%04lx:CALL %s.%ld(",GetCurrentThreadId(),dll->name,dll->ordbase+ordinal);
+ if (fun->nrofargs>0) {
+ max = fun->nrofargs; if (max>16) max=16;
+ for (i=0;i<max;i++)
+ {
+ SNOOP_PrintArg(*(DWORD*)(context->Esp + 4 + sizeof(DWORD)*i));
+ if (i<fun->nrofargs-1) DPRINTF(",");
+ }
+ if (max!=fun->nrofargs)
+ DPRINTF(" ...");
+ } else if (fun->nrofargs<0) {
+ DPRINTF("<unknown, check return>");
+ ret->args = RtlAllocateHeap(ntdll_get_process_heap(),
+ 0,16*sizeof(DWORD));
+ memcpy(ret->args,(LPBYTE)(context->Esp + 4),sizeof(DWORD)*16);
+ }
+ DPRINTF(") ret=%08lx\n",(DWORD)ret->origreturn);
+}
+
+
+void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
+{
+ SNOOP_RETURNENTRY *ret = (SNOOP_RETURNENTRY*)(context->Eip - 5);
+ SNOOP_FUN *fun = &ret->dll->funs[ret->ordinal];
+
+ /* We haven't found out the nrofargs yet. If we called a cdecl
+ * function it is too late anyway and we can just set '0' (which
+ * will be the difference between orig and current ESP
+ * If stdcall -> everything ok.
+ */
+ if (ret->dll->funs[ret->ordinal].nrofargs<0)
+ ret->dll->funs[ret->ordinal].nrofargs=(context->Esp - ret->origESP-4)/4;
+ context->Eip = (DWORD)ret->origreturn;
+ if (ret->args) {
+ int i,max;
+
+ if (fun->name)
+ DPRINTF("%04lx:RET %s.%s(", GetCurrentThreadId(), ret->dll->name, fun->name);
+ else
+ DPRINTF("%04lx:RET %s.%ld(", GetCurrentThreadId(),
+ ret->dll->name,ret->dll->ordbase+ret->ordinal);
+
+ max = fun->nrofargs;
+ if (max>16) max=16;
+
+ for (i=0;i<max;i++)
+ {
+ SNOOP_PrintArg(ret->args[i]);
+ if (i<max-1) DPRINTF(",");
+ }
+ DPRINTF(") retval=%08lx ret=%08lx\n",
+ context->Eax,(DWORD)ret->origreturn );
+ RtlFreeHeap(ntdll_get_process_heap(),0,ret->args);
+ ret->args = NULL;
+ }
+ else
+ {
+ if (fun->name)
+ DPRINTF("%04lx:RET %s.%s() retval=%08lx ret=%08lx\n",
+ GetCurrentThreadId(),
+ ret->dll->name, fun->name, context->Eax, (DWORD)ret->origreturn);
+ else
+ DPRINTF("%04lx:RET %s.%ld() retval=%08lx ret=%08lx\n",
+ GetCurrentThreadId(),
+ ret->dll->name,ret->dll->ordbase+ret->ordinal,
+ context->Eax, (DWORD)ret->origreturn);
+ }
+ ret->origreturn = NULL; /* mark as empty */
+}
+
+/* assembly wrappers that save the context */
+__ASM_GLOBAL_FUNC( SNOOP_Entry,
+ "call " __ASM_NAME("__wine_call_from_32_regs") "\n\t"
+ ".long " __ASM_NAME("SNOOP_DoEntry") ",0" );
+__ASM_GLOBAL_FUNC( SNOOP_Return,
+ "call " __ASM_NAME("__wine_call_from_32_regs") "\n\t"
+ ".long " __ASM_NAME("SNOOP_DoReturn") ",0" );
+
#else /* __i386__ */
FARPROC RELAY_GetProcAddress( HMODULE module, IMAGE_EXPORT_DIRECTORY *exports,
@@ -687,8 +1094,19 @@
return proc;
}
+FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports,
+ DWORD exp_size, FARPROC origfun, DWORD ordinal )
+{
+ return origfun;
+}
+
void RELAY_SetupDLL( const char *module )
{
}
+void SNOOP_SetupDLL( HMODULE hmod )
+{
+ FIXME("snooping works only on i386 for now.\n");
+}
+
#endif /* __i386__ */
diff --git a/include/snoop.h b/include/snoop.h
deleted file mode 100644
index 5e7a880..0000000
--- a/include/snoop.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Definitions for inter-dll snooping
- *
- * Copyright 1998 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __WINE_SNOOP_H
-#define __WINE_SNOOP_H
-
-#include <module.h>
-
-extern void SNOOP16_RegisterDLL(NE_MODULE*,LPCSTR);
-extern FARPROC16 SNOOP16_GetProcAddress16(HMODULE16,DWORD,FARPROC16);
-extern int SNOOP_ShowDebugmsgSnoop(const char *dll,int ord,const char *fname);
-#endif
diff --git a/loader/ne/module.c b/loader/ne/module.c
index 1e479b1..2b7556e 100644
--- a/loader/ne/module.c
+++ b/loader/ne/module.c
@@ -41,7 +41,6 @@
#include "toolhelp.h"
#include "file.h"
#include "task.h"
-#include "snoop.h"
#include "builtin16.h"
#include "stackframe.h"
#include "excpt.h"
diff --git a/relay32/snoop.c b/relay32/snoop.c
deleted file mode 100644
index 2ad07de..0000000
--- a/relay32/snoop.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * 386-specific Win32 dll<->dll snooping functions
- *
- * Copyright 1998 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "config.h"
-#include "wine/port.h"
-
-#include <assert.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <string.h>
-#include "ntstatus.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winternl.h"
-#include "snoop.h"
-#include "wine/debug.h"
-#include "wine/exception.h"
-#include "excpt.h"
-#include "ntdll_misc.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(snoop);
-WINE_DECLARE_DEBUG_CHANNEL(seh);
-
-static WINE_EXCEPTION_FILTER(page_fault)
-{
- if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
- GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
- return EXCEPTION_EXECUTE_HANDLER;
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-extern const char **debug_snoop_excludelist;
-extern const char **debug_snoop_includelist;
-
-#ifdef __i386__
-
-extern void WINAPI SNOOP_Entry();
-extern void WINAPI SNOOP_Return();
-
-#include "pshpack1.h"
-
-typedef struct tagSNOOP_FUN {
- /* code part */
- BYTE lcall; /* 0xe8 call snoopentry (relative) */
- /* NOTE: If you move snoopentry OR nrofargs fix the relative offset
- * calculation!
- */
- DWORD snoopentry; /* SNOOP_Entry relative */
- /* unreached */
- int nrofargs;
- FARPROC origfun;
- const char *name;
-} SNOOP_FUN;
-
-typedef struct tagSNOOP_DLL {
- HMODULE hmod;
- SNOOP_FUN *funs;
- DWORD ordbase;
- DWORD nrofordinals;
- struct tagSNOOP_DLL *next;
- char name[1];
-} SNOOP_DLL;
-
-typedef struct tagSNOOP_RETURNENTRY {
- /* code part */
- BYTE lcall; /* 0xe8 call snoopret relative*/
- /* NOTE: If you move snoopret OR origreturn fix the relative offset
- * calculation!
- */
- DWORD snoopret; /* SNOOP_Ret relative */
- /* unreached */
- FARPROC origreturn;
- SNOOP_DLL *dll;
- DWORD ordinal;
- DWORD origESP;
- DWORD *args; /* saved args across a stdcall */
-} SNOOP_RETURNENTRY;
-
-typedef struct tagSNOOP_RETURNENTRIES {
- SNOOP_RETURNENTRY entry[4092/sizeof(SNOOP_RETURNENTRY)];
- struct tagSNOOP_RETURNENTRIES *next;
-} SNOOP_RETURNENTRIES;
-
-#include "poppack.h"
-
-static SNOOP_DLL *firstdll = NULL;
-static SNOOP_RETURNENTRIES *firstrets = NULL;
-
-/***********************************************************************
- * SNOOP_ShowDebugmsgSnoop
- *
- * Simple function to decide if a particular debugging message is
- * wanted.
- */
-int SNOOP_ShowDebugmsgSnoop(const char *dll, int ord, const char *fname) {
-
- if(debug_snoop_excludelist || debug_snoop_includelist) {
- const char **listitem;
- char buf[80];
- int len, len2, itemlen, show;
-
- if(debug_snoop_excludelist) {
- show = 1;
- listitem = debug_snoop_excludelist;
- } else {
- show = 0;
- listitem = debug_snoop_includelist;
- }
- len = strlen(dll);
- assert(len < 64);
- sprintf(buf, "%s.%d", dll, ord);
- len2 = strlen(buf);
- for(; *listitem; listitem++) {
- itemlen = strlen(*listitem);
- if((itemlen == len && !strncasecmp(*listitem, buf, len)) ||
- (itemlen == len2 && !strncasecmp(*listitem, buf, len2)) ||
- !strcasecmp(*listitem, fname)) {
- show = !show;
- break;
- }
- }
- return show;
- }
- return 1;
-}
-
-void SNOOP_SetupDLL(HMODULE hmod)
-{
- SNOOP_DLL **dll = &firstdll;
- char *p, *name;
- void *addr;
- SIZE_T size;
- IMAGE_EXPORT_DIRECTORY *exports;
-
- exports = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
- if (!exports) return;
- name = (char *)hmod + exports->Name;
-
- TRACE("hmod=%p, name=%s\n", hmod, name);
-
- while (*dll) {
- if ((*dll)->hmod == hmod)
- {
- /* another dll, loaded at the same address */
- addr = (*dll)->funs;
- size = (*dll)->nrofordinals * sizeof(SNOOP_FUN);
- NtFreeVirtualMemory(GetCurrentProcess(), &addr, &size, MEM_RELEASE);
- break;
- }
- dll = &((*dll)->next);
- }
- *dll = RtlReAllocateHeap(ntdll_get_process_heap(),
- HEAP_ZERO_MEMORY, *dll,
- sizeof(SNOOP_DLL) + strlen(name));
- (*dll)->hmod = hmod;
- (*dll)->ordbase = exports->Base;
- (*dll)->nrofordinals = exports->NumberOfFunctions;
- strcpy( (*dll)->name, name );
- p = (*dll)->name + strlen((*dll)->name) - 4;
- if (p > (*dll)->name && !strcasecmp( p, ".dll" )) *p = 0;
-
- size = exports->NumberOfFunctions * sizeof(SNOOP_FUN);
- NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size,
- MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!addr) {
- RtlFreeHeap(ntdll_get_process_heap(),0,*dll);
- FIXME("out of memory\n");
- return;
- }
- (*dll)->funs = addr;
- memset((*dll)->funs,0,size);
-}
-
-FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
- FARPROC origfun, DWORD ordinal )
-{
- int i;
- const char *ename;
- WORD *ordinals;
- DWORD *names;
- SNOOP_DLL *dll = firstdll;
- SNOOP_FUN *fun;
- IMAGE_SECTION_HEADER *sec;
-
- if (!TRACE_ON(snoop)) return origfun;
- if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
- return origfun;
-
- sec = RtlImageRvaToSection( RtlImageNtHeader(hmod), hmod, (char *)origfun - (char *)hmod );
-
- if (!sec || !(sec->Characteristics & IMAGE_SCN_CNT_CODE))
- return origfun; /* most likely a data reference */
-
- while (dll) {
- if (hmod == dll->hmod)
- break;
- dll=dll->next;
- }
- if (!dll) /* probably internal */
- return origfun;
-
- /* try to find a name for it */
- ename = NULL;
- names = (DWORD *)((char *)hmod + exports->AddressOfNames);
- ordinals = (WORD *)((char *)hmod + exports->AddressOfNameOrdinals);
- if (names) for (i = 0; i < exports->NumberOfNames; i++)
- {
- if (ordinals[i] == ordinal)
- {
- ename = (char *)hmod + names[i];
- break;
- }
- }
- if (!SNOOP_ShowDebugmsgSnoop(dll->name,ordinal,ename))
- return origfun;
- assert(ordinal < dll->nrofordinals);
- fun = dll->funs+ordinal;
- if (!fun->name)
- {
- fun->name = ename;
- fun->lcall = 0xe8;
- /* NOTE: origreturn struct member MUST come directly after snoopentry */
- fun->snoopentry = (char*)SNOOP_Entry-((char*)(&fun->nrofargs));
- fun->origfun = origfun;
- fun->nrofargs = -1;
- }
- return (FARPROC)&(fun->lcall);
-}
-
-static void SNOOP_PrintArg(DWORD x)
-{
- int i,nostring;
-
- DPRINTF("%08lx",x);
- if (!HIWORD(x) || TRACE_ON(seh)) return; /* trivial reject to avoid faults */
- __TRY
- {
- LPBYTE s=(LPBYTE)x;
- i=0;nostring=0;
- while (i<80) {
- if (s[i]==0) break;
- if (s[i]<0x20) {nostring=1;break;}
- if (s[i]>=0x80) {nostring=1;break;}
- i++;
- }
- if (!nostring && i > 5)
- DPRINTF(" %s",debugstr_an((LPSTR)x,i));
- else /* try unicode */
- {
- LPWSTR s=(LPWSTR)x;
- i=0;nostring=0;
- while (i<80) {
- if (s[i]==0) break;
- if (s[i]<0x20) {nostring=1;break;}
- if (s[i]>0x100) {nostring=1;break;}
- i++;
- }
- if (!nostring && i > 5) DPRINTF(" %s",debugstr_wn((LPWSTR)x,i));
- }
- }
- __EXCEPT(page_fault)
- {
- }
- __ENDTRY
-}
-
-#define CALLER1REF (*(DWORD*)context->Esp)
-
-void WINAPI SNOOP_DoEntry( CONTEXT86 *context )
-{
- DWORD ordinal=0,entry = context->Eip - 5;
- SNOOP_DLL *dll = firstdll;
- SNOOP_FUN *fun = NULL;
- SNOOP_RETURNENTRIES **rets = &firstrets;
- SNOOP_RETURNENTRY *ret;
- int i=0, max;
-
- while (dll) {
- if ( ((char*)entry>=(char*)dll->funs) &&
- ((char*)entry<=(char*)(dll->funs+dll->nrofordinals))
- ) {
- fun = (SNOOP_FUN*)entry;
- ordinal = fun-dll->funs;
- break;
- }
- dll=dll->next;
- }
- if (!dll) {
- FIXME("entrypoint 0x%08lx not found\n",entry);
- return; /* oops */
- }
- /* guess cdecl ... */
- if (fun->nrofargs<0) {
- /* Typical cdecl return frame is:
- * add esp, xxxxxxxx
- * which has (for xxxxxxxx up to 255 the opcode "83 C4 xx".
- * (after that 81 C2 xx xx xx xx)
- */
- LPBYTE reteip = (LPBYTE)CALLER1REF;
-
- if (reteip) {
- if ((reteip[0]==0x83)&&(reteip[1]==0xc4))
- fun->nrofargs=reteip[2]/4;
- }
- }
-
-
- while (*rets) {
- for (i=0;i<sizeof((*rets)->entry)/sizeof((*rets)->entry[0]);i++)
- if (!(*rets)->entry[i].origreturn)
- break;
- if (i!=sizeof((*rets)->entry)/sizeof((*rets)->entry[0]))
- break;
- rets = &((*rets)->next);
- }
- if (!*rets) {
- SIZE_T size = 4096;
- VOID* addr;
-
- NtAllocateVirtualMemory(GetCurrentProcess(), &addr, NULL, &size,
- MEM_COMMIT | MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
- if (!addr) return;
- *rets = addr;
- memset(*rets,0,4096);
- i = 0; /* entry 0 is free */
- }
- ret = &((*rets)->entry[i]);
- ret->lcall = 0xe8;
- /* NOTE: origreturn struct member MUST come directly after snoopret */
- ret->snoopret = ((char*)SNOOP_Return)-(char*)(&ret->origreturn);
- ret->origreturn = (FARPROC)CALLER1REF;
- CALLER1REF = (DWORD)&ret->lcall;
- ret->dll = dll;
- ret->args = NULL;
- ret->ordinal = ordinal;
- ret->origESP = context->Esp;
-
- context->Eip = (DWORD)fun->origfun;
-
- if (fun->name) DPRINTF("%04lx:CALL %s.%s(",GetCurrentThreadId(),dll->name,fun->name);
- else DPRINTF("%04lx:CALL %s.%ld(",GetCurrentThreadId(),dll->name,dll->ordbase+ordinal);
- if (fun->nrofargs>0) {
- max = fun->nrofargs; if (max>16) max=16;
- for (i=0;i<max;i++)
- {
- SNOOP_PrintArg(*(DWORD*)(context->Esp + 4 + sizeof(DWORD)*i));
- if (i<fun->nrofargs-1) DPRINTF(",");
- }
- if (max!=fun->nrofargs)
- DPRINTF(" ...");
- } else if (fun->nrofargs<0) {
- DPRINTF("<unknown, check return>");
- ret->args = RtlAllocateHeap(ntdll_get_process_heap(),
- 0,16*sizeof(DWORD));
- memcpy(ret->args,(LPBYTE)(context->Esp + 4),sizeof(DWORD)*16);
- }
- DPRINTF(") ret=%08lx\n",(DWORD)ret->origreturn);
-}
-
-
-void WINAPI SNOOP_DoReturn( CONTEXT86 *context )
-{
- SNOOP_RETURNENTRY *ret = (SNOOP_RETURNENTRY*)(context->Eip - 5);
- SNOOP_FUN *fun = &ret->dll->funs[ret->ordinal];
-
- /* We haven't found out the nrofargs yet. If we called a cdecl
- * function it is too late anyway and we can just set '0' (which
- * will be the difference between orig and current ESP
- * If stdcall -> everything ok.
- */
- if (ret->dll->funs[ret->ordinal].nrofargs<0)
- ret->dll->funs[ret->ordinal].nrofargs=(context->Esp - ret->origESP-4)/4;
- context->Eip = (DWORD)ret->origreturn;
- if (ret->args) {
- int i,max;
-
- if (fun->name)
- DPRINTF("%04lx:RET %s.%s(", GetCurrentThreadId(), ret->dll->name, fun->name);
- else
- DPRINTF("%04lx:RET %s.%ld(", GetCurrentThreadId(),
- ret->dll->name,ret->dll->ordbase+ret->ordinal);
-
- max = fun->nrofargs;
- if (max>16) max=16;
-
- for (i=0;i<max;i++)
- {
- SNOOP_PrintArg(ret->args[i]);
- if (i<max-1) DPRINTF(",");
- }
- DPRINTF(") retval=%08lx ret=%08lx\n",
- context->Eax,(DWORD)ret->origreturn );
- RtlFreeHeap(ntdll_get_process_heap(),0,ret->args);
- ret->args = NULL;
- }
- else
- {
- if (fun->name)
- DPRINTF("%04lx:RET %s.%s() retval=%08lx ret=%08lx\n",
- GetCurrentThreadId(),
- ret->dll->name, fun->name, context->Eax, (DWORD)ret->origreturn);
- else
- DPRINTF("%04lx:RET %s.%ld() retval=%08lx ret=%08lx\n",
- GetCurrentThreadId(),
- ret->dll->name,ret->dll->ordbase+ret->ordinal,
- context->Eax, (DWORD)ret->origreturn);
- }
- ret->origreturn = NULL; /* mark as empty */
-}
-
-/* assembly wrappers that save the context */
-__ASM_GLOBAL_FUNC( SNOOP_Entry,
- "call " __ASM_NAME("__wine_call_from_32_regs") "\n\t"
- ".long " __ASM_NAME("SNOOP_DoEntry") ",0" );
-__ASM_GLOBAL_FUNC( SNOOP_Return,
- "call " __ASM_NAME("__wine_call_from_32_regs") "\n\t"
- ".long " __ASM_NAME("SNOOP_DoReturn") ",0" );
-
-#else /* !__i386__ */
-
-void SNOOP_SetupDLL(HMODULE hmod)
-{
- FIXME("snooping works only on i386 for now.\n");
-}
-
-FARPROC SNOOP_GetProcAddress( HMODULE hmod, IMAGE_EXPORT_DIRECTORY *exports, DWORD exp_size,
- FARPROC origfun, DWORD ordinal )
-{
- return origfun;
-}
-#endif /* !__i386__ */