|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.