Check all Callouts function pointers for NULL before using them.
Don't load USER dll if not needed by the application.
This commit is contained in:
parent
d3576a9f85
commit
4e951ea25b
|
@ -617,15 +617,26 @@ INT16 WINAPI WriteSpool16(HPJOB16 hJob, LPSTR lpData, INT16 cch)
|
||||||
return nRet;
|
return nRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef INT WINAPI (*MSGBOX_PROC)( HWND, LPCSTR, LPCSTR, UINT );
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* WriteDialog (GDI.242)
|
* WriteDialog (GDI.242)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
INT16 WINAPI WriteDialog16(HPJOB16 hJob, LPSTR lpMsg, INT16 cchMsg)
|
INT16 WINAPI WriteDialog16(HPJOB16 hJob, LPSTR lpMsg, INT16 cchMsg)
|
||||||
{
|
{
|
||||||
|
HMODULE mod;
|
||||||
|
MSGBOX_PROC pMessageBoxA;
|
||||||
|
INT16 ret = 0;
|
||||||
|
|
||||||
TRACE("%04x %04x '%s'\n", hJob, cchMsg, lpMsg);
|
TRACE("%04x %04x '%s'\n", hJob, cchMsg, lpMsg);
|
||||||
|
|
||||||
return Callout.MessageBoxA(0, lpMsg, "Printing Error", MB_OKCANCEL);
|
if ((mod = GetModuleHandleA("user32.dll")))
|
||||||
|
{
|
||||||
|
if ((pMessageBoxA = (MSGBOX_PROC)GetProcAddress( mod, "MessageBoxA" )))
|
||||||
|
ret = pMessageBoxA(0, lpMsg, "Printing Error", MB_OKCANCEL);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,7 @@ static void CALLBACK comm_notification( ULONG_PTR private )
|
||||||
/* send notifications, if any */
|
/* send notifications, if any */
|
||||||
if (ptr->wnd && mask) {
|
if (ptr->wnd && mask) {
|
||||||
TRACE("notifying %04x: cid=%d, mask=%02x\n", ptr->wnd, cid, mask);
|
TRACE("notifying %04x: cid=%d, mask=%02x\n", ptr->wnd, cid, mask);
|
||||||
Callout.PostMessageA(ptr->wnd, WM_COMMNOTIFY, cid, mask);
|
if (Callout.PostMessageA) Callout.PostMessageA(ptr->wnd, WM_COMMNOTIFY, cid, mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ CALLOUT_TABLE Callout = {
|
||||||
/* GetMessageA */ NULL,
|
/* GetMessageA */ NULL,
|
||||||
/* SendMessageA */ NULL,
|
/* SendMessageA */ NULL,
|
||||||
/* PostMessageA */ NULL,
|
/* PostMessageA */ NULL,
|
||||||
/* PostAppMessage16 */ NULL,
|
|
||||||
/* TranslateMessage */ NULL,
|
/* TranslateMessage */ NULL,
|
||||||
/* DispatchMessageA */ NULL,
|
/* DispatchMessageA */ NULL,
|
||||||
/* RedrawWindow */ NULL,
|
/* RedrawWindow */ NULL,
|
||||||
|
@ -168,7 +167,7 @@ void THUNK_InitCallout(void)
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
NE_MODULE *pModule;
|
NE_MODULE *pModule;
|
||||||
|
|
||||||
hModule = LoadLibraryA( "user32.dll" );
|
hModule = GetModuleHandleA( "user32.dll" );
|
||||||
if ( hModule )
|
if ( hModule )
|
||||||
{
|
{
|
||||||
#define GETADDR( name ) \
|
#define GETADDR( name ) \
|
||||||
|
@ -188,21 +187,21 @@ void THUNK_InitCallout(void)
|
||||||
GETADDR( MessageBoxW );
|
GETADDR( MessageBoxW );
|
||||||
#undef GETADDR
|
#undef GETADDR
|
||||||
}
|
}
|
||||||
|
else WARN("no 32-bit USER\n");
|
||||||
|
|
||||||
pModule = NE_GetPtr( LoadLibrary16( "USER.EXE" ) );
|
pModule = NE_GetPtr( GetModuleHandle16( "USER.EXE" ) );
|
||||||
if ( pModule )
|
if ( pModule )
|
||||||
{
|
{
|
||||||
#define GETADDR( var, name, thk ) \
|
#define GETADDR( var, name, thk ) \
|
||||||
*(FARPROC *)&Callout.var = THUNK_GetCalloutThunk( pModule, name, \
|
*(FARPROC *)&Callout.var = THUNK_GetCalloutThunk( pModule, name, \
|
||||||
(RELAY)THUNK_CallTo16_##thk )
|
(RELAY)THUNK_CallTo16_##thk )
|
||||||
|
|
||||||
GETADDR( PostAppMessage16, "PostAppMessage", word_wwwl );
|
|
||||||
GETADDR( FinalUserInit16, "FinalUserInit", word_ );
|
GETADDR( FinalUserInit16, "FinalUserInit", word_ );
|
||||||
GETADDR( InitThreadInput16, "InitThreadInput", word_ww );
|
GETADDR( InitThreadInput16, "InitThreadInput", word_ww );
|
||||||
GETADDR( UserYield16, "UserYield", word_ );
|
GETADDR( UserYield16, "UserYield", word_ );
|
||||||
GETADDR( DestroyIcon32, "DestroyIcon32", word_ww );
|
GETADDR( DestroyIcon32, "DestroyIcon32", word_ww );
|
||||||
GETADDR( UserSignalProc, "SignalProc32", word_lllw );
|
GETADDR( UserSignalProc, "SignalProc32", word_lllw );
|
||||||
|
|
||||||
#undef GETADDR
|
#undef GETADDR
|
||||||
}
|
}
|
||||||
|
else WARN("no 16-bit USER\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,6 @@ typedef struct
|
||||||
BOOL WINAPI (*GetMessageA)( MSG*, HWND, UINT, UINT );
|
BOOL WINAPI (*GetMessageA)( MSG*, HWND, UINT, UINT );
|
||||||
LRESULT WINAPI (*SendMessageA)( HWND, UINT, WPARAM, LPARAM );
|
LRESULT WINAPI (*SendMessageA)( HWND, UINT, WPARAM, LPARAM );
|
||||||
BOOL WINAPI (*PostMessageA)( HWND, UINT, WPARAM, LPARAM );
|
BOOL WINAPI (*PostMessageA)( HWND, UINT, WPARAM, LPARAM );
|
||||||
BOOL16 WINAPI (*PostAppMessage16)( HTASK16, UINT16, WPARAM16, LPARAM );
|
|
||||||
BOOL WINAPI (*TranslateMessage)( const MSG *msg );
|
BOOL WINAPI (*TranslateMessage)( const MSG *msg );
|
||||||
LONG WINAPI (*DispatchMessageA)( const MSG* msg );
|
LONG WINAPI (*DispatchMessageA)( const MSG* msg );
|
||||||
BOOL WINAPI (*RedrawWindow)( HWND, const RECT *, HRGN, UINT );
|
BOOL WINAPI (*RedrawWindow)( HWND, const RECT *, HRGN, UINT );
|
||||||
|
|
|
@ -147,7 +147,7 @@ extern THHOOK *pThhook;
|
||||||
|
|
||||||
extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow,
|
extern BOOL TASK_Create( struct _NE_MODULE *pModule, UINT16 cmdShow,
|
||||||
struct _TEB *teb, LPCSTR cmdline, BYTE len );
|
struct _TEB *teb, LPCSTR cmdline, BYTE len );
|
||||||
extern void TASK_KillTask( HTASK16 hTask );
|
extern void TASK_ExitTask(void);
|
||||||
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
|
extern HTASK16 TASK_GetNextTask( HTASK16 hTask );
|
||||||
extern void TASK_Reschedule(void);
|
extern void TASK_Reschedule(void);
|
||||||
extern void TASK_InstallTHHook( THHOOK *pNewThook );
|
extern void TASK_InstallTHHook( THHOOK *pNewThook );
|
||||||
|
|
|
@ -420,6 +420,8 @@ void DOSVM_Wait( int read_pipe, HANDLE hObject )
|
||||||
objc=hObject?2:1;
|
objc=hObject?2:1;
|
||||||
do {
|
do {
|
||||||
/* check for messages (waste time before the response check below) */
|
/* check for messages (waste time before the response check below) */
|
||||||
|
if (Callout.PeekMessageA)
|
||||||
|
{
|
||||||
while (Callout.PeekMessageA(&msg,0,0,0,PM_REMOVE|PM_NOYIELD)) {
|
while (Callout.PeekMessageA(&msg,0,0,0,PM_REMOVE|PM_NOYIELD)) {
|
||||||
/* got a message */
|
/* got a message */
|
||||||
DOSVM_ProcessMessage(&msg);
|
DOSVM_ProcessMessage(&msg);
|
||||||
|
@ -427,6 +429,7 @@ void DOSVM_Wait( int read_pipe, HANDLE hObject )
|
||||||
Callout.DispatchMessageA(&msg);
|
Callout.DispatchMessageA(&msg);
|
||||||
got_msg = TRUE;
|
got_msg = TRUE;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!got_msg) {
|
if (!got_msg) {
|
||||||
/* check for console input */
|
/* check for console input */
|
||||||
INPUT_RECORD msg;
|
INPUT_RECORD msg;
|
||||||
|
@ -448,7 +451,11 @@ void DOSVM_Wait( int read_pipe, HANDLE hObject )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* nothing yet, block while waiting for something to do */
|
/* nothing yet, block while waiting for something to do */
|
||||||
waitret=Callout.MsgWaitForMultipleObjects(objc,objs,FALSE,INFINITE,QS_ALLINPUT);
|
if (Callout.MsgWaitForMultipleObjects)
|
||||||
|
waitret = Callout.MsgWaitForMultipleObjects(objc,objs,FALSE,INFINITE,QS_ALLINPUT);
|
||||||
|
else
|
||||||
|
waitret = WaitForMultipleObjects(objc,objs,FALSE,INFINITE);
|
||||||
|
|
||||||
if (waitret==(DWORD)-1) {
|
if (waitret==(DWORD)-1) {
|
||||||
ERR_(module)("dosvm wait error=%ld\n",GetLastError());
|
ERR_(module)("dosvm wait error=%ld\n",GetLastError());
|
||||||
}
|
}
|
||||||
|
|
|
@ -827,7 +827,8 @@ HINSTANCE WINAPI WinExec( LPCSTR lpCmdLine, UINT nCmdShow )
|
||||||
0, NULL, NULL, &startup, &info ))
|
0, NULL, NULL, &startup, &info ))
|
||||||
{
|
{
|
||||||
/* Give 30 seconds to the app to come up */
|
/* Give 30 seconds to the app to come up */
|
||||||
if (Callout.WaitForInputIdle ( info.hProcess, 30000 ) == 0xFFFFFFFF)
|
if (Callout.WaitForInputIdle &&
|
||||||
|
Callout.WaitForInputIdle( info.hProcess, 30000 ) == 0xFFFFFFFF)
|
||||||
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
|
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
|
||||||
hInstance = 33;
|
hInstance = 33;
|
||||||
/* Close off the handles */
|
/* Close off the handles */
|
||||||
|
@ -884,7 +885,8 @@ HINSTANCE WINAPI LoadModule( LPCSTR name, LPVOID paramBlock )
|
||||||
params->lpEnvAddress, NULL, &startup, &info ))
|
params->lpEnvAddress, NULL, &startup, &info ))
|
||||||
{
|
{
|
||||||
/* Give 30 seconds to the app to come up */
|
/* Give 30 seconds to the app to come up */
|
||||||
if ( Callout.WaitForInputIdle ( info.hProcess, 30000 ) == 0xFFFFFFFF )
|
if (Callout.WaitForInputIdle &&
|
||||||
|
Callout.WaitForInputIdle( info.hProcess, 30000 ) == 0xFFFFFFFF )
|
||||||
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
|
WARN("WaitForInputIdle failed: Error %ld\n", GetLastError() );
|
||||||
hInstance = 33;
|
hInstance = 33;
|
||||||
/* Close off the handles */
|
/* Close off the handles */
|
||||||
|
|
|
@ -379,78 +379,62 @@ static void TASK_DeleteTask( HTASK16 hTask )
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* TASK_KillTask
|
* TASK_KillTask
|
||||||
*/
|
*/
|
||||||
void TASK_KillTask( HTASK16 hTask )
|
void TASK_ExitTask(void)
|
||||||
{
|
{
|
||||||
TDB *pTask;
|
TDB *pTask;
|
||||||
|
DWORD lockCount;
|
||||||
|
|
||||||
/* Enter the Win16Lock to protect global data structures */
|
/* Enter the Win16Lock to protect global data structures */
|
||||||
SYSLEVEL_EnterWin16Lock();
|
SYSLEVEL_EnterWin16Lock();
|
||||||
|
|
||||||
if ( !hTask ) hTask = GetCurrentTask();
|
pTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||||
pTask = (TDB *)GlobalLock16( hTask );
|
|
||||||
if ( !pTask )
|
if ( !pTask )
|
||||||
{
|
{
|
||||||
SYSLEVEL_LeaveWin16Lock();
|
SYSLEVEL_LeaveWin16Lock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("Killing task %04x\n", hTask );
|
TRACE("Killing task %04x\n", pTask->hSelf );
|
||||||
|
|
||||||
/* Perform USER cleanup */
|
/* Perform USER cleanup */
|
||||||
|
|
||||||
TASK_CallTaskSignalProc( USIG16_TERMINATION, hTask );
|
TASK_CallTaskSignalProc( USIG16_TERMINATION, pTask->hSelf );
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0 );
|
PROCESS_CallUserSignalProc( USIG_PROCESS_EXIT, 0 );
|
||||||
PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
|
PROCESS_CallUserSignalProc( USIG_THREAD_EXIT, 0 );
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0 );
|
PROCESS_CallUserSignalProc( USIG_PROCESS_DESTROY, 0 );
|
||||||
|
|
||||||
if (nTaskCount <= 1)
|
/* Remove the task from the list to be sure we never switch back to it */
|
||||||
|
TASK_UnlinkTask( pTask->hSelf );
|
||||||
|
|
||||||
|
if (!nTaskCount || (nTaskCount == 1 && hFirstTask == initial_task))
|
||||||
{
|
{
|
||||||
TRACE("this is the last task, exiting\n" );
|
TRACE("this is the last task, exiting\n" );
|
||||||
|
ERR("done\n");
|
||||||
ExitKernel16();
|
ExitKernel16();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Hack! Send a message to the initial task so that
|
|
||||||
* the GetMessage wakes up and the initial task can check whether
|
|
||||||
* it is the only remaining one and terminate itself ...
|
|
||||||
* The initial task should probably install hooks or something
|
|
||||||
* to get informed about task termination :-/
|
|
||||||
*/
|
|
||||||
Callout.PostAppMessage16( initial_task, WM_NULL, 0, 0 );
|
|
||||||
|
|
||||||
/* Remove the task from the list to be sure we never switch back to it */
|
|
||||||
TASK_UnlinkTask( hTask );
|
|
||||||
if( nTaskCount )
|
if( nTaskCount )
|
||||||
{
|
{
|
||||||
TDB* p = (TDB *)GlobalLock16( hFirstTask );
|
TDB* p = (TDB *)GlobalLock16( hFirstTask );
|
||||||
while( p )
|
while( p )
|
||||||
{
|
{
|
||||||
if( p->hYieldTo == hTask ) p->hYieldTo = 0;
|
if( p->hYieldTo == pTask->hSelf ) p->hYieldTo = 0;
|
||||||
p = (TDB *)GlobalLock16( p->hNext );
|
p = (TDB *)GlobalLock16( p->hNext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pTask->nEvents = 0;
|
pTask->nEvents = 0;
|
||||||
|
|
||||||
if ( hLockedTask == hTask )
|
if ( hLockedTask == pTask->hSelf )
|
||||||
hLockedTask = 0;
|
hLockedTask = 0;
|
||||||
|
|
||||||
TASK_DeleteTask( hTask );
|
TASK_DeleteTask( pTask->hSelf );
|
||||||
|
|
||||||
/* When deleting the current task ... */
|
|
||||||
if ( hTask == hCurrentTask )
|
|
||||||
{
|
|
||||||
DWORD lockCount;
|
|
||||||
|
|
||||||
/* ... schedule another one ... */
|
/* ... schedule another one ... */
|
||||||
TASK_Reschedule();
|
TASK_Reschedule();
|
||||||
|
|
||||||
/* ... and completely release the Win16Lock, just in case. */
|
/* ... and completely release the Win16Lock, just in case. */
|
||||||
ReleaseThunkLock( &lockCount );
|
ReleaseThunkLock( &lockCount );
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SYSLEVEL_LeaveWin16Lock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -838,7 +822,7 @@ void WINAPI Yield16(void)
|
||||||
TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
TDB *pCurTask = (TDB *)GlobalLock16( GetCurrentTask() );
|
||||||
|
|
||||||
if (pCurTask) pCurTask->hYieldTo = 0;
|
if (pCurTask) pCurTask->hYieldTo = 0;
|
||||||
if (pCurTask && pCurTask->hQueue) Callout.UserYield16();
|
if (pCurTask && pCurTask->hQueue && Callout.UserYield16) Callout.UserYield16();
|
||||||
else OldYield16();
|
else OldYield16();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1148,7 +1132,7 @@ HANDLE WINAPI GetFastQueue16( void )
|
||||||
TEB *teb = NtCurrentTeb();
|
TEB *teb = NtCurrentTeb();
|
||||||
if (!teb) return 0;
|
if (!teb) return 0;
|
||||||
|
|
||||||
if (!teb->queue)
|
if (!teb->queue && Callout.InitThreadInput16)
|
||||||
Callout.InitThreadInput16( 0, THREAD_IsWin16(teb)? 4 : 5 );
|
Callout.InitThreadInput16( 0, THREAD_IsWin16(teb)? 4 : 5 );
|
||||||
|
|
||||||
if (!teb->queue)
|
if (!teb->queue)
|
||||||
|
|
|
@ -23,6 +23,13 @@ void wine_initial_task(void)
|
||||||
HINSTANCE16 instance;
|
HINSTANCE16 instance;
|
||||||
STARTUPINFOA info;
|
STARTUPINFOA info;
|
||||||
|
|
||||||
|
if (!LoadLibraryA( "user32.dll" ))
|
||||||
|
{
|
||||||
|
MESSAGE( "Cannot load user32.dll\n" );
|
||||||
|
ExitProcess( GetLastError() );
|
||||||
|
}
|
||||||
|
THUNK_InitCallout();
|
||||||
|
|
||||||
GetStartupInfoA( &info );
|
GetStartupInfoA( &info );
|
||||||
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
|
if (!(info.dwFlags & STARTF_USESHOWWINDOW)) info.wShowWindow = SW_SHOWNORMAL;
|
||||||
|
|
||||||
|
|
|
@ -787,6 +787,8 @@ INT16 WINAPI UpdateColors16( HDC16 hDC )
|
||||||
if (!(dc = DC_GetDCPtr( hDC ))) return 0;
|
if (!(dc = DC_GetDCPtr( hDC ))) return 0;
|
||||||
size = dc->devCaps->sizePalette;
|
size = dc->devCaps->sizePalette;
|
||||||
GDI_ReleaseObj( hDC );
|
GDI_ReleaseObj( hDC );
|
||||||
|
if (Callout.WindowFromDC)
|
||||||
|
{
|
||||||
hWnd = Callout.WindowFromDC( hDC );
|
hWnd = Callout.WindowFromDC( hDC );
|
||||||
|
|
||||||
/* Docs say that we have to remap current drawable pixel by pixel
|
/* Docs say that we have to remap current drawable pixel by pixel
|
||||||
|
@ -794,7 +796,7 @@ INT16 WINAPI UpdateColors16( HDC16 hDC )
|
||||||
*/
|
*/
|
||||||
if (hWnd && size)
|
if (hWnd && size)
|
||||||
Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
|
Callout.RedrawWindow( hWnd, NULL, 0, RDW_INVALIDATE );
|
||||||
|
}
|
||||||
return 0x666;
|
return 0x666;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -236,39 +236,6 @@ static BOOL process_init( char *argv[] )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* load_system_dlls
|
|
||||||
*
|
|
||||||
* Load system DLLs into the initial process (and initialize them)
|
|
||||||
*/
|
|
||||||
static int load_system_dlls(void)
|
|
||||||
{
|
|
||||||
/* Load KERNEL */
|
|
||||||
if (!LoadLibraryA( "KERNEL32" )) return 0;
|
|
||||||
|
|
||||||
/* Get pointers to USER routines called by KERNEL */
|
|
||||||
THUNK_InitCallout();
|
|
||||||
|
|
||||||
/* Call FinalUserInit routine */
|
|
||||||
Callout.FinalUserInit16();
|
|
||||||
|
|
||||||
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
|
|
||||||
* context of the parent process. Actually, the USER signal proc
|
|
||||||
* doesn't really care about that, but it *does* require that the
|
|
||||||
* startup parameters are correctly set up, so that GetProcessDword
|
|
||||||
* works. Furthermore, before calling the USER signal proc the
|
|
||||||
* 16-bit stack must be set up, which it is only after TASK_Create
|
|
||||||
* in the case of a 16-bit process. Thus, we send the signal here.
|
|
||||||
*/
|
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
|
|
||||||
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
|
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
|
|
||||||
PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* build_command_line
|
* build_command_line
|
||||||
*
|
*
|
||||||
|
@ -361,14 +328,29 @@ static void start_process(void)
|
||||||
goto error;
|
goto error;
|
||||||
wm->refCount++;
|
wm->refCount++;
|
||||||
|
|
||||||
/* Load the system dlls */
|
|
||||||
if (!load_system_dlls()) goto error;
|
|
||||||
|
|
||||||
EnterCriticalSection( ¤t_process.crit_section );
|
EnterCriticalSection( ¤t_process.crit_section );
|
||||||
PE_InitTls();
|
PE_InitTls();
|
||||||
MODULE_DllProcessAttach( current_process.exe_modref, (LPVOID)1 );
|
MODULE_DllProcessAttach( current_process.exe_modref, (LPVOID)1 );
|
||||||
LeaveCriticalSection( ¤t_process.crit_section );
|
LeaveCriticalSection( ¤t_process.crit_section );
|
||||||
|
|
||||||
|
/* Get pointers to USER routines called by KERNEL */
|
||||||
|
THUNK_InitCallout();
|
||||||
|
|
||||||
|
/* Call FinalUserInit routine */
|
||||||
|
if (Callout.FinalUserInit16) Callout.FinalUserInit16();
|
||||||
|
|
||||||
|
/* Note: The USIG_PROCESS_CREATE signal is supposed to be sent in the
|
||||||
|
* context of the parent process. Actually, the USER signal proc
|
||||||
|
* doesn't really care about that, but it *does* require that the
|
||||||
|
* startup parameters are correctly set up, so that GetProcessDword
|
||||||
|
* works. Furthermore, before calling the USER signal proc the
|
||||||
|
* 16-bit stack must be set up, which it is only after TASK_Create
|
||||||
|
* in the case of a 16-bit process. Thus, we send the signal here.
|
||||||
|
*/
|
||||||
|
PROCESS_CallUserSignalProc( USIG_PROCESS_CREATE, 0 );
|
||||||
|
PROCESS_CallUserSignalProc( USIG_THREAD_INIT, 0 );
|
||||||
|
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
|
||||||
|
PROCESS_CallUserSignalProc( USIG_PROCESS_LOADED, 0 );
|
||||||
/* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
|
/* Call UserSignalProc ( USIG_PROCESS_RUNNING ... ) only for non-GUI win32 apps */
|
||||||
if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
|
if (console_app) PROCESS_CallUserSignalProc( USIG_PROCESS_RUNNING, 0 );
|
||||||
|
|
||||||
|
|
|
@ -374,7 +374,7 @@ void WINAPI ExitThread( DWORD code ) /* [in] Exit code for this thread */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MODULE_DllThreadDetach( NULL );
|
MODULE_DllThreadDetach( NULL );
|
||||||
if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_KillTask( 0 );
|
if (!(NtCurrentTeb()->tibflags & TEBF_WIN32)) TASK_ExitTask();
|
||||||
SYSDEPS_ExitThread( code );
|
SYSDEPS_ExitThread( code );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,10 @@ void WINAPI FatalAppExit16( UINT16 action, LPCSTR str )
|
||||||
void WINAPI FatalAppExitA( UINT action, LPCSTR str )
|
void WINAPI FatalAppExitA( UINT action, LPCSTR str )
|
||||||
{
|
{
|
||||||
WARN("AppExit\n");
|
WARN("AppExit\n");
|
||||||
|
if (Callout.MessageBoxA)
|
||||||
Callout.MessageBoxA( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
|
Callout.MessageBoxA( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
|
||||||
|
else
|
||||||
|
ERR( "%s\n", debugstr_a(str) );
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +296,9 @@ void WINAPI FatalAppExitA( UINT action, LPCSTR str )
|
||||||
void WINAPI FatalAppExitW( UINT action, LPCWSTR str )
|
void WINAPI FatalAppExitW( UINT action, LPCWSTR str )
|
||||||
{
|
{
|
||||||
WARN("AppExit\n");
|
WARN("AppExit\n");
|
||||||
|
if (Callout.MessageBoxW)
|
||||||
Callout.MessageBoxW( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
|
Callout.MessageBoxW( 0, str, NULL, MB_SYSTEMMODAL | MB_OK );
|
||||||
|
else
|
||||||
|
ERR( "%s\n", debugstr_w(str) );
|
||||||
ExitProcess(0);
|
ExitProcess(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue