Annotation of mstools/samples/deb/debdebug.c, revision 1.1.1.3

1.1.1.3 ! root        1: 
        !             2: /******************************************************************************\
        !             3: *       This is a part of the Microsoft Source Code Samples. 
        !             4: *       Copyright (C) 1993 Microsoft Corporation.
        !             5: *       All rights reserved. 
        !             6: *       This source code is only intended as a supplement to 
        !             7: *       Microsoft Development Tools and/or WinHelp documentation.
        !             8: *       See these sources for detailed information regarding the 
        !             9: *       Microsoft samples programs.
        !            10: \******************************************************************************/
        !            11: 
1.1.1.2   root       12: // ************************************************************************
                     13: // MODULE    : DEBDebug.C
1.1       root       14: // PURPOSE   : Debug support functions for the Debug Event Browser
                     15: // FUNCTIONS :
1.1.1.3 ! root       16: //   DebugEventThread()         - debug event processing thread
1.1       root       17: // COMMENTS  :
1.1.1.2   root       18: //
1.1       root       19: // ************************************************************************
1.1.1.3 ! root       20: #define   STRICT               // enable strict typing
        !            21: #include <Windows.H>           // required for all Windows applications
        !            22: #include <StdDef.H>            // offsetof()
        !            23: 
        !            24: #include "LinkList.H"          // include the linked list functions
        !            25: #include "DEBMisc.H"           // include the misc. support functions
        !            26: #include "DEBDebug.H"          // include the DEB debugging functions
        !            27: 
        !            28: // internal global data
        !            29: // ------------------------------------------------------------------------
        !            30: HANDLE hHeap;                  // local heap
        !            31: PLIST  pProcessList;           // pointer to the process list
        !            32: BOOL   fFinished = FALSE;      // set to TRUE if the DebugEventThread
        !            33:                                //  is no longer needed (such as the
        !            34:                                //  debuggee failed to load or the number
        !            35:                                //  of debuggee threads goes to zero
        !            36:                                //  indicating debug session termination
        !            37: 
        !            38: static LPCTSTR lpszSourceFileName = TEXT(__FILE__);
        !            39: 
        !            40: // internal function prototypes
        !            41: // ------------------------------------------------------------------------
        !            42: 
        !            43: //-- debug event handling functions
        !            44: BOOL HandleExceptionEvent( LPDEBUG_EVENT );
        !            45: BOOL HandleBreakPointException( LPDEBUG_EVENT );
        !            46: BOOL HandleCreateThreadEvent( LPDEBUG_EVENT );
        !            47: BOOL HandleCreateProcessEvent( LPDEBUG_EVENT );
        !            48: BOOL HandleExitThreadEvent( LPDEBUG_EVENT );
        !            49: BOOL HandleExitProcessEvent( LPDEBUG_EVENT );
        !            50: BOOL HandleLoadDllEvent( LPDEBUG_EVENT );
        !            51: BOOL HandleUnloadDllEvent( LPDEBUG_EVENT );
        !            52: BOOL HandleOutputDebugStringEvent( LPDEBUG_EVENT );
        !            53: BOOL HandleRipEvent( LPDEBUG_EVENT );
        !            54: BOOL HandleUnknownEvent( LPDEBUG_EVENT );
        !            55: 
        !            56: //-- misc debug event helper functions
        !            57: BOOL  DebugNewProcess( LPTSTR, LPTSTR );
        !            58: BOOL  GetDllFileName( LPDEBUG_EVENT, LPTSTR, DWORD );
        !            59: BOOL  GetDllFileNameFromList( LPDEBUG_EVENT, LPTSTR, DWORD );
        !            60: BOOL  GetOutputDebugString( LPDEBUG_EVENT, LPTSTR, DWORD );
        !            61: DWORD GetModuleFileNameFromHeader( HANDLE, HANDLE, DWORD, LPTSTR, DWORD );
        !            62: #if( _MIPS_ == 1 || _ALPHA_ == 1 )
        !            63:  BOOL  SkipBreakPoint( HANDLE );
1.1.1.2   root       64: #endif
1.1       root       65: 
1.1.1.3 ! root       66: //-- linked list wrapper functions
        !            67: 
        !            68: //-- process list and node specific linked list wrapper functions
        !            69: int  ProcessOrderFunction( PNODE, PNODE );
        !            70: BOOL CreateProcessList( PLIST* );
        !            71: BOOL DestroyProcessList( PLIST );
        !            72: BOOL AllocProcessNode( PNODE*, PDEB_PROCESS_NODE_INFO* );
        !            73: BOOL InitProcessNodeInfo( PDEB_PROCESS_NODE_INFO*, LPDEBUG_EVENT );
        !            74: BOOL InsertProcessNode( PLIST, PNODE );
        !            75: BOOL SetCurrentProcessNode( PLIST, PNODE );
        !            76: BOOL DeleteProcessNode( PLIST, PNODE );
        !            77: BOOL FreeProcessNodeInfo( PNODE );
        !            78: BOOL DestroyProcessNode( PNODE );
        !            79: BOOL DeleteCurrentProcessNode( PLIST );
        !            80: 
        !            81: //-- thread list and node specific linked list wrapper functions
        !            82: int  ThreadOrderFunction( PNODE, PNODE );
        !            83: BOOL CreateThreadList( PLIST* );
        !            84: BOOL DestroyThreadList( PLIST );
        !            85: BOOL AllocThreadNode( PNODE*, PDEB_THREAD_NODE_INFO* );
        !            86: BOOL InitThreadNodeInfo( PDEB_THREAD_NODE_INFO*, LPDEBUG_EVENT );
        !            87: BOOL InsertThreadNode( PLIST, PNODE );
        !            88: BOOL SetCurrentThreadNode( PLIST, PNODE );
        !            89: BOOL DeleteThreadNode( PLIST, PNODE );
        !            90: BOOL FreeThreadNodeInfo( PNODE );
        !            91: BOOL DestroyThreadNode( PNODE );
        !            92: BOOL DeleteCurrentThreadNode( PLIST );
        !            93: 
        !            94: //-- dll list and node specific linked list wrapper functions
        !            95: int  DllOrderFunction( PNODE, PNODE );
        !            96: BOOL CreateDllList( PLIST* );
        !            97: BOOL DestroyDllList( PLIST );
        !            98: BOOL AllocDllNode( PNODE*, PDEB_DLL_NODE_INFO* );
        !            99: BOOL InitDllNodeInfo( PDEB_DLL_NODE_INFO*, LPDEBUG_EVENT );
        !           100: BOOL InsertDllNode( PLIST, PNODE );
        !           101: BOOL SetCurrentDllNode( PLIST, PNODE );
        !           102: BOOL DeleteDllNode( PLIST, PNODE );
        !           103: BOOL FreeDllNodeInfo( PNODE );
        !           104: BOOL DestroyDllNode( PNODE );
        !           105: BOOL DeleteCurrentDllNode( PLIST );
        !           106: 
        !           107: 
1.1       root      108: // ************************************************************************
1.1.1.3 ! root      109: // FUNCTION : DebugEventThread( PDEB_STARTUP_INFO )
1.1       root      110: // PURPOSE  : Main debug event processing loop
1.1.1.2   root      111: // COMMENTS :
1.1.1.3 ! root      112: //   A new debug event thread is created for each Debuggee process.
        !           113: //   Return TRUE (non 0) if success, else FALSE (0)
1.1       root      114: // ************************************************************************
1.1.1.2   root      115: DWORD WINAPI
1.1.1.3 ! root      116: DebugEventThread( PDEB_STARTUP_INFO pDebStartupInfo )
1.1       root      117: {
1.1.1.3 ! root      118:   #define BUFFER_SIZE 256
1.1.1.2   root      119: 
1.1       root      120:   static BOOL  fFirstTime = TRUE;
1.1.1.3 ! root      121:   static TCHAR szDebuggeeTitle[128];
1.1       root      122: 
                    123:   DEBUG_EVENT  DebugEvent;
1.1.1.2   root      124: 
1.1.1.3 ! root      125:   LPTSTR lpszDebugEventBuffer;
        !           126:   LPTSTR lpszTempBuffer;
1.1       root      127: 
1.1.1.3 ! root      128:   //-- set the minimum error level for debugging events
        !           129:   SetDebugErrorLevel( Profile.DebugErrorLevel );
1.1       root      130: 
1.1.1.3 ! root      131:   if( fFirstTime ) {
        !           132:     if( !LoadString( Global.hInstance, IDS_OFN_DEBUGGEE_TITLE, szDebuggeeTitle,
        !           133:            sizeof(szDebuggeeTitle)/sizeof(TCHAR) ) )
        !           134:       ErrorMessageBox( TEXT("LoadString()"),
        !           135:         Global.szApiFailedMsg, lpszSourceFileName, __LINE__ );
        !           136:   }
1.1       root      137: 
1.1.1.3 ! root      138:   //-- determine if 'attach to' or 'open new' debuggee
        !           139:   if( pDebStartupInfo->fActive ) {
        !           140:     if( !DebugActiveProcess( pDebStartupInfo->dwProcessId ) )
        !           141:       ErrorMessageBox( TEXT("DebugActiveProcess()"),
        !           142:         Global.szApiFailedMsg, lpszSourceFileName, __LINE__ );
        !           143:   }
        !           144:   else {
        !           145:     if( !DebugNewProcess( pDebStartupInfo->lpstrPathName, szDebuggeeTitle ) )
        !           146:     ExitThread( FALSE );
        !           147:   }
1.1       root      148: 
1.1.1.3 ! root      149:   //-- increment active process count
        !           150:   Global.dwActiveDebuggees++;
        !           151: 
        !           152:   //-- create a local heap
        !           153:   {
        !           154:     SYSTEM_INFO SysInfo;
        !           155: 
        !           156:     GetSystemInfo( &SysInfo );  // get the system memory page size
        !           157:     hHeap = HeapCreate( (DWORD) NULL, SysInfo.dwPageSize, 1000*SysInfo.dwPageSize );
1.1       root      158:   }
                    159: 
1.1.1.3 ! root      160:   //-- create and initialize the process list
        !           161:   CreateProcessList( &pProcessList );
        !           162: 
        !           163:   //-- alloc temporary (life of thread) string buffers
        !           164:   lpszDebugEventBuffer = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL, BUFFER_SIZE );
        !           165:   lpszTempBuffer = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL, BUFFER_SIZE );
        !           166: 
        !           167:   // ----------------------------------------------------------------------
        !           168:   // begin debug event processing loop
        !           169:   // ----------------------------------------------------------------------
1.1       root      170:   for(;;) {
1.1.1.3 ! root      171: 
        !           172:     //-- wait for debug events
        !           173:     if( !WaitForDebugEvent( &DebugEvent, INFINITE ) ) {
        !           174:       ListBoxPrintF( pDebStartupInfo->hWndListBox, TEXT( "%s" ), TEXT( "Failed to attach to Debuggee..." ) );
        !           175:       fFinished = TRUE;
        !           176:       break;
        !           177:     }
        !           178: 
        !           179:     // --------------------------------------------------------------------
        !           180:     // display each debug event as it occurs and handle minimal debug
        !           181:     // event processing
        !           182:     // --------------------------------------------------------------------
        !           183:     MakeCommonDebugEventString( lpszDebugEventBuffer, &DebugEvent );
1.1       root      184: 
                    185:     switch( DebugEvent.dwDebugEventCode ) {
                    186: 
1.1.1.3 ! root      187:       // ------------------------------------------------------------------
        !           188:       // exception occured
        !           189:       // ------------------------------------------------------------------
1.1       root      190:       case EXCEPTION_DEBUG_EVENT:
                    191: 
1.1.1.3 ! root      192:         //-- figure out which type of exception
1.1       root      193:         switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
                    194: 
1.1.1.3 ! root      195:           //--standard exceptions
1.1       root      196:           case EXCEPTION_ACCESS_VIOLATION:
1.1.1.3 ! root      197:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           198:               TEXT( "Exception: " ), TEXT( "Access Violation" ) );
1.1       root      199:             break;
                    200: 
1.1.1.3 ! root      201:           case EXCEPTION_DATATYPE_MISALIGNMENT:
        !           202:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           203:               TEXT( "Exception: " ), TEXT( "Datatype Misalignment" ) );
1.1       root      204:             break;
                    205: 
1.1.1.3 ! root      206:           case EXCEPTION_BREAKPOINT:
        !           207:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           208:               TEXT( "Exception: " ), TEXT( "Breakpoint" ) );
1.1       root      209:             break;
                    210: 
                    211:           case EXCEPTION_SINGLE_STEP:
1.1.1.3 ! root      212:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           213:               TEXT( "Exception: " ), TEXT( "Single Step" ) );
1.1       root      214:             break;
                    215: 
                    216:           case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1.1.1.3 ! root      217:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           218:               TEXT( "Exception: " ), TEXT( "Array Bound Exceeded" ) );
        !           219:             break;
        !           220: 
        !           221:           case EXCEPTION_FLT_DENORMAL_OPERAND:
        !           222:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           223:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           224:               TEXT( "Denormal Operand" ) );
1.1       root      225:             break;
                    226: 
                    227:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:
1.1.1.3 ! root      228:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           229:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           230:               TEXT( "Divide By Zero" ) );
        !           231:             break;
        !           232: 
        !           233:           case EXCEPTION_FLT_INEXACT_RESULT:
        !           234:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           235:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           236:               TEXT( "Inexact Result" ) );
1.1       root      237:             break;
                    238: 
                    239:           case EXCEPTION_FLT_INVALID_OPERATION:
1.1.1.3 ! root      240:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           241:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           242:               TEXT( "Invalid Operation" ) );
1.1       root      243:             break;
                    244: 
                    245:           case EXCEPTION_FLT_OVERFLOW:
1.1.1.3 ! root      246:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           247:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           248:               TEXT( "Overflow" ) );
1.1       root      249:             break;
                    250: 
                    251:           case EXCEPTION_FLT_STACK_CHECK:
1.1.1.3 ! root      252:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           253:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           254:               TEXT( "Stack Check" ) );
1.1       root      255:             break;
                    256: 
                    257:           case EXCEPTION_FLT_UNDERFLOW:
1.1.1.3 ! root      258:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           259:               TEXT( "Exception: " ), TEXT( "Floating Point" ),
        !           260:               TEXT( "Underflow" ) );
1.1       root      261:             break;
                    262: 
                    263:           case EXCEPTION_INT_DIVIDE_BY_ZERO:
1.1.1.3 ! root      264:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           265:               TEXT( "Exception: " ), TEXT( "Integer" ),
        !           266:               TEXT( "Divide By Zero" ) );
1.1       root      267:             break;
                    268: 
                    269:           case EXCEPTION_INT_OVERFLOW:
1.1.1.3 ! root      270:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s %s" ),
        !           271:               TEXT( "Exception: " ), TEXT( "Integer" ),
        !           272:               TEXT( "Overflow" ) );
1.1       root      273:             break;
                    274: 
                    275:           case EXCEPTION_PRIV_INSTRUCTION:
1.1.1.3 ! root      276:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           277:               TEXT( "Exception: " ), TEXT( "Privileged Instruction" ) );
        !           278:             break;
        !           279: 
        !           280:           case EXCEPTION_IN_PAGE_ERROR:
        !           281:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           282:               TEXT( "Exception: " ), TEXT( "In Page Error" ) );
1.1       root      283:             break;
                    284: 
1.1.1.3 ! root      285:           //-- Debug exceptions
        !           286:           case DBG_TERMINATE_THREAD:
        !           287:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           288:               TEXT( "Debug Exception: " ), TEXT( "Terminate Thread" ) );
        !           289:             break;
        !           290: 
        !           291:           case DBG_TERMINATE_PROCESS:
        !           292:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           293:               TEXT( "Debug Exception: " ), TEXT( "Terminate Process" ) );
        !           294:             break;
        !           295: 
        !           296:           case DBG_CONTROL_C:
        !           297:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           298:               TEXT( "Debug Exception: " ), TEXT( "Control+C" ) );
        !           299:             break;
        !           300: 
        !           301:           case DBG_CONTROL_BREAK:
        !           302:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           303:               TEXT( "Debug Exception: " ), TEXT( "Control+Break" ) );
        !           304:             break;
        !           305: 
        !           306:           //-- RPC exceptions (some)
        !           307:           case RPC_S_UNKNOWN_IF:
        !           308:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           309:               TEXT( "RPC Exception: " ), TEXT( "Unknown Interface" ) );
        !           310:             break;
        !           311: 
        !           312:           case RPC_S_SERVER_UNAVAILABLE:
        !           313:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s" ),
        !           314:               TEXT( "RPC Exception: " ), TEXT( "Server Unavailable" ) );
        !           315:             break;
        !           316: 
        !           317:           //-- VDM exceptions (minimal information)
        !           318:           case EXCEPTION_VDM_EVENT:  // see DEBDebug.H for definition
        !           319:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           320:               TEXT( "VDM Exception: " ) );
        !           321: 
1.1       root      322:           default:
1.1.1.3 ! root      323:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s%s%X%s" ),
        !           324:               TEXT( "Exception: " ), TEXT( "Unknown [0x" ),
        !           325:                DebugEvent.u.Exception.ExceptionRecord.ExceptionCode,
        !           326:                TEXT( "]" ) );
1.1       root      327:             break;
1.1.1.3 ! root      328: 
1.1       root      329:         }
1.1.1.3 ! root      330:         if( Profile.fVerbose ) {
        !           331:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d" ),
        !           332:             TEXT( "dwFirstChance: " ), DebugEvent.u.Exception.dwFirstChance );
1.1       root      333:         }
                    334:         else {
1.1.1.3 ! root      335:           if( DebugEvent.u.Exception.dwFirstChance != 0 )
        !           336:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           337:               TEXT( " - First Chance" ) );
1.1       root      338:           else
1.1.1.3 ! root      339:             StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           340:               TEXT( " - Second Chance" ) );
1.1       root      341:         }
1.1.1.3 ! root      342:         HandleExceptionEvent( &DebugEvent );
1.1       root      343:         break;
                    344: 
1.1.1.3 ! root      345:       // ------------------------------------------------------------------
        !           346:       // new thread started
        !           347:       // ------------------------------------------------------------------
1.1       root      348:       case CREATE_THREAD_DEBUG_EVENT:
1.1.1.3 ! root      349:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           350:           TEXT( "Create Thread: " ) );
        !           351:         if( Profile.fVerbose ) {
        !           352:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d\n + %s%X\n + %s%d" ),
        !           353:             TEXT( "hThread:0x" ), DebugEvent.u.CreateThread.hThread,
        !           354:             TEXT( "lpThreadLocalBase:0x" ), DebugEvent.u.CreateThread.lpThreadLocalBase,
        !           355:             TEXT( "lpStartAddress:0x" ), DebugEvent.u.CreateThread.lpStartAddress );
1.1       root      356:         }
1.1.1.3 ! root      357:         HandleCreateThreadEvent( &DebugEvent );
1.1       root      358:         break;
                    359: 
1.1.1.3 ! root      360:       // ------------------------------------------------------------------
        !           361:       // new process started
        !           362:       // ------------------------------------------------------------------
1.1       root      363:       case CREATE_PROCESS_DEBUG_EVENT:
1.1.1.3 ! root      364:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           365:           TEXT( "Create Process: " ) );
        !           366:         if( Profile.fVerbose ) {
        !           367:           StringAppendF( lpszDebugEventBuffer,
        !           368:             TEXT( "\n + %s%X\n + %s%X\n + %s%X\n + %s%X\n + %s%d" )
        !           369:             TEXT( "\n + %s%d\n + %s%X\n + %s%X\n + %s%X\n + %s%d" ),
        !           370:             TEXT( "hFile:0x" ), DebugEvent.u.CreateProcessInfo.hFile,
        !           371:             TEXT( "hProcess:0x" ), DebugEvent.u.CreateProcessInfo.hProcess,
        !           372:             TEXT( "hThread:0x" ), DebugEvent.u.CreateProcessInfo.hThread,
        !           373:             TEXT( "lpBaseOfImage:0x" ), DebugEvent.u.CreateProcessInfo.lpBaseOfImage,
        !           374:             TEXT( "dwDebugInfoFileOffset: " ), DebugEvent.u.CreateProcessInfo.dwDebugInfoFileOffset,
        !           375:             TEXT( "nDebugInfoSize: " ), DebugEvent.u.CreateProcessInfo.nDebugInfoSize,
        !           376:             TEXT( "lpThreadLocalBase:0x" ), DebugEvent.u.CreateProcessInfo.lpThreadLocalBase,
        !           377:             TEXT( "lpStartAddress:0x" ), DebugEvent.u.CreateProcessInfo.lpStartAddress,
        !           378:             TEXT( "lpImageName:0x" ), DebugEvent.u.CreateProcessInfo.lpImageName,
        !           379:             TEXT( "fUnicode: " ), DebugEvent.u.CreateProcessInfo.fUnicode );
1.1       root      380:         }
1.1.1.3 ! root      381:         HandleCreateProcessEvent( &DebugEvent );
1.1       root      382:         break;
                    383: 
1.1.1.3 ! root      384:       // ------------------------------------------------------------------
        !           385:       // existing thread terminated
        !           386:       // ------------------------------------------------------------------
1.1       root      387:       case EXIT_THREAD_DEBUG_EVENT:
1.1.1.3 ! root      388:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           389:           TEXT( "Exit Thread: " ) );
        !           390:         if( Profile.fVerbose ) {
        !           391:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d" ),
        !           392:             TEXT( "dwExitCode: " ), DebugEvent.u.ExitThread.dwExitCode );
1.1       root      393:         }
                    394:         else {
1.1.1.3 ! root      395:           StringAppendF( lpszDebugEventBuffer, TEXT( "%s%d" ),
        !           396:             TEXT( "Returned " ), DebugEvent.u.ExitThread.dwExitCode );
1.1       root      397:         }
1.1.1.3 ! root      398:         HandleExitThreadEvent( &DebugEvent );
1.1       root      399:         break;
                    400: 
1.1.1.3 ! root      401:       // ------------------------------------------------------------------
        !           402:       // existing process terminated
        !           403:       // ------------------------------------------------------------------
1.1       root      404:       case EXIT_PROCESS_DEBUG_EVENT:
1.1.1.3 ! root      405:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           406:           TEXT( "Exit Process: " ) );
        !           407:         if( Profile.fVerbose ) {
        !           408:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d" ),
        !           409:             TEXT( "dwExitCode: " ), DebugEvent.u.ExitProcess.dwExitCode );
1.1       root      410:         }
                    411:         else {
1.1.1.3 ! root      412:           StringAppendF( lpszDebugEventBuffer, TEXT( "%s%d" ),
        !           413:             TEXT( "Returned " ), DebugEvent.u.ExitProcess.dwExitCode );
1.1       root      414:         }
1.1.1.3 ! root      415:         HandleExitProcessEvent( &DebugEvent );
1.1       root      416:         break;
                    417: 
1.1.1.3 ! root      418:       // ------------------------------------------------------------------
        !           419:       // new DLL loaded
        !           420:       // ------------------------------------------------------------------
1.1       root      421:       case LOAD_DLL_DEBUG_EVENT:
1.1.1.3 ! root      422:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           423:           TEXT( "Load DLL: " ) );
        !           424:         lstrcpy( lpszTempBuffer, TEXT("Empty!") );
        !           425:         GetDllFileName( &DebugEvent, lpszTempBuffer, BUFFER_SIZE );
        !           426:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ), lpszTempBuffer );
        !           427:         if( Profile.fVerbose ) {
        !           428:           StringAppendF( lpszDebugEventBuffer,
        !           429:             TEXT( "\n + %s%X\n + %s%X\n + %s%d\n + %s%d\n + %s%X\n + %s%d" ),
        !           430:             TEXT( "hFile:0x" ), DebugEvent.u.LoadDll.hFile,
        !           431:             TEXT( "lpBaseOfDll:0x" ), DebugEvent.u.LoadDll.lpBaseOfDll,
        !           432:             TEXT( "dwDebugInfoFileOffset: " ), DebugEvent.u.LoadDll.dwDebugInfoFileOffset,
        !           433:             TEXT( "nDebugInfoSize: " ), DebugEvent.u.LoadDll.nDebugInfoSize,
        !           434:             TEXT( "lpImageName:0x" ), DebugEvent.u.LoadDll.lpImageName,
        !           435:             TEXT( "fUnicode: " ), DebugEvent.u.LoadDll.fUnicode );
1.1       root      436:         }
1.1.1.3 ! root      437:         HandleLoadDllEvent( &DebugEvent );
1.1       root      438:         break;
                    439: 
1.1.1.3 ! root      440:       // ------------------------------------------------------------------
        !           441:       // existing DLL explicitly unloaded
        !           442:       // ------------------------------------------------------------------
1.1       root      443:       case UNLOAD_DLL_DEBUG_EVENT:
1.1.1.3 ! root      444:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ), TEXT( "Unload DLL: " ) );
        !           445:         GetDllFileNameFromList( &DebugEvent, lpszTempBuffer, BUFFER_SIZE );
        !           446:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ), lpszTempBuffer );
        !           447:         if( Profile.fVerbose ) {
        !           448:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%X" ),
        !           449:             TEXT( "lpBaseOfDLL:0x" ), DebugEvent.u.UnloadDll.lpBaseOfDll );
1.1       root      450:         }
1.1.1.3 ! root      451:         HandleUnloadDllEvent( &DebugEvent );
1.1       root      452:         break;
                    453: 
1.1.1.3 ! root      454:       // ------------------------------------------------------------------
        !           455:       // OutputDebugString() occured
        !           456:       // ------------------------------------------------------------------
1.1       root      457:       case OUTPUT_DEBUG_STRING_EVENT:
1.1.1.3 ! root      458:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           459:           TEXT( "Output Debug String: " ) );
        !           460:         GetOutputDebugString( &DebugEvent, lpszTempBuffer, BUFFER_SIZE );
        !           461:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ), lpszTempBuffer );
        !           462:         if( Profile.fVerbose ) {
        !           463:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%X\n + %s%d\n + %s%d" ),
        !           464:             TEXT( "lpDebugStringData:0x" ), DebugEvent.u.DebugString.lpDebugStringData,
        !           465:             TEXT( "fUnicode: " ), DebugEvent.u.DebugString.fUnicode,
        !           466:             TEXT( "nDebugStringLength: " ), DebugEvent.u.DebugString.nDebugStringLength );
1.1       root      467:         }
1.1.1.3 ! root      468:         HandleOutputDebugStringEvent( &DebugEvent );
1.1       root      469:         break;
                    470: 
1.1.1.3 ! root      471:       // ------------------------------------------------------------------
        !           472:       // RIP occured
        !           473:       // ------------------------------------------------------------------
        !           474:       case RIP_EVENT:
        !           475:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s" ),
        !           476:           TEXT( "RIP" ) );
        !           477:         if( Profile.fVerbose ) {
        !           478:           StringAppendF( lpszDebugEventBuffer, TEXT( "\n + %s%d\n + %s%d" ),
        !           479:             TEXT( "dwError: " ), DebugEvent.u.RipInfo.dwError,
        !           480:             TEXT( "dwType: " ), DebugEvent.u.RipInfo.dwType );
        !           481:         }
        !           482:         HandleRipEvent( &DebugEvent );
        !           483:         break;
        !           484: 
        !           485:       // ------------------------------------------------------------------
        !           486:       // unknown debug event occured
        !           487:       // ------------------------------------------------------------------
1.1       root      488:       default:
1.1.1.3 ! root      489:         StringAppendF( lpszDebugEventBuffer, TEXT( "%s%X%s" ),
        !           490:           TEXT( "Debug Event:Unknown [0x" ),
        !           491:           DebugEvent.dwDebugEventCode, lpszTempBuffer,
        !           492:           TEXT( "]" ) );
        !           493:         HandleUnknownEvent( &DebugEvent );
1.1       root      494:         break;
                    495:     }
                    496: 
                    497:     //-- insert the debug event string into the listbox
1.1.1.3 ! root      498:     ListBoxPrintF( pDebStartupInfo->hWndListBox, TEXT( "%s" ), lpszDebugEventBuffer );
1.1       root      499: 
1.1.1.3 ! root      500:     //-- default action, just continue
        !           501:     if( fFinished ) {
        !           502:       fFinished = FALSE;   // reset the value
        !           503:       break;
        !           504:     }
        !           505:     else
        !           506:       ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId,
        !           507:         DBG_CONTINUE );
        !           508:   }
1.1       root      509: 
1.1.1.3 ! root      510:   //-- free temporary (life of thread) string buffers
        !           511:   HeapFree( hHeap, (DWORD) NULL, (PVOID) lpszDebugEventBuffer );
        !           512:   HeapFree( hHeap, (DWORD) NULL, (PVOID) lpszTempBuffer );
1.1       root      513: 
1.1.1.3 ! root      514:   //-- free list
        !           515:   DestroyProcessList( pProcessList );
1.1       root      516: 
1.1.1.3 ! root      517:   //-- free the heap
        !           518:   HeapDestroy( hHeap );
1.1       root      519: 
1.1.1.3 ! root      520:   //-- decrement active process count
        !           521:   Global.dwActiveDebuggees--;
        !           522:   ExitThread( TRUE );
1.1       root      523: 
1.1.1.3 ! root      524:   return( TRUE );  // avoid the "no return value" warning
        !           525: }
1.1       root      526: 
                    527: 
1.1.1.3 ! root      528: // ========================================================================
        !           529: // debug event handling functions
        !           530: // ========================================================================
        !           531: 
        !           532: 
        !           533: // ************************************************************************
        !           534: // FUNCTION : HandleExceptionEvent( LPDEBUG_EVENT lpDebugEvent )
        !           535: // PURPOSE  : handle EXCEPTION_DEBUG_EVENT
        !           536: // COMMENTS : except for the BreakPoint event, continue and let the
        !           537: //            application or system exception handlers to the work
        !           538: // ************************************************************************
        !           539: BOOL
        !           540: HandleExceptionEvent( LPDEBUG_EVENT lpDebugEvent )
        !           541: {
        !           542:   switch( lpDebugEvent->u.Exception.ExceptionRecord.ExceptionCode ) {
        !           543: 
        !           544:     case EXCEPTION_BREAKPOINT:
        !           545:       HandleBreakPointException( lpDebugEvent );
        !           546:       break;
        !           547: 
        !           548:     default:
        !           549:       ContinueDebugEvent( lpDebugEvent->dwProcessId, lpDebugEvent->dwThreadId,
        !           550:         DBG_EXCEPTION_NOT_HANDLED );
        !           551: 
        !           552:   }
        !           553: 
        !           554:   return( TRUE );
        !           555: }
        !           556: 
        !           557: 
        !           558: // ************************************************************************
        !           559: // FUNCTION : HandleBreakPointException( LPDEBUG_EVENT lpDebugEvent )
        !           560: // PURPOSE  : handle the BREAKPOINT exception
        !           561: // COMMENTS : search process list, search thread list, skip over breakpoint
        !           562: // ************************************************************************
        !           563: BOOL
        !           564: HandleBreakPointException( LPDEBUG_EVENT lpDebugEvent )
        !           565: {
        !           566:  #if( _MIPS_ == 1 || _ALPHA_ == 1 )
        !           567:   PNODE                  pProcessNode, pSearchProcessNode;
        !           568:   PNODE                  pThreadNode, pSearchThreadNode;
        !           569:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           570:   PDEB_THREAD_NODE_INFO  pThreadNodeInfo, pSearchThreadNodeInfo;
        !           571:   PDEB_THREAD_LIST_INFO  pThreadListInfo;
        !           572: 
        !           573:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           574:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           575:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           576:   GetCurrentNode( pProcessList, &pProcessNode );
        !           577:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           578:   pThreadListInfo = (PDEB_THREAD_LIST_INFO) pProcessNodeInfo->pThreadList->pListData;
        !           579:   //-- if no thread nodes then hThread is stored in the process node
        !           580:   if( !pThreadListInfo->dwActiveThreads ) {
        !           581:     SkipBreakPoint( (pProcessNodeInfo->ProcessDebugInfo).hThread );
        !           582:   }
        !           583:   else {
        !           584:     AllocThreadNode( &pSearchThreadNode, &pSearchThreadNodeInfo );
        !           585:     pSearchThreadNodeInfo->dwThreadId = lpDebugEvent->dwThreadId;
        !           586:     SetCurrentThreadNode( pProcessNodeInfo->pThreadList, pSearchThreadNode );
        !           587:     GetCurrentNode( pProcessNodeInfo->pThreadList, &pThreadNode );
        !           588:     pThreadNodeInfo = (PDEB_THREAD_NODE_INFO) pThreadNode->pNodeData;
        !           589:     SkipBreakPoint( (pThreadNodeInfo->ThreadDebugInfo).hThread );
        !           590:     DestroyThreadNode( pSearchThreadNode );
        !           591:   }
        !           592:   DestroyProcessNode( pSearchProcessNode );
        !           593:  #else
        !           594:   ContinueDebugEvent( lpDebugEvent->dwProcessId, lpDebugEvent->dwThreadId,
        !           595:     DBG_CONTINUE );
        !           596:  #endif
        !           597: 
        !           598:   return( TRUE );
        !           599: }
        !           600: 
        !           601: 
        !           602: // ************************************************************************
        !           603: // FUNCTION : HandleCreateThreadEvent( LPDEBUG_EVENT )
        !           604: // PURPOSE  : handle CREATE_THREAD_DEBUG_EVENT
        !           605: // COMMENTS : search process list, insert new thread node
        !           606: // ************************************************************************
        !           607: BOOL
        !           608: HandleCreateThreadEvent( LPDEBUG_EVENT lpDebugEvent )
        !           609: {
        !           610:   PNODE                  pProcessNode, pSearchProcessNode;
        !           611:   PNODE                  pThreadNode;
        !           612:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           613:   PDEB_THREAD_NODE_INFO  pThreadNodeInfo;
        !           614: 
        !           615:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           616:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           617:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           618:   GetCurrentNode( pProcessList, &pProcessNode );
        !           619:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           620:   AllocThreadNode( &pThreadNode, &pThreadNodeInfo );
        !           621:   InitThreadNodeInfo( &pThreadNodeInfo, lpDebugEvent );
        !           622:   InsertThreadNode( pProcessNodeInfo->pThreadList, pThreadNode );
        !           623:   DestroyProcessNode( pSearchProcessNode );
        !           624: 
        !           625:   return( TRUE );
        !           626: }
        !           627: 
        !           628: 
        !           629: // ************************************************************************
        !           630: // FUNCTION : HandleCreateProcessEvent( LPDEBUG_EVENT )
        !           631: // PURPOSE  : handle CREATE_PROCESS_DEBUG_EVENT
        !           632: // COMMENTS : insert new process node
        !           633: // ************************************************************************
        !           634: BOOL
        !           635: HandleCreateProcessEvent( LPDEBUG_EVENT lpDebugEvent )
        !           636: {
        !           637:   PNODE                  pProcessNode;
        !           638:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo;
        !           639: 
        !           640:   AllocProcessNode( &pProcessNode, &pProcessNodeInfo );
        !           641:   InitProcessNodeInfo( &pProcessNodeInfo, lpDebugEvent );
        !           642:   InsertProcessNode( pProcessList, pProcessNode );
        !           643: 
        !           644:   return( TRUE );
        !           645: }
        !           646: 
        !           647: 
        !           648: // ************************************************************************
        !           649: // FUNCTION : HandleExitThreadEvent( LPDEBUG_EVENT )
        !           650: // PURPOSE  : handle EXIT_THREAD_DEBUG_EVENT
        !           651: // COMMENTS : search process list, search thread list, delete existing
        !           652: //            thread node
        !           653: // ************************************************************************
        !           654: BOOL
        !           655: HandleExitThreadEvent( LPDEBUG_EVENT lpDebugEvent )
        !           656: {
        !           657:   PNODE                  pProcessNode, pSearchProcessNode;
        !           658:   PNODE                  pSearchThreadNode;
        !           659:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           660:   PDEB_THREAD_NODE_INFO  pSearchThreadNodeInfo;
        !           661: 
        !           662:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           663:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           664:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           665:   GetCurrentNode( pProcessList, &pProcessNode );
        !           666:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           667:   AllocThreadNode( &pSearchThreadNode, &pSearchThreadNodeInfo );
        !           668:   pSearchThreadNodeInfo->dwThreadId = lpDebugEvent->dwThreadId;
        !           669:   DeleteThreadNode( pProcessNodeInfo->pThreadList, pSearchThreadNode );
        !           670:   DestroyThreadNode( pSearchThreadNode );
        !           671:   DestroyProcessNode( pSearchProcessNode );
        !           672: 
        !           673:   return( TRUE );
        !           674: }
        !           675: 
        !           676: 
        !           677: // ************************************************************************
        !           678: // FUNCTION : HandleExitProcessEvent( LPDEBUG_EVENT )
        !           679: // PURPOSE  : handle EXIT_PROCESS_DEBUG_EVENT
        !           680: // COMMENTS : search process list, delete existing process node,
        !           681: // ************************************************************************
        !           682: BOOL
        !           683: HandleExitProcessEvent( LPDEBUG_EVENT lpDebugEvent )
        !           684: {
        !           685:   PNODE                  pSearchProcessNode;
        !           686:   PDEB_PROCESS_NODE_INFO pSearchProcessNodeInfo;
        !           687:   PDEB_PROCESS_LIST_INFO pProcessListInfo;
        !           688: 
        !           689:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           690:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           691:   DeleteProcessNode( pProcessList, pSearchProcessNode );
        !           692:   //-- if last process? free all temporary memory, exit thread
        !           693:   pProcessListInfo = (PDEB_PROCESS_LIST_INFO) pProcessList->pListData;
        !           694:   if( !pProcessListInfo->dwActiveProcesses )
        !           695:     fFinished = TRUE;
        !           696:   DestroyProcessNode( pSearchProcessNode );
        !           697: 
        !           698:   return( TRUE );
        !           699: }
        !           700: 
        !           701: 
        !           702: // ************************************************************************
        !           703: // FUNCTION : HandleLoadDllEvent( LPDEBUG_EVENT )
        !           704: // PURPOSE  : handle LOAD_DLL_DEBUG_EVENT
        !           705: // COMMENTS : search process list, insert new DLL node
        !           706: // ************************************************************************
        !           707: BOOL
        !           708: HandleLoadDllEvent( LPDEBUG_EVENT lpDebugEvent )
        !           709: {
        !           710:   PNODE                  pProcessNode, pSearchProcessNode;
        !           711:   PNODE                  pDllNode;
        !           712:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           713:   PDEB_DLL_NODE_INFO     pDllNodeInfo;
        !           714: 
        !           715:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           716:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           717:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           718:   GetCurrentNode( pProcessList, &pProcessNode );
        !           719:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           720:   AllocDllNode( &pDllNode, &pDllNodeInfo );
        !           721:   InitDllNodeInfo( &pDllNodeInfo, lpDebugEvent );
        !           722:   InsertDllNode( pProcessNodeInfo->pDllList, pDllNode );
        !           723:   DestroyProcessNode( pSearchProcessNode );
        !           724: 
        !           725:   return( TRUE );
        !           726: }
        !           727: 
        !           728: 
        !           729: // ************************************************************************
        !           730: // FUNCTION : HandleUnloadDllEvent( LPDEBUG_EVENT )
        !           731: // PURPOSE  : handle UNLOAD_DLL_DEBUG_EVENT
        !           732: // COMMENTS : search process list, search DLL list, delete existing DLL
        !           733: //            node
        !           734: // ************************************************************************
        !           735: BOOL
        !           736: HandleUnloadDllEvent( LPDEBUG_EVENT lpDebugEvent )
        !           737: {
        !           738:   PNODE                  pProcessNode, pSearchProcessNode;
        !           739:   PNODE                  pSearchDllNode;
        !           740:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           741:   PDEB_DLL_NODE_INFO     pSearchDllNodeInfo;
        !           742: 
        !           743:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           744:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           745:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           746:   GetCurrentNode( pProcessList, &pProcessNode );
        !           747:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           748:   AllocDllNode( &pSearchDllNode, &pSearchDllNodeInfo );
        !           749:   pSearchDllNodeInfo->DllDebugInfo.lpBaseOfDll = lpDebugEvent->u.UnloadDll.lpBaseOfDll;
        !           750:   DeleteDllNode( pProcessNodeInfo->pDllList, pSearchDllNode );
        !           751:   DestroyDllNode( pSearchDllNode );
        !           752:   DestroyProcessNode( pSearchProcessNode );
        !           753: 
        !           754:   return( TRUE );
        !           755: }
        !           756: 
        !           757: 
        !           758: // ************************************************************************
        !           759: // FUNCTION : HandleOutputDebugStringEvent( LPDEBUG_EVENT )
        !           760: // PURPOSE  : handle OUTPUT_DEBUG_STRING_EVENT
        !           761: // COMMENTS : do nothing
        !           762: // ************************************************************************
        !           763: BOOL
        !           764: HandleOutputDebugStringEvent( LPDEBUG_EVENT lpDebugEvent )
        !           765: {
        !           766:   return( TRUE );
        !           767: }
        !           768: 
        !           769: 
        !           770: // ************************************************************************
        !           771: // FUNCTION : HandleRipEvent( LPDEBUG_EVENT )
        !           772: // PURPOSE  : handle RIP_EVENT
        !           773: // COMMENTS : do nothing
        !           774: // ************************************************************************
        !           775: BOOL
        !           776: HandleRipEvent( LPDEBUG_EVENT lpDebugEvent )
        !           777: {
        !           778:   return( TRUE );
        !           779: }
        !           780: 
        !           781: 
        !           782: // ************************************************************************
        !           783: // FUNCTION : HandleUnknownEvent( LPDEBUG_EVENT )
        !           784: // PURPOSE  : handle all unknown debug events
        !           785: // COMMENTS : do nothing
        !           786: // ************************************************************************
        !           787: BOOL
        !           788: HandleUnknownEvent( LPDEBUG_EVENT lpDebugEvent )
        !           789: {
        !           790:   return( TRUE );
        !           791: }
        !           792: 
        !           793: 
        !           794: // ========================================================================
        !           795: // misc debug event helper functions
        !           796: // ========================================================================
        !           797: 
        !           798: 
        !           799: // ************************************************************************
        !           800: // FUNCTION : DebugNewProcess( LPTSTR, LPTSTR )
        !           801: // PURPOSE  : starts a new process as a debuggee
        !           802: // COMMENTS :
        !           803: // ************************************************************************
        !           804: BOOL
        !           805: DebugNewProcess( LPTSTR lpszFileName, LPTSTR lpszTitle )
        !           806: {
        !           807:   static STARTUPINFO           StartupInfo;
        !           808:   static LPSTARTUPINFO         lpStartupInfo = &StartupInfo;
        !           809:   static PROCESS_INFORMATION   ProcessInfo;
        !           810:   static LPPROCESS_INFORMATION lpProcessInfo = &ProcessInfo;
        !           811: 
        !           812:   lpStartupInfo->cb          = sizeof( STARTUPINFO );
        !           813:   lpStartupInfo->lpDesktop   = NULL;
        !           814:   lpStartupInfo->lpTitle     = lpszTitle;
        !           815:   lpStartupInfo->dwX         = 0;
        !           816:   lpStartupInfo->dwY         = 0;
        !           817:   lpStartupInfo->dwXSize     = 0;
        !           818:   lpStartupInfo->dwYSize     = 0;
        !           819:   lpStartupInfo->dwFlags     = (DWORD) NULL;
        !           820:   lpStartupInfo->wShowWindow = SW_SHOWDEFAULT;
        !           821: 
        !           822:   lpProcessInfo->hProcess = NULL;
        !           823: 
        !           824:   //-- create the Debuggee process instead
        !           825:   if( !CreateProcess(
        !           826:          NULL,
        !           827:          lpszFileName,
        !           828:          (LPSECURITY_ATTRIBUTES) NULL,
        !           829:          (LPSECURITY_ATTRIBUTES) NULL,
        !           830:          TRUE,
        !           831:          Profile.DebugMode | Profile.DebuggeePriority | CREATE_NEW_CONSOLE,
        !           832:          (LPVOID) NULL,
        !           833:          (LPTSTR) NULL,
        !           834:          lpStartupInfo, lpProcessInfo ) ) {
        !           835: 
        !           836:     switch( GetLastError() ) {
        !           837: 
        !           838:       case ERROR_FILE_NOT_FOUND:
        !           839:         MessageBox( GetDesktopWindow(), TEXT( "This file does not exist." ),
        !           840:           TEXT( "Open File Error" ), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND );
        !           841:         break;
        !           842:       case ERROR_ACCESS_DENIED:
        !           843:         MessageBox( GetDesktopWindow(), TEXT( "Access denied." ),
        !           844:           TEXT( "Open File Error" ), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND );
        !           845:         break;
        !           846:       case ERROR_FILE_INVALID:
        !           847:         MessageBox( GetDesktopWindow(), TEXT( "Invalid file." ),
        !           848:           TEXT( "Open File Error" ), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND );
1.1       root      849:         break;
1.1.1.3 ! root      850:       case ERROR_FILE_CORRUPT:
        !           851:         MessageBox( GetDesktopWindow(), TEXT( "The file is corrupt." ),
        !           852:           TEXT( "Open File Error" ), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND );
        !           853:         break;
        !           854:       case ERROR_BAD_EXE_FORMAT:
        !           855:         MessageBox( GetDesktopWindow(), TEXT( "The file has a bad format." ),
        !           856:           TEXT( "Open File Error" ), MB_OK | MB_APPLMODAL | MB_SETFOREGROUND );
        !           857:         break;
        !           858:       default:
        !           859:         ErrorMessageBox( TEXT( "CreateProcess()" ),
        !           860:           Global.szApiFailedMsg, lpszSourceFileName, __LINE__ );
        !           861:         break;
        !           862: 
1.1       root      863:     }
1.1.1.3 ! root      864:     return( FALSE );
1.1       root      865: 
                    866:   }
1.1.1.3 ! root      867:   else {
        !           868:     CloseHandle( ProcessInfo.hProcess );
        !           869:     CloseHandle( ProcessInfo.hThread );
        !           870:   }
        !           871: 
        !           872:   return( TRUE
        !           873:  );
        !           874: }
        !           875: 
        !           876: 
        !           877: // ************************************************************************
        !           878: // FUNCTION : GetDllFileName( LPDEBUG_EVENT, LPTSTR, DWORD )
        !           879: // PURPOSE  : get DLL filename when LOAD_DLL_DEBUG_EVENT occurs
        !           880: // COMMENTS : search process list, get DLL name from header
        !           881: // ************************************************************************
        !           882: BOOL
        !           883: GetDllFileName( LPDEBUG_EVENT lpDebugEvent, LPTSTR lpszBuffer,
        !           884:   DWORD cchBuffer )
        !           885: {
        !           886:   PNODE                  pProcessNode, pSearchProcessNode;
        !           887:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           888: 
        !           889:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           890:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           891:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           892:   GetCurrentNode( pProcessList, &pProcessNode );
        !           893:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           894:   GetModuleFileNameFromHeader(
        !           895:     pProcessNodeInfo->ProcessDebugInfo.hProcess,
        !           896:     lpDebugEvent->u.LoadDll.hFile,
        !           897:     (DWORD) lpDebugEvent->u.LoadDll.lpBaseOfDll,
        !           898:     lpszBuffer, cchBuffer);
        !           899:   DestroyProcessNode( pSearchProcessNode );
1.1       root      900: 
1.1.1.3 ! root      901:   return( TRUE );
        !           902: }
        !           903: 
        !           904: 
        !           905: // ************************************************************************
        !           906: // FUNCTION : GetDllFileNameFromList( LPDEBUG_EVENT, LPTSTR, DWORD )
        !           907: // PURPOSE  : get DLL filename when UNLOAD_DLL_DEBUG_EVENT occurs
        !           908: // COMMENTS : search process list, search DLL list, get DLL name
        !           909: // ************************************************************************
        !           910: BOOL
        !           911: GetDllFileNameFromList( LPDEBUG_EVENT lpDebugEvent, LPTSTR lpszBuffer,
        !           912:   DWORD cchBuffer )
        !           913: {
        !           914:   PNODE                  pProcessNode, pSearchProcessNode;
        !           915:   PNODE                  pDllNode, pSearchDllNode;
        !           916:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           917:   PDEB_DLL_NODE_INFO     pDllNodeInfo, pSearchDllNodeInfo;
        !           918: 
        !           919:   UNREFERENCED_PARAMETER( cchBuffer );
        !           920: 
        !           921:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           922:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           923:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           924:   GetCurrentNode( pProcessList, &pProcessNode );
        !           925:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           926:   AllocDllNode( &pSearchDllNode, &pSearchDllNodeInfo );
        !           927:   pSearchDllNodeInfo->DllDebugInfo.lpBaseOfDll = lpDebugEvent->u.UnloadDll.lpBaseOfDll;
        !           928:   SetCurrentDllNode( pProcessNodeInfo->pDllList, pSearchDllNode );
        !           929:   GetCurrentNode( pProcessNodeInfo->pDllList, &pDllNode );
        !           930:   pDllNodeInfo = (PDEB_DLL_NODE_INFO) pDllNode->pNodeData;
        !           931:   lstrcpy( lpszBuffer, pDllNodeInfo->lpstrFileName );
        !           932: 
        !           933:   return( TRUE );
        !           934: }
        !           935: 
        !           936: 
        !           937: // ************************************************************************
        !           938: // FUNCTION : GetOutputDebugString( LPDEBUG_EVENT, LPTSTR, DWORD )
        !           939: // PURPOSE  : get the output debug string from the debuggee when
        !           940: //            OUTPUT_DEBUG_STRING_EVENT occurs
        !           941: // COMMENTS : search process list, read the string from the debuggee
        !           942: // ************************************************************************
        !           943: BOOL
        !           944: GetOutputDebugString( LPDEBUG_EVENT lpDebugEvent, LPTSTR lpszBuffer,
        !           945:   DWORD cchBuffer )
        !           946: {
        !           947:   PNODE                  pProcessNode, pSearchProcessNode;
        !           948:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo, pSearchProcessNodeInfo;
        !           949:   DWORD dwNumberOfBytesRead;
        !           950: 
        !           951:   UNREFERENCED_PARAMETER( cchBuffer );
        !           952: 
        !           953:   AllocProcessNode( &pSearchProcessNode, &pSearchProcessNodeInfo );
        !           954:   pSearchProcessNodeInfo->dwProcessId = lpDebugEvent->dwProcessId;
        !           955:   SetCurrentProcessNode( pProcessList, pSearchProcessNode );
        !           956:   GetCurrentNode( pProcessList, &pProcessNode );
        !           957:   pProcessNode = (PNODE) pProcessList->pCurrentNode;
        !           958:   pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !           959:   ReadProcessMemory(
        !           960:     pProcessNodeInfo->ProcessDebugInfo.hProcess,
        !           961:     lpDebugEvent->u.DebugString.lpDebugStringData,
        !           962:     lpszBuffer, lpDebugEvent->u.DebugString.nDebugStringLength,
        !           963:     &dwNumberOfBytesRead );
        !           964:   DestroyProcessNode( pSearchProcessNode );
1.1.1.2   root      965: 
1.1.1.3 ! root      966:   return( TRUE );
1.1       root      967: }
                    968: 
                    969: 
                    970: // ************************************************************************
1.1.1.3 ! root      971: // FUNCTION : GetModuleFileNameFromHeader( HANDLE, HANDLE, DWORD, LPTSTR, DWORD )
1.1       root      972: // PURPOSE  : Retrieves the DLL module name for a given file handle of a
                    973: //            the module.  Reads the module name from the EXE header.
1.1.1.2   root      974: // COMMENTS :
1.1.1.3 ! root      975: //   Retrieves only the module name and not the pathname.  Returns the
        !           976: //   number of characters copies to the buffer, else returns 0.
1.1       root      977: // ************************************************************************
1.1.1.3 ! root      978: DWORD
        !           979: GetModuleFileNameFromHeader( HANDLE hProcess, HANDLE hFile, DWORD BaseOfDll,
        !           980:   LPTSTR lpszPath, DWORD cchPath )
1.1       root      981: {
1.1.1.3 ! root      982:   #define IMAGE_SECOND_HEADER_OFFSET    (15 * sizeof(ULONG)) // relative to file beginning
        !           983:   #define IMAGE_BASE_OFFSET             (13 * sizeof(DWORD)) // relative to PE header base
        !           984:   #define IMAGE_EXPORT_TABLE_RVA_OFFSET (30 * sizeof(DWORD)) // relative to PE header base
        !           985:   #define IMAGE_NAME_RVA_OFFSET         offsetof(IMAGE_EXPORT_DIRECTORY, Name)
1.1       root      986: 
                    987:   WORD   DosSignature;
                    988:   DWORD  NtSignature;
1.1.1.3 ! root      989:   DWORD  dwNumberOfBytesRead = 0;
1.1       root      990:   DWORD  PeHeader, ImageBase, ExportTableRVA, NameRVA;
                    991: 
                    992:   //-- verify that the handle is not NULL
                    993:   if( !hFile ) {
1.1.1.3 ! root      994:     lstrcpy( lpszPath, TEXT("Invalid File Handle") );
1.1       root      995:     return( 0 );
                    996:   }
                    997: 
                    998:   //-- verify that the handle is for a disk file
                    999:   if( GetFileType(hFile) != FILE_TYPE_DISK ) {
1.1.1.3 ! root     1000:     lstrcpy( lpszPath, TEXT("Invalid File Type") );
1.1       root     1001:     return( 0 );
                   1002:   }
                   1003: 
                   1004:   //-- Extract the filename from the EXE header
1.1.1.3 ! root     1005:   SetFilePointer( hFile, 0L, NULL, FILE_BEGIN );
        !          1006:   ReadFile( hFile, &DosSignature, sizeof(DosSignature), &dwNumberOfBytesRead,
1.1       root     1007:     (LPOVERLAPPED) NULL);
                   1008: 
1.1.1.3 ! root     1009:   //-- verify DOS signature found
        !          1010:   if( DosSignature != IMAGE_DOS_SIGNATURE ) {
        !          1011:     wsprintf( lpszPath, TEXT( "Bad MZ Signature: 0x%x" ), DosSignature );
        !          1012:     return( 0 );
        !          1013:   }
1.1       root     1014: 
1.1.1.3 ! root     1015:   SetFilePointer( hFile, IMAGE_SECOND_HEADER_OFFSET, (LPLONG) NULL,
        !          1016:     FILE_BEGIN );
        !          1017:   ReadFile( hFile, &PeHeader, sizeof(PeHeader), &dwNumberOfBytesRead,
        !          1018:     (LPOVERLAPPED) NULL );
        !          1019:   SetFilePointer( hFile, PeHeader, (LPLONG) NULL, FILE_BEGIN );
        !          1020:   ReadFile( hFile, &NtSignature, sizeof(NtSignature), &dwNumberOfBytesRead,
        !          1021:     (LPOVERLAPPED) NULL);
1.1       root     1022: 
1.1.1.3 ! root     1023:   //-- verify Windows NT (PE) signature found
        !          1024:   if( NtSignature != IMAGE_NT_SIGNATURE ) {
        !          1025:     wsprintf( lpszPath, TEXT( "Bad PE Signature: 0x%x" ), DosSignature );
        !          1026:     return( 0 );
1.1       root     1027:   }
                   1028: 
1.1.1.3 ! root     1029:   SetFilePointer( hFile, PeHeader + IMAGE_BASE_OFFSET, (LPLONG) NULL,
        !          1030:     FILE_BEGIN );
        !          1031:   ReadFile( hFile, &ImageBase, sizeof(ImageBase), &dwNumberOfBytesRead,
        !          1032:     (LPOVERLAPPED) NULL);
        !          1033:   SetFilePointer( hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET,
        !          1034:     (LPLONG) NULL, FILE_BEGIN );
        !          1035:   ReadFile( hFile, &ExportTableRVA, sizeof(ExportTableRVA),
        !          1036:     &dwNumberOfBytesRead, (LPOVERLAPPED) NULL);
        !          1037: 
        !          1038:   //-- now read from the virtual address space in the process
        !          1039:   ReadProcessMemory( hProcess,
        !          1040:      (LPVOID) (BaseOfDll + ExportTableRVA + IMAGE_NAME_RVA_OFFSET),
        !          1041:      &NameRVA, sizeof(NameRVA), &dwNumberOfBytesRead );
        !          1042:   lstrcpy( lpszPath, TEXT("Empty!") );
        !          1043:   if( !ReadProcessMemory( hProcess,
        !          1044:          (LPVOID) (BaseOfDll + NameRVA),
        !          1045:          lpszPath, cchPath, &dwNumberOfBytesRead ) )
        !          1046:      lstrcpy( lpszPath, TEXT("Access Denied!") );
        !          1047: 
        !          1048:   return( dwNumberOfBytesRead );
1.1       root     1049: }
                   1050: 
                   1051: 
1.1.1.3 ! root     1052: #if( _MIPS_ == 1 || _ALPHA_ == 1 )
1.1       root     1053: // ************************************************************************
1.1.1.3 ! root     1054: // FUNCTION : SkipThreadBreakPoint( HANDLE );
1.1       root     1055: // PURPOSE  : Skip over the break point instruction belonging to
1.1.1.3 ! root     1056: //            hThread.
1.1.1.2   root     1057: // COMMENTS :
1.1.1.3 ! root     1058: //   Only the MIPS R4x00 and DEC Alpha AXP require this.
1.1       root     1059: // ************************************************************************
                   1060: BOOL
1.1.1.3 ! root     1061: SkipBreakPoint( HANDLE hThread )
1.1       root     1062: {
1.1.1.3 ! root     1063:   static CONTEXT Context;
1.1       root     1064: 
                   1065:   Context.ContextFlags = CONTEXT_CONTROL;
1.1.1.3 ! root     1066:   if( !GetThreadContext( hThread, &Context ) )
1.1       root     1067:     return( FALSE );
                   1068:   Context.Fir += 4L;  // Fir is the PC (program counter)
                   1069:                       // BREAK (breakpoint instruction) occupies 4 bytes
                   1070: 
                   1071:   // -----------------------------------------------------------------------
1.1.1.3 ! root     1072:   //  Below would be equivalent for the Intel 80x86 if it were necessary
1.1       root     1073:   //  Context.Eip += 2L;  // Eip is the PC (program counter)
                   1074:   //                      // int 3 (breakpoint instruction) occupies 2 bytes
                   1075:   // -----------------------------------------------------------------------
                   1076: 
1.1.1.3 ! root     1077:   if( !SetThreadContext( hThread, &Context ) )
        !          1078:     return( FALSE );
1.1       root     1079: 
                   1080:   return( TRUE );
                   1081: }
                   1082: #endif
1.1.1.3 ! root     1083: 
        !          1084: 
        !          1085: 
        !          1086: // ========================================================================
        !          1087: // wrapper functions to the linked list services
        !          1088: // ========================================================================
        !          1089: 
        !          1090: // ========================================================================
        !          1091: // Debug Event Browser Data Structure Overview
        !          1092: // -------------------------------------------
        !          1093: //
        !          1094: // The Debug Event Browser (DEB) maintains a rather involved data structure
        !          1095: // to store various debug event and debuggee process information.  It
        !          1096: // attempts to encapsulate the intricacies of what makes a process based on
        !          1097: // the occuring events.  Much of this stored information is never utilized
        !          1098: // by the Debug Event Browser but it is included to demonstrate what types
        !          1099: // of debug event may be useful to a full blown debugger application.
        !          1100: //
        !          1101: // This data structure uses the generalized, sorted, double-linked list
        !          1102: // package provided with the sample.  Each list can store list-specific
        !          1103: // instance data, list-specific node data, and maintain various pointers
        !          1104: // to these nodes.  The list is sorted via the insertion sort method where
        !          1105: // the programmer defines the list-specific sort function whose purpose is
        !          1106: // to compare two given nodes and return their relative sort location.  The
        !          1107: // list package in generalized in the sense that the list and node-specific
        !          1108: // data type is not known to this package at compile time or at runtime.
        !          1109: // The application programmer is merely responsible for defining the list
        !          1110: // and node-specific data structures and the sorting and optional searching
        !          1111: // functions and the list package keeps track of these nodes and provides
        !          1112: // easy access to them.
        !          1113: //
        !          1114: // DEB uses this list package to create three unique list types: process,
        !          1115: // thread and DLL lists.
        !          1116: //
        !          1117: // The backbone of the data structure is the process list.  The nodes of
        !          1118: // the process list are the individual debuggee processes.  DEB allows
        !          1119: // debugging (or should I say debug event browsing) of other processes that
        !          1120: // are spawned by the initial debuggee.  Thus each debug session may have
        !          1121: // multiple debuggees and thus the process becomes the logical node unit.
        !          1122: //
        !          1123: // A visual diagram of the process list is as follows:
        !          1124: //
        !          1125: //                 (ProcessList)
        !          1126: //                      |
        !          1127: //                      |
        !          1128: //                      v
        !          1129: //                 +-----------------+           +----------------------+
        !          1130: //                 | -ProcessList-   |           | -ListData-           |
        !          1131: //                 |                 |           |                      |
        !          1132: //                 | ListData--------+---------->| ActiveProcessCount=N |
        !          1133: //           +-----+-FirstNode       |           +----------------------+
        !          1134: //           |   +-+ CurrentNode     |
        !          1135: //           |   | | LastNode--------+-----------------------+
        !          1136: //           |   | | OrderFunction=& |                       |
        !          1137: //           |   | | ListError=0     |                       |
        !          1138: //           |   | +-----------------+                       |
        !          1139: //           |   |                                           |
        !          1140: //           |   +-------------------+                       |
        !          1141: //           |                       |                       |
        !          1142: //           v                       v                       v
        !          1143: //         +------------+     +------------+             +------------+
        !          1144: // NULL <- |ProcessNode1| <=> |ProcessNode2| <=> ... <=> |ProcessNodeN| -> NULL
        !          1145: //         +------------+     +------------+             +------------+
        !          1146: //
        !          1147: // Each process node also contains two lists: the thread list and the DLL list.
        !          1148: // This node also stores some of the relevent debug event information
        !          1149: // particular to the create process event.  Visually it is as follows:
        !          1150: //
        !          1151: //    +------------------+         +--------------+
        !          1152: //    | -ProcessNode-    | +------>| -ThreadList- |
        !          1153: //    |                  | |       +--------------+
        !          1154: //    | ProcessID=0      | |
        !          1155: //    | ThreadID=0       | |       +-----------+
        !          1156: //    | FileName=""      | |   +-->| -DllList- |
        !          1157: //    | PathName=""      | |   |   +-----------+
        !          1158: //    | ThreadList-------+-+   |
        !          1159: //    | DllList----------+-----+   +-------------------+
        !          1160: //    | ProcessDebugInfo-+-------->|-ProcessDebugInfo- |
        !          1161: //    +------------------+         +-------------------+
        !          1162: //
        !          1163: // Much like the process list, the visual diagram of the thread list is as
        !          1164: // follows:
        !          1165: //
        !          1166: //                 +-----------------+           +---------------------+
        !          1167: //                 | -ThreadList-    |           | -ListData-          |
        !          1168: //                 |                 |           |                     |
        !          1169: //                 | ListData--------+---------->| ActiveThreadCount=N |
        !          1170: //           +-----+-FirstNode       |           +---------------------+
        !          1171: //           |   +-+ CurrentNode     |
        !          1172: //           |   | | LastNode--------+-----------------------+
        !          1173: //           |   | | OrderFunction=& |                       |
        !          1174: //           |   | | ListError=0     |                       |
        !          1175: //           |   | +-----------------+                       |
        !          1176: //           |   |                                           |
        !          1177: //           |   +-------------------+                       |
        !          1178: //           |                       |                       |
        !          1179: //           v                       v                       v
        !          1180: //          +-----------+     +-----------+             +-----------+
        !          1181: //  NULL <- |ThreadNode1| <=> |ThreadNode2| <=> ... <=> |ThreadNodeN| -> NULL
        !          1182: //          +-----------+     +-----------+             +-----------+
        !          1183: //
        !          1184: // The thread nodes store some of the relevent debug event information
        !          1185: // particular to the create thread event.  Visually it is as follows:
        !          1186: //
        !          1187: //    +--------------------+
        !          1188: //    | -ThreadNode-       |
        !          1189: //    |                    |
        !          1190: //    | ProcessID=0        |
        !          1191: //    | ThreadID=0         |
        !          1192: //    | ThreadDebugInfo={} |
        !          1193: //    +--------------------+
        !          1194: //
        !          1195: // Much like the process and thread lists, the visual diagram of the Dll list
        !          1196: // is as follows:
        !          1197: //
        !          1198: //                 +-----------------+           +------------------+
        !          1199: //                 | -DllList-       |           | -ListData-       |
        !          1200: //                 |                 |           |                  |
        !          1201: //                 | ListData--------+---------->| ActiveDllCount=N |
        !          1202: //           +-----+-FirstNode       |           +------------------+
        !          1203: //           |   +-+ CurrentNode     |
        !          1204: //           |   | | LastNode--------+-----------------+
        !          1205: //           |   | | OrderFunction=& |                 |
        !          1206: //           |   | | ListError=0     |                 |
        !          1207: //           |   | +-----------------+                 |
        !          1208: //           |   |                                     |
        !          1209: //           |   +-------------+                       |
        !          1210: //           |                 |                       |
        !          1211: //           v                 v                       v
        !          1212: //          +--------+     +--------+             +--------+
        !          1213: //  NULL <- |DllNode1| <=> |DllNode2| <=> ... <=> |DllNodeN| -> NULL
        !          1214: //          +--------+     +--------+             +--------+
        !          1215: //
        !          1216: // The Dll nodes store some of the relevent debug event information particular
        !          1217: // to the Dll load event.  Visually it is as follows:
        !          1218: //
        !          1219: //    +----------------+
        !          1220: //    | -DllNode-      |
        !          1221: //    |                |
        !          1222: //    | FileName=""    |
        !          1223: //    | PathName=""    |
        !          1224: //    | DllDebugInfo={}|
        !          1225: //    +----------------+
        !          1226: //
        !          1227: // ========================================================================
        !          1228: 
        !          1229: // ------------------------------------------------------------------------
        !          1230: // Process list and node specific linked list wrapper functions
        !          1231: // ------------------------------------------------------------------------
        !          1232: 
        !          1233: 
        !          1234: // ************************************************************************
        !          1235: // FUNCTION : ProcessOrderFunction( PNODE, PNODE );
        !          1236: // PURPOSE  : Provides the sorting/search logic for the double linked
        !          1237: //            list package.
        !          1238: // COMMENTS :
        !          1239: //   Sorted by process ID value
        !          1240: // ************************************************************************
        !          1241: int
        !          1242: ProcessOrderFunction( PNODE pNode1, PNODE pNode2 )
        !          1243: {
        !          1244:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo1 = pNode1->pNodeData;
        !          1245:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo2 = pNode2->pNodeData;
        !          1246: 
        !          1247:   if( pProcessNodeInfo1->dwProcessId < pProcessNodeInfo2->dwProcessId )
        !          1248:     return( LIST_LEFT_OF );
        !          1249: 
        !          1250:   if( pProcessNodeInfo1->dwProcessId > pProcessNodeInfo2->dwProcessId )
        !          1251:     return( LIST_RIGHT_OF );
        !          1252: 
        !          1253:   return( LIST_MATCH );
        !          1254: }
        !          1255: 
        !          1256: 
        !          1257: // ************************************************************************
        !          1258: // FUNCTION : CreateProcessList( PLIST* )
        !          1259: // PURPOSE  :
        !          1260: // COMMENTS :
        !          1261: //
        !          1262: // ************************************************************************
        !          1263: BOOL
        !          1264: CreateProcessList( PLIST* ppProcessList )
        !          1265: {
        !          1266:   PDEB_PROCESS_LIST_INFO pProcessListInfo;
        !          1267: 
        !          1268:   //-- create list
        !          1269:   CreateList( ppProcessList, ProcessOrderFunction );
        !          1270: 
        !          1271:   //-- alloc info data
        !          1272:   pProcessListInfo = (PDEB_PROCESS_LIST_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1273:                                                 sizeof( DEB_PROCESS_LIST_INFO ) );
        !          1274:   (*ppProcessList)->pListData = pProcessListInfo;
        !          1275: 
        !          1276:   //-- init info data
        !          1277:   pProcessListInfo->dwActiveProcesses = 0;
        !          1278: 
        !          1279:   return( TRUE );
        !          1280: }
        !          1281: 
        !          1282: 
        !          1283: // ************************************************************************
        !          1284: // FUNCTION : DestroyProcessList( PLIST )
        !          1285: // PURPOSE  :
        !          1286: // COMMENTS :
        !          1287: //
        !          1288: // ************************************************************************
        !          1289: BOOL
        !          1290: DestroyProcessList( PLIST pProcessList )
        !          1291: {
        !          1292:   PDEB_PROCESS_LIST_INFO pProcessListInfo = pProcessList->pListData;
        !          1293:   PNODE                  pDeleteNode;
        !          1294: 
        !          1295:   //-- make sure all nodes are removed first
        !          1296:   while( pProcessListInfo->dwActiveProcesses ) {
        !          1297:     GetCurrentNode( pProcessList, &pDeleteNode );
        !          1298:     DeleteCurrentProcessNode( pProcessList );
        !          1299:   }
        !          1300: 
        !          1301:   //-- free info data
        !          1302:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pProcessListInfo );
        !          1303: 
        !          1304:   //-- destroy list
        !          1305:   DestroyList( pProcessList );
        !          1306: 
        !          1307:   return( TRUE );
        !          1308: }
        !          1309: 
        !          1310: 
        !          1311: // ************************************************************************
        !          1312: // FUNCTION : AllocProcessNode( PNODE*, PDEB_PROCESS_NODE_INFO* )
        !          1313: // PURPOSE  :
        !          1314: // COMMENTS :
        !          1315: //
        !          1316: // ************************************************************************
        !          1317: BOOL
        !          1318: AllocProcessNode( PNODE* ppProcessNode, PDEB_PROCESS_NODE_INFO* ppProcessNodeInfo )
        !          1319: {
        !          1320:   //-- create node
        !          1321:   CreateNode( ppProcessNode );
        !          1322: 
        !          1323:   //-- alloc info data
        !          1324:   *ppProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1325:                                               sizeof( DEB_PROCESS_NODE_INFO ) );
        !          1326:   (*ppProcessNode)->pNodeData = *(ppProcessNodeInfo);
        !          1327: 
        !          1328:   (*ppProcessNodeInfo)->lpstrFileName = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL,
        !          1329:                                                (DWORD) MAX_PATH );
        !          1330:   (*ppProcessNodeInfo)->lpstrPathName = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL,
        !          1331:                                                (DWORD) MAX_PATH );
        !          1332:   CreateThreadList( &((*ppProcessNodeInfo)->pThreadList) );
        !          1333:   CreateDllList( &((*ppProcessNodeInfo)->pDllList) );
        !          1334: 
        !          1335:   return( TRUE );
        !          1336: }
        !          1337: 
        !          1338: 
        !          1339: // ************************************************************************
        !          1340: // FUNCTION : InitProcessNodeInfo( PDEB_PROCESS_NODE_INFO*, LPDEBUG_EVENT )
        !          1341: // PURPOSE  :
        !          1342: // COMMENTS :
        !          1343: //
        !          1344: // ************************************************************************
        !          1345: BOOL
        !          1346: InitProcessNodeInfo( PDEB_PROCESS_NODE_INFO* ppProcessNodeInfo, LPDEBUG_EVENT lpDebugEvent )
        !          1347: {
        !          1348:   //-- init info data
        !          1349:   (*ppProcessNodeInfo)->dwProcessId = lpDebugEvent->dwProcessId;
        !          1350:   (*ppProcessNodeInfo)->dwThreadId  = lpDebugEvent->dwThreadId;
        !          1351:   // Note:pThreadList initialized via previous CreateThreadList() call
        !          1352:   // Note:pDllList initialized via previous CreateDllList() call
        !          1353:   (*ppProcessNodeInfo)->ProcessDebugInfo = lpDebugEvent->u.CreateProcessInfo;
        !          1354: 
        !          1355:   return( TRUE );
        !          1356: }
        !          1357: 
        !          1358: 
        !          1359: // ************************************************************************
        !          1360: // FUNCTION : InsertProcessNode( PLIST, PNODE )
        !          1361: // PURPOSE  :
        !          1362: // COMMENTS :
        !          1363: //
        !          1364: // ************************************************************************
        !          1365: BOOL
        !          1366: InsertProcessNode( PLIST pProcessList, PNODE pProcessNode )
        !          1367: {
        !          1368:   PDEB_PROCESS_LIST_INFO pProcessListInfo = pProcessList->pListData;
        !          1369: 
        !          1370:   //-- insert the node
        !          1371:   InsertNode( pProcessList, pProcessNode );
        !          1372: 
        !          1373:   //-- increment dwActiveProcesss
        !          1374:   pProcessListInfo->dwActiveProcesses++;
        !          1375: 
        !          1376:   return( TRUE );
        !          1377: }
        !          1378: 
        !          1379: 
        !          1380: // ************************************************************************
        !          1381: // FUNCTION : SetCurrentProcessNode( PLIST, PNODE )
        !          1382: // PURPOSE  :
        !          1383: // COMMENTS :
        !          1384: //
        !          1385: // ************************************************************************
        !          1386: BOOL
        !          1387: SetCurrentProcessNode( PLIST pProcessList, PNODE pProcessNode )
        !          1388: {
        !          1389:   SetCurrentNode( pProcessList, pProcessNode, pProcessList->OrderFunction );
        !          1390: 
        !          1391:   return( TRUE );
        !          1392: }
        !          1393: 
        !          1394: 
        !          1395: // ************************************************************************
        !          1396: // FUNCTION : DeleteProcessNode( PLIST, PNODE )
        !          1397: // PURPOSE  :
        !          1398: // COMMENTS :
        !          1399: //
        !          1400: // ************************************************************************
        !          1401: BOOL
        !          1402: DeleteProcessNode( PLIST pProcessList, PNODE pProcessNode )
        !          1403: {
        !          1404:   PNODE pDeleteNode;
        !          1405: 
        !          1406:   SetCurrentNode( pProcessList, pProcessNode, pProcessList->OrderFunction );
        !          1407:   GetCurrentNode( pProcessList, &pDeleteNode );
        !          1408:   DeleteCurrentProcessNode( pProcessList );
        !          1409: 
        !          1410:   return( TRUE );
        !          1411: }
        !          1412: 
        !          1413: 
        !          1414: // ************************************************************************
        !          1415: // FUNCTION : FreeProcessNodeInfo( PNODE )
        !          1416: // PURPOSE  :
        !          1417: // COMMENTS :
        !          1418: //
        !          1419: // ************************************************************************
        !          1420: BOOL
        !          1421: FreeProcessNodeInfo( PNODE pProcessNode )
        !          1422: {
        !          1423:   PDEB_PROCESS_NODE_INFO pProcessNodeInfo = (PDEB_PROCESS_NODE_INFO) pProcessNode->pNodeData;
        !          1424: 
        !          1425:   //-- free info data
        !          1426:   DestroyDllList( pProcessNodeInfo->pDllList );
        !          1427:   DestroyThreadList( pProcessNodeInfo->pThreadList );
        !          1428:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pProcessNodeInfo->lpstrPathName );
        !          1429:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pProcessNodeInfo->lpstrFileName );
        !          1430:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pProcessNodeInfo );
        !          1431: 
        !          1432:   return( TRUE );
        !          1433: }
        !          1434: 
        !          1435: 
        !          1436: // ************************************************************************
        !          1437: // FUNCTION : DestroyProcessNode( PNODE )
        !          1438: // PURPOSE  :
        !          1439: // COMMENTS : Frees all memory associated with the node.
        !          1440: // ************************************************************************
        !          1441: BOOL
        !          1442: DestroyProcessNode( PNODE pProcessNode )
        !          1443: {
        !          1444:   //-- free info data
        !          1445:   FreeProcessNodeInfo( pProcessNode );
        !          1446: 
        !          1447:   //-- destroy node
        !          1448:   DestroyNode( pProcessNode );
        !          1449: 
        !          1450:   return( TRUE );
        !          1451: }
        !          1452: 
        !          1453: 
        !          1454: // ************************************************************************
        !          1455: // FUNCTION : DeleteCurrentProcessNode( PLIST )
        !          1456: // PURPOSE  :
        !          1457: // COMMENTS :
        !          1458: //
        !          1459: // ************************************************************************
        !          1460: BOOL
        !          1461: DeleteCurrentProcessNode( PLIST pProcessList )
        !          1462: {
        !          1463:   PDEB_PROCESS_LIST_INFO pProcessListInfo = pProcessList->pListData;
        !          1464:   PNODE                  pProcessNode = (PNODE) pProcessList->pCurrentNode;
        !          1465: 
        !          1466:   //-- free info data
        !          1467:   FreeProcessNodeInfo( pProcessNode );
        !          1468: 
        !          1469:   //-- delete and destroy node
        !          1470:   DeleteCurrentNode( pProcessList );
        !          1471: 
        !          1472:   //-- decrement dwActiveProcesss
        !          1473:   pProcessListInfo->dwActiveProcesses--;
        !          1474: 
        !          1475:   return( TRUE );
        !          1476: }
        !          1477: 
        !          1478: 
        !          1479: // ------------------------------------------------------------------------
        !          1480: // Thread list and node specific linked list wrapper functions
        !          1481: // ------------------------------------------------------------------------
        !          1482: 
        !          1483: 
        !          1484: // ************************************************************************
        !          1485: // FUNCTION : ThreadOrderFunction( PNODE, PNODE );
        !          1486: // PURPOSE  : Provides the sorting/search logic for the double linked
        !          1487: //            list package.
        !          1488: // COMMENTS :
        !          1489: //   Sorted by thread ID value
        !          1490: // ************************************************************************
        !          1491: int
        !          1492: ThreadOrderFunction( PNODE pNode1, PNODE pNode2 )
        !          1493: {
        !          1494:   PDEB_THREAD_NODE_INFO pThreadNodeInfo1 = pNode1->pNodeData;
        !          1495:   PDEB_THREAD_NODE_INFO pThreadNodeInfo2 = pNode2->pNodeData;
        !          1496: 
        !          1497:   if( pThreadNodeInfo1->dwThreadId < pThreadNodeInfo2->dwThreadId )
        !          1498:     return( LIST_LEFT_OF );
        !          1499: 
        !          1500:   if( pThreadNodeInfo1->dwThreadId > pThreadNodeInfo2->dwThreadId )
        !          1501:     return( LIST_RIGHT_OF );
        !          1502: 
        !          1503:   return( LIST_MATCH );
        !          1504: }
        !          1505: 
        !          1506: 
        !          1507: // ************************************************************************
        !          1508: // FUNCTION : CreateThreadList( PLIST* )
        !          1509: // PURPOSE  :
        !          1510: // COMMENTS :
        !          1511: //
        !          1512: // ************************************************************************
        !          1513: BOOL
        !          1514: CreateThreadList( PLIST* ppThreadList )
        !          1515: {
        !          1516:   PDEB_THREAD_LIST_INFO pThreadListInfo;
        !          1517: 
        !          1518:   //-- create list
        !          1519:   CreateList( ppThreadList, ThreadOrderFunction );
        !          1520: 
        !          1521:   //-- alloc info data
        !          1522:   pThreadListInfo = (PDEB_THREAD_LIST_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1523:                                                 sizeof( DEB_THREAD_LIST_INFO ) );
        !          1524:   (*ppThreadList)->pListData = pThreadListInfo;
        !          1525: 
        !          1526:   //-- init info data
        !          1527:   pThreadListInfo->dwActiveThreads = 0;
        !          1528: 
        !          1529:   return( TRUE );
        !          1530: }
        !          1531: 
        !          1532: 
        !          1533: // ************************************************************************
        !          1534: // FUNCTION : DestroyThreadList( PLIST )
        !          1535: // PURPOSE  :
        !          1536: // COMMENTS :
        !          1537: //
        !          1538: // ************************************************************************
        !          1539: BOOL
        !          1540: DestroyThreadList( PLIST pThreadList )
        !          1541: {
        !          1542:   PDEB_THREAD_LIST_INFO pThreadListInfo = pThreadList->pListData;
        !          1543:   PNODE                 pDeleteNode;
        !          1544: 
        !          1545:   //-- make sure all nodes are removed first
        !          1546:   while( pThreadListInfo->dwActiveThreads ) {
        !          1547:     GetCurrentNode( pThreadList, &pDeleteNode );
        !          1548:     DeleteCurrentThreadNode( pThreadList );
        !          1549:   }
        !          1550: 
        !          1551:   //-- free info data
        !          1552:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pThreadListInfo );
        !          1553: 
        !          1554:   //-- destroy list
        !          1555:   DestroyList( pThreadList );
        !          1556: 
        !          1557:   return( TRUE );
        !          1558: }
        !          1559: 
        !          1560: 
        !          1561: // ************************************************************************
        !          1562: // FUNCTION : AllocThreadNode( PNODE*, PDEB_THREAD_NODE_INFO* )
        !          1563: // PURPOSE  :
        !          1564: // COMMENTS :
        !          1565: //
        !          1566: // ************************************************************************
        !          1567: BOOL
        !          1568: AllocThreadNode( PNODE* ppThreadNode, PDEB_THREAD_NODE_INFO* ppThreadNodeInfo )
        !          1569: {
        !          1570:   //-- create node
        !          1571:   CreateNode( ppThreadNode );
        !          1572: 
        !          1573:   //-- alloc info data
        !          1574:   *ppThreadNodeInfo = (PDEB_THREAD_NODE_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1575:                                             (DWORD) sizeof( DEB_THREAD_NODE_INFO ) );
        !          1576:   (*ppThreadNode)->pNodeData = *(ppThreadNodeInfo);
        !          1577: 
        !          1578:   return( TRUE );
        !          1579: }
        !          1580: 
        !          1581: 
        !          1582: // ************************************************************************
        !          1583: // FUNCTION : InitThreadNodeInfo( PDEB_THREAD_NODE_INFO*, LPDEBUG_EVENT )
        !          1584: // PURPOSE  :
        !          1585: // COMMENTS :
        !          1586: //
        !          1587: // ************************************************************************
        !          1588: BOOL
        !          1589: InitThreadNodeInfo( PDEB_THREAD_NODE_INFO* ppThreadNodeInfo,
        !          1590:   LPDEBUG_EVENT lpDebugEvent )
        !          1591: {
        !          1592:   //-- init info data
        !          1593:   (*ppThreadNodeInfo)->dwProcessId     = lpDebugEvent->dwProcessId;
        !          1594:   (*ppThreadNodeInfo)->dwThreadId      = lpDebugEvent->dwThreadId;
        !          1595:   (*ppThreadNodeInfo)->ThreadDebugInfo = lpDebugEvent->u.CreateThread;
        !          1596: 
        !          1597:   return( TRUE );
        !          1598: }
        !          1599: 
        !          1600: 
        !          1601: // ************************************************************************
        !          1602: // FUNCTION : InsertThreadNode( PLIST, PNODE )
        !          1603: // PURPOSE  :
        !          1604: // COMMENTS :
        !          1605: //
        !          1606: // ************************************************************************
        !          1607: BOOL
        !          1608: InsertThreadNode( PLIST pThreadList, PNODE pThreadNode )
        !          1609: {
        !          1610:   PDEB_THREAD_LIST_INFO pThreadListInfo = (PDEB_THREAD_LIST_INFO) pThreadList->pListData;
        !          1611: 
        !          1612:   //-- insert the thread node
        !          1613:   InsertNode( pThreadList, pThreadNode );
        !          1614: 
        !          1615:   //-- increment dwActiveThreads
        !          1616:   pThreadListInfo->dwActiveThreads++;
        !          1617: 
        !          1618:   return( TRUE );
        !          1619: }
        !          1620: 
        !          1621: 
        !          1622: // ************************************************************************
        !          1623: // FUNCTION : SetCurrentThreadNode( PLIST, PNODE )
        !          1624: // PURPOSE  :
        !          1625: // COMMENTS :
        !          1626: //
        !          1627: // ************************************************************************
        !          1628: BOOL
        !          1629: SetCurrentThreadNode( PLIST pThreadList, PNODE pThreadNode )
        !          1630: {
        !          1631:   SetCurrentNode( pThreadList, pThreadNode, pThreadList->OrderFunction );
        !          1632: 
        !          1633:   return( TRUE );
        !          1634: }
        !          1635: 
        !          1636: 
        !          1637: // ************************************************************************
        !          1638: // FUNCTION : DeleteThreadNode( PLIST, PNODE )
        !          1639: // PURPOSE  :
        !          1640: // COMMENTS :
        !          1641: //
        !          1642: // ************************************************************************
        !          1643: BOOL
        !          1644: DeleteThreadNode( PLIST pThreadList, PNODE pThreadNode )
        !          1645: {
        !          1646:   PNODE pDeleteNode;
        !          1647: 
        !          1648:   SetCurrentNode( pThreadList, pThreadNode, pThreadList->OrderFunction );
        !          1649:   GetCurrentNode( pThreadList, &pDeleteNode );
        !          1650:   DeleteCurrentThreadNode( pThreadList );
        !          1651: 
        !          1652:   return( TRUE );
        !          1653: }
        !          1654: 
        !          1655: 
        !          1656: // ************************************************************************
        !          1657: // FUNCTION : FreeThreadNodeInfo( PNODE )
        !          1658: // PURPOSE  :
        !          1659: // COMMENTS :
        !          1660: //
        !          1661: // ************************************************************************
        !          1662: BOOL
        !          1663: FreeThreadNodeInfo( PNODE pThreadNode )
        !          1664: {
        !          1665:   PDEB_THREAD_NODE_INFO pThreadNodeInfo = (PDEB_THREAD_NODE_INFO) pThreadNode->pNodeData;
        !          1666: 
        !          1667:   //-- free info data
        !          1668:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pThreadNodeInfo );
        !          1669: 
        !          1670:   return( TRUE );
        !          1671: }
        !          1672: 
        !          1673: 
        !          1674: // ************************************************************************
        !          1675: // FUNCTION : DestroyThreadNode( PNODE )
        !          1676: // PURPOSE  :
        !          1677: // COMMENTS : Frees all memory associated with the node.
        !          1678: // ************************************************************************
        !          1679: BOOL
        !          1680: DestroyThreadNode( PNODE pThreadNode )
        !          1681: {
        !          1682:   //-- free info data
        !          1683:   FreeThreadNodeInfo( pThreadNode );
        !          1684: 
        !          1685:   //-- destroy node
        !          1686:   DestroyNode( pThreadNode );
        !          1687: 
        !          1688:   return( TRUE );
        !          1689: }
        !          1690: 
        !          1691: 
        !          1692: // ************************************************************************
        !          1693: // FUNCTION : DeleteCurrentThreadNode( PLIST )
        !          1694: // PURPOSE  :
        !          1695: // COMMENTS :
        !          1696: //
        !          1697: // ************************************************************************
        !          1698: BOOL
        !          1699: DeleteCurrentThreadNode( PLIST pThreadList )
        !          1700: {
        !          1701:   PDEB_THREAD_LIST_INFO pThreadListInfo = pThreadList->pListData;
        !          1702:   PNODE                 pThreadNode = (PNODE) pThreadList->pCurrentNode;
        !          1703: 
        !          1704:   //-- free info data
        !          1705:   FreeThreadNodeInfo( pThreadNode );
        !          1706: 
        !          1707:   //-- delete and destroy node
        !          1708:   DeleteCurrentNode( pThreadList );
        !          1709: 
        !          1710:   //-- decrement dwActiveThreads
        !          1711:   pThreadListInfo->dwActiveThreads--;
        !          1712: 
        !          1713:   return( TRUE );
        !          1714: }
        !          1715: 
        !          1716: 
        !          1717: // ------------------------------------------------------------------------
        !          1718: // DLL list and node specific linked list wrapper functions
        !          1719: // ------------------------------------------------------------------------
        !          1720: 
        !          1721: 
        !          1722: // ************************************************************************
        !          1723: // FUNCTION : DllOrderFunction( PNODE, PNODE );
        !          1724: // PURPOSE  : Provides the sorting/search logic for the double linked
        !          1725: //            list package.
        !          1726: // COMMENTS :
        !          1727: //   Sorted by base address of the DLL
        !          1728: // ************************************************************************
        !          1729: int
        !          1730: DllOrderFunction( PNODE pNode1, PNODE pNode2 )
        !          1731: {
        !          1732:   PDEB_DLL_NODE_INFO pDllNodeInfo1 = pNode1->pNodeData;
        !          1733:   PDEB_DLL_NODE_INFO pDllNodeInfo2 = pNode2->pNodeData;
        !          1734: 
        !          1735:   if( pDllNodeInfo1->DllDebugInfo.lpBaseOfDll < pDllNodeInfo2->DllDebugInfo.lpBaseOfDll )
        !          1736:     return( LIST_LEFT_OF );
        !          1737: 
        !          1738:   if( pDllNodeInfo1->DllDebugInfo.lpBaseOfDll > pDllNodeInfo2->DllDebugInfo.lpBaseOfDll )
        !          1739:     return( LIST_RIGHT_OF );
        !          1740: 
        !          1741:   return( LIST_MATCH );
        !          1742: }
        !          1743: 
        !          1744: 
        !          1745: // ************************************************************************
        !          1746: // FUNCTION : CreateDllList( PLIST* )
        !          1747: // PURPOSE  :
        !          1748: // COMMENTS :
        !          1749: //
        !          1750: // ************************************************************************
        !          1751: BOOL
        !          1752: CreateDllList( PLIST* ppDllList )
        !          1753: {
        !          1754:   PDEB_DLL_LIST_INFO pDllListInfo;
        !          1755: 
        !          1756:   //-- create list
        !          1757:   CreateList( ppDllList, DllOrderFunction );
        !          1758: 
        !          1759:   //-- alloc info data
        !          1760:   pDllListInfo = (PDEB_DLL_LIST_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1761:                                                 sizeof( DEB_DLL_LIST_INFO ) );
        !          1762:   (*ppDllList)->pListData = pDllListInfo;
        !          1763: 
        !          1764:   //-- init info data
        !          1765:   pDllListInfo->dwActiveDlls = 0;
        !          1766: 
        !          1767:   return( TRUE );
        !          1768: }
        !          1769: 
        !          1770: 
        !          1771: // ************************************************************************
        !          1772: // FUNCTION : DestroyDllList( PLIST )
        !          1773: // PURPOSE  :
        !          1774: // COMMENTS :
        !          1775: //
        !          1776: // ************************************************************************
        !          1777: BOOL
        !          1778: DestroyDllList( PLIST pDllList )
        !          1779: {
        !          1780:   PDEB_DLL_LIST_INFO pDllListInfo = pDllList->pListData;
        !          1781:   PNODE              pDeleteNode;
        !          1782: 
        !          1783:   //-- make sure all nodes are removed first
        !          1784:   while( pDllListInfo->dwActiveDlls ) {
        !          1785:     GetCurrentNode( pDllList, &pDeleteNode );
        !          1786:     DeleteCurrentDllNode( pDllList );
        !          1787:   }
        !          1788: 
        !          1789:   //-- free list data and destroy the list
        !          1790:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pDllListInfo );
        !          1791:   DestroyList( pDllList );
        !          1792: 
        !          1793:   return( TRUE );
        !          1794: }
        !          1795: 
        !          1796: 
        !          1797: // ************************************************************************
        !          1798: // FUNCTION : AllocDllNode( PNODE*, PDEB_DLL_NODE_INFO* )
        !          1799: // PURPOSE  :
        !          1800: // COMMENTS :
        !          1801: //
        !          1802: // ************************************************************************
        !          1803: BOOL
        !          1804: AllocDllNode( PNODE* ppDllNode, PDEB_DLL_NODE_INFO* ppDllNodeInfo )
        !          1805: {
        !          1806:   //-- create node
        !          1807:   CreateNode( ppDllNode );
        !          1808: 
        !          1809:   //-- alloc info data
        !          1810:   *ppDllNodeInfo = (PDEB_DLL_NODE_INFO) HeapAlloc( hHeap, (DWORD) NULL,
        !          1811:                                       sizeof( DEB_DLL_NODE_INFO ) );
        !          1812:   (*ppDllNode)->pNodeData = *(ppDllNodeInfo);
        !          1813:   (*ppDllNodeInfo)->lpstrFileName = (LPTSTR) HeapAlloc( hHeap, (DWORD) NULL, (DWORD) MAX_PATH );
        !          1814: 
        !          1815:   return( TRUE );
        !          1816: }
        !          1817: 
        !          1818: 
        !          1819: // ************************************************************************
        !          1820: // FUNCTION : InitDllNodeInfo( PDEB_DLL_NODE_INFO*, LPDEBUG_EVENT )
        !          1821: // PURPOSE  :
        !          1822: // COMMENTS :
        !          1823: //
        !          1824: // ************************************************************************
        !          1825: BOOL
        !          1826: InitDllNodeInfo( PDEB_DLL_NODE_INFO* ppDllNodeInfo,
        !          1827:   LPDEBUG_EVENT lpDebugEvent )
        !          1828: {
        !          1829:   //-- init info data
        !          1830:   GetDllFileName( lpDebugEvent, (*ppDllNodeInfo)->lpstrFileName, MAX_PATH );
        !          1831:   (*ppDllNodeInfo)->DllDebugInfo = lpDebugEvent->u.LoadDll;
        !          1832: 
        !          1833:   return( TRUE );
        !          1834: }
        !          1835: 
        !          1836: 
        !          1837: // ************************************************************************
        !          1838: // FUNCTION : InsertDllNode( PLIST, PNODE )
        !          1839: // PURPOSE  :
        !          1840: // COMMENTS :
        !          1841: //
        !          1842: // ************************************************************************
        !          1843: BOOL
        !          1844: InsertDllNode( PLIST pDllList, PNODE pDllNode )
        !          1845: {
        !          1846:   PDEB_DLL_LIST_INFO pDllListInfo = pDllList->pListData;
        !          1847: 
        !          1848:   // insert the node
        !          1849:   InsertNode( pDllList, pDllNode );
        !          1850: 
        !          1851:   //-- increment dwActiveDlls
        !          1852:   pDllListInfo->dwActiveDlls++;
        !          1853: 
        !          1854:   return( TRUE );
        !          1855: }
        !          1856: 
        !          1857: 
        !          1858: // ************************************************************************
        !          1859: // FUNCTION : SetCurrentDllNode( PLIST, PNODE )
        !          1860: // PURPOSE  :
        !          1861: // COMMENTS :
        !          1862: //
        !          1863: // ************************************************************************
        !          1864: BOOL
        !          1865: SetCurrentDllNode( PLIST pDllList, PNODE pDllNode )
        !          1866: {
        !          1867:   SetCurrentNode( pDllList, pDllNode, pDllList->OrderFunction );
        !          1868: 
        !          1869:   return( TRUE );
        !          1870: }
        !          1871: 
        !          1872: 
        !          1873: // ************************************************************************
        !          1874: // FUNCTION : DeleteDllNode( PLIST, PNODE )
        !          1875: // PURPOSE  :
        !          1876: // COMMENTS :
        !          1877: //
        !          1878: // ************************************************************************
        !          1879: BOOL
        !          1880: DeleteDllNode( PLIST pDllList, PNODE pDllNode )
        !          1881: {
        !          1882:   PNODE pDeleteNode;
        !          1883: 
        !          1884:   SetCurrentNode( pDllList, pDllNode, pDllList->OrderFunction );
        !          1885:   GetCurrentNode( pDllList, &pDeleteNode );
        !          1886:   DeleteCurrentDllNode( pDllList );
        !          1887: 
        !          1888:   return( TRUE );
        !          1889: }
        !          1890: 
        !          1891: 
        !          1892: // ************************************************************************
        !          1893: // FUNCTION : FreeDllNodeInfo( PNODE )
        !          1894: // PURPOSE  :
        !          1895: // COMMENTS :
        !          1896: //
        !          1897: // ************************************************************************
        !          1898: BOOL
        !          1899: FreeDllNodeInfo( PNODE pDllNode )
        !          1900: {
        !          1901:   PDEB_DLL_NODE_INFO pDllNodeInfo = (PDEB_DLL_NODE_INFO) pDllNode->pNodeData;
        !          1902: 
        !          1903:   //-- free info data
        !          1904:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pDllNodeInfo->lpstrFileName );
        !          1905:   HeapFree( hHeap, (DWORD) NULL, (PVOID) pDllNodeInfo );
        !          1906: 
        !          1907:   return( TRUE );
        !          1908: }
        !          1909: 
        !          1910: 
        !          1911: // ************************************************************************
        !          1912: // FUNCTION : DestroyDllNode( PNODE )
        !          1913: // PURPOSE  :
        !          1914: // COMMENTS : Frees all memory associated with the node.
        !          1915: // ************************************************************************
        !          1916: BOOL
        !          1917: DestroyDllNode( PNODE pDllNode )
        !          1918: {
        !          1919:   //-- free info data
        !          1920:   FreeDllNodeInfo( pDllNode );
        !          1921: 
        !          1922:   //-- destroy node
        !          1923:   DestroyNode( pDllNode );
        !          1924: 
        !          1925:   return( TRUE );
        !          1926: }
        !          1927: 
        !          1928: 
        !          1929: // ************************************************************************
        !          1930: // FUNCTION : DeleteCurrentDllNode( PLIST )
        !          1931: // PURPOSE  :
        !          1932: // COMMENTS : Deletes the current DLL node from the list and frees all
        !          1933: //            memory associated with it.
        !          1934: // ************************************************************************
        !          1935: BOOL
        !          1936: DeleteCurrentDllNode( PLIST pDllList )
        !          1937: {
        !          1938:   PDEB_DLL_LIST_INFO pDllListInfo = pDllList->pListData;
        !          1939:   PNODE              pDllNode = (PNODE) pDllList->pCurrentNode;
        !          1940: 
        !          1941:   //-- free info data
        !          1942:   FreeDllNodeInfo( pDllNode );
        !          1943: 
        !          1944:   //-- delete and destroy node
        !          1945:   DeleteCurrentNode( pDllList );
        !          1946: 
        !          1947:   //-- decrement dwActiveDlls
        !          1948:   pDllListInfo->dwActiveDlls--;
        !          1949: 
        !          1950:   return( TRUE );
        !          1951: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.