/* * InitDebugging: * * - check for WDEBUG.386 * - register an interrupt handler (for handling 16-bit faults) * - register a notify handler (for receiving all system notifications) * - if we have WDEBUG.386, then we load WINT32.DLL, get all its entry * points, and then tell it we want to handle 32-bit faults * - we then get a data segment alias for our code segment, so that we * can write stuff into our code segment (see FAULT.C) * */ char *InitDebugging( void ) { DebuggerState=ACTIVE; StartWDebug386(); faultInstance = MakeProcInstance( (FARPROC)IntHandler, Instance ); if( !InterruptRegister( NULL, faultInstance ) ) { return( TRP_WIN_Failed_to_get_interrupt_hook ); } notifyInstance = MakeProcInstance( (FARPROC)NotifyHandler, Instance ); if( !NotifyRegister( NULL, (LPFNNOTIFYCALLBACK)notifyInstance, NF_NORMAL | NF_RIP ) ) { return( TRP_WIN_Failed_to_get_notify_hook ); } Out(( OUT_INIT,"ds=%04x, faultInstance=%Fp, notifyInstance=%Fp,Instance=%04x", FP_SEG( &faultInstance ), faultInstance, notifyInstance, Instance )); if( WDebug386 ) { wint32 = LoadLibrary( "wint32.dll" ); if( (UINT)wint32 < 32 ) { WDebug386 = FALSE; } else { DoneWithInterrupt = (LPVOID) GetProcAddress( wint32, "DoneWithInterrupt" ); GetDebugInterruptData = (LPVOID) GetProcAddress( wint32, "GetDebugInterruptData" ); ResetDebugInterrupts32 = (LPVOID) GetProcAddress( wint32, "ResetDebugInterrupts32" ); SetDebugInterrupts32 = (LPVOID) GetProcAddress( wint32, "SetDebugInterrupts32" ); DebuggerIsExecuting = (LPVOID) GetProcAddress( wint32, "DebuggerIsExecuting" ); if( !SetDebugInterrupts32() ) { WDebug386 = FALSE; FreeLibrary( wint32 ); } else { DebuggerIsExecuting( 1 ); Out((OUT_INIT,"Hooked Interrupts")); } } } // SubClassProcInstance = MakeProcInstance( (FARPROC)SubClassProc, Instance ); InitDebugHook(); CSAlias = AllocCSToDSAlias( CS() ); return( "" ); } /* InitDebugging */
/* * WinMain - main windows entry point */ int PASCAL WinMain( HINSTANCE inst, HINSTANCE previnst, LPSTR cmd, int show) { HINSTANCE newinst; HANDLE h; MSG msg; parm_data parm; command_data cmddat; char FAR_PTR *cmdline; char filename[_MAX_PATH]; /* * are we the first? if so, winexec another one of ourselves * and then start sampling */ if( !previnst ) { SharedMemory = NULL; StartWDebug386(); if( !WDebug386 ) { WinMessage( "Could not find WDEBUG.386" ); return( FALSE ); } if( !MsgInit( inst ) ) fatal(); cmddat.nCmdShow = SW_NORMAL; if( cmd == NULL || cmd[0] == 0 ) { if( !GetFileName( inst, show, filename ) ) { CloseShop(); return( FALSE ); } cmdline = filename; } else { cmddat.nCmdShow = SW_MINIMIZE; cmdline = cmd; } h = GlobalAlloc( GMEM_SHARE | GMEM_FIXED | GMEM_ZEROINIT, sizeof( shared_data ) ); if( h == NULL ) { CloseShop(); return( FALSE ); } SharedMemory = MK_FP( h,0 ); WaitForFirst = TRUE; /* tell our counterpart to wait for us before starting the timer */ cmddat.always2= 2; parm.wEnvSeg = 0; parm.lpCmdLine = (char far *) ""; parm.lpCmdShow = (void far *) &cmddat; parm.dwReserved = 0; newinst = LoadModule( "wsamplew.exe", (LPVOID) &parm ); if( (UINT)newinst < 32 ) { WinMessage( MsgArray[MSG_SAMPLE_12-ERR_FIRST_MESSAGE] ); CloseShop(); return( FALSE ); } /* * wait for our counterpart to initialize - if he fails, * then we must die too */ do { GetIData( newinst, (void near *)&IsSecondOK, sizeof( IsSecondOK ) ); MessageLoop(); } while( !IsSecondOK ); if( IsSecondOK == NOT_OK ) { WinMessage( MsgArray[MSG_SAMPLE_12-ERR_FIRST_MESSAGE] ); CloseShop(); return( FALSE ); } /* * get data created by our counterpart */ GetIData( newinst, &OutputWindow, sizeof( OutputWindow ) ); GetIData( newinst, &MainWindowHandle, sizeof( MainWindowHandle ) ); GetIData( newinst, &SampSave, sizeof( SampSave) ); /* * start the sampler - our other half will be re-started * once we have loaded the task to be sampled. */ sample_main( cmdline ); CloseShop(); SendMessage( MainWindowHandle, WM_CLOSE, 0, 0 ); return( FALSE ); } else { /* * we are the second instance (the guy who waits for * timer events and then tries to write the sample file) * init our windows stuff, then wait for the first instance * to start the samplee, set a timer, and go */ PrevInstance = previnst; if( !MsgInit( inst ) ) fatal(); if( !WindowsInit( inst, show ) ) { IsSecondOK = NOT_OK; return( FALSE ); } IsSecondOK = A_OK; do { GetIData( previnst, (void near *)&WaitForFirst, sizeof( WaitForFirst ) ); MessageLoop(); } while( WaitForFirst ); GetIData( previnst, (void near *) &Samples, sizeof( Samples ) ); GetIData( previnst, &SharedMemory, sizeof( SharedMemory ) ); KillTimer( MainWindowHandle, TIMER_ID ); SetTimer( MainWindowHandle, TIMER_ID, 4500, 0L); /* 4.5 seconds */ } /* * main message loop for the second instance */ while( GetMessage( &msg, NULL, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } return( FALSE ); } /* WinMain */