Partial implementation of NotifyRegister notifications
Joshua Thielen
thielen at netprince.net
Wed Aug 21 21:17:55 CDT 2002
Hello!
This patch implements the ToolHelpHook and NotifyRegister notifications,
NFY_STARTTASK, NFY_STARTDLL, NFY_LOADSEG, NFY_FREESEG, NFY_EXITTASK and
NFY_DELMODULE, needed to fix bug 575 (SmartForms installer).
I expect there to be problems with this patch (some of it is probably a
bit over my head) so eyes are requested, please! I already know that the
number and order of the segment messages (NFY_LOADSEG and FREESEG)
doesn't exactly match those sent in Windows, and I'm not totally sure of
the affect this patch will have on 16-bit memory and threading details
in wine.
Well anyway, here it goes...
Changelog:
Implemented NotifyRegister notifications, NFY_STARTTASK, NFY_STARTDLL,
NFY_LOADSEG, NFY_FREESEG, NFY_EXITTASK and NFY_DELMODULE
Modified Files:
wine/dlls/kernel/toolhelp.c
wine/dlls/kernel/toolhelp.spec
wine/dlls/ntdll/Makefile.in
wine/include/toolhelp.h
wine/loader/task.c
wine/loader/ne/module.c
wine/loader/ne/segment.c
wine/scheduler/thread.c
License:
GPL, X11
Josh Thielen
-------------- next part --------------
Index: wine/dlls/kernel/toolhelp.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/toolhelp.c,v
retrieving revision 1.17
diff -u -r1.17 toolhelp.c
--- wine/dlls/kernel/toolhelp.c 31 May 2002 23:25:48 -0000 1.17
+++ wine/dlls/kernel/toolhelp.c 18 Aug 2002 21:20:32 -0000
@@ -27,18 +27,15 @@
#include "wine/winbase16.h"
#include "winerror.h"
#include "local.h"
+#include "stackframe.h"
#include "tlhelp32.h"
#include "toolhelp.h"
#include "wine/server.h"
#include "wine/debug.h"
+#include "miscemu.h"
WINE_DEFAULT_DEBUG_CHANNEL(toolhelp);
-
-/* FIXME: to make this work, we have to call back all these registered
- * functions from all over the WINE code. Someone with more knowledge than
- * me please do that. -Marcus
- */
static struct notify
{
HTASK16 htask;
@@ -46,9 +43,96 @@
WORD wFlags;
} *notifys = NULL;
-static int nrofnotifys = 0;
+static int num_notifys = 0;
+/* ### start build ### */
+extern WORD CALLBACK TOOLHELP_CallTo16_word_wl(FARPROC16,WORD,DWORD);
+/* ### stop build ### */
+
+FARPROC16 ToolHelpHookProc = NULL;
+
+FARPROC16 WINAPI ToolHelpHook16(FARPROC16 lpfnNotifyHandler);
+
+void NotifyRegisterHook(CONTEXT86 *context)
+{
+ WORD wID = NFY_UNKNOWN;
+ DWORD dwData = 0;
+ NFYLOADSEG nfyls;
+ NFYSTARTDLL nfysd;
+ TEB *teb = NtCurrentTeb();
+ HANDLE16 handle = 0;
+ LPVOID p;
+ int i;
+
+ /* see INT 41h */
+ switch(context->Eax)
+ {
+ case 0x50:
+ wID = NFY_LOADSEG;
+ nfyls.dwSize = sizeof(nfyls);
+ nfyls.wSelector = CX_reg(context);
+ nfyls.wSegNum = BX_reg(context);
+ nfyls.wType = SI_reg(context);
+ nfyls.wcInstance = DX_reg(context);
+ nfyls.lpstrModuleName = CTX_SEG_OFF_TO_LIN(context,
+ context->SegEs, context->Edi);
+ handle = GlobalAlloc16(0, sizeof(nfyls));
+ p = GlobalLock16(handle);
+ memcpy(p, &nfyls, sizeof(nfyls));
+ GlobalUnlock16(handle);
+ dwData = K32WOWGlobalLock16(handle);
+ break;
+
+ case 0x52:
+ wID = NFY_FREESEG;
+ dwData = context->Ebx; /* selector of freed segment */
+ break;
+
+ case 0x59:
+ wID = NFY_STARTTASK;
+ dwData = (DWORD) CTX_SEG_OFF_TO_LIN(context,
+ context->SegCs, context->Esi);
+ break;
+
+ case 0x62:
+ wID = NFY_EXITTASK;
+ dwData = *(BYTE *)MapSL((SEGPTR)teb->cur_stack + 6);
+ stack16_pop(6);
+ NotifyUnRegister16(GetCurrentTask());
+ break;
+
+ case 0x64:
+ wID = NFY_STARTDLL;
+ nfysd.dwSize = sizeof(NFYSTARTDLL);
+ nfysd.hModule = SI_reg(context);
+ nfysd.wCS = context->Ecx;
+ nfysd.wIP = context->Ebx;
+ handle = GlobalAlloc16(0, sizeof(nfysd));
+ p = GlobalLock16(handle);
+ memcpy(p, &nfysd, sizeof(nfysd));
+ GlobalUnlock16(handle);
+ dwData = K32WOWGlobalLock16(handle);
+ break;
+
+ case 0x65:
+ wID = NFY_DELMODULE;
+ dwData = context->SegEs;
+ break;
+
+ default:
+ wID = NFY_UNKNOWN;
+ }
-static FARPROC16 HookNotify = NULL;
+ /* Call the registered notification handlers */
+ for(i = 0; i < num_notifys; i++)
+ {
+ TOOLHELP_CallTo16_word_wl(notifys[i].lpfnCallback, wID, dwData);
+ }
+
+ if(handle) {
+ GlobalUnlock16(handle);
+ GlobalFree16(handle);
+ }
+}
/***********************************************************************
* NotifyRegister (TOOLHELP.73)
@@ -56,48 +140,75 @@
BOOL16 WINAPI NotifyRegister16( HTASK16 htask, FARPROC16 lpfnCallback,
WORD wFlags )
{
- int i;
+ int i;
- FIXME("(%x,%lx,%x), semi-stub.\n",
+ FIXME("(%x,%lx,%x), not all notifications are implemented.\n",
htask, (DWORD)lpfnCallback, wFlags );
+ if(!num_notifys)
+ {
+ FARPROC16 proc = GetProcAddress16(GetModuleHandle16("TOOLHELP"),
+ "NotifyRegisterHook");
+ ToolHelpHook16(proc);
+ }
+
if (!htask) htask = GetCurrentTask();
- for (i=0;i<nrofnotifys;i++)
- if (notifys[i].htask==htask)
+ for (i = 0; i < num_notifys; i++)
+ {
+ if (notifys[i].htask == htask)
+ {
break;
- if (i==nrofnotifys) {
- if (notifys==NULL)
- notifys=(struct notify*)HeapAlloc( GetProcessHeap(), 0,
- sizeof(struct notify) );
- else
- notifys=(struct notify*)HeapReAlloc( GetProcessHeap(), 0, notifys,
- sizeof(struct notify)*(nrofnotifys+1));
+ }
+ }
+ if (i == num_notifys)
+ {
+ if (notifys == NULL)
+ {
+ notifys = (struct notify*)HeapAlloc( GetProcessHeap(), 0,
+ sizeof(struct notify) );
+ }
+ else
+ {
+ notifys = (struct notify*)HeapReAlloc( GetProcessHeap(), 0,
+ notifys, sizeof(struct notify) * (num_notifys + 1));
+ }
if (!notifys) return FALSE;
- nrofnotifys++;
+ num_notifys++;
}
- notifys[i].htask=htask;
- notifys[i].lpfnCallback=lpfnCallback;
- notifys[i].wFlags=wFlags;
+ notifys[i].htask = htask;
+ notifys[i].lpfnCallback = lpfnCallback;
+ notifys[i].wFlags = wFlags;
return TRUE;
}
/***********************************************************************
- * NotifyUnregister (TOOLHELP.74)
+ * NotifyUnRegister (TOOLHELP.74)
*/
-BOOL16 WINAPI NotifyUnregister16( HTASK16 htask )
+BOOL16 WINAPI NotifyUnRegister16( HTASK16 htask )
{
int i;
- FIXME("(%x), semi-stub.\n", htask );
if (!htask) htask = GetCurrentTask();
- for (i=nrofnotifys;i--;)
- if (notifys[i].htask==htask)
+ for (i = 0; i < num_notifys; i++)
+ {
+ if (notifys[i].htask == htask)
+ {
break;
- if (i==-1)
+ }
+ }
+ if (i == num_notifys)
+ {
return FALSE;
- memcpy(notifys+i,notifys+(i+1),sizeof(struct notify)*(nrofnotifys-i-1));
- notifys=(struct notify*)HeapReAlloc( GetProcessHeap(), 0, notifys,
- (nrofnotifys-1)*sizeof(struct notify));
- nrofnotifys--;
+ }
+ memcpy(notifys+i, notifys+i+1, sizeof(struct notify)*(num_notifys-i-1));
+ notifys = (struct notify *) HeapReAlloc( GetProcessHeap(), 0, notifys,
+ (num_notifys-1) * sizeof(struct notify));
+ num_notifys--;
+
+ if(!num_notifys)
+ {
+ /* remove hook proc */
+ ToolHelpHook16(0);
+ }
return TRUE;
}
@@ -191,9 +302,9 @@
{
FARPROC16 tmp;
- FIXME("(%p), stub.\n", lpfnNotifyHandler);
- tmp = HookNotify;
- HookNotify = lpfnNotifyHandler;
+ tmp = ToolHelpHookProc;
+ ToolHelpHookProc = lpfnNotifyHandler;
+ TRACE("installed tool help hook function %p\n", ToolHelpHookProc);
/* just return previously installed notification function */
return tmp;
}
Index: wine/dlls/kernel/toolhelp.spec
===================================================================
RCS file: /home/wine/wine/dlls/kernel/toolhelp.spec,v
retrieving revision 1.5
diff -u -r1.5 toolhelp.spec
--- wine/dlls/kernel/toolhelp.spec 21 Jun 2002 19:15:47 -0000 1.5
+++ wine/dlls/kernel/toolhelp.spec 18 Aug 2002 21:20:32 -0000
@@ -25,7 +25,7 @@
71 pascal16 SystemHeapInfo(ptr) SystemHeapInfo16
72 pascal16 MemManInfo(ptr) MemManInfo16
73 pascal16 NotifyRegister(word segptr word) NotifyRegister16
-74 pascal16 NotifyUnregister(word) NotifyUnregister16
+74 pascal16 NotifyUnRegister(word) NotifyUnRegister16
75 pascal16 InterruptRegister(word segptr) InterruptRegister16
76 pascal16 InterruptUnRegister(word) InterruptUnRegister16
77 pascal16 TerminateApp(word word) TerminateApp16
@@ -38,3 +38,5 @@
84 pascal16 Local32Info(ptr word) Local32Info16
85 pascal16 Local32First(ptr word) Local32First16
86 pascal16 Local32Next(ptr) Local32Next16
+# wine-specific
+100 pascal16 -register NotifyRegisterHook() NotifyRegisterHook
Index: wine/dlls/ntdll/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/ntdll/Makefile.in,v
retrieving revision 1.31
diff -u -r1.31 Makefile.in
--- wine/dlls/ntdll/Makefile.in 1 Aug 2002 18:36:58 -0000 1.31
+++ wine/dlls/ntdll/Makefile.in 18 Aug 2002 21:20:37 -0000
@@ -7,6 +7,7 @@
EXTRALIBS = $(LIBUNICODE)
C_SRCS = \
+ $(TOPOBJDIR)/dlls/kernel/toolhelp.c \
$(TOPOBJDIR)/files/change.c \
$(TOPOBJDIR)/files/directory.c \
$(TOPOBJDIR)/files/dos_fs.c \
===================================================================
RCS file: /home/wine/wine/include/task.h,v
retrieving revision 1.30
diff -u -r1.30 task.h
--- wine/include/task.h 31 May 2002 23:06:49 -0000 1.30
+++ wine/include/task.h 18 Aug 2002 21:21:20 -0000
@@ -162,7 +162,7 @@
extern void TASK_CreateMainTask(void);
extern HTASK16 TASK_SpawnTask( struct _NE_MODULE *pModule, WORD cmdShow,
LPCSTR cmdline, BYTE len, HANDLE *hThread );
-extern void TASK_ExitTask(void);
+extern void TASK_ExitTask(DWORD code);
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
extern TDB *TASK_GetPtr( HTASK16 hTask );
extern TDB *TASK_GetCurrent(void);
Index: wine/include/toolhelp.h
===================================================================
RCS file: /home/wine/wine/include/toolhelp.h,v
retrieving revision 1.13
diff -u -r1.13 toolhelp.h
--- wine/include/toolhelp.h 10 Mar 2002 00:02:34 -0000 1.13
+++ wine/include/toolhelp.h 18 Aug 2002 21:21:21 -0000
@@ -328,6 +328,7 @@
#define NF_RIP 2 /* get debugerrors of system */
BOOL16 WINAPI NotifyRegister16(HTASK16 htask,FARPROC16 lpfnCallback,WORD wFlags);
+BOOL16 WINAPI NotifyUnRegister16(HTASK16 hTask);
#define NFY_UNKNOWN 0
#define NFY_LOADSEG 1
@@ -338,6 +339,7 @@
WORD wSegNum;
WORD wType; /* bit 0 set if this is a code segment */
WORD wcInstance; /* only valid for data segment */
+ LPCSTR lpstrModuleName;
} NFYLOADSEG;
/* called when freeing a segment. LOWORD(dwData) is the freed selector */
#define NFY_FREESEG 2
@@ -385,7 +387,7 @@
#define NFY_INCHAR 10
/* output debugstring (pointed to by dwData) */
-#define NFY_OUTSTRING 11
+#define NFY_OUTSTR 11
/* log errors */
#define NFY_LOGERROR 12
Index: wine/loader/task.c
===================================================================
RCS file: /home/wine/wine/loader/task.c,v
retrieving revision 1.120
diff -u -r1.120 task.c
--- wine/loader/task.c 28 Jul 2002 23:48:28 -0000 1.120
+++ wine/loader/task.c 18 Aug 2002 21:21:30 -0000
@@ -56,6 +56,7 @@
/* Min. number of thunks allocated when creating a new segment */
#define MIN_THUNKS 32
+extern FARPROC16 ToolHelpHookProc;
static THHOOK DefaultThhook;
THHOOK *pThhook = &DefaultThhook;
@@ -338,10 +339,7 @@
pTask->pdb.cmdLine[0] = len;
memcpy( pTask->pdb.cmdLine + 1, cmdline, len );
/* pTask->pdb.cmdLine[len+1] = 0; */
-
- TRACE("module='%s' cmdline='%.*s' task=%04x\n", name, len, cmdline, hTask );
-
- /* Get the compatibility flags */
+ /* Get the compatibility flags */
pTask->compat_flags = GetProfileIntA( "Compatibility", name, 0 );
@@ -468,10 +466,28 @@
/***********************************************************************
* TASK_ExitTask
*/
-void TASK_ExitTask(void)
+void TASK_ExitTask(DWORD code)
{
TDB *pTask;
DWORD lockCount;
+ CONTEXT86 context;
+ SEGPTR ptr;
+
+ /* send notification */
+ if(ToolHelpHookProc)
+ {
+ TRACE_(toolhelp)("Sending termination notification\n");
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x62;
+ ptr = stack16_push(6);
+ *(BYTE *)MapSL(ptr) = LOBYTE(code);
+ context.Esp -= 6;
+ wine_call_to_16_regs_short( &context, 0 );
+ }
/* Enter the Win16Lock to protect global data structures */
_EnterWin16Lock();
@@ -516,10 +532,10 @@
if ( hLockedTask == pTask->hSelf )
hLockedTask = 0;
- TASK_DeleteTask( pTask->hSelf );
-
/* ... and completely release the Win16Lock, just in case. */
ReleaseThunkLock( &lockCount );
+
+ TASK_DeleteTask( pTask->hSelf );
}
@@ -1535,6 +1555,7 @@
ERR( "%s\n", debugstr_a(str) );
}
done:
+ NotifyUnRegister16(pTask->hSelf);
ExitThread(0xff);
}
Index: wine/loader/ne/module.c
===================================================================
RCS file: /home/wine/wine/loader/ne/module.c,v
retrieving revision 1.116
diff -u -r1.116 module.c
--- wine/loader/ne/module.c 31 Jul 2002 19:26:04 -0000 1.116
+++ wine/loader/ne/module.c 18 Aug 2002 21:21:36 -0000
@@ -42,6 +42,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(module);
WINE_DECLARE_DEBUG_CHANNEL(loaddll);
+WINE_DECLARE_DEBUG_CHANNEL(toolhelp);
/*
* Segment table entry
@@ -56,6 +57,7 @@
#define hFirstModule (pThhook->hExeHead)
+extern FARPROC16 ToolHelpHookProc;
static NE_MODULE *pCachedModule = 0; /* Module cached by NE_OpenFile */
static HINSTANCE16 NE_LoadModule( LPCSTR name, BOOL lib_only );
@@ -1187,6 +1189,22 @@
sp -= sizeof(STACK16FRAME);
pTask->teb->cur_stack = MAKESEGPTR( GlobalHandleToSel16(hInstance), sp );
+ /* send notification */
+ if(ToolHelpHookProc)
+ {
+ TRACE_(toolhelp)("Sending start task notification\n");
+ pSegTable = NE_SEG_TABLE( pModule );
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x59;
+ context.Ecx = pModule->cs;
+ context.Ebx = pModule->ip;
+ wine_call_to_16_regs_short( &context, 0 );
+ }
+
/* Registers at initialization must be:
* ax zero
* bx stack size in bytes
@@ -1245,6 +1263,38 @@
return NE_CallTo16_word_w( WEP, WEP_FREE_DLL );
}
+/**********************************************************************
+ * NE_FreeModuleSegments
+ *
+ * Does not actually free the segment memory. Simply sends the free
+ * segment notification for each segment in the module.
+ */
+void NE_FreeModuleSegments(NE_MODULE *pModule)
+{
+ SEGTABLEENTRY *pSegTable, *pSeg;
+ CONTEXT86 context;
+ int i;
+
+ pSegTable = NE_SEG_TABLE( pModule );
+ for(i = 0; i < pModule->seg_count; i++) {
+ memset(&context, 0, sizeof(context));
+ pSeg = pSegTable + i;
+
+ /* send notification */
+ if(ToolHelpHookProc) {
+ TRACE_(toolhelp)("sending free segment notification\n");
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x52;
+ context.Ebx = GlobalHandleToSel16( pSeg->hSeg );
+ context.SegEs = pModule->self;
+ wine_call_to_16_regs_short(&context, 0);
+ }
+ }
+}
/**********************************************************************
* NE_FreeModule
@@ -1256,6 +1306,7 @@
HMODULE16 *hPrevModule;
NE_MODULE *pModule;
HMODULE16 *pModRef;
+ CONTEXT86 context;
int i;
if (!(pModule = NE_GetPtr( hModule ))) return FALSE;
@@ -1266,6 +1317,22 @@
if (((INT16)(--pModule->count)) > 0 ) return TRUE;
else pModule->count = 0;
+ /* send notifications */
+ if(ToolHelpHookProc) {
+ TRACE_(toolhelp)("sending toolhelp notification to hook proc %p\n", ToolHelpHookProc);
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x65;
+ context.Ebx = GlobalHandleToSel16( pModule->self );
+ context.SegEs = pModule->self;
+ wine_call_to_16_regs_short(&context, 0);
+ }
+
+ NE_FreeModuleSegments(pModule);
+
if (pModule->flags & NE_FFLAGS_BUILTIN)
return FALSE; /* Can't free built-in module */
Index: wine/loader/ne/segment.c
===================================================================
RCS file: /home/wine/wine/loader/ne/segment.c,v
retrieving revision 1.46
diff -u -r1.46 segment.c
--- wine/loader/ne/segment.c 31 Jul 2002 17:20:01 -0000 1.46
+++ wine/loader/ne/segment.c 18 Aug 2002 21:21:40 -0000
@@ -42,6 +42,7 @@
WINE_DECLARE_DEBUG_CHANNEL(fixup);
WINE_DECLARE_DEBUG_CHANNEL(module);
WINE_DECLARE_DEBUG_CHANNEL(segment);
+WINE_DECLARE_DEBUG_CHANNEL(toolhelp);
/*
* Relocation table entry
@@ -76,6 +77,7 @@
#define SEL(x) ((x)|1)
+extern FARPROC16 ToolHelpHookProc;
static void NE_FixupSegmentPrologs(NE_MODULE *pModule, WORD segnum);
/* ### start build ### */
@@ -113,14 +115,17 @@
FARPROC16 address = 0;
HANDLE hf;
DWORD res;
+ LPSTR lpstrModuleName;
struct relocation_entry_s *rep, *reloc_entries;
BYTE *func_name;
int size;
char* mem;
-
char buffer[256];
int ordinal, additive;
- unsigned short *sp;
+ unsigned short *sp;
+ CONTEXT86 context;
+
+ lpstrModuleName = (char *) pModule + pModule->name_table + 1,
pSegTable = NE_SEG_TABLE( pModule );
pSeg = pSegTable + segnum - 1;
@@ -143,6 +148,27 @@
hf = NE_OpenFile( pModule );
TRACE_(module)("Loading segment %d, hSeg=%04x, flags=%04x\n",
segnum, pSeg->hSeg, pSeg->flags );
+
+ /* send notification */
+ if(ToolHelpHookProc)
+ {
+ TRACE_(toolhelp)("sending segment load notification\n");
+ /* send segment load notification */
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x50;
+ context.Ebx = segnum;
+ context.Ecx = GlobalHandleToSel16(pSeg->hSeg);
+ context.Edx = pModule->self;
+ context.SegDs = SELECTOROF(lpstrModuleName);
+ context.Edi = OFFSETOF(lpstrModuleName);
+ context.Esi = pSeg->flags;
+ wine_call_to_16_regs_short(&context, 0);
+ }
+
SetFilePointer( hf, pSeg->filepos << pModule->alignment, NULL, SEEK_SET );
if (pSeg->size) size = pSeg->size;
else size = pSeg->minsize ? pSeg->minsize : 0x10000;
@@ -644,9 +670,6 @@
/* Call USER signal handler for Win3.1 compatibility. */
TASK_CallTaskSignalProc( USIG16_DLL_LOAD, pModule->self );
- if (!pModule->cs) return TRUE; /* no initialization code */
-
-
/* Registers at initialization must be:
* cx heap size
* di library instance
@@ -656,6 +679,32 @@
memset( &context, 0, sizeof(context) );
+ /* send notification */
+ if(ToolHelpHookProc)
+ {
+ TRACE_(toolhelp)("sending start DLL notification\n");
+ memset(&context, 0, sizeof(context));
+ context.SegCs = SELECTOROF(ToolHelpHookProc);
+ context.Eip = OFFSETOF(ToolHelpHookProc);
+ context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack)
+ + (WORD)&((STACK16FRAME*)0)->bp;
+ context.Eax = 0x64;
+ if (!pModule->cs)
+ {
+ context.Ecx = 0;
+ context.Ebx = 0;
+ }
+ else
+ {
+ context.Ecx = SEL(pSegTable[pModule->cs-1].hSeg);
+ context.Ebx = pModule->ip;
+ }
+ context.Esi = pModule->self;
+ wine_call_to_16_regs_short(&context, 0);
+ }
+
+ if (!pModule->cs) return TRUE; /* no initialization code */
+
NE_GetDLLInitParams( pModule, &hInst, &ds, &heap );
context.Ecx = heap;
@@ -667,12 +716,13 @@
context.Eip = pModule->ip;
context.Ebp = OFFSETOF(NtCurrentTeb()->cur_stack) + (WORD)&((STACK16FRAME*)0)->bp;
-
pModule->cs = 0; /* Don't initialize it twice */
+
TRACE_(dll)("Calling LibMain, cs:ip=%04lx:%04lx ds=%04lx di=%04x cx=%04x\n",
context.SegCs, context.Eip, context.SegDs,
LOWORD(context.Edi), LOWORD(context.Ecx) );
wine_call_to_16_regs_short( &context, 0 );
+
return TRUE;
}
Index: wine/scheduler/thread.c
===================================================================
RCS file: /home/wine/wine/scheduler/thread.c,v
retrieving revision 1.119
diff -u -r1.119 thread.c
--- wine/scheduler/thread.c 31 Jul 2002 19:26:05 -0000 1.119
+++ wine/scheduler/thread.c 18 Aug 2002 21:21:54 -0000
@@ -377,7 +377,8 @@
else
{
MODULE_DllThreadDetach( NULL );
- if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_ExitTask();
+ TRACE("Exit code=%08x\n", code);
+ if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_ExitTask(code);
SYSDEPS_ExitThread( code );
}
}
More information about the wine-patches
mailing list