ULONG APIENTRY ExceptionHandler( PEXCEPTIONREPORTRECORD pRep, PEXCEPTIONREGISTRATIONRECORD2 pReg, PCONTEXTRECORD pCtx, PVOID pDispCtx) { if (pRep->fHandlerFlags & (EH_EXIT_UNWIND|EH_UNWINDING|EH_NESTED_CALL)) { return XCPT_CONTINUE_SEARCH; } switch (pRep->ExceptionNum) { case XCPT_ACCESS_VIOLATION: case XCPT_ILLEGAL_INSTRUCTION: case XCPT_PRIVILEGED_INSTRUCTION: case XCPT_INVALID_LOCK_SEQUENCE: case XCPT_INTEGER_DIVIDE_BY_ZERO: case XCPT_INTEGER_OVERFLOW: case XCPT_FLOAT_DIVIDE_BY_ZERO: case XCPT_FLOAT_OVERFLOW: case XCPT_FLOAT_UNDERFLOW: case XCPT_FLOAT_INVALID_OPERATION: case XCPT_FLOAT_DENORMAL_OPERAND: case XCPT_FLOAT_INEXACT_RESULT: case XCPT_FLOAT_STACK_CHECK: convToBigEndian(&pReg->repRec.rep,pRep,sizeof(*pRep)); // template can only format bytes { APIRET rc=NO_ERROR; HMODULE hmod = NULLHANDLE; ULONG ulObjNum = 0; ULONG ulOffset = 0; APIRET16 rc16 = NO_ERROR; rc = DosQueryModFromEIP( &hmod, &ulObjNum, sizeof(pReg->repRec.modName), pReg->repRec.modName, &ulOffset, pCtx->ctx_RegEip ); if (rc != NO_ERROR) { QMRESULT qmresult={0}; rc16 = Dos16QueryModFromCS(pCtx->ctx_SegCs,&qmresult); strcpy(pReg->repRec.modName,qmresult.name); } } longjmp(pReg->jmp,1); default: break; } return XCPT_CONTINUE_SEARCH; }
char *get_module_name(char *buf, size_t len) { HMODULE hmod; ULONG obj, offset; APIRET arc; arc = DosQueryModFromEIP(&hmod, &obj, len, buf, &offset, (ULONG)get_module_name); TRACE_IF(arc, "DosQueryModFromEIP %ld\n", arc); ASSERT_MSG(!arc || arc == ERROR_BAD_LENGTH, "%ld %d", arc, len); if (arc) return NULL; arc = DosQueryModuleName(hmod, len, buf); TRACE_IF(arc, "DosQueryModuleName %ld\n", arc); ASSERT_MSG(!arc || arc == ERROR_BAD_LENGTH, "%ld %d", arc, len); if (arc) return NULL; return buf; }
int main(int argc, char *argv[]) { int do_load,do_unload,do_help,do_path; do_load=do_unload=do_help=do_path=0; char basepath[CCHMAXPATH]; if (argc == 1) do_help = 1; else { for (int i=1; i < argc; i++) { if (strnicmp(argv[i],"-l", 2) == 0) do_load = 1; else if (strnicmp(argv[i],"-u", 2) == 0) do_unload = 1; else if (strnicmp(argv[i],"-h", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-?", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-p", 2) == 0) { if (argc > i+1) { strcpy(basepath, argv[i+1]); if (basepath[strlen(basepath)] !='\\') { strcat(basepath, "\\"); } do_path = 1; } else { do_help = 1; } } } } if (do_help) { printf("%s for OS/2 preloader\n"\ "\n"\ "Usage: %s [-h] [-l | -u] [-p path]\n"\ " -h display this help\n"\ " -l load modules\n"\ " -u unload modules\n"\ " -p specify fully qualified path to directory where EXE is located\n", MOZ_APP_DISPLAYNAME, argv[0]); return(1); } if (do_unload) { HEV hev = NULLHANDLE; if (DosOpenEventSem(SEMNAME, &hev) == NO_ERROR) { if (DosPostEventSem(hev) == NO_ERROR) { if (DosCloseEventSem(hev) == NO_ERROR) { return(0); } } } printf("%s for OS/2 preloader is not running\n", MOZ_APP_DISPLAYNAME); return(1); } if (do_path == 0) { /* Get the name of this EXE and use its location as the path */ HMODULE hmodule; DosQueryModFromEIP(&hmodule, NULL, 0, NULL, NULL, (ULONG)ForceModuleLoad); DosQueryModuleName(hmodule, CCHMAXPATH, basepath); char *pchar = strrchr(basepath, '\\'); pchar++; *pchar = '\0'; } if (do_load) { ULONG ulCurMaxFH; LONG ulReqFH = 40; DosSetRelMaxFH(&ulReqFH, &ulCurMaxFH); HEV hev; if (DosCreateEventSem(SEMNAME, &hev, DC_SEM_SHARED, FALSE) != NO_ERROR) { printf("%s for OS/2 preloader is already running\n", MOZ_APP_DISPLAYNAME); return(1); } /* Add directory where EXE is located to LIBPATH */ DosSetExtLIBPATH(basepath, BEGIN_LIBPATH); /* loop through list loading named modules */ char filepath[CCHMAXPATH]; HMODULE hmod; int i = 0, nummodules = 0; while (bindir[i]) { strcpy(filepath,basepath); strcat(filepath,bindir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } i = 0; while (compdir[i]) { strcpy(filepath, basepath); strcat(filepath, "COMPONENTS\\"); strcat(filepath, compdir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } if (nummodules > 0) { if (DosWaitEventSem(hev, SEM_INDEFINITE_WAIT) != NO_ERROR) { printf("DosWaitEventSem failed\n"); return(1); } if (DosCloseEventSem(hev) != NO_ERROR) { printf("DosCloseEventSem failed\n"); return(1); } } else { printf("No modules available to load\n"); } } return(0); }
VOID excExplainException(FILE *file, // in: logfile from fopen() PSZ pszHandlerName, // in: descriptive string PEXCEPTIONREPORTRECORD pReportRec, // in: excpt info PCONTEXTRECORD pContextRec) // in: excpt info { PTIB ptib = NULL; PPIB ppib = NULL; HMODULE hMod1, hMod2; CHAR szMod1[CCHMAXPATH] = "unknown", szMod2[CCHMAXPATH] = "unknown"; ULONG ulObjNum, ulOffset, ulCountPages, ulFlagsPage; APIRET arc; PULONG pulStackWord, pulStackBegin; ULONG ul; ULONG ulOldPriority = 0x0100; // regular, delta 0 // raise this thread's priority, because this // might take some time if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR) if (ptib) if (ptib->tib_ptib2) { ulOldPriority = ptib->tib_ptib2->tib2_ulpri; DosSetPriority(PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MAXIMUM, 0); // current thread } // make some noise DosBeep(4000, 30); DosBeep(2000, 30); DosBeep(1000, 30); DosBeep( 500, 30); DosBeep( 250, 30); DosBeep( 500, 30); DosBeep(1000, 30); DosBeep(2000, 30); DosBeep(4000, 30); // generic exception info fprintf(file, "\n%s:\n Exception type: %08X\n Address: %08X\n Params: ", pszHandlerName, pReportRec->ExceptionNum, pReportRec->ExceptionAddress); for (ul = 0; ul < pReportRec->cParameters; ul++) { fprintf(file, "%08X ", pReportRec->ExceptionInfo[ul]); } // now explain the exception in a bit more detail; // depending on the exception, pReportRec->ExceptionInfo // contains some useful data switch (pReportRec->ExceptionNum) { case XCPT_ACCESS_VIOLATION: { fprintf(file, "\nAccess violation: "); if (pReportRec->ExceptionInfo[0] & XCPT_READ_ACCESS) fprintf(file, "Invalid read access from 0x%04X:%08X.\n", pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]); else if (pReportRec->ExceptionInfo[0] & XCPT_WRITE_ACCESS) fprintf(file, "Invalid write access to 0x%04X:%08X.\n", pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]); else if (pReportRec->ExceptionInfo[0] & XCPT_SPACE_ACCESS) fprintf(file, "Invalid space access at 0x%04X.\n", pReportRec->ExceptionInfo[1]); else if (pReportRec->ExceptionInfo[0] & XCPT_LIMIT_ACCESS) fprintf(file, "Invalid limit access occurred.\n"); else if (pReportRec->ExceptionInfo[0] == XCPT_UNKNOWN_ACCESS) fprintf(file, "unknown at 0x%04X:%08X\n", pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]); fprintf(file, "Explanation: An attempt was made to access a memory object which does\n" " not belong to the current process. Most probable causes\n" " for this are that an invalid pointer was used, there was\n" " confusion with administering memory or error conditions \n" " were not properly checked for.\n"); break; } case XCPT_INTEGER_DIVIDE_BY_ZERO: { fprintf(file, "\nInteger division by zero.\n"); fprintf(file, "Explanation: An attempt was made to divide an integer value by zero,\n" " which is not defined.\n"); break; } case XCPT_ILLEGAL_INSTRUCTION: { fprintf(file, "\nIllegal instruction found.\n"); fprintf(file, "Explanation: An attempt was made to execute an instruction that\n" " is not defined on this machine's architecture.\n"); break; } case XCPT_PRIVILEGED_INSTRUCTION: { fprintf(file, "\nPrivileged instruction found.\n"); fprintf(file, "Explanation: An attempt was made to execute an instruction that\n" " is not permitted in the current machine mode or that\n" " XFolder had no permission to execute.\n"); break; } case XCPT_INTEGER_OVERFLOW: fprintf(file, "\nInteger overflow.\n"); fprintf(file, "Explanation: An integer operation generated a carry-out of the most\n" " significant bit. This is a sign of an attempt to store\n" " a value which does not fit into an integer variable.\n"); } if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR) { /* * process info: * */ if (ppib) { if (pContextRec->ContextFlags & CONTEXT_CONTROL) { // get the main module hMod1 = ppib->pib_hmte; DosQueryModuleName(hMod1, sizeof(szMod1), szMod1); // get the trapping module DosQueryModFromEIP(&hMod2, &ulObjNum, sizeof(szMod2), szMod2, &ulOffset, pContextRec->ctx_RegEip); DosQueryModuleName(hMod2, sizeof(szMod2), szMod2); } fprintf(file, "\nProcess information: PID 0x%lX" "\n Module handle: 0x%lX (%s)" "\n Trapping module: 0x%lX (%s)" "\n Object: %d\n", ppib->pib_ulpid, hMod1, szMod1, hMod2, szMod2, ulObjNum); } else fprintf(file, "\nProcess information was not available."); // *** registers fprintf(file, "\nRegisters:"); if (pContextRec->ContextFlags & CONTEXT_INTEGER) { // EAX fprintf(file, "\n EAX = %08X ", pContextRec->ctx_RegEax); excDescribePage(file, pContextRec->ctx_RegEax); // EBX fprintf(file, "\n EBX = %08X ", pContextRec->ctx_RegEbx); excDescribePage(file, pContextRec->ctx_RegEbx); // ECX fprintf(file, "\n ECX = %08X ", pContextRec->ctx_RegEcx); excDescribePage(file, pContextRec->ctx_RegEcx); // EDX fprintf(file, "\n EDX = %08X ", pContextRec->ctx_RegEdx); excDescribePage(file, pContextRec->ctx_RegEdx); // ESI fprintf(file, "\n ESI = %08X ", pContextRec->ctx_RegEsi); excDescribePage(file, pContextRec->ctx_RegEsi); // EDI fprintf(file, "\n EDI = %08X ", pContextRec->ctx_RegEdi); excDescribePage(file, pContextRec->ctx_RegEdi); fprintf(file, "\n"); } else fprintf(file, " not available\n"); if (pContextRec->ContextFlags & CONTEXT_CONTROL) { // *** instruction fprintf(file, "Instruction:\n CS:EIP = %04X:%08X ", pContextRec->ctx_SegCs, pContextRec->ctx_RegEip); excDescribePage(file, pContextRec->ctx_RegEip); // *** CPU flags fprintf(file, "\n FLG = %08X", pContextRec->ctx_EFlags); /* * stack: * */ fprintf(file, "\nStack:\n Base: %08X\n Limit: %08X", (ptib ? ptib->tib_pstack : 0), (ptib ? ptib->tib_pstacklimit :0)); fprintf(file, "\n SS:ESP = %04X:%08X ", pContextRec->ctx_SegSs, pContextRec->ctx_RegEsp); excDescribePage(file, pContextRec->ctx_RegEsp); fprintf(file, "\n EBP = %08X ", pContextRec->ctx_RegEbp); excDescribePage(file, pContextRec->ctx_RegEbp); dbgPrintStack(file, (PUSHORT)ptib->tib_pstack, (PUSHORT)ptib->tib_pstacklimit, (PUSHORT)pContextRec->ctx_RegEbp, (PUSHORT)pReportRec->ExceptionAddress); /* * stack dump: * this code is mostly (W) Roman Stangl. */ if (ptib != 0) { #ifdef DEBUG_EXCPT_STACKDUMP // start with Stack dump; if EBP is within stack and smaller // than ESP, use EBP, otherwise use ESP (which points into the // stack anyway, so no check needed) fprintf(file, "\n\nStack dump : +0 +4 +8 +C"); if (pContextRec->ctx_RegEbp < pContextRec->ctx_RegEsp) pulStackWord = (PULONG)(pContextRec->ctx_RegEbp & 0xFFFFFFF0); else pulStackWord = (PULONG)(pContextRec->ctx_RegEsp & 0xFFFFFFF0); for (pulStackBegin = pulStackWord; pulStackWord <= (PULONG)ptib->tib_pstacklimit; /* NOP */) { if (((ULONG)pulStackWord & 0x00000FFF) == 0x00000000) { // we're on a page boundary: check access ulCountPages = 0x1000; ulFlagsPage = 0; arc = DosQueryMem((void *)pulStackWord, &ulCountPages, &ulFlagsPage); if ( (arc != NO_ERROR) || ( (arc == NO_ERROR) && ( !( ((ulFlagsPage & (PAG_COMMIT|PAG_READ)) == (PAG_COMMIT|PAG_READ)) ) ) ) ) { fprintf(file, "\n %08X: ", pulStackWord); fprintf(file, "Page inaccessible"); pulStackWord += 0x1000; continue; // for } } if (((ULONG)pulStackWord & 0x0000000F) == 0) fprintf(file, "\n %08X: ", pulStackWord); if ( (*pulStackWord >= (ULONG)pulStackBegin) && (*pulStackWord <= (ULONG)ptib->tib_pstacklimit) ) fprintf(file, "<%08X> ", *pulStackWord); else fprintf(file, " %08X ", *pulStackWord); pulStackWord++; } // end for #endif // *** stack frames fprintf(file, "\n\nStack frames:\n Address Module:Object\n"); pulStackWord = (PULONG)pContextRec->ctx_RegEbp; while ( (pulStackWord != 0) && (pulStackWord < (PULONG)ptib->tib_pstacklimit) ) { fprintf(file, " %08X: %08X ", pulStackWord, *(pulStackWord+1)); if (DosQueryModFromEIP(&hMod1, &ulObjNum, sizeof(szMod1), szMod1, &ulOffset, *(pulStackWord+1)) == NO_ERROR) { fprintf(file, " %s:%d\n", szMod1, ulObjNum); } pulStackWord = (PULONG)*(pulStackWord); } // end while } } } fprintf(file, "\n"); // reset old priority DosSetPriority(PRTYS_THREAD, (ulOldPriority & 0x0F00) >> 8, (UCHAR)ulOldPriority, 0); // current thread }
APIRET APIENTRY WtkGetNlsPackageFilename( PFN pfnMod, PSZ pszDefaultLanguage, PSZ pszEnvVar, PSZ pszFileMaskPath, PSZ pszBuffer, ULONG ulBuflen) { APIRET rc = NO_ERROR; PSZ pszEnvLanguage = NULL; PSZ pszSystemLanguage = NULL; PSZ pszLocaleLanguage = NULL; PLANGDEF pldSystem = NULL; PLANGDEF pldLocale = NULL; PLANGDEF pldDefault = NULL; PPIB ppib; PTIB ptib; CHAR szDir[ _MAX_PATH]; CHAR szFile[ _MAX_PATH]; CHAR szMaskEntry[ _MAX_PATH]; PSZ pszMaskEntry; PSZ p; CHAR szVariants[ 128]; do { // check parms if ((!pszFileMaskPath) || (!pszBuffer)) { rc = ERROR_INVALID_PARAMETER; break; } // NOTE: we now translate all codes to the 639-1 code plus country identifier // this code is the most specific one !!! // check for default language pszDefaultLanguage = WtkTranslateLanguageCode( pszDefaultLanguage, WTK_LANGUAGEID_639_1C); if (rc != NO_ERROR) break; // check env var or system language if ((pszEnvVar) && (*pszEnvVar)) pszEnvLanguage = getenv( pszEnvVar); if (pszEnvLanguage) { pszEnvLanguage = WtkTranslateLanguageCode( pszEnvLanguage, WTK_LANGUAGEID_639_1C); // use always this language ! pszSystemLanguage = pszEnvLanguage; pszLocaleLanguage = pszEnvLanguage; } else { // determine languages of system and locale // for the second code, use the transform pszSystemLanguage = WtkQuerySystemLanguage( WTK_LANGUAGEID_639_1C); pszLocaleLanguage = WtkQueryLocaleLanguage( WTK_LANGUAGEID_639_1C); } // get gefinitions of languages in question pldSystem = _getLangDef( pszSystemLanguage); pldLocale = _getLangDef( pszLocaleLanguage); pldDefault = _getLangDef( pszDefaultLanguage); // determine directory of executable or DLL if (!pfnMod) { DosGetInfoBlocks( &ptib, &ppib); rc = DosQueryModuleName( ppib->pib_hmte, sizeof( szDir), szDir); } else { HMODULE hmod; ULONG ulObjNum; ULONG ulOffs; rc = DosQueryModFromEIP( &hmod, &ulObjNum, sizeof( szDir), szDir, &ulOffs, (ULONG)pfnMod); rc = DosQueryModuleName( hmod, sizeof( szDir), szDir); } if (rc != NO_ERROR) break; // cut off filename from path strcpy( strrchr( szDir, '\\') + 1, ""); // now process all file path entries rc = ERROR_FILE_NOT_FOUND; pszMaskEntry = pszFileMaskPath; while (*pszMaskEntry) { // isolate entry memset( szMaskEntry, 0, sizeof( szMaskEntry)); p = strchr( pszMaskEntry, ';'); if (p) { strncpy( szMaskEntry, pszMaskEntry, p - pszMaskEntry); pszMaskEntry += strlen( szMaskEntry) + 1; } else { strcpy( szMaskEntry, pszMaskEntry); pszMaskEntry += strlen( szMaskEntry); } // check for a file matching any of the lanuages (or one of its variants) rc = _getLanguageFile( szFile, sizeof( szFile), szDir, szMaskEntry, pldSystem, pldLocale, pldDefault); if (rc == NO_ERROR) // found a file !!! break; // for debugging purposes, place the mask into the target buffer // memset( pszBuffer, 0, ulBuflen); // strncpy( pszBuffer, szFile, ulBuflen - 1); } // while (*pszMaskEntry) if (rc != NO_ERROR) break; // hand over result, query full pathname rc = DosQueryPathInfo( szFile, FIL_QUERYFULLNAME, pszBuffer, ulBuflen); } while (FALSE); // cleanup if (pldSystem) free( pldSystem); if (pldLocale) free( pldLocale); if (pldDefault) free( pldDefault); return rc; }