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

1.1       root        1: // ************************************************************************
1.1.1.2 ! root        2: //
        !             3: //                      Microsoft Developer Support
        !             4: //               Copyright (c) 1992 Microsoft Corporation
        !             5: //
        !             6: // ************************************************************************
        !             7: // MODULE    : DEBDebug.C
1.1       root        8: // PURPOSE   : Debug support functions for the Debug Event Browser
                      9: // FUNCTIONS :
                     10: //   DbgEventThread()              - debug event processing thread
                     11: //   GetModuleFileNameFromHeader() - get the module name
1.1.1.2 ! root       12: //   SkipBreakPoint()              - skips over the break point in the
        !            13: //                                   debugee (R4000 only)
1.1       root       14: // COMMENTS  :
1.1.1.2 ! root       15: //
1.1       root       16: // ************************************************************************
1.1.1.2 ! root       17: #define   STRICT
1.1       root       18: #include <Windows.H>
                     19: 
                     20: #include "LinkList.H"
                     21: #include "DEBMain.H"
                     22: #include "DEBMisc.H"
                     23: #include "DEBDebug.H"
                     24: 
1.1.1.2 ! root       25: //-- internal fucntion prototypes
        !            26: DWORD WINAPI GetModuleFileNameFromHeader( HANDLE, HANDLE, LPTSTR, DWORD );
        !            27: #if( MIPS == 1 )
        !            28:  BOOL  SkipBreakPoint( DWORD );
        !            29: #endif
1.1       root       30: 
                     31: // ************************************************************************
                     32: // FUNCTION : DebugEventThread( LPCTSTR  )
                     33: // PURPOSE  : Main debug event processing loop
1.1.1.2 ! root       34: // COMMENTS :
        !            35: //   A new debug event thread is created for each debugee process.
        !            36: //   DebugeeFileName may be the process ID of an active process or the
        !            37: //   name of a process to create.
1.1       root       38: // ************************************************************************
1.1.1.2 ! root       39: DWORD WINAPI
1.1       root       40: DebugEventThread( LPCTSTR DebugeeFileName )
                     41: {
1.1.1.2 ! root       42:   #define STRING_BUFSIZ 256
        !            43: 
1.1       root       44:   static BOOL  fFirstTime = TRUE;
1.1.1.2 ! root       45:   static TCHAR szDebugeeTitle[128];
1.1       root       46:   static PNODE ThreadNode;          // used for inserting new thread nodes
                     47: 
                     48:   PNODE        TempNode;            // used for queries on thread linked list
                     49:   DEBUG_EVENT  DebugEvent;
1.1.1.2 ! root       50:   TCHAR        szDebugEventBuffer[STRING_BUFSIZ];
        !            51:   TCHAR        szTempBuf[STRING_BUFSIZ];
1.1       root       52:   DWORD        NumberOfBytesRead;
                     53: 
                     54:   //-- temporary thread info node used for queries
                     55:   CreateNode( &ProcessList, &TempNode );
                     56: 
                     57:   //-- determine if 'attach to' or 'open' debugee
                     58:   //   DebugeeFileName may be dwProcessId and an actual filename
                     59:   if( !DebugActiveProcess( (DWORD) DebugeeFileName ) ) {
                     60: 
1.1.1.2 ! root       61:     STARTUPINFO   StartInfo;
        !            62:     LPSTARTUPINFO lpStartInfo = &StartInfo;
        !            63: 
        !            64:     PROCESS_INFORMATION   ProcessInfo;
        !            65:     LPPROCESS_INFORMATION lpProcessInfo = &ProcessInfo;
        !            66: 
        !            67:     if( fFirstTime ) {
        !            68:       LoadString( hInstance, IDS_OFN_DEBUGEE_TITLE, szDebugeeTitle,
        !            69:         sizeof(szDebugeeTitle)/sizeof(TCHAR) );
        !            70:     }
        !            71: 
        !            72:     lpStartInfo->cb          = sizeof( STARTUPINFO );
        !            73:     lpStartInfo->lpDesktop   = NULL;
        !            74:     lpStartInfo->lpTitle     = szDebugeeTitle;
        !            75:     lpStartInfo->dwX         = 0;
        !            76:     lpStartInfo->dwY         = 0;
        !            77:     lpStartInfo->dwXSize     = 0;
        !            78:     lpStartInfo->dwYSize     = 0;
        !            79:     lpStartInfo->dwFlags     = NULL;
        !            80:     lpStartInfo->wShowWindow = SW_SHOWDEFAULT;
        !            81: 
        !            82:     lpProcessInfo->hProcess = NULL;
        !            83: 
1.1       root       84:     //-- create the debugee process instead
                     85:     if( !CreateProcess(
                     86:            NULL,
                     87:            DebugeeFileName,
                     88:            (LPSECURITY_ATTRIBUTES) NULL,
                     89:            (LPSECURITY_ATTRIBUTES) NULL,
                     90:            TRUE,
                     91:            DebugMode | DebugeePriority | CREATE_NEW_CONSOLE,
                     92:            (LPVOID) NULL,
                     93:            (LPTSTR) NULL,
1.1.1.2 ! root       94:            &StartInfo, &ProcessInfo ) ) {
1.1       root       95: 
1.1.1.2 ! root       96:       ErrorBox( "Failed", "CreateProcess()", __FILE__, __LINE__ );
        !            97:       ExitThread( FALSE );
1.1       root       98: 
                     99:     }
                    100:     else {
                    101: 
1.1.1.2 ! root      102:       hProcess = ProcessInfo.hProcess;
        !           103:       CloseHandle( ProcessInfo.hProcess );
        !           104:       CloseHandle( ProcessInfo.hThread );
1.1       root      105: 
                    106:     }
                    107:   }
                    108: 
                    109:   for(;;) {
                    110:     if( !WaitForDebugEvent( &DebugEvent, (DWORD) -1L ) ) {
                    111:       ListBoxPrintF( "%s", "Waiting..." );
                    112:       continue;
                    113:   }
                    114: 
                    115:     switch( DebugEvent.dwDebugEventCode ) {
                    116: 
                    117:       case EXCEPTION_DEBUG_EVENT:
                    118:         MakeDebugEventString( szDebugEventBuffer, "Exception:",
                    119:           &DebugEvent);
                    120: 
                    121:         switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
                    122: 
                    123:           case EXCEPTION_ACCESS_VIOLATION:
1.1.1.2 ! root      124:             lstrcat(szDebugEventBuffer, "ACCESS_VIOLATION");
1.1       root      125:             break;
                    126: 
                    127:           case EXCEPTION_BREAKPOINT:
1.1.1.2 ! root      128:             lstrcat(szDebugEventBuffer, "BREAKPOINT");
1.1       root      129:             break;
                    130: 
                    131:           case EXCEPTION_DATATYPE_MISALIGNMENT:
1.1.1.2 ! root      132:             lstrcat(szDebugEventBuffer, "DATATYPE_MISALIGNMENT");
1.1       root      133:             break;
                    134: 
                    135:           case EXCEPTION_SINGLE_STEP:
1.1.1.2 ! root      136:             lstrcat(szDebugEventBuffer, "SINGLE_STEP");
1.1       root      137:             break;
                    138: 
                    139:           case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1.1.1.2 ! root      140:             lstrcat(szDebugEventBuffer, "ARRAY_BOUNDS_EXCEEDED");
1.1       root      141:             break;
                    142: 
                    143:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:
1.1.1.2 ! root      144:             lstrcat(szDebugEventBuffer, "FLT_DIVIDE_BY_ZERO");
1.1       root      145:             break;
                    146: 
                    147:           case EXCEPTION_FLT_INVALID_OPERATION:
1.1.1.2 ! root      148:             lstrcat(szDebugEventBuffer, "FLT_INVALID_OPERATION");
1.1       root      149:             break;
                    150: 
                    151:           case EXCEPTION_FLT_OVERFLOW:
1.1.1.2 ! root      152:             lstrcat(szDebugEventBuffer, "FLT_OVERFLOW");
1.1       root      153:             break;
                    154: 
                    155:           case EXCEPTION_FLT_STACK_CHECK:
1.1.1.2 ! root      156:             lstrcat(szDebugEventBuffer, "FLT_STACK_CHECK");
1.1       root      157:             break;
                    158: 
                    159:           case EXCEPTION_FLT_UNDERFLOW:
1.1.1.2 ! root      160:             lstrcat(szDebugEventBuffer, "FLT_UNDERFLOW");
1.1       root      161:             break;
                    162: 
                    163:           case EXCEPTION_INT_DIVIDE_BY_ZERO:
1.1.1.2 ! root      164:             lstrcat(szDebugEventBuffer, "INT_DIVIDE_BY_ZERO");
1.1       root      165:             break;
                    166: 
                    167:           case EXCEPTION_INT_OVERFLOW:
1.1.1.2 ! root      168:             lstrcat(szDebugEventBuffer, "INT_OVERFLOW");
1.1       root      169:             break;
                    170: 
                    171:           case EXCEPTION_PRIV_INSTRUCTION:
1.1.1.2 ! root      172:             lstrcat(szDebugEventBuffer, "PRIV_INSTRUCTION");
1.1       root      173:             break;
                    174: 
                    175:           default:
1.1.1.2 ! root      176:             lstrcat(szDebugEventBuffer, "Unknown [0x");
        !           177:             lstrcat(szDebugEventBuffer,
1.1       root      178:               LongToCharUpper( (LONG) DebugEvent.u.Exception.ExceptionRecord.ExceptionCode, szTempBuf, 16) );
1.1.1.2 ! root      179:             lstrcat(szDebugEventBuffer, "]");
1.1       root      180:             break;
                    181:         }
                    182:         if( fVerbose ) {
1.1.1.2 ! root      183:           lstrcat(szDebugEventBuffer, " - dwFirstChance:");
        !           184:           lstrcat(szDebugEventBuffer,
1.1       root      185:             LongToCharUpper( (LONG) DebugEvent.u.Exception.dwFirstChance, szTempBuf, 10) );
                    186:         }
                    187:         else {
                    188:           if(DebugEvent.u.Exception.dwFirstChance != 0)
1.1.1.2 ! root      189:             lstrcat(szDebugEventBuffer, " - First Chance");
1.1       root      190:           else
1.1.1.2 ! root      191:             lstrcat(szDebugEventBuffer, " - Second Chance");
1.1       root      192:         }
                    193:         break;
                    194: 
                    195:       case CREATE_THREAD_DEBUG_EVENT:
                    196:         MakeDebugEventString(szDebugEventBuffer, "Create Thread",
                    197:           &DebugEvent);
                    198:         if( fVerbose ) {
1.1.1.2 ! root      199:           lstrcat(szDebugEventBuffer, " - hThread:0x");
        !           200:           lstrcat(szDebugEventBuffer,
1.1       root      201:             LongToCharUpper( (LONG)  DebugEvent.u.CreateThread.hThread, szTempBuf, 16) );
1.1.1.2 ! root      202:           lstrcat(szDebugEventBuffer, " - lpStartAddress:0x");
        !           203:           lstrcat(szDebugEventBuffer,
1.1       root      204:             LongToCharUpper( (LONG) DebugEvent.u.CreateThread.lpStartAddress, szTempBuf, 16) );
                    205:         }
                    206:         break;
                    207: 
                    208:       case CREATE_PROCESS_DEBUG_EVENT:
                    209:         MakeDebugEventString(szDebugEventBuffer, "Create Process",
                    210:           &DebugEvent);
                    211:         if( fVerbose ) {
1.1.1.2 ! root      212:           lstrcat(szDebugEventBuffer, " - hFile:0x");
        !           213:           lstrcat(szDebugEventBuffer,
1.1       root      214:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hFile, szTempBuf, 16) );
1.1.1.2 ! root      215:           lstrcat(szDebugEventBuffer, " - hProcess:0x");
        !           216:           lstrcat(szDebugEventBuffer,
1.1       root      217:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hProcess, szTempBuf, 16) );
1.1.1.2 ! root      218:           lstrcat(szDebugEventBuffer, " - hThread:0x");
        !           219:           lstrcat(szDebugEventBuffer,
1.1       root      220:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.hThread, szTempBuf, 16) );
1.1.1.2 ! root      221:           lstrcat(szDebugEventBuffer, " - lpBaseOfImage:0x");
        !           222:           lstrcat(szDebugEventBuffer,
1.1       root      223:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpBaseOfImage, szTempBuf, 16) );
1.1.1.2 ! root      224:           lstrcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:");
        !           225:           lstrcat(szDebugEventBuffer,
1.1       root      226:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.dwDebugInfoFileOffset, szTempBuf, 10) );
1.1.1.2 ! root      227:           lstrcat(szDebugEventBuffer, " - nDebugInfoSize:");
        !           228:           lstrcat(szDebugEventBuffer,
1.1       root      229:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.nDebugInfoSize, szTempBuf, 10) );
1.1.1.2 ! root      230:           lstrcat(szDebugEventBuffer, " - lpStartAddress:0x");
        !           231:           lstrcat(szDebugEventBuffer,
1.1       root      232:             LongToCharUpper( (LONG) DebugEvent.u.CreateProcessInfo.lpStartAddress, szTempBuf, 16) );
                    233:         }
                    234:         break;
                    235: 
                    236:       case EXIT_THREAD_DEBUG_EVENT:
                    237:         MakeDebugEventString(szDebugEventBuffer, "Exit Thread",
                    238:           &DebugEvent);
                    239: 
                    240:         if( fVerbose ) {
1.1.1.2 ! root      241:           lstrcat(szDebugEventBuffer, " - dwExitCode:");
1.1       root      242:         }
                    243:         else {
1.1.1.2 ! root      244:           lstrcat(szDebugEventBuffer, " - Returned:");
1.1       root      245:         }
1.1.1.2 ! root      246:         lstrcat(szDebugEventBuffer,
1.1       root      247:           LongToCharUpper( (LONG) DebugEvent.u.ExitThread.dwExitCode, szTempBuf, 10) );
                    248:         break;
                    249: 
                    250:       case EXIT_PROCESS_DEBUG_EVENT:
                    251:         MakeDebugEventString(szDebugEventBuffer, "Exit Process",
                    252:           &DebugEvent);
                    253:         if( fVerbose ) {
1.1.1.2 ! root      254:           lstrcat(szDebugEventBuffer, " - dwExitCode:");
1.1       root      255:         }
                    256:         else {
1.1.1.2 ! root      257:           lstrcat(szDebugEventBuffer, " - Returned:");
1.1       root      258:         }
1.1.1.2 ! root      259:         lstrcat(szDebugEventBuffer,
1.1       root      260:           LongToCharUpper( (LONG) DebugEvent.u.ExitProcess.dwExitCode, szTempBuf, 10) );
                    261:         break;
                    262: 
                    263:       case LOAD_DLL_DEBUG_EVENT:
                    264:         MakeDebugEventString(szDebugEventBuffer, "Load DLL:",
                    265:           &DebugEvent);
                    266: 
                    267:         GetModuleFileNameFromHeader(
                    268:           hProcess, DebugEvent.u.LoadDll.hFile,
1.1.1.2 ! root      269:           szTempBuf, STRING_BUFSIZ );
        !           270:         lstrcat( szDebugEventBuffer, szTempBuf );
1.1       root      271:         if( fVerbose ) {
1.1.1.2 ! root      272:           lstrcat(szDebugEventBuffer, " - hFile:0x");
        !           273:           lstrcat(szDebugEventBuffer,
1.1       root      274:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.hFile, szTempBuf, 16) );
1.1.1.2 ! root      275:           lstrcat(szDebugEventBuffer, " - lpBaseOfDll:0x");
        !           276:           lstrcat(szDebugEventBuffer,
1.1       root      277:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.lpBaseOfDll, szTempBuf, 16) );
1.1.1.2 ! root      278:           lstrcat(szDebugEventBuffer, " - dwDebugInfoFileOffset:");
        !           279:           lstrcat(szDebugEventBuffer,
1.1       root      280:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.dwDebugInfoFileOffset, szTempBuf, 10) );
1.1.1.2 ! root      281:           lstrcat(szDebugEventBuffer, " - nDebugInfoSize:");
        !           282:           lstrcat(szDebugEventBuffer,
1.1       root      283:             LongToCharUpper( (LONG) DebugEvent.u.LoadDll.nDebugInfoSize, szTempBuf, 10) );
                    284:         }
                    285:         break;
                    286: 
                    287:       case UNLOAD_DLL_DEBUG_EVENT:
                    288:         MakeDebugEventString(szDebugEventBuffer, "Unload DLL",
                    289:           &DebugEvent);
                    290:         if( fVerbose ) {
1.1.1.2 ! root      291:           lstrcat(szDebugEventBuffer, " - lpBaseOfDLL:0x");
        !           292:           lstrcat(szDebugEventBuffer,
1.1       root      293:             LongToCharUpper( (LONG) DebugEvent.u.UnloadDll.lpBaseOfDll, szTempBuf, 16) );
                    294:         }
                    295:         break;
                    296: 
                    297:       case OUTPUT_DEBUG_STRING_EVENT:
                    298:         MakeDebugEventString(szDebugEventBuffer, "Output Debug String",
                    299:           &DebugEvent);
1.1.1.2 ! root      300:         lstrcat(szDebugEventBuffer, ":\"");
1.1       root      301: 
                    302:         //-- According to Win32 Specs Rev3, I need to use ReadVirtualMemory
                    303:         //   however this incorrect.  ReadProcessMemory is the correct API
                    304:         ReadProcessMemory( hProcess,
                    305:           DebugEvent.u.DebugString.lpDebugStringData,
                    306:           szTempBuf, DebugEvent.u.DebugString.nDebugStringLength,
                    307:           &NumberOfBytesRead );
1.1.1.2 ! root      308:         lstrcat(szDebugEventBuffer, szTempBuf );
        !           309:         lstrcat(szDebugEventBuffer, "\"" );
1.1       root      310:         if( fVerbose ) {
1.1.1.2 ! root      311:           lstrcat(szDebugEventBuffer, " - fUnicode:");
        !           312:           lstrcat(szDebugEventBuffer,
1.1       root      313:             LongToCharUpper( (LONG) DebugEvent.u.DebugString.fUnicode, szTempBuf, 10) );
1.1.1.2 ! root      314:           lstrcat(szDebugEventBuffer, " - nDebugStringLength:");
        !           315:           lstrcat(szDebugEventBuffer,
1.1       root      316:             LongToCharUpper( (LONG) DebugEvent.u.DebugString.nDebugStringLength, szTempBuf, 10) );
                    317:         }
                    318:         break;
                    319: 
                    320:       default:
                    321:         MakeDebugEventString(szDebugEventBuffer, "Debug Event:",
                    322:           &DebugEvent);
1.1.1.2 ! root      323:         lstrcat(szDebugEventBuffer, "Unknown [0x");
        !           324:         lstrcat(szDebugEventBuffer,
1.1       root      325:           LongToCharUpper( (LONG) DebugEvent.dwDebugEventCode, szTempBuf, 16) );
1.1.1.2 ! root      326:         lstrcat(szDebugEventBuffer, "]");
1.1       root      327:         break;
                    328:     }
                    329: 
                    330:     //-- insert the debug event string into the listbox
                    331:     ListBoxPrintF( "%s", szDebugEventBuffer );
                    332: 
                    333:     //-- handle minimal exception handling needs for particular events
                    334:     switch( DebugEvent.dwDebugEventCode ) {
                    335: 
                    336:       case EXCEPTION_DEBUG_EVENT:
                    337:         switch( DebugEvent.u.Exception.ExceptionRecord.ExceptionCode ) {
                    338: 
                    339:          #if( MIPS == 1 )
                    340:           case STATUS_BREAKPOINT:
                    341:             //-- increment instruction pointer past the break point
                    342:             //   only needed for the MIPS R4000
                    343:             if( !SkipBreakPoint( DebugEvent.dwThreadId ) )
                    344:               ListBoxInsert( hWndDebugList, &MaxStrLen,
                    345:                 "--> Failed To skip over the Break Point" );
                    346:             break;
                    347:          #endif
                    348: 
                    349:           case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
                    350:           case EXCEPTION_FLT_DIVIDE_BY_ZERO:
                    351:           case EXCEPTION_FLT_INVALID_OPERATION:
                    352:           case EXCEPTION_FLT_OVERFLOW:
                    353:           case EXCEPTION_FLT_STACK_CHECK:
                    354:           case EXCEPTION_FLT_UNDERFLOW:
                    355:           case EXCEPTION_INT_DIVIDE_BY_ZERO:
                    356:           case EXCEPTION_INT_OVERFLOW:
                    357:           case EXCEPTION_PRIV_INSTRUCTION:
                    358:           case STATUS_ACCESS_VIOLATION:
                    359:             ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId,
                    360:               DBG_EXCEPTION_NOT_HANDLED );
                    361:         }
                    362:         break;
                    363: 
                    364:       case CREATE_PROCESS_DEBUG_EVENT:
                    365:         CreateNode( &ProcessList, &ThreadNode );
                    366:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    367:         (ThreadNode->NodeData).hThread    = DebugEvent.u.CreateProcessInfo.hThread;
                    368:         InsertNode( &ProcessList, ThreadNode );
                    369:         if( ++ActiveProcesses == 1 ) {
                    370:           //-- store the current process handle in the temp global handle
                    371:           hProcess = DebugEvent.u.CreateProcessInfo.hProcess;
                    372:         }
                    373:         break;
                    374: 
                    375:       case CREATE_THREAD_DEBUG_EVENT:
                    376:         CreateNode( &ProcessList, &ThreadNode );
                    377:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    378:         (ThreadNode->NodeData).hThread    = DebugEvent.u.CreateThread.hThread;
                    379:         InsertNode( &ProcessList, ThreadNode );
                    380:         break;
                    381: 
                    382:       case EXIT_THREAD_DEBUG_EVENT:
                    383:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    384:         GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 );
                    385:         DeleteCurrentNode( &ProcessList );
                    386:         break;
                    387: 
                    388:       case EXIT_PROCESS_DEBUG_EVENT:
                    389:         //-- if the event was EXIT_PROCESS_DEBUG_EVENT and it was the
                    390:         //   original process opened/attached to then exit the
                    391:         //   debug event processing thread.  Also do some cleanup first.
                    392:         (ThreadNode->NodeData).dwThreadId = DebugEvent.dwThreadId;
                    393:         GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 );
                    394:         DeleteCurrentNode( &ProcessList );
                    395:         DestroyNode( TempNode );
                    396:         if( --ActiveProcesses == 0 ) {
1.1.1.2 ! root      397:          // return( TRUE );
1.1       root      398:           ExitThread( TRUE );
                    399:         }
                    400:         break;
                    401:     }
                    402: 
                    403:     //-- default action - just continue
                    404:     ContinueDebugEvent( DebugEvent.dwProcessId, DebugEvent.dwThreadId,
                    405:       DBG_CONTINUE );
                    406:   }
                    407: 
1.1.1.2 ! root      408:   ExitThread( FALSE );
        !           409: 
        !           410:   return( FALSE );  // avoid the "no return value" warning
1.1       root      411: }
                    412: 
                    413: 
                    414: // ************************************************************************
                    415: // FUNCTION : GetModuleFileNameFromHeader( HANDLE, HANDLE, LPTSTR, DWORD )
                    416: // PURPOSE  : Retrieves the DLL module name for a given file handle of a
                    417: //            the module.  Reads the module name from the EXE header.
1.1.1.2 ! root      418: // COMMENTS :
        !           419: //   Retrieves only the module name and not the pathname.
1.1       root      420: // ************************************************************************
1.1.1.2 ! root      421: DWORD WINAPI
1.1       root      422: GetModuleFileNameFromHeader( HANDLE hProcess, HANDLE hFile, LPTSTR lpszPath,
                    423:   DWORD cbPath )
                    424: {
                    425:   #define IMAGE_DOS_SIGNATURE     0x5A4D      // MZ
                    426:   #define IMAGE_OS2_SIGNATURE     0x454E      // NE
                    427:   #define IMAGE_NT_SIGNATURE      0x00004550  // PE00
                    428: 
                    429:   #define IMAGE_SECOND_HEADER_OFFSET     (15 * sizeof(ULONG)) // relative to file beginning
                    430:   #define IMAGE_BASE_OFFSET              (13 * sizeof(DWORD)) // relative to PE header base
                    431:   #define IMAGE_EXPORT_TABLE_RVA_OFFSET  (30 * sizeof(DWORD)) // relative to PE header base
                    432:   #define IMAGE_NAME_RVA_OFFSET           (3 * sizeof(DWORD)) // relative to Exports/Imports table base
                    433: 
                    434:   WORD   DosSignature;
                    435:   DWORD  NtSignature;
                    436:   DWORD  NumberOfBytesRead;
                    437: 
                    438:   DWORD  PeHeader, ImageBase, ExportTableRVA, NameRVA;
                    439: 
                    440:   //-- verify that the handle is not NULL
                    441:   if( !hFile ) {
1.1.1.2 ! root      442:     lstrcpy( lpszPath, "hFile is NULL!" );
1.1       root      443:     return( 0 );
                    444:   }
                    445: 
                    446:   //-- verify that the handle is for a disk file
                    447:   if( GetFileType(hFile) != FILE_TYPE_DISK ) {
1.1.1.2 ! root      448:     lstrcpy( lpszPath, "Incorrect hFile Type!" );
1.1       root      449:     return( 0 );
                    450:   }
                    451: 
                    452:   //-- Extract the filename from the EXE header
                    453:   ReadFile( hFile, &DosSignature, sizeof(DosSignature), &NumberOfBytesRead,
                    454:     (LPOVERLAPPED) NULL);
                    455: 
                    456:   if( DosSignature == IMAGE_DOS_SIGNATURE ) {
                    457: 
                    458:     SetFilePointer( hFile, IMAGE_SECOND_HEADER_OFFSET, (LPLONG) NULL,
                    459:       FILE_BEGIN );
                    460:     ReadFile( hFile, &PeHeader, sizeof(PeHeader),
                    461:       &NumberOfBytesRead, (LPOVERLAPPED) NULL );
                    462: 
                    463:     SetFilePointer( hFile, PeHeader, (LPLONG) NULL,
                    464:       FILE_BEGIN );
                    465:     ReadFile( hFile, &NtSignature, sizeof(NtSignature),
                    466:       &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    467: 
                    468:     if( NtSignature == IMAGE_NT_SIGNATURE ) {
                    469: 
                    470:       SetFilePointer( hFile, PeHeader+IMAGE_BASE_OFFSET,
                    471:          (LPLONG) NULL, FILE_BEGIN );
                    472:       ReadFile( hFile, &ImageBase, sizeof(ImageBase),
                    473:         &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    474: 
                    475:       SetFilePointer( hFile, PeHeader + IMAGE_EXPORT_TABLE_RVA_OFFSET,
                    476:          (LPLONG) NULL, FILE_BEGIN );
                    477:       ReadFile( hFile, &ExportTableRVA, sizeof(ExportTableRVA),
                    478:         &NumberOfBytesRead, (LPOVERLAPPED) NULL);
                    479: 
                    480:       //-- now read from the virtual address space in the process
                    481:       ReadProcessMemory( hProcess,
                    482:          (LPVOID) (ImageBase + ExportTableRVA + IMAGE_NAME_RVA_OFFSET),
                    483:          &NameRVA, sizeof(NameRVA), &NumberOfBytesRead );
                    484: 
                    485:       ReadProcessMemory( hProcess,
                    486:          (LPVOID) (ImageBase+NameRVA),
                    487:          lpszPath, cbPath, &NumberOfBytesRead );
                    488: 
                    489:       return( NumberOfBytesRead );
                    490:     }
                    491:     else
1.1.1.2 ! root      492:       wsprintf( lpszPath, "NtSignature is 0x%x!", NtSignature );
1.1       root      493: 
                    494:   }
                    495:   else
1.1.1.2 ! root      496:     wsprintf( lpszPath, "DosSignature is 0x%x!", DosSignature );
1.1       root      497: 
                    498:   return( 0 );
                    499: }
                    500: 
                    501: 
                    502: #if( MIPS == 1 )
                    503: // ************************************************************************
                    504: // FUNCTION : SkipThreadBreakPoint( DWORD );
                    505: // PURPOSE  : Skip over the break point instruction belonging to
1.1.1.2 ! root      506: //            dwThreadId.
        !           507: // COMMENTS :
        !           508: //   Only the MIPS R4000 requires this.
1.1       root      509: // ************************************************************************
                    510: BOOL
                    511: SkipBreakPoint( DWORD dwThreadId )
                    512: {
                    513:   CONTEXT Context;
                    514:   PNODE   ThreadNode;
                    515:   PNODE   InputNode;
                    516: 
                    517:   CreateNode( &ProcessList, &InputNode );
                    518:   ThreadNode = InputNode;
                    519:   (InputNode->NodeData).dwThreadId = dwThreadId;
                    520: 
                    521:   if( GetNode( &ProcessList, &ThreadNode, OrderFunc, 1 ) == NO_MATCH_ERROR ) {
                    522:     ListBoxInsert( hWndDebugList, &MaxStrLen, "--> Error: Node not found" );
                    523:     return( FALSE );
                    524:   }
                    525: 
                    526:   Context.ContextFlags = CONTEXT_CONTROL;
                    527: 
                    528:   if( !GetThreadContext( (ThreadNode->NodeData).hThread, &Context ) ) {
                    529:     char szTempBuf[64];
                    530: 
1.1.1.2 ! root      531:     wsprintf(szTempBuf, "--> Error: dwThreadId = 0x%8.8lx", dwThreadId );
1.1       root      532:     ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf );
1.1.1.2 ! root      533:     wsprintf(szTempBuf, "--> Error: GetThreadContext( %lx ) failed, error 0x%8.8lx",
1.1       root      534:       (DWORD) (ThreadNode->NodeData).hThread,
                    535:       (DWORD) GetLastError() );
                    536:     ListBoxInsert( hWndDebugList, &MaxStrLen, szTempBuf);
                    537: 
                    538:     return( FALSE );
                    539:   }
                    540: 
                    541:   Context.Fir += 4L;  // Fir is the PC (program counter)
                    542:                       // BREAK (breakpoint instruction) occupies 4 bytes
                    543: 
                    544:   // -----------------------------------------------------------------------
                    545:   //  Below would be equvalent for the Intel 80x86 if it were necessary
                    546:   //  Context.Eip += 2L;  // Eip is the PC (program counter)
                    547:   //                      // int 3 (breakpoint instruction) occupies 2 bytes
                    548:   // -----------------------------------------------------------------------
                    549: 
                    550:   SetThreadContext( (ThreadNode->NodeData).hThread, &Context );
                    551:   DestroyNode( InputNode );
                    552: 
                    553:   return( TRUE );
                    554: }
                    555: #endif

unix.superglobalmegacorp.com

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