This is a multi-part message in MIME format. -- Rockefeller wrote: > hi. > > It seems that since the last update of Steam the Debug Mode does not > work correctly any more. I'm getting "No EXPORT" messages for ALL entities: > > Can't find address: 1b1b2ce3 > ERROR: No EXPORT: func_door:LinearMoveDone (1b1b2ce3) > > It seems that g_engfuncs.pfnNameForFunction() always returns false. > > Anyone else noticed this?
You could always replace the engine version with your own code. See the namefunc.cpp file I created for my patches to get the SDK to build with the Borland compiler (see attached). Just edit dlls\enginecallback.h and change it to this... //#define FUNCTION_FROM_NAME (*g_engfuncs.pfnFunctionFromName) unsigned long FUNCTION_FROM_NAME(const char *pName); //#define NAME_FOR_FUNCTION (*g_engfuncs.pfnNameForFunction) const char *NAME_FOR_FUNCTION(unsigned long function); ...and add namefunc.cpp to your project. Note that the save games created by the engine won't work with this code (you'll have to create new save games for single player) and any saved games created with this code won't load when the engine gets fixed later. -- Jeffrey "botman" Broome -- // // (http://planethalflife.com/botman/) // // namefunc.cpp // #ifndef __linux__ #include <windows.h> #endif #include "extdll.h" #include "util.h" #include "enginecallback.h" #include "cbase.h" #define MAX_SYMBOLS 1000 /* max exported symbols */ #define DOS_SIGNATURE 0x5A4D /* MZ */ #define NT_SIGNATURE 0x00004550 /* PE00 */ // externs extern "C" DLLEXPORT void EXPORT GiveFnptrsToDll(enginefuncs_t* pengfuncsFromEngine, globalvars_t *pGlobals); // globals WORD *p_Ordinals = NULL; DWORD *p_Functions = NULL; DWORD *p_Names = NULL; char *p_FunctionNames[MAX_SYMBOLS]; int num_ordinals; unsigned long base_offset; typedef struct { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } DOS_HEADER, *P_DOS_HEADER; typedef struct { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } PE_HEADER, *P_PE_HEADER; #define SIZEOF_SHORT_NAME 8 typedef struct { BYTE Name[SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } SECTION_HEADER, *P_SECTION_HEADER; typedef struct { DWORD VirtualAddress; DWORD Size; } DATA_DIRECTORY, *P_DATA_DIRECTORY; #define NUMBEROF_DIRECTORY_ENTRIES 16 typedef struct { WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; DATA_DIRECTORY DataDirectory[NUMBEROF_DIRECTORY_ENTRIES]; } OPTIONAL_HEADER, *P_OPTIONAL_HEADER; typedef struct { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD AddressOfFunctions; // RVA from base of image DWORD AddressOfNames; // RVA from base of image DWORD AddressOfNameOrdinals; // RVA from base of image } EXPORT_DIRECTORY, *P_EXPORT_DIRECTORY; void GetDllFilename(char *dll_name) { FILE *lfp; char buffer[256]; int len, i, j; char *ptr; char game_dir[256]; char filename[256]; (*g_engfuncs.pfnGetGameDir)(game_dir); strcpy(filename, game_dir); strcat(filename, "\\liblist.gam"); if ((lfp=fopen(filename, "r")) == NULL) { *dll_name = 0; return; } while (fgets(buffer, 255, lfp) != NULL) { len = strlen(buffer); if (buffer[len-1] == '\n') { buffer[len-1] = 0; // remove '\n' len--; } for (i=0; i<len; i++) { if (buffer[i] == '\t') // convert tabs to spaces buffer[i] = ' '; } while (buffer[0] == ' ') { for (j=0; j<len; j++) // remove leading spaces buffer[j] = buffer[j+1]; buffer[len-1] = 0; len--; } for (i=0; i<len; i++) { while ((buffer[i] == ' ') && (buffer[i+1] == ' ')) { for (j=i+1; j<len; j++) // remove redundant spaces buffer[j] = buffer[j+1]; buffer[len-1] = 0; len--; } } if (strncmp(buffer, "gamedll ", 8) == 0) { if ((ptr = strstr(buffer, "\"")) != NULL) { ptr++; strcpy(dll_name, ptr); // copy dll file name to dll_name if ((ptr = strstr(dll_name, "\"")) != NULL) { *ptr = 0; // terminate at second " (if there is one) } fclose(lfp); return; } } } fclose(lfp); } void FgetString(char *str, FILE *bfp) { char ch; while ((ch = fgetc(bfp)) != EOF) { *str++ = ch; if (ch == 0) break; } } void FreeNameFuncGlobals(void) { if (p_Ordinals) free(p_Ordinals); if (p_Functions) free(p_Functions); if (p_Names) free(p_Names); for (int i=0; i < num_ordinals; i++) { if (p_FunctionNames[i]) free(p_FunctionNames[i]); } } extern HINSTANCE h_DllInstance; void LoadSymbols(void) { FILE *bfp; DOS_HEADER dos_header; LONG nt_signature; PE_HEADER pe_header; SECTION_HEADER section_header; BOOL edata_found; OPTIONAL_HEADER optional_header; LONG edata_offset; LONG edata_delta; EXPORT_DIRECTORY export_directory; LONG name_offset; char game_dir[256]; char dll_name[64]; char filename[256]; LONG ordinal_offset; LONG function_offset; char function_name[256]; int i, index; BOOL error; char msg[80]; for (i=0; i < num_ordinals; i++) p_FunctionNames[i] = NULL; #ifdef _WIN32 GetModuleFileName( h_DllInstance, filename, 256 ); #else GetDllFilename(dll_name); // get gamedll name from the liblist.gam file (*g_engfuncs.pfnGetGameDir)(game_dir); strcpy(filename, game_dir); strcat(filename, "\\"); strcat(filename, dll_name); #endif if ((bfp=fopen(filename, "rb")) == NULL) { sprintf(msg, "DLL file %s not found!", filename); ALERT(at_error, msg); return; } if (fread(&dos_header, sizeof(dos_header), 1, bfp) != 1) { sprintf(msg, "%s is NOT a valid DLL file!", filename); ALERT(at_error, msg); return; } if (dos_header.e_magic != DOS_SIGNATURE) { ALERT(at_error, "file does not have a valid DLL signature!"); return; } if (fseek(bfp, dos_header.e_lfanew, SEEK_SET) == -1) { ALERT(at_error, "error seeking to new exe header!"); return; } if (fread(&nt_signature, sizeof(nt_signature), 1, bfp) != 1) { ALERT(at_error, "file does not have a valid NT signature!"); return; } if (nt_signature != NT_SIGNATURE) { ALERT(at_error, "file does not have a valid NT signature!"); return; } if (fread(&pe_header, sizeof(pe_header), 1, bfp) != 1) { ALERT(at_error, "file does not have a valid PE header!"); return; } if (pe_header.SizeOfOptionalHeader == 0) { ALERT(at_error, "file does not have an optional header!"); return; } if (fread(&optional_header, sizeof(optional_header), 1, bfp) != 1) { ALERT(at_error, "file does not have a valid optional header!"); return; } edata_found = FALSE; for (i=0; i < pe_header.NumberOfSections; i++) { if (fread(§ion_header, sizeof(section_header), 1, bfp) != 1) { ALERT(at_error, "error reading section header!"); return; } if (strcmp((char *)section_header.Name, ".edata") == 0) { edata_found = TRUE; break; } } if (edata_found) { edata_offset = section_header.PointerToRawData; edata_delta = section_header.VirtualAddress - section_header.PointerToRawData; } else { edata_offset = optional_header.DataDirectory[0].VirtualAddress; edata_delta = 0L; } if (fseek(bfp, edata_offset, SEEK_SET) == -1) { ALERT(at_error, "file does not have a valid exports section!"); return; } if (fread(&export_directory, sizeof(export_directory), 1, bfp) != 1) { ALERT(at_error, "file does not have a valid optional header!"); return; } num_ordinals = export_directory.NumberOfNames; // also number of ordinals if (num_ordinals > MAX_SYMBOLS) { ALERT(at_error, "too many symbols to process. make MAX_SYMBOLS bigger."); return; } ordinal_offset = export_directory.AddressOfNameOrdinals - edata_delta; if (fseek(bfp, ordinal_offset, SEEK_SET) == -1) { ALERT(at_error, "file does not have a valid ordinals section!"); return; } if ((p_Ordinals = (WORD *)malloc(num_ordinals * sizeof(WORD))) == NULL) { ALERT(at_error, "error allocating memory for ordinals section!"); return; } if (fread(p_Ordinals, num_ordinals * sizeof(WORD), 1, bfp) != 1) { FreeNameFuncGlobals(); ALERT(at_error, "error reading ordinals table!"); return; } function_offset = export_directory.AddressOfFunctions - edata_delta; if (fseek(bfp, function_offset, SEEK_SET) == -1) { ALERT(at_error, "file does not have a valid export address section!"); return; } if ((p_Functions = (DWORD *)malloc(num_ordinals * sizeof(DWORD))) == NULL) { ALERT(at_error, "error allocating memory for export address section!"); return; } if (fread(p_Functions, num_ordinals * sizeof(DWORD), 1, bfp) != 1) { FreeNameFuncGlobals(); ALERT(at_error, "error reading export address section!"); return; } name_offset = export_directory.AddressOfNames - edata_delta; if (fseek(bfp, name_offset, SEEK_SET) == -1) { FreeNameFuncGlobals(); ALERT(at_error, "file does not have a valid names section!"); return; } if ((p_Names = (DWORD *)malloc(num_ordinals * sizeof(DWORD))) == NULL) { FreeNameFuncGlobals(); ALERT(at_error, "error allocating memory for names section!"); return; } if (fread(p_Names, num_ordinals * sizeof(DWORD), 1, bfp) != 1) { FreeNameFuncGlobals(); ALERT(at_error, "error reading names table!"); return; } error = FALSE; for (i=0; (i < num_ordinals) && (error==FALSE); i++) { name_offset = p_Names[i] - edata_delta; if (name_offset != 0) { if (fseek(bfp, name_offset, SEEK_SET) == -1) error = TRUE; else { FgetString(function_name, bfp); if ((p_FunctionNames[i] = (char *)malloc(strlen(function_name)+1)) == NULL) error = TRUE; else strcpy(p_FunctionNames[i], function_name); } } } if (error) { FreeNameFuncGlobals(); ALERT(at_error, "error in loading names section!"); return; } fclose(bfp); for (i=0; i < num_ordinals; i++) { if (strcmp("GiveFnptrsToDll", p_FunctionNames[i]) == 0) { index = p_Ordinals[i]; base_offset = (unsigned long)&GiveFnptrsToDll - p_Functions[index]; break; } } } unsigned long FUNCTION_FROM_NAME(const char *pName) { int i, index; for (i=0; i < num_ordinals; i++) { if (strcmp(pName, p_FunctionNames[i]) == 0) { index = p_Ordinals[i]; return p_Functions[index] + base_offset; } } return 0L; // couldn't find the function name to return address } const char *NAME_FOR_FUNCTION(unsigned long function) { int i, index; for (i=0; i < num_ordinals; i++) { index = p_Ordinals[i]; if ((function - base_offset) == p_Functions[index]) { return p_FunctionNames[i]; } } return NULL; // couldn't find the function address to return name } -- _______________________________________________ To unsubscribe, edit your list preferences, or view the list archives, please visit: http://list.valvesoftware.com/mailman/listinfo/hlcoders

