#include #include #include #ifdef BUILD_DBGHELP BOOL GetDllVersionInfo( HINSTANCE hinst, LPVOID *lpVersionInfo ); #define FreeLib(hDll) \ {if (hDll && hDll != INVALID_HANDLE_VALUE) FreeLibrary(hDll);} #endif // #ifdef BUILD_DBGHELP typedef struct { PCHAR Name; FARPROC Function; } FUNCPTRS; #if DBG void OutputDBString( CHAR *text ); #endif #ifdef BUILD_IMAGEHLP BOOL IMAGEAPI FailEnumerateLoadedModules( IN HANDLE hProcess, IN PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailEnumerateLoadedModules64( IN HANDLE hProcess, IN PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, IN PVOID UserContext ) { return FALSE; } HANDLE IMAGEAPI FailFindDebugInfoFile ( PSTR FileName, PSTR SymbolPath, PSTR DebugFilePath ) {return NULL;} HANDLE IMAGEAPI FailFindDebugInfoFileEx ( PSTR FileName, PSTR SymbolPath, PSTR DebugFilePath, PFIND_DEBUG_FILE_CALLBACK Callback, PVOID CallerData ) { return NULL; } HANDLE IMAGEAPI FailFindExecutableImage( PSTR FileName, PSTR SymbolPath, PSTR ImageFilePath ) { return NULL; } LPAPI_VERSION IMAGEAPI FailImagehlpApiVersion( VOID ) { return NULL; } LPAPI_VERSION IMAGEAPI FailImagehlpApiVersionEx( LPAPI_VERSION AppVersion ) { return NULL; } BOOL IMAGEAPI FailMakeSureDirectoryPathExists( PCSTR DirPath ) { return FALSE; } #ifndef _WIN64 PIMAGE_DEBUG_INFORMATION IMAGEAPI FailMapDebugInformation( HANDLE FileHandle, PSTR FileName, PSTR SymbolPath, DWORD ImageBase ) { return NULL; } #endif BOOL IMAGEAPI FailSearchTreeForFile( PSTR RootPath, PSTR InputPathName, PSTR OutputPathBuffer ) { return FALSE; } BOOL IMAGEAPI FailStackWalk( DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE TranslateAddress ) { return FALSE; } BOOL IMAGEAPI FailStackWalk64( DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress ) { return FALSE; } BOOL IMAGEAPI FailSymCleanup( IN HANDLE hProcess ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateModules( IN HANDLE hProcess, IN PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateModules64( IN HANDLE hProcess, IN PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateSymbols( IN HANDLE hProcess, IN DWORD BaseOfDll, IN PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateSymbolsW( IN HANDLE hProcess, IN DWORD BaseOfDll, IN PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateSymbols64( IN HANDLE hProcess, IN DWORD64 BaseOfDll, IN PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymEnumerateSymbolsW64( IN HANDLE hProcess, IN DWORD64 BaseOfDll, IN PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } PVOID IMAGEAPI FailSymFunctionTableAccess( HANDLE hProcess, DWORD AddrBase ) { return NULL; } PVOID IMAGEAPI FailSymFunctionTableAccess64( HANDLE hProcess, DWORD64 AddrBase ) { return NULL; } BOOL IMAGEAPI FailSymGetLineFromAddr( IN HANDLE hProcess, IN DWORD dwAddr, OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLineFromAddr64( IN HANDLE hProcess, IN DWORD64 qwAddr, OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_LINE64 Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLineFromName( IN HANDLE hProcess, IN PSTR ModuleName, IN PSTR FileName, IN DWORD dwLineNumber, OUT PLONG plDisplacement, IN OUT PIMAGEHLP_LINE Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLineFromName64( IN HANDLE hProcess, IN PSTR ModuleName, IN PSTR FileName, IN DWORD dwLineNumber, OUT PLONG plDisplacement, IN OUT PIMAGEHLP_LINE64 Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLineNext( IN HANDLE hProcess, IN OUT PIMAGEHLP_LINE Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLineNext64( IN HANDLE hProcess, IN OUT PIMAGEHLP_LINE64 Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLinePrev( IN HANDLE hProcess, IN OUT PIMAGEHLP_LINE Line ) { return FALSE; } BOOL IMAGEAPI FailSymGetLinePrev64( IN HANDLE hProcess, IN OUT PIMAGEHLP_LINE64 Line ) { return FALSE; } DWORD IMAGEAPI FailSymGetModuleBase( IN HANDLE hProcess, IN DWORD dwAddr ) { return 0; } DWORD64 IMAGEAPI FailSymGetModuleBase64( IN HANDLE hProcess, IN DWORD64 qwAddr ) { return 0; } BOOL IMAGEAPI FailSymGetModuleInfo( IN HANDLE hProcess, IN DWORD dwAddr, OUT PIMAGEHLP_MODULE ModuleInfo ) { return FALSE; } BOOL IMAGEAPI FailSymGetModuleInfoW( IN HANDLE hProcess, IN DWORD dwAddr, OUT PIMAGEHLP_MODULEW ModuleInfo ) { return FALSE; } BOOL IMAGEAPI FailSymGetModuleInfo64( IN HANDLE hProcess, IN DWORD64 qwAddr, OUT PIMAGEHLP_MODULE64 ModuleInfo ) { return FALSE; } BOOL IMAGEAPI FailSymGetModuleInfoW64( IN HANDLE hProcess, IN DWORD64 qwAddr, OUT PIMAGEHLP_MODULEW64 ModuleInfo ) { return FALSE; } DWORD IMAGEAPI FailSymGetOptions( VOID ) { return 0; } BOOL IMAGEAPI FailSymGetSearchPath( IN HANDLE hProcess, OUT PSTR SearchPath, IN DWORD SearchPathLength ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymFromAddr( IN HANDLE hProcess, IN DWORD dwAddr, OUT PDWORD pdwDisplacement, OUT PIMAGEHLP_SYMBOL Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymFromAddr64( IN HANDLE hProcess, IN DWORD64 qwAddr, OUT PDWORD64 pdwDisplacement, OUT PIMAGEHLP_SYMBOL64 Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymFromName( IN HANDLE hProcess, IN PSTR Name, OUT PIMAGEHLP_SYMBOL Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymFromName64( IN HANDLE hProcess, IN PSTR Name, OUT PIMAGEHLP_SYMBOL64 Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymNext( IN HANDLE hProcess, IN OUT PIMAGEHLP_SYMBOL Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymNext64( IN HANDLE hProcess, IN OUT PIMAGEHLP_SYMBOL64 Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymPrev( IN HANDLE hProcess, IN OUT PIMAGEHLP_SYMBOL Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetSymPrev64( IN HANDLE hProcess, IN OUT PIMAGEHLP_SYMBOL64 Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymGetTypeInfo( IN HANDLE hProcess, IN DWORD64 ModBase, IN ULONG TypeId, IN IMAGEHLP_SYMBOL_TYPE_INFO GetType, OUT PVOID pInfo ) { return FALSE; } BOOL IMAGEAPI FailSymGetTypeFromName( IN HANDLE hProcess, IN ULONG64 BaseOfDll, IN LPSTR Name, OUT PSYMBOL_INFO Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymEnumTypes( IN HANDLE hProcess, IN ULONG64 BaseOfDll, IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymInitialize( IN HANDLE hProcess, IN PSTR UserSearchPath, IN BOOL fInvadeProcess ) { return FALSE; } DWORD IMAGEAPI FailSymLoadModule( IN HANDLE hProcess, IN HANDLE hFile, IN PSTR ImageName, IN PSTR ModuleName, IN DWORD BaseOfDll, IN DWORD SizeOfDll ) { return 0; } DWORD64 IMAGEAPI FailSymLoadModule64( IN HANDLE hProcess, IN HANDLE hFile, IN PSTR ImageName, IN PSTR ModuleName, IN DWORD64 BaseOfDll, IN DWORD SizeOfDll ) { return 0; } BOOL IMAGEAPI FailSymMatchFileName( IN PSTR FileName, IN PSTR Match, OUT PSTR *FileNameStop, OUT PSTR *MatchStop ) { return FALSE; } BOOL IMAGEAPI FailSymRegisterCallback( IN HANDLE hProcess, IN PSYMBOL_REGISTERED_CALLBACK CallbackFunction, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymRegisterCallback64( IN HANDLE hProcess, IN PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, IN ULONG64 UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymRegisterFunctionEntryCallback( IN HANDLE hProcess, IN PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymRegisterFunctionEntryCallback64( IN HANDLE hProcess, IN PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, IN ULONG64 UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymSetContext( HANDLE hProcess, PIMAGEHLP_STACK_FRAME StackFrame, PIMAGEHLP_CONTEXT Context ) { return FALSE;} DWORD IMAGEAPI FailSymSetOptions( IN DWORD SymOptions ) { return 0; } BOOL IMAGEAPI FailSymSetSearchPath( IN HANDLE hProcess, IN PSTR SearchPath ) { return FALSE; } BOOL IMAGEAPI FailSymUnDName( IN PIMAGEHLP_SYMBOL sym, // Symbol to undecorate OUT PSTR UnDecName, // Buffer to store undecorated name in IN DWORD UnDecNameLength // Size of the buffer ) { return FALSE; } BOOL IMAGEAPI FailSymUnDName64( IN PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate OUT PSTR UnDecName, // Buffer to store undecorated name in IN DWORD UnDecNameLength // Size of the buffer ) { return FALSE; } BOOL IMAGEAPI FailSymUnloadModule( IN HANDLE hProcess, IN DWORD BaseOfDll ) { return FALSE; } BOOL IMAGEAPI FailSymUnloadModule64( IN HANDLE hProcess, IN DWORD64 BaseOfDll ) { return FALSE; } #ifndef _WIN64 BOOL IMAGEAPI FailUnmapDebugInformation( PIMAGE_DEBUG_INFORMATION DebugInfo ) { return FALSE; } #endif BOOL IMAGEAPI FailSymEnumSym( IN HANDLE hProcess, IN DWORD64 BaseOfDll, IN PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, IN PVOID UserContext ) { return FALSE; } BOOL IMAGEAPI FailSymFromAddr( IN HANDLE hProcess, IN DWORD64 dwAddr, OUT PDWORD pdwDisplacement, OUT PSYMBOL_INFO Symbol ) { return FALSE; } BOOL IMAGEAPI FailSymFromName( IN HANDLE hProcess, IN PSTR Name, OUT PSYMBOL_INFO Symbol ) { return FALSE; } FUNCPTRS DbgHelpFailPtrs[] = { {"EnumerateLoadedModules", (FARPROC)FailEnumerateLoadedModules}, {"EnumerateLoadedModules64", (FARPROC)FailEnumerateLoadedModules64}, {"FindDebugInfoFile", (FARPROC)FailFindDebugInfoFile}, {"FindDebugInfoFileEx", (FARPROC)FailFindDebugInfoFileEx}, {"FindExecutableImage", (FARPROC)FailFindExecutableImage}, {"ImagehlpApiVersion", (FARPROC)FailImagehlpApiVersion}, {"ImagehlpApiVersionEx", (FARPROC)FailImagehlpApiVersionEx}, {"MakeSureDirectoryPathExists", (FARPROC)FailMakeSureDirectoryPathExists}, #ifndef _WIN64 {"MapDebugInformation", (FARPROC)FailMapDebugInformation}, #endif {"SearchTreeForFile", (FARPROC)FailSearchTreeForFile}, {"StackWalk", (FARPROC)FailStackWalk}, {"StackWalk64", (FARPROC)FailStackWalk64}, {"SymCleanup", (FARPROC)FailSymCleanup}, {"SymEnumerateModules", (FARPROC)FailSymEnumerateModules}, {"SymEnumerateModules64", (FARPROC)FailSymEnumerateModules64}, {"SymEnumerateSymbols", (FARPROC)FailSymEnumerateSymbols}, {"SymEnumerateSymbols64", (FARPROC)FailSymEnumerateSymbols64}, {"SymEnumerateSymbolsW", (FARPROC)FailSymEnumerateSymbolsW}, {"SymEnumerateSymbolsW64", (FARPROC)FailSymEnumerateSymbolsW64}, {"SymEnumSym", (FARPROC)FailSymEnumSym}, {"SymEnumTypes", (FARPROC)FailSymEnumTypes}, {"SymFromAddr", (FARPROC)FailSymFromAddr}, {"SymFromName", (FARPROC)FailSymFromName}, {"SymFunctionTableAccess", (FARPROC)FailSymFunctionTableAccess}, {"SymFunctionTableAccess64", (FARPROC)FailSymFunctionTableAccess64}, {"SymGetLineFromAddr", (FARPROC)FailSymGetLineFromAddr}, {"SymGetLineFromAddr64", (FARPROC)FailSymGetLineFromAddr64}, {"SymGetLineFromName", (FARPROC)FailSymGetLineFromName}, {"SymGetLineFromName64", (FARPROC)FailSymGetLineFromName64}, {"SymGetLineNext", (FARPROC)FailSymGetLineNext}, {"SymGetLineNext64", (FARPROC)FailSymGetLineNext64}, {"SymGetLinePrev", (FARPROC)FailSymGetLinePrev}, {"SymGetLinePrev64", (FARPROC)FailSymGetLinePrev64}, {"SymGetModuleBase", (FARPROC)FailSymGetModuleBase}, {"SymGetModuleBase64", (FARPROC)FailSymGetModuleBase64}, {"SymGetModuleInfo", (FARPROC)FailSymGetModuleInfo}, {"SymGetModuleInfo64", (FARPROC)FailSymGetModuleInfo64}, {"SymGetModuleInfoW", (FARPROC)FailSymGetModuleInfoW}, {"SymGetModuleInfoW64", (FARPROC)FailSymGetModuleInfoW64}, {"SymGetOptions", (FARPROC)FailSymGetOptions}, {"SymGetSearchPath", (FARPROC)FailSymGetSearchPath}, {"SymGetSymFromAddr", (FARPROC)FailSymGetSymFromAddr}, {"SymGetSymFromAddr64", (FARPROC)FailSymGetSymFromAddr64}, {"SymGetSymFromName", (FARPROC)FailSymGetSymFromName}, {"SymGetSymFromName64", (FARPROC)FailSymGetSymFromName64}, {"SymGetSymNext", (FARPROC)FailSymGetSymNext}, {"SymGetSymNext64", (FARPROC)FailSymGetSymNext64}, {"SymGetSymPrev", (FARPROC)FailSymGetSymPrev}, {"SymGetSymPrev64", (FARPROC)FailSymGetSymPrev64}, {"SymGetTypeFromName", (FARPROC)FailSymGetTypeFromName}, {"SymGetTypeInfo", (FARPROC)FailSymGetTypeInfo}, {"SymInitialize", (FARPROC)FailSymInitialize}, {"SymLoadModule", (FARPROC)FailSymLoadModule}, {"SymLoadModule64", (FARPROC)FailSymLoadModule64}, {"SymMatchFileName", (FARPROC)FailSymMatchFileName}, {"SymRegisterCallback", (FARPROC)FailSymRegisterCallback}, {"SymRegisterCallback64", (FARPROC)FailSymRegisterCallback64}, {"SymRegisterFunctionEntryCallback", (FARPROC)FailSymRegisterFunctionEntryCallback}, {"SymRegisterFunctionEntryCallback64", (FARPROC)FailSymRegisterFunctionEntryCallback64}, {"SymSetContext", (FARPROC)FailSymSetContext}, {"SymSetOptions", (FARPROC)FailSymSetOptions}, {"SymSetSearchPath", (FARPROC)FailSymSetSearchPath}, {"SymUnDName", (FARPROC)FailSymUnDName}, {"SymUnDName64", (FARPROC)FailSymUnDName64}, {"SymUnloadModule", (FARPROC)FailSymUnloadModule}, {"SymUnloadModule64", (FARPROC)FailSymUnloadModule64}, #ifndef _WIN64 {"UnmapDebugInformation", (FARPROC)FailUnmapDebugInformation}, #endif {NULL, NULL} }; #endif // BUILD_IMAGEHLP #ifdef BUILD_IMAGEHLP FUNCPTRS *FailFunctions[2] = {NULL, DbgHelpFailPtrs}; // {MsDbiFailPtrs, DbgHelpFailPtrs}; HINSTANCE hDelayLoadDll[2]; #else FUNCPTRS *FailFunctions[1] = {MsDbiFailPtrs}; HINSTANCE hDelayLoadDll[1]; #endif FARPROC FindFailureProc( UINT Index, const char *szProcName ) { FUNCPTRS *fp = FailFunctions[Index]; UINT x = 0; while (fp[x].Name) { if (!lstrcmpi(fp[x].Name, szProcName)) { return fp[x].Function; } x++; } return NULL; } /* * this function exists to prevent us from calling msvcrt!splitpath */ VOID ParsePath( CHAR *fullpath, CHAR *path, CHAR *file ) { CHAR *c; CHAR sz[_MAX_PATH]; assert(fullpath); if (path) *path = 0; if (file) *file = 0; lstrcpy(sz, fullpath); for (c = sz + lstrlen(sz); c > sz; c--) { if (*c == '\\') { c++; if (file) lstrcpy(file, c); *c = 0; if (path) lstrcpy(path, sz); return; } } if (file) lstrcpy(file, fullpath); } FARPROC WINAPI ImagehlpDelayLoadHook ( UINT unReason, PDelayLoadInfo pDelayInfo ) { FARPROC ReturnValue = NULL; if (dliStartProcessing == unReason) { DWORD iDll = 0; #ifdef BUILD_IMAGEHLP if (!lstrcmpi(pDelayInfo->szDll, "dbghelp.dll")) { iDll = 2; } #endif if (iDll) { iDll--; // If the dll isn't loaded and isn't inproc already, attempt to load // from the same dir as imagehlp lives... if (!hDelayLoadDll[iDll] && !(hDelayLoadDll[iDll] = GetModuleHandle(pDelayInfo->szDll)) && g.hinst) { CHAR szImageName[_MAX_PATH]; CHAR szPath[_MAX_DIR]; CHAR szDll[_MAX_PATH]; // Only load if dbghelp/msdbi are in the same dir as imagehlp GetModuleFileName(g.hinst, szImageName, sizeof(szImageName)); ParsePath(szImageName, szPath, szDll); lstrcpy(szImageName, szPath); lstrcat(szImageName, pDelayInfo->szDll); hDelayLoadDll[iDll] = LoadLibrary(szImageName); if (!hDelayLoadDll[iDll]) { hDelayLoadDll[iDll] = (HINSTANCE)INVALID_HANDLE_VALUE; } } if (INVALID_HANDLE_VALUE != hDelayLoadDll[iDll] && g.hinst) { ReturnValue = GetProcAddress(hDelayLoadDll[iDll], pDelayInfo->dlp.szProcName); } if (!ReturnValue) { ReturnValue = FindFailureProc(iDll, pDelayInfo->dlp.szProcName); } #if DBG if (!ReturnValue) { OutputDBString("BogusDelayLoad function encountered...\n"); } } else { OutputDBString("BogusDelayLoad function encountered...\n"); #endif } } if (ReturnValue && g.hinst) { *pDelayInfo->ppfn = ReturnValue; } return ReturnValue; } #ifdef BUILD_DBGHELP typedef struct tagVERHEAD { WORD wTotLen; WORD wValLen; WORD wType; /* always 0 */ WCHAR szKey[(sizeof("VS_VERSION_INFO")+3)&~03]; VS_FIXEDFILEINFO vsf; } VERHEAD ; BOOL GetDllVersionInfo( HINSTANCE hinst, LPVOID *lpVersionInfo ) { VS_FIXEDFILEINFO *pvsFFI = NULL; HRSRC hVerRes; VERHEAD *pVerHead; BOOL rc = FALSE; assert(lpVersionInfo && hinst); *lpVersionInfo = NULL; hVerRes = FindResource(hinst, MAKEINTRESOURCE(VS_VERSION_INFO), VS_FILE_INFO); if (hVerRes == NULL) goto Cleanup; pVerHead = (VERHEAD*)LoadResource(hinst, hVerRes); if (pVerHead == NULL) goto Cleanup; *lpVersionInfo = MemAlloc(pVerHead->wTotLen + pVerHead->wTotLen/2); if (*lpVersionInfo == NULL) goto Cleanup; memcpy(*lpVersionInfo, (PVOID)pVerHead, pVerHead->wTotLen); rc = TRUE; Cleanup: if (*lpVersionInfo && rc == FALSE) MemFree(*lpVersionInfo); return rc; } #endif // #ifdef BUILD_DBGHELP PfnDliHook __pfnDliNotifyHook = ImagehlpDelayLoadHook; PfnDliHook __pfnDliFailureHook = NULL; #if DBG void OutputDBString( CHAR *text ) { CHAR sz[256]; sprintf(sz, "%s: %s", MOD_FILENAME, text); OutputDebugString(sz); } #endif