/* The main DLL entry for DLL Initialization and Uninitialization: */ unsigned _System LibMain(unsigned hmod, unsigned termination) { if (termination) { #ifdef DEBUG_BUILD /* printf("[SDL DLL Unintialization] : Removing exception handler\n"); */ #endif DosUnsetExceptionHandler(&SDL_Main_xcpthand); return 1; } else { #ifdef DEBUG_BUILD /* Make stdout and stderr unbuffered! */ setbuf(stdout, NULL); setbuf(stderr, NULL); #endif /* Fire up exception handler */ #ifdef DEBUG_BUILD /* printf("[SDL DLL Initialization] : Setting exception handler\n"); */ #endif /* Set exception handler */ DosSetExceptionHandler(&SDL_Main_xcpthand); return 1; } }
void hb_vmUnsetExceptionHandler( void ) { #if defined( HB_OS_OS2 ) /* Add OS2TermHandler to this thread's chain of exception handlers */ { APIRET rc; /* Return code */ /* I don't do any check on return code since Harbour is exiting in any case */ rc = DosUnsetExceptionHandler( &s_regRec ); HB_SYMBOL_UNUSED( rc ); } #elif defined( HB_SIGNAL_EXCEPTION_HANDLER ) { /* we are using static buffer for alternative stack so we do not * have to deallocate it to free the memory on application exit */ #if 0 stack_t ss, oss; ss.ss_sp = NULL; ss.ss_size = SIGSTKSZ; ss.ss_flags = SS_DISABLE; /* set alternative stack for SIGSEGV executed on stack overflow */ if( sigaltstack( &ss, &oss ) == 0 ) { if( oss.ss_sp && SS_DISABLE ) free( oss.ss_sp ); } #endif } #endif }
static void unset_intr_run (void) { #if defined(_WIN32) SetConsoleCtrlHandler (stop_run, FALSE); #elif defined(__OS2__) APIRET rc; rc = DosUnsetExceptionHandler (&os2_excrr); /*if (rc != NO_ERROR) ...*/ #elif defined(__DOS__) setsignal (SIGINT, SIG_DFL); #else setsignal (SIGINT, SIG_DFL, 1); #endif }
ULONG FileGetJPEGInfo( CAMJpgInfo * pji, char * szFile, ULONG cbFile) { ULONG rc; ULONG ul; ULONG cbAlloc; BOOL fHandler = FALSE; CAMJXRR reg; do { memset( ®, 0, sizeof(CAMJXRR)); memset( pji, 0, sizeof(CAMJpgInfo)); rc = DosOpen( szFile, ®.hFile, &ul, 0, 0, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_SEQUENTIAL | OPEN_SHARE_DENYWRITE | OPEN_ACCESS_READONLY, 0); if (rc) { printf( "DosOpen - rc= 0x%x\n", (int)rc); break; } // allocate a lot of uncommited memory cbAlloc = ((cbFile + 0xfff) & ~0xfff); rc = DosAllocMem( (void**)(®.pBase), cbAlloc, PAG_READ | PAG_WRITE); if (rc) { printf( "DosAllocMem - rc= 0x%x\n", (int)rc); break; } // get up to the first 16k of the file - this is enough // for my Canon but not enough for a Sony I've tried ul = (cbFile >= 0x4000) ? 0x4000 : cbAlloc; rc = DosSetMem( reg.pBase, ul, PAG_COMMIT | PAG_DEFAULT); if (rc) { printf( "FileGetJPEGInfo - DosSetMem - rc= 0x%x\n", (int)rc); break; } ul = (cbFile >= 0x4000) ? 0x4000 : cbFile; ul = FileReadFile( reg.hFile, reg.pBase, ul, szFile); if (!ul) { rc = CAMERR_NEEDDATA; break; } // any access beyond 16k will generate an exception; // the handler will commit the page and read the corresponding // 4k from the file; if it encounters a file error, it will // longjmp() back to here so we can abort reg.lFilePtr += ul; reg.lEOF = cbFile; reg.pEnd = reg.pBase + cbAlloc; reg.szFile = szFile; reg.xrr.ExceptionHandler = FileExceptionHandler; // since the handler is lower on the stack than the jmpbuf, // longjmp() will unwind it before returning, so prevent // the cleanup code below from unsetting it if (setjmp( reg.jmpbuf)) { fHandler = FALSE; break; } rc = DosSetExceptionHandler( ®.xrr); if (rc) { printf( "DosSetExceptionHandler - rc= 0x%x\n", (int)rc); break; } fHandler = TRUE; // parse the file rc = FileIdentifyFile( pji, reg.pBase); if (rc) { printf( "FileIdentifyFile - rc= 0x%x\n", (int)rc); break; } // change the address of the thumb into an offset into the file if (pji->pThumb) pji->offsThumb = pji->pThumb - reg.pBase; } while (0); if (fHandler) { rc = DosUnsetExceptionHandler( ®.xrr); if (rc) printf( "DosUnsetExceptionHandler - rc= 0x%lx\n", rc); } if (reg.pBase) { rc = DosFreeMem( reg.pBase); if (rc) printf( "DosFreeMem - rc= 0x%x\n", (int)rc); } if (reg.hFile) { rc = DosClose( reg.hFile); if (rc) printf( "DosClose - rc= 0x%x\n", (int)rc); } return (0); }
/* Test each page. */ static bool TestPage(const char *pagelabel, uintptr_t pageaddr, int should_succeed) { const char *oplabel; uintptr_t opaddr; bool failed = false; for (unsigned int test = 0; test < 3; test++) { switch (test) { // The execute test must be done before the write test, because the // write test will clobber memory at the target address. case 0: oplabel = "reading"; opaddr = pageaddr + PAGESIZE/2 - 1; break; case 1: oplabel = "executing"; opaddr = pageaddr + PAGESIZE/2; break; case 2: oplabel = "writing"; opaddr = pageaddr + PAGESIZE/2 - 1; break; default: abort(); } #ifdef _WIN32 BOOL badptr; switch (test) { case 0: badptr = IsBadReadPtr((const void*)opaddr, 1); break; case 1: badptr = IsBadExecPtr(opaddr); break; case 2: badptr = IsBadWritePtr((void*)opaddr, 1); break; default: abort(); } if (badptr) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } else { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } } else { // if control reaches this point the probe succeeded if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } } #elif defined(__OS2__) XCPT xcpt; volatile int code = setjmp(xcpt.jmpbuf); if (!code) { xcpt.regrec.prev_structure = 0; xcpt.regrec.ExceptionHandler = ExceptionHandler; DosSetExceptionHandler(&xcpt.regrec); unsigned char scratch; switch (test) { case 0: scratch = *(volatile unsigned char *)opaddr; break; case 1: ((void (*)())opaddr)(); break; case 2: *(volatile unsigned char *)opaddr = 0; break; default: abort(); } } if (code) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s | exception code %x\n", oplabel, pagelabel, code); failed = true; } else { printf("TEST-PASS | %s %s | exception code %x\n", oplabel, pagelabel, code); } } else { if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s\n", oplabel, pagelabel); failed = true; } DosUnsetExceptionHandler(&xcpt.regrec); } #else pid_t pid = fork(); if (pid == -1) { printf("ERROR | %s %s | fork=%s\n", oplabel, pagelabel, LastErrMsg()); exit(2); } else if (pid == 0) { volatile unsigned char scratch; switch (test) { case 0: scratch = *(volatile unsigned char *)opaddr; break; case 1: JumpTo(opaddr); break; case 2: *(volatile unsigned char *)opaddr = 0; break; default: abort(); } _exit(0); } else { int status; if (waitpid(pid, &status, 0) != pid) { printf("ERROR | %s %s | wait=%s\n", oplabel, pagelabel, LastErrMsg()); exit(2); } if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { if (should_succeed) { printf("TEST-PASS | %s %s\n", oplabel, pagelabel); } else { printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected successful exit\n", oplabel, pagelabel); failed = true; } } else if (WIFEXITED(status)) { printf("ERROR | %s %s | unexpected exit code %d\n", oplabel, pagelabel, WEXITSTATUS(status)); exit(2); } else if (WIFSIGNALED(status)) { if (should_succeed) { printf("TEST-UNEXPECTED-FAIL | %s %s | unexpected signal %d\n", oplabel, pagelabel, WTERMSIG(status)); failed = true; } else { printf("TEST-PASS | %s %s | signal %d (as expected)\n", oplabel, pagelabel, WTERMSIG(status)); } } else { printf("ERROR | %s %s | unexpected exit status %d\n", oplabel, pagelabel, status); exit(2); } } #endif } return failed; }
/* draw_thread This is the drawing-thread. You have a valid presentation space handle (hps), a valid window handle (hwndSaver) and the configuration_data structure is loaded. The screen size is stored in "screenSizeX" and "screenSizeY". IMPORTANT NOTE 1: You must check the "stop_draw_thread" flag regularly. If it is set, free all resources you have allocated and call _endthread (or just return) to end the drawing-thread. IMPORTANT NOTE 2: If the "low_priority" flag is NOT set (that means you run with regular priority, sharing CPU usage with other programs), you should call DosSleep(x) with "x" set at least to 1 as often as possible, to allow other programs to do their work. A screen saver should not eat up other program's CPU time! IMPORTANT NOTE 3: For some of the PM calls to work properly, your thread needs an own HAB and maybe even a message queue. You have to get and release both of them here if you use such PM calls. The following sample code is from the "Pyramids" module that comes with the ScreenSaver distribution. It selects a random color and a random point on the screen, then draws lines in the selected color from each corner of the screen to the selected point (looks somewhat like a pyramid). It remembers a number of points (this number can be set in the configuration dialog). Having filled the point memory, it redraws the "oldest" visible pyramid in black. This has the effect that more and more pixels on the screen get black, only a few constantly changing colored lines remain. */ void draw_thread(void *args) { int i, j; const RECTL ScreenRect = { 0, 0, screenSizeX, screenSizeY }; int color_count = 0; ULONG color; int pushleftx = 11, pushlefty = 11, pushrightx = 11, pushrighty = 11; BOOL point_buffer_filled; BOOL first_paint = TRUE; POINTL *ptleft, *ptright; EXCEPTIONREGISTRATIONRECORD xcpthand = { (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler }; DosSetExceptionHandler(&xcpthand) ; i = 0; point_buffer_filled = FALSE; /* allocate memory for circular point buffer */ ptleft = malloc(configuration_data.count * sizeof(POINTL)); ptright = malloc(configuration_data.count * sizeof(POINTL)); if( (ptleft == NULL) || (ptright == NULL) ) goto end; GpiSetLineWidth( hps, LINEWIDTH_THICK ); srand(WinGetCurrentTime(hab)); do{ color = ((unsigned)rand()) % 17 - 2; }while ( color == -1 || color == 0 || color == 7 || color == 8 ); /* blank screen if requested */ if( configuration_data.blank_screen ) WinFillRect( hps, &ScreenRect, CLR_BLACK ); while(!stop_draw_thread){ if(point_buffer_filled){ /* redraw old line in black */ GpiSetColor(hps, CLR_BLACK); GpiMove(hps, &ptleft[i]); GpiLine(hps, &ptright[i]); } if( color_count == configuration_data.colors ){ /* select random color */ do{ color = ((unsigned)rand()) % 17 - 2; }while ( color == -1 || color == 0 || color == 7 || color == 8 ); color_count = 0; } GpiSetColor(hps, color); color_count++; if (first_paint ){ /* set the start coordinates */ ptleft[0].x = rand() % screenSizeX; ptleft[0].y = rand() % screenSizeY; ptright[0].x = rand() % screenSizeX; ptright[0].y = rand() % screenSizeY; first_paint = FALSE; } else { /* calculate new line points */ j = i==0 ? configuration_data.count - 1 : i - 1; ptleft[i].x = ptleft[j].x + pushleftx; ptleft[i].y = ptleft[j].y + pushlefty; ptright[i].x = ptright[j].x + pushrightx; ptright[i].y = ptright[j].y + pushrighty; } /* adjust lines if they hit a screen border */ if( ptleft[i].x >= screenSizeX ) { ptleft[i].x = 2 * screenSizeX - ptleft[i].x; pushleftx = - pushleftx + (rand() % 2); } if( ptleft[i].y >= screenSizeY ) { ptleft[i].y = 2 * screenSizeY - ptleft[i].y; pushlefty = - pushlefty + (rand() % 2); } if( ptright[i].x >= screenSizeX ) { ptright[i].x = 2 * screenSizeX - ptright[i].x; pushrightx = - pushrightx + ( rand() % 2); } if( ptright[i].y >= screenSizeY ) { ptright[i].y = 2 * screenSizeY - ptright[i].y; pushrighty = - pushrighty + ( rand() % 2); } if( ptleft[i].x < 0 ) { ptleft[i].x *= -1; pushleftx = - pushleftx + (rand() % 2); } if( ptleft[i].y < 0 ) { ptleft[i].y *= -1; pushlefty = - pushlefty + (rand() % 2); } if( ptright[i].x < 0 ) { ptright[i].x *= -1; pushrightx = - pushrightx + (rand() % 2); } if( ptright[i].y < 0 ) { ptright[i].y *= -1; pushrighty = - pushrighty + (rand() % 2); } /* draw line */ GpiMove(hps, &ptleft[i]); GpiLine(hps, &ptright[i]); /* sleep if necessary */ if(low_priority == FALSE) DosSleep(1); // sleep if user requests slower animation switch(configuration_data.animation_speed){ case 4: break; case 3: DosSleep(10); break; case 2: DosSleep(30); break; case 1: DosSleep(50); break; case 0: DosSleep(70); break; } i++; /* move circular buffer index */ if(i == configuration_data.count){ point_buffer_filled = TRUE; i = 0; } } /* free resources */ end: // goto from memory allocation free( ptleft ); free( ptright ); DosUnsetExceptionHandler(&xcpthand); _endthread(); }
int main(int argc, char *argv) { APIRET rc = NO_ERROR; PVOID pAlloc = NULL; PPQUEUE heap = NULL; int iRet = 0; EXCEPTIONREGISTRATIONRECORD xcpthand = { 0, &exception_handler }; int i = 0; srand(time(NULL)); /* * The whole idea with this sample is to demonstrate how to allocate memory * 'as needed'. The best way to do this is to use an exception handler */ rc = DosSetExceptionHandler(&xcpthand); /* * Allocate a very large buffer. This will fit approx 524280 nodes * which is way more than you'll need. */ rc = DosAllocMem(&pAlloc, 16*1024*1024, PAG_READ | PAG_WRITE); if(rc == NO_ERROR) { heap = pAlloc; } /* * Add some nodes with random priorities */ if(heap) { NODE tmpNode = { 0 }; PNODE node = NULL; puts("Add nodes"); for(i = 0; i < 100; i++) { tmpNode.priority = rand(); printf("Added node with priority: %u\n", tmpNode.priority); pqueue_push(heap, &tmpNode); } /* * Actually, it's neater to use the nodes-counter.. */ puts("\n\nEmpty heap"); while((node = pqueue_pop2(heap)) != NULL) { printf("Priority: %u\n", node->priority); } } /* * Free heap buffer */ if(heap) { DosFreeMem(heap); } /* * All registered exception handlers must be deregistered */ DosUnsetExceptionHandler(&xcpthand); return iRet; }
/* draw_thread This is the drawing-thread. You have a valid presentation space handle (hps), a valid window handle (hwndSaver) and the configuration_data structure is loaded. The screen size is stored in "screenSizeX" and "screenSizeY". IMPORTANT NOTE 1: You must check the "stop_draw_thread" flag regularly. If it is set, free all resources you have allocated and call _endthread (or just return) to end the drawing-thread. IMPORTANT NOTE 2: If the "low_priority" flag is NOT set (that means you run with regular priority, sharing CPU usage with other programs), you should call DosSleep(x) with "x" set at least to 1 as often as possible, to allow other programs to do their work. A screen saver should not eat up other program's CPU time! IMPORTANT NOTE 3: For some of the PM calls to work properly, your thread needs an own HAB and maybe even a message queue. You have to get and release both of them here if you use such PM calls. The following sample code is from the "Pyramids" module that comes with the ScreenSaver distribution. It selects a random color and a random point on the screen, then draws lines in the selected color from each corner of the screen to the selected point (looks somewhat like a pyramid). It remembers a number of points (this number can be set in the configuration dialog). Having filled the point memory, it redraws the "oldest" visible pyramid in black. This has the effect that more and more pixels on the screen get black, only a few constantly changing colored lines remain. */ void draw_thread(void *args) { INT i, j; typedef struct { INT x; INT y; float dx; float dy; INT step; } STAR; STAR *star; RECTL rect; BOOL point_buffer_filled; BOOL free_star_field = TRUE; float norm; EXCEPTIONREGISTRATIONRECORD xcpthand = { (PEXCEPTIONREGISTRATIONRECORD)0, GPFHandler }; DosSetExceptionHandler(&xcpthand) ; /* random seed (needed for each thread) */ srand(WinGetCurrentTime(hab)); i = 0; point_buffer_filled = FALSE; /* allocate stack memory for circular point buffer */ star = malloc(configuration_data.count * sizeof(STAR)); if( star == NULL ) stop_draw_thread = TRUE; /* blank Screen */ rect.xLeft = 0; rect.xRight = screenSizeX; rect.yBottom = 0; rect.yTop = screenSizeY; WinFillRect( hps, &rect, CLR_BLACK ); while(!stop_draw_thread){ if( free_star_field ){ /* create a new star */ star[i].x = rand() % screenSizeX/10 + screenSizeX * 9 / 20; star[i].y = rand() % screenSizeY / 10 + screenSizeY * 9 / 20; /* distance from screen center: */ star[i].dx = star[i].x - screenSizeX / 2; star[i].dy = star[i].y - screenSizeY / 2; /* it was created right in the middle: move it a little */ if( !star[i].dx && !star[i].dy) star[i].dx = 1; /* half the distance to the center: */ norm = sqrt( star[i].dx * star[i].dx + star[i].dy * star[i].dy ) / 2; if( norm < 1 ) norm = 1; /* Offsets normieren */ star[i].dx /= norm; star[i].dy /= norm; /* step counter for increasing star size: */ star[i].step = 1; rect.xLeft = star[i].x; rect.xRight = star[i].x + star[i].step / 22 + 1; rect.yBottom = star[i].y; rect.yTop = star[i].y + star[i].step / 22 + 1; WinFillRect( hps, &rect, CLR_WHITE ); } for( j = 0; j < (point_buffer_filled ? configuration_data.count : i + 1); j++){ /* move all stars */ rect.xLeft = star[j].x; rect.xRight = star[j].x + star[j].step / 22 + 1; rect.yBottom = star[j].y; rect.yTop = star[j].y + star[j].step / 22 + 1; WinFillRect( hps, &rect, CLR_BLACK ); star[j].step++; star[j].x += star[j].dx * star[j].step / 4; /* neu */ star[j].y += star[j].dy * star[j].step / 4; rect.xLeft = star[j].x; rect.xRight = star[j].x + star[j].step / 22 + 1; rect.yBottom = star[j].y; rect.yTop = star[j].y + star[j].step / 22 + 1; WinFillRect( hps, &rect, CLR_WHITE ); } i++; if( i==configuration_data.count ){ /* index wrap */ i = 0; point_buffer_filled = TRUE; free_star_field = FALSE; } if( point_buffer_filled ){ for( j = 0; j < configuration_data.count; j++){ /* check all stars whether they are still on screen */ if( star[j].x < - 10 || star[j].x > screenSizeX || star[j].y < -10 || star[j].y > screenSizeY ) { free_star_field = TRUE; i = j; break; } else { free_star_field = FALSE; } } } /* sleep if necessary */ if(low_priority == FALSE) DosSleep(1); /* sleep if user requests slower animation */ switch(configuration_data.animation_speed){ case 4: break; case 3: DosSleep(10); break; case 2: DosSleep(30); break; case 1: DosSleep(50); break; case 0: DosSleep(70); break; } } /* free resources */ free( star ); DosUnsetExceptionHandler(&xcpthand); _endthread(); }
PR_OS2_UnsetFloatExcpHandler(EXCEPTIONREGISTRATIONRECORD* excpreg) { /* unset exception handler */ APIRET rv = DosUnsetExceptionHandler(excpreg); PR_ASSERT(rv == NO_ERROR); }
ULONG _System Handler(PEXCEPTIONREPORTRECORD x, PEXCEPTIONREGISTRATIONRECORD y, PCONTEXTRECORD z, PVOID a) { ULONG rc; switch (x->ExceptionNum) { case XCPT_GUARD_PAGE_VIOLATION : case XCPT_UNABLE_TO_GROW_STACK : rc = XCPT_CONTINUE_SEARCH; break; case XCPT_ACCESS_VIOLATION : case XCPT_INTEGER_DIVIDE_BY_ZERO : case XCPT_FLOAT_DIVIDE_BY_ZERO : case XCPT_FLOAT_INVALID_OPERATION : case XCPT_ILLEGAL_INSTRUCTION : case XCPT_PRIVILEGED_INSTRUCTION : case XCPT_INTEGER_OVERFLOW : case XCPT_FLOAT_OVERFLOW : case XCPT_FLOAT_UNDERFLOW : case XCPT_FLOAT_DENORMAL_OPERAND : case XCPT_FLOAT_INEXACT_RESULT : case XCPT_FLOAT_STACK_CHECK : case XCPT_DATATYPE_MISALIGNMENT : case XCPT_ASYNC_PROCESS_TERMINATE: DosUnsetExceptionHandler(y); rc = XCPT_CONTINUE_SEARCH; break; default : rc = XCPT_CONTINUE_SEARCH; break; case XCPT_SIGNAL: switch (x->ExceptionInfo[0]) { case XCPT_SIGNAL_KILLPROC : { ALLPIDS *p = NULL; p = GetPid( GetEspProcessID() ); /**********************************************************************/ /* - if p==NULL, then the probe is being killed before starting */ /* to debug any processes. */ /**********************************************************************/ if( p == NULL) goto casexcpt_signal_intr; if( p->PidFlags.CtrlBreak == TRUE ) { /*********************************************************************/ /* - If we fall into this code, then the user is trying to do */ /* a Ctrl-Break: */ /* */ /* - Thread 1 is waiting on a DosDebug command. */ /* - The signal was sent by the esp queue in response to */ /* a Ctrl-Break message. */ /*********************************************************************/ p->PidFlags.CtrlBreak = FALSE; rc = XCPT_CONTINUE_EXECUTION; } else { /*********************************************************************/ /* - If we get here, then we're being killed by an external process */ /* such as PSPM2. We need to be a good citizen and die. */ /*********************************************************************/ rc = XCPT_CONTINUE_SEARCH; } } break; casexcpt_signal_intr: case XCPT_SIGNAL_INTR : case XCPT_SIGNAL_BREAK : { /***********************************************************************/ /* - Come here when the user enters a Ctrl-Break in the probe */ /* session. */ /***********************************************************************/ CloseConnectSema4(); ConnectClose( DEFAULT_HANDLE ); DosUnsetExceptionHandler(y); rc = XCPT_CONTINUE_SEARCH; } break; } break; } return(rc); }
int main( int argc, char **argv ) { APIRET rc; COMMAND cmd = {0,0}; int n; char *cp; char rc_string[12]; CONNECTION Connection; EXCEPTIONREGISTRATIONRECORD reg_rec; ESP_QUE_ELEMENT Qelement; if( argc == 1 ) SayMsg(HELP_INVOCATION_ESP); /****************************************************************************/ /* */ /* Parse the invocation options. */ /* */ /* - If this is a child debugger, then these additional parameters will */ /* precede the invocation parameters inherited from the parent. */ /* */ /* - /child=xxxxx where child = child debugger and */ /* xxxxx = child pid (for serial connections only.)*/ /* */ /* - /handle=xxxxx where handle = switch for com handle( serial only ) */ /* xxxxx = parent's com handle - inherited by */ /* the child. */ /* */ /****************************************************************************/ memset( &EspParms, 0, sizeof( ESP_PARMS ) ); memset( &Connection, 0, sizeof(Connection) ); if( strstr( argv[1], "/child" ) ) { ParseEspChildOptions( argc, argv, &EspParms, &Connection ); } else { ParseOptions( argc, argv, &EspParms, &Connection ); } printf("\nESP Version 5.00 \n");fflush(0); /****************************************************************************/ /* - Send connection info to the router. */ /****************************************************************************/ SendConnectionToRouter( &Connection ); /****************************************************************************/ /* - Make the connection. */ /****************************************************************************/ { int RcMoreInfo = 0; rc = ConnectInit( &RcMoreInfo ); if( rc != 0 ) { char BadConnectMsg[32] = ""; int MsgId; if( (Connection.ConnectType == _NETBIOS) && (RcMoreInfo != 0) ) { /*************************************************************************/ /* - handle netbios specific connect errors. */ /*************************************************************************/ n = 1; MsgId = ERR_NB_INADEQUATE_RESOURCES; switch( RcMoreInfo ) { case CANT_LOAD_NETB_DLL: n = 0; MsgId = ERR_NB_CANT_LOAD_DLL; break; case INADEQUATE_SESSIONS: strcpy( BadConnectMsg,"sessions"); break; case INADEQUATE_COMMANDS: strcpy( BadConnectMsg,"commands"); break; case INADEQUATE_NAMES: strcpy( BadConnectMsg,"names"); break; default: n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "NetBios error rc=%d", rc ); break; } } else if( (Connection.ConnectType == SOCKET) && (RcMoreInfo != 0) ) { /*************************************************************************/ /* - handle tcpip specific connect errors. */ /*************************************************************************/ switch( RcMoreInfo ) { case CANT_LOAD_TCPIP_DLL: n = 1; MsgId = ERR_TCPIP_CANT_LOAD_DLL; sprintf( BadConnectMsg, "%d", rc ); break; case TCPIP_NOT_RUNNING: n = 0; MsgId = ERR_TCPIP_NOT_RUNNING; break; case TCPIP_ERROR: n = 0; MsgId = ERR_TCPIP_ERROR; break; case TCPIP_NO_SERVICES_PORT: n = 0; MsgId = ERR_TCPIP_NO_SERVICES_PORT; break; default: n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "tcpip error rc=%d", rc ); break; } } else { /*************************************************************************/ /* - handle generic connect errors. */ /*************************************************************************/ n = 1; MsgId = ERR_BAD_CONNECT; sprintf( BadConnectMsg, "rc=%d", rc ); } ErrorPrintf( MsgId, n, BadConnectMsg ); } } /****************************************************************************/ /* - register an exception handler for the probe. */ /****************************************************************************/ reg_rec.ExceptionHandler = Handler; DosSetExceptionHandler(®_rec); /****************************************************************************/ /* - Add a connect sema4 for serial connections and wait to be posted. */ /****************************************************************************/ if( (SerialParallel() == SERIAL) && ( IsParent() == FALSE ) ) { USHORT EspPid; TIB *pTib; PIB *pPib; ALLPIDS *p; SetComHandle( EspParms.handle ); DosGetInfoBlocks(&pTib,&pPib); EspPid = (USHORT)pPib->pib_ulpid; CreateConnectSema4( EspPid, _ESP ); SerialConnect( JUST_WAIT, 0, _ESP, SendMsgToEspQue ); p = GetEspPid( EspPid ); p->Connect = CONNECTED; } /****************************************************************************/ /* - Each child debugger will have a termination que so we can kill the */ /* child debuggers on quit/restart. */ /****************************************************************************/ if( IsParent() == FALSE ) { rc = StartEspTermQue( ); if( rc != 0 ) { sprintf(rc_string, "%d",rc); ErrorPrintf( ERR_CANT_START_QUE, TRUE, 1, rc_string ); } } /****************************************************************************/ /* - Now, start the command processing loop. */ /****************************************************************************/ for(;;) { memset(&cmd,0,sizeof(cmd) ); RmtRecv(DEFAULT_HANDLE, (char*)&cmd, sizeof(cmd)); if( IsVerbose() ) PrintCmdMessage( cmd.api ) ; switch( cmd.api ) { case FINDEXE: RxFindExe(cmd); break; case STARTUSER: RxStartUser( cmd ); break; case GOINIT: RxGoInit(cmd); break; case GOENTRY: RxGoEntry(cmd); break; case DEFBRK: RxDefBrk(cmd); break; case UNDBRK: RxUndBrk(cmd); break; case PUTINBRK: RxPutInBrk(cmd); break; case PULLOUTBRK: RxPullOutBrk(cmd); break; case INSERTALLBRK: RxInsertAllBrk(); break; case REMOVEALLBRK: RxRemoveAllBrk(); break; case SELECT_SESSION: /*************************************************************************/ /* - Only the parent probe can select one of the debuggee sessions, so */ /* we send a message and tell him to do it. */ /*************************************************************************/ Qelement.ChildPid = GetEspProcessID(); SendMsgToEspQue( ESP_QMSG_SELECT_SESSION, &Qelement, sizeof(Qelement) ); memset(&cmd,0,sizeof(cmd) ); cmd.api = SELECT_SESSION; RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) ); break; case GOSTEP: RxGoStep(cmd); break; case GOFAST: RxGoFast(cmd); break; case DOSDEBUG: RxDosDebug( cmd ); break; case GETTHREADINFO: RxGetThreadInfo( cmd ); break; case FREEZETHREAD: RxFreezeThread( cmd ); break; case THAWTHREAD: RxThawThread( cmd ); break; case GETCALLSTACK: RxGetCallStack(cmd); break; case GETEXEORDLLENTRY: RxGetExeOrDllEntryOrExitPt(cmd); break; case NORMALQUIT: RxNormalQuit(cmd); /*************************************************************************/ /* - The que has to be up until after the normal quit because the */ /* system will need to post an end session message to the queue. */ /*************************************************************************/ if( IsParent() ) { if( SingleMultiple() == MULTIPLE ) { ALLPIDS *p; /***********************************************************************/ /* - Send a message to all of the child probes telling them that */ /* they are going to be killed. */ /***********************************************************************/ for( p = GetAllpids(); p ; p = p->next ) { if( (p->PidFlags.IsDebug) == TRUE && (p->pid != GetEspProcessID()) ) { ESP_QUE_ELEMENT Qelement; Qelement.ChildPid = p->EspPid; SendMsgToEspTermQue(ESP_PROBE_TERM, &Qelement, sizeof(Qelement) ); } } /***********************************************************************/ /* - send a message to the que to kill all the child probes and */ /* then wait until they are all dead. */ /***********************************************************************/ ResetAllProbesAreDeadFlag( ); SendMsgToEspQue(ESP_QMSG_PARENT_TERM,NULL,0); while( AllProbesAreDead() == FALSE ){ DosSleep(100) ;} } SendMsgToEspQue(ESP_QMSG_QUE_TERM,NULL,0); } CloseConnectSema4(); cmd.api = NORMALQUIT; cmd.len = sizeof(rc); /*************************************************************************/ /* - Now, tell dbg that we're finished normal quitting. */ /*************************************************************************/ RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) ); RmtSend(DEFAULT_HANDLE, &rc, cmd.len ); break; case SETEXECADDR: RxSetExecAddr(cmd); break; case DEFWPS: RxDefWps(cmd); break; case PUTINWPS: RxPutInWps(cmd); break; case PULLOUTWPS: RxPullOutWps(cmd); break; case GETDATABYTES: RxGetDataBytes(cmd); break; case GETMEMBLKS: RxGetMemBlocks(cmd); break; case SETXCPTNOTIFY: RxSetExceptions(cmd); break; case SETEXECTHREAD: RxSetExecThread(cmd); break; case WRITEREGS: RxWriteRegs(cmd); break; case GETCOREGS: RxGetCoRegs(cmd); break; case SETESPRUNOPTS: RxSetEspRunOpts(cmd); break; case TERMINATEESP: if( IsParent() == FALSE ) { memset( &Qelement, 0, sizeof(Qelement) ); Qelement.ChildPid = GetEspProcessID(); SendMsgToEspQue( ESP_QMSG_CHILD_TERM, &Qelement, sizeof(Qelement) ); } DosUnsetExceptionHandler(®_rec); RmtSend(DEFAULT_HANDLE, &cmd , sizeof(cmd) ); ConnectClose( DEFAULT_HANDLE ); exit(0); break; case START_QUE_LISTEN: SendMsgToEspQue(ESP_QMSG_OPEN_CONNECT,NULL,0); break; case START_ESP_QUE: RxStartEspQue(cmd); break; case CONNECT_ESP: /*************************************************************************/ /* - Serial connection only. */ /*************************************************************************/ { USHORT GoToPid; USHORT YieldPid; ALLPIDS *pYield; ALLPIDS *pGoTo; BOOL TorF; /************************************************************************/ /* - Receive the pid to be connected and mark it connected. */ /* - If this pid has not yet been assigned to a probe, then pGoTo */ /* will be NULL. */ /* - There MUST be a probe with a pid==0, so we release that probe. */ /* ( The pid will be stuffed into the structure at goinit() time.) */ /* - Post the connect sema4 for the goto pid. */ /************************************************************************/ RmtRecv( DEFAULT_HANDLE, &GoToPid, cmd.len ); pGoTo = GetPid( GoToPid ); if( pGoTo == NULL ) pGoTo = GetPid(0); pGoTo->Connect = CONNECTED; TorF = TRUE; if( GoToPid == GetEspProcessID() ) TorF = FALSE; /************************************************************************/ /* - Send back verification that the connection has been made. */ /************************************************************************/ memset(&cmd,0,sizeof(cmd) ); cmd.api = SERIAL_POLL; RmtSend( DEFAULT_HANDLE, &cmd, sizeof(cmd) ); PostConnectSema4( &pGoTo->ConnectSema4, TorF ); /************************************************************************/ /* - Disconnect/block this probe. */ /************************************************************************/ YieldPid = (USHORT)GetEspProcessID(); pYield = GetPid( YieldPid ); pYield->Connect = DISCONNECTED; SerialConnect( SET_WAIT, YieldPid, _ESP, SendMsgToEspQue ); } break; case CTRL_BREAK: { USHORT ThisPid; USHORT CtrlBreakPid; RmtRecv( DEFAULT_HANDLE, &CtrlBreakPid, cmd.len ); ThisPid = (USHORT)GetEspProcessID(); Qelement.ChildPid = CtrlBreakPid; Qelement.ChildSid = ThisPid; SendMsgToEspQue(ESP_QMSG_CTRL_BREAK, &Qelement, sizeof(Qelement)); SerialConnect( SET_WAIT, ThisPid, _ESP, SendMsgToEspQue ); } break; case SERIAL_POLL: ReportMessage(); break; default: cp = (char*)&cmd; for( n=1; n<=sizeof(cmd); n++,cp++) printf("%c",*cp); AsyncFlushModem(); break; } } }
void _cdecl main (SHORT argc, char *argv[]) { // bool ok = FALSE; // char test[5]; // test for trap 05 errors ULONG ulTimes; // need for Trap Ctrl-Break Signal #ifdef TESTING if(!dout) { DosBeep(500,300); } if(!memout) { DosBeep(1000,300); } #endif #ifdef ERR_HAND rc = set_int24(); if(rc != 0) { err_exit("Error initializing error handler", 3); } MYEXCEPTIONREGISTRATIONRECORD myExceptionRegRecord; myExceptionRegRecord.prev_structure = NULL; myExceptionRegRecord.ExceptionHandler = MyExceptionHandler; DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); DosSetSignalExceptionFocus(SIG_SETFOCUS, &ulTimes); if(setjmp(myExceptionRegRecord.env)) goto OnException; #endif DBG_INI(dout<<"file "<<__FILE__<<" line "<<__LINE__<<" settings.numlock_on = "<<settings.numlock_on<<endl); filesys_init(); get_current_directory(cwd); // init cur dir Mem::vmem_setup(); strcpy(exe_dir, *argv); // assume loaded via X:\subdir\KED.EXE DBG_FILE(dout << "EXE_DIR = " << exe_dir <<endl); DBG_MEM(memout<< " main after except setup "<< checkmem2 << endl); assure_windows_ready(); if(!thread_init()) { err_exit("Error creating initial threads", 5); } process_env_string ("EDITOR"); /* do parameters from environment string */ strcpy (progname,*argv); argc--; /* don't count program name */ argv++; while (argc--) { /* process each parameter */ process_arg (*argv); argv++; } if (!*settings.help_path) { /* help is usually in same dir as program */ delta_filename (settings.help_path, progname, "*.HLP"); } //#ifdef TESTING //if(!debug_on) { // dout.close(); // memout.close(); //} //#endif assure_1_view(); DBG_INI(dout<<"edit.cpp line "<<__LINE__<<" shell_command.s = °"<<settings.shell_command.s<<"°"<<endl); DBG_INI(dout<<"file "<<__FILE__<<" line "<<__LINE__<<" settings.numlock_on = "<<settings.numlock_on<<endl); // ok = load_keys(); // Version 2.08 // if(!ok) // err_exit("Failed to load Keyboard driver", 10); edit_loop(); // test[5000] = 'A'; // test trap array bounds goto Ked_Exit; OnException: #ifdef ERR_HAND DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); // Screen.term_mess = "application trapped"; err_exit(" application trapped", 20); #endif Ked_Exit: #ifdef ERR_HAND if(ORG_NUMLOCK) { DBG_NUML(dout<<" exit - setting NUMLOCK on"<<endl); numlock_set(TRUE); } else { DBG_NUML(dout<<" exit - setting NUMLOCK off"<<endl); numlock_set(FALSE); } DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD) &myExceptionRegRecord); #endif DBG_MEM(memout<< " main after except setup "<< checkmem2 << endl); DBG_BUGS(dout<<'\n'<<" Normal Closedown in LOGFILE "<<endl); }