int main(int argc, char *argv[]) { if (argc != 2) { fprintf(stderr, "Usage: %s port\n", argv[0]); exit(EXIT_FAILURE); } int pid = fork(); if(pid) { waitpid(pid, NULL, 0); } else { pid_t sid = setsid(); if (sid == (pid_t) -1) { perror("setsid"); _exit(EXIT_FAILURE); } AddrInit(); SetConnection(argv[1]); struct pollfd ufds[MAX_CLIENTS + 1]; int ufdsCount = 1; ufds[0].fd = sfd; ufds[0].events = POLLIN; gamesCount = 0; int curGame = 0; int rv; for (;;) { rv = poll(ufds, ufdsCount + 1, -1); if (rv == -1) { printf("poll Error"); perror("poll"); // error occurred in poll() } else { if (rv > 0) { // check for events on soket ( adding new clients) if (ufds[0].revents & POLLIN) { int new_cfd; // client fd struct sockaddr_storage peer_addr; socklen_t addr_size = sizeof(peer_addr); if ( (new_cfd = accept(sfd, (struct sockaddr *) &peer_addr, &addr_size)) == -1) { if(close(sfd) == -1) { _exit(EXIT_FAILURE);} perror("accept fail"); return 6; } if (new_cfd < MAX_CLIENTS ) { ufds[new_cfd].fd = new_cfd; ufds[new_cfd].events = POLLIN | POLLRDHUP; // check for just normal data ufdsCount = new_cfd; printf("creating new games[%d]\n", new_cfd); games[new_cfd].game_state = 0; } else { printf("New client dismist\n"); if(close(new_cfd) == -1) { _exit(EXIT_FAILURE);} continue; } //write_to_client(new_cfd, "cenected to server.\n"); printf("New client %d\n", new_cfd); int pair_player; if(new_cfd % 2 == 0) { pair_player = new_cfd + 1; games[new_cfd].setMesToBuf("Please wait for second player.\n"); ufds[new_cfd].events |= POLLOUT; continue; } else { pair_player = new_cfd - 1; } games[new_cfd].game_state = 1; games[pair_player].game_state = 1; games[new_cfd].setMesToBuf("Ready to play.\nYour tearn.\n"); games[pair_player].setMesToBuf("Ready to play.\nYour tearn.\n"); ufds[new_cfd].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; continue; } int i; char mes = ' '; for (i = 1; i <= ufdsCount; ++i) { if (ufds[i].revents & POLLRDHUP) { printf("POLLRDHUP ivent\n"); int pair_player; if(i % 2 == 0) { pair_player = i + 1; } else { pair_player = i - 1; } if(close(i) == -1) { _exit(EXIT_FAILURE);} if(close(pair_player) == -1) { _exit(EXIT_FAILURE);} //games[pair_player].setMesToBuf("You partner is off, game over.\n"); ufds[i].fd = -1; ufds[i].events = 0; ufds[pair_player].fd = -1; ufds[pair_player].events = 0; games.erase(i); games.erase(pair_player); printf("Game %d end %d is over. One of the players is off.\n", i, pair_player); continue; } if (ufds[i].revents & POLLOUT) { //printf("POLLOUT ivent\n"); if (games[i].len_out != 0) { int writen = write(ufds[i].fd, games[i].buf_out, games[i].len_out); //int writen = write(ufds[i].fd, "meage\n", 6); if (writen == -1) { printf("Write error\n"); //handle_error("write", ufds, inputs, i, &nfds); } else { games[i].len_out -= writen; printf("write game[%d].buf_out:%s, %zu\n", i, games[i].buf_out, games[i].len_out); if (games[i].len_out == 0) { ufds[i].events = POLLIN | POLLRDHUP; } } } } if (ufds[i].revents & POLLIN) { printf("POLLIN ivent\n"); nread = read(ufds[i].fd, games[i].buf_in + games[i].len_in, BUF_SIZE - games[i].len_in); if (nread == -1) { printf("reading tearn error\n"); continue; /* Ignore failed request */ } if (games[i].len_in + nread < BUF_SIZE) { games[i].len_in += nread; } else { printf("reading from client error, to long mes\n"); continue; } printf("Received %zu bytes from soket %d :%s\n", nread, ufds[i].fd, games[i].buf_in); if(games[i].game_state == 1) { if (games[i].state == 0) { printf("Player%d did tearn: %c\n", i, games[i].mes); games[i].handleIncomingData(); games[i].setMesToBuf("Your turn ecepted.\n"); ufds[i].events |= POLLOUT; } else { printf("Player%d did extra tearn: %c\n", i, games[i].mes); games[i].len_in = 0; games[i].setMesToBuf("Wait till your tern.\n"); ufds[i].events |= POLLOUT; continue; } } else { printf("Player %d has no partner.\n", i); games[i].setMesToBuf("Wait before second plyer conected.\n"); ufds[i].events |= POLLOUT; games[i].len_in = 0; continue; } int pair_player; if(i % 2 == 0) { pair_player = i + 1; } else { pair_player = i - 1; } //assert( games[i].state && games[pair_player].state); if(games[i].state == 1 && games[pair_player].state == 1) { printf("Got bouth tearns.\n", i); int res = Solve(games[i].mes, games[pair_player].mes); if(res == 0) { games[i].setMesToBuf("Nobody win!\n"); games[pair_player].setMesToBuf("Nobody win!\n"); ufds[i].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; } if(res == 1) { games[i].setMesToBuf("You win!\n"); games[pair_player].setMesToBuf("You lose!\n"); ufds[i].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; } if(res == 2) { games[i].setMesToBuf("You lose!\n"); games[pair_player].setMesToBuf("You win!\n"); ufds[i].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; } if(res == -1) { games[i].setMesToBuf("Wrong licsikon!\n"); games[pair_player].setMesToBuf("Wrong licsikon!\n"); ufds[i].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; } games[i].state = 0; games[pair_player].state = 0; games[i].setMesToBuf("Next game\nYour tearn!\n"); games[pair_player].setMesToBuf("Next game\nYour tearn!\n"); ufds[i].events |= POLLOUT; ufds[pair_player].events |= POLLOUT; printf("Game res:%d\n", res); } else { printf("Not bouth stre = 1.\n"); } } } } } } if(close(sfd) == -1) { _exit(EXIT_FAILURE);} } _exit(EXIT_SUCCESS); }
void ProcessSegmentLoadEvent( DEBUG_EVENT64 * pde, HTHDX hthdx ) /*++ Routine Description: This function takes care of dealing with segment load events from the wow system. These come in as exceptions and are translated to segment load events in ProcessDebugEvent. Arguments: pde - Supplies a pointer to the modified debug event hthdx - Supplies the handle to the thread of the debug event Return Value: None. --*/ { #if defined(i386) && !defined(WIN32S) PDWORDLONG lpdw = &pde->u.Exception.ExceptionRecord.ExceptionInformation[0]; int mode = LOWORD( (DWORD)lpdw[0] ); int cb; int cbRead; int b; char * lpb; WORD packetType = tlfDebugPacket; HEMI hemi; HPRCX hprcx = hthdx->hprc; int idx; SEGMENT_NOTE sn; ADDR addr; EXPECTED_EVENT * pee; DWORD eventCode; DWORD subClass; LDT_ENTRY ldt; BREAKPOINT *bp; DeWow = *pde; if ( !FVDMInitDone ) { HANDLE hmodVDM; hmodVDM = LoadLibrary("VDMDBG.DLL"); if ( hmodVDM != (HANDLE)NULL ) { FVDMActive = TRUE; pfnVDMProcessException = (VDMPROCESSEXCEPTIONPROC) GetProcAddress( hmodVDM, "VDMProcessException" ); pfnVDMGetPointer = (VDMGETPOINTERPROC) GetProcAddress( hmodVDM, "VDMGetPointer" ); pfnVDMGetThreadSelectorEntry = (VDMGETTHREADSELECTORENTRYPROC) GetProcAddress( hmodVDM, "VDMGetThreadSelectorEntry" ); pfnVDMGetThreadContext = (VDMGETCONTEXTPROC) GetProcAddress( hmodVDM, "VDMGetContext" ); pfnVDMSetThreadContext = (VDMSETCONTEXTPROC) GetProcAddress( hmodVDM, "VDMSetContext" ); pfnVDMGetSelectorModule = (VDMGETSELECTORMODULEPROC) GetProcAddress( hmodVDM, "VDMGetSelectorModule" ); pfnVDMEnumProcessWOW = (VDMENUMPROCESSWOWPROC) GetProcAddress( hmodVDM, "VDMEnumProcessWOW" ); } else { DMPrintShellMsg( _T("LoadLibrary(VDMDBG.DLL) failed\n")); } FVDMInitDone = TRUE; } if ( !FVDMActive ) { return; } else { DebugEvent64To32(pde, &DeWow32); (*pfnVDMProcessException)((LPDEBUG_EVENT)&DeWow32); DebugEvent32To64(&DeWow32, pde); } hthdx->fWowEvent = TRUE; switch ( mode ) { /* * SEG LOAD: * * LOWORD(lpdw[0]) --- DBG_SEGLOAD * HIWORD(lpdw[0]) --- Unused * LOWORD(lpdw[1]) --- Unused * HIWORD(lpdw[1]) --- Unused * lpdw[2] --- pointer to SEGMENT_NOTE structure * lpdw[3] --- Reserved */ case DBG_SEGLOAD: lpb = (char *) lpdw[2]; b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead); if ((b == 0) || (cbRead != sizeof(sn))) { b = GetLastError(); AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } if (sn.FileName[0] == 0) { AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } cb = _tcslen(sn.FileName)+1; idx = LookupDllName(hprcx, sn.FileName); if ( idx != -1 ) { if (hprcx->rgDllList[idx].fReal) { // // Changing from real to protected mode. We don't // support this, so we'll throw away what we have // and start from scratch. // WORD w = (WORD)idx; DMSendDebugPacket(dbceModFree16, hprcx->hpid, hthdx->htid, sizeof(WORD), &w ); RemoveDllName( hprcx, idx ); idx = -1; } } if (idx == -1) { LPMODULELOAD lpmdl; cb = cb + sizeof(MODULELOAD) + (sn.Segment+1)*sizeof(OBJD); lpmdl = (LPMODULELOAD) MHAlloc(cb); lpmdl->cobj = sn.Segment+1; lpmdl->rgobjd[sn.Segment].wSel = sn.Selector1; lpmdl->rgobjd[sn.Segment].cb = (DWORD) -1; lpmdl->rgobjd[sn.Segment].wPad = 1; lpmdl->mte = InsertDllName(hprcx, sn.FileName); _tcscpy((char *) &lpmdl->rgobjd[lpmdl->cobj], sn.FileName); lpmdl->fRealMode = FALSE; lpmdl->fFlatMode = FALSE; lpmdl->fOffset32 = FALSE; DMSendRequestReply(dbcModLoad, hprcx->hpid, hthdx->htid, cb, lpmdl, sizeof(HEMI), &hemi ); hemi = *((HEMI *) abEMReplyBuf); MHFree(lpmdl); AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); } else { SLI sli; sli.wSelector = sn.Selector1; sli.wSegNo = sn.Segment; sli.mte = idx; DMSendDebugPacket(dbceSegLoad, hprcx->hpid, hthdx->htid, sizeof(SLI), &sli ); } break; /* * SEGMOVE: * * This event will be triggered if a selector number * is to be changed. * * LOWORD( lpdw[0] ) - SEGMOVE * LOWORD( lpdw[1] ) - old selector number * HIWORD( lpdw[1] ) - new selector number */ case DBG_SEGMOVE: lpb = (char *) lpdw[2]; b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead); if ((b == 0) || (cbRead != sizeof(sn))) { b = GetLastError(); AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } if (sn.FileName[0] == 0) { AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } cb = _tcslen(sn.FileName)+1; idx = LookupDllName(hprcx, sn.FileName); if ( idx != -1 ) { SLI sli; assert( sn.Selector1 == 0 ); sli.wSelector = sn.Selector2; sli.wSegNo = sn.Segment; sli.mte = idx; DMSendDebugPacket(dbceSegMove, hprcx->hpid, hthdx->htid, sizeof(SLI), &sli ); } AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); break; /* * SEGFREE: * * This event is triggered if a selector is freed * * LOWORD( lpdw[0] ) - SEGFREE * HIWORD( lpdw[0] ) - fBPRelease * LOWORD( lpdw[1] ) - selector to be freed */ case DBG_SEGFREE: AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); break; /* * MODLOAD: * * This event is triggered when a new DLL is loaded * * LOWORD( lpdw[0] ) - MODLOAD * HIWORD( lpdw[0] ) - length of module name * HIWORD( lpdw[1] ) - selector * lpdw[2] - address of module name * lpdw[3] - image length * */ case DBG_MODLOAD: lpb = (char *) lpdw[2]; b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead); if ((b == 0) || (cbRead != sizeof(sn))) { b = GetLastError(); AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } if (sn.FileName[0] == 0) { AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } cb = _tcslen(sn.FileName)+1; idx = LookupDllName(hprcx, sn.FileName); if (idx == -1) { LPMODULELOAD lpmdl; cb = cb + sizeof(MODULELOAD); lpmdl = (LPMODULELOAD) MHAlloc(cb); lpmdl->cobj = 0; lpmdl->mte = InsertDllName(hprcx, sn.FileName); idx = LookupDllName(hprcx, sn.FileName); if ( idx != -1 ) { hprcx->rgDllList[idx].fReal = TRUE; } _tcscpy((char *) &lpmdl->rgobjd[lpmdl->cobj], sn.FileName); lpmdl->StartingSegment = sn.Segment; lpmdl->fRealMode = TRUE; lpmdl->fFlatMode = FALSE; lpmdl->fOffset32 = FALSE; DMSendRequestReply(dbcModLoad, hprcx->hpid, hthdx->htid, cb, lpmdl, sizeof(HEMI), &hemi ); MHFree(lpmdl); } AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); break; /* * MODFREE: * * This event is triggered when a DLL is unloaded * * LOWORD( lpdw[0] ) - MODFREE */ case DBG_MODFREE: lpb = (char *) lpdw[2]; b = DbgReadMemory(hprcx, (UINT_PTR)lpb, &sn, sizeof(sn), &cbRead); if ((b == 0) || (cbRead != sizeof(sn))) { b = GetLastError(); AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } if (sn.FileName[0] == 0) { AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); return; } cb = _tcslen(sn.FileName)+1; idx = LookupDllName(hprcx, sn.FileName); if (idx != -1) { WORD w = (WORD)idx; DMSendDebugPacket(dbceModFree16, hprcx->hpid, hthdx->htid, sizeof(WORD), &w ); RemoveDllName( hprcx, idx ); } AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); //hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); //hthdx->tstate |= ts_running; hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate & ~(ts_stopped|ts_first|ts_second)); hthdx->tstate = (TSTATEX)((DWORD)hthdx->tstate | (ts_running)); break; /* * Int 01h break; */ case DBG_SINGLESTEP: hthdx->context.ContextFlags = VDMCONTEXT_FULL; (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context); eventCode = EXCEPTION_DEBUG_EVENT; pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; pde->u.Exception.ExceptionRecord.ExceptionCode = subClass = (DWORD)EXCEPTION_SINGLE_STEP; /* * They are not clearing the trace bit */ hthdx->context.EFlags &= ~TF_BIT_MASK; hthdx->fContextDirty = TRUE; AddrInit(&addr, 0, (SEGMENT) hthdx->context.SegCs, SE32To64( hthdx->context.Eip ), FALSE, FALSE, FALSE, FALSE ); bp = FindBP(hthdx->hprc, hthdx, bptpExec, (BPNS)-1, &addr, FALSE); if ( bp ) { SetBPFlag( hthdx, bp ); } goto dispatch; case DBG_TASKSTART: hthdx->context.ContextFlags = VDMCONTEXT_FULL; (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context); eventCode = pde->dwDebugEventCode = ENTRYPOINT_DEBUG_EVENT; goto dispatch; case DBG_TASKSTOP: case DBG_DLLSTART: case DBG_DLLSTOP: case DBG_ATTACH: AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); hthdx->tstate |= ts_running; break; /* * Int 03h break * * LOWORD(lpdw[0]) --- BREAKPOINT * HIWORD(lpdw[0]) --- Protect Mode */ case DBG_BREAK: hthdx->context.ContextFlags = VDMCONTEXT_FULL; (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context); Set_PC(hthdx, PC(hthdx) - 1); hthdx->fContextDirty = TRUE; eventCode = pde->dwDebugEventCode = BREAKPOINT_DEBUG_EVENT; // NOTENOTE --- jimsch -- assuming only 0xcc not 0xcd 0x3 breakpoints AddrInit(&addr, 0, (SEGMENT) hthdx->context.SegCs, SE32To64( hthdx->context.Eip ), FALSE, FALSE, FALSE, FALSE ); bp = FindBP(hthdx->hprc, hthdx, bptpExec, (BPNS)-1, &addr, FALSE); if ( bp && bp->isStep ) { eventCode = EXCEPTION_DEBUG_EVENT; pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; pde->u.Exception.ExceptionRecord.ExceptionCode = subClass = (DWORD)EXCEPTION_SINGLE_STEP; RemoveBP(bp); } else { if ( bp ) { SetBPFlag( hthdx, bp ); } pde->u.Exception.ExceptionRecord.ExceptionCode = subClass = (DWORD)bp; } pde->u.Exception.ExceptionRecord.ExceptionAddress = PC(hthdx); dispatch: hthdx->fAddrIsReal = FALSE; hthdx->fAddrIsFlat = FALSE; DebugEvent64To32(pde, &DeWow32); if ((*pfnVDMGetThreadSelectorEntry)(&DeWow32, hthdx->rwHand, (WORD) hthdx->context.SegCs, &ldt)) { if (ldt.HighWord.Bits.Default_Big) { hthdx->fAddrOff32 = TRUE; } else { hthdx->fAddrOff32 = FALSE; } } else { hthdx->fAddrOff32 = FALSE; } /* * Check if this debug event was expected */ pee = PeeIsEventExpected(hthdx, eventCode, subClass, TRUE); /* * If it wasn't, run the standard handler with * notifications going to the execution model */ assert((0 < eventCode) && (eventCode < MAX_EVENT_CODE)); if (pee == NULL) { if ((hthdx != NULL) && (hthdx->tstate & ts_funceval)) { RgfnFuncEventDispatch[eventCode-EXCEPTION_DEBUG_EVENT](pde, hthdx); } else { DebugDispatchTable[eventCode-EXCEPTION_DEBUG_EVENT](pde,hthdx); } return; } /* * If it was expected then call the action * function if one was specified */ if (pee->action) { (pee->action)(pde, hthdx, 0, pee->lparam); } /* * And call the notifier if one was specified */ if (pee->notifier) { METHOD *nm = pee->notifier; (nm->notifyFunction)(pde, hthdx, 0, nm->lparam); } free(pee); break; #if 0 // why is this here?? case DBG_DIVOVERFLOW: pde->dwDebugEventCode = 3; goto fault_occured; case DBG_INSTRFAULT: pde->dwDebugEventCode = 1; goto fault_occured; #endif case DBG_DIVOVERFLOW: case DBG_INSTRFAULT: case DBG_GPFAULT: pde->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; #if 0 // why is this here?? fault_occured: #endif hthdx->context.ContextFlags = VDMCONTEXT_FULL; (*pfnVDMGetThreadContext)(hthdx->hprc->rwHand, hthdx->rwHand, &hthdx->context); pde->u.Exception.ExceptionRecord.ExceptionCode = 13; hthdx->fAddrIsReal = FALSE; hthdx->fAddrIsFlat = FALSE; DebugEvent64To32(pde, &DeWow32); if ((*pfnVDMGetThreadSelectorEntry)(&DeWow32, hthdx->rwHand, (WORD) hthdx->context.SegCs, &ldt)) { if (ldt.HighWord.Bits.Default_Big) { hthdx->fAddrOff32 = TRUE; } else { hthdx->fAddrOff32 = FALSE; } } else { hthdx->fAddrOff32 = FALSE; } ProcessExceptionEvent(pde, hthdx); break; default: AddQueue( QT_CONTINUE_DEBUG_EVENT, hthdx->hprc->pid, hthdx->tid, DBG_CONTINUE, 0); hthdx->tstate &= ~(ts_stopped|ts_first|ts_second); hthdx->tstate |= ts_running; break; } #endif // i386 && !Win32S return; } /* ProcessSegmentLoadEvent() */