void WIN32_Console() { AllocConsole(); SetConsoleTitle("DOSBox Debugger"); ResizeConsole(GetStdHandle(STD_OUTPUT_HANDLE),80,50); }
VOID CServiceModule::RunAsExecutable() { //Imago: we parents needs to keep track of our children #if defined(SRV_PARENT) InitPIDs(); #endif HRESULT hr; #if defined(SRV_PARENT) if (g.bRestarting == false) { ZVersionInfo vi; printf("%s\n%s\n\n", (LPCSTR)vi.GetFileDescription(), (LPCSTR)vi.GetLegalCopyright()); } #else #if !defined(SRV_CHILD) ZVersionInfo vi; printf("%s\n%s\n\n", (LPCSTR)vi.GetFileDescription(), (LPCSTR)vi.GetLegalCopyright()); #endif #endif if (IsWinNT()) printf("Running as an executable.\n"); printf("Initializing...\n"); hr = FedSrv_Init(); #if !defined(_CONSOLE) if (SUCCEEDED(hr)) { RunAsWindow(); return; } #endif if (SUCCEEDED(hr)) { HANDLE hConsole; printf("\rType 'Q' to Quit.\n"); printf("\rType 'P' to Pause.\n"); printf("\rType 'C' to Continue.\n"); hConsole = GetStdHandle(STD_INPUT_HANDLE); SetConsoleMode(hConsole, 0); SetConsoleCtrlHandler(HandlerRoutine, true); assert(g.hKillReceiveEvent); //Imago - parents restart everything after tricking the lobby into sending the client to our child #if defined(SRV_PARENT) g.bRestarting = false; #endif HANDLE hEventArray[] = { g.hKillReceiveEvent, hConsole }; DWORD dwAwaker; // // Wait until Receive Thread dies; if Q is pressed, kill Receive Thread // do { dwAwaker = MsgWaitForMultipleObjects(2, hEventArray, FALSE, INFINITE, 0); if (dwAwaker == WAIT_OBJECT_0 + 1) { INPUT_RECORD Key; DWORD dwRead; ReadConsoleInput(hConsole, &Key, 1, &dwRead); if (Key.EventType == KEY_EVENT && Key.Event.KeyEvent.wVirtualKeyCode == 'Q') { debugf("Q pressed\n"); SetEvent(g.hKillReceiveEvent); } if (Key.EventType == KEY_EVENT && Key.Event.KeyEvent.wVirtualKeyCode == 'P') { debugf("P pressed\n"); FedSrv_Pause(); } if (Key.EventType == KEY_EVENT && Key.Event.KeyEvent.wVirtualKeyCode == 'C') { debugf("C pressed\n"); FedSrv_Continue(); } } } while (dwAwaker != WAIT_OBJECT_0); FedSrv_Terminate(); // here is a good spot to restart -Imago #if defined(SRV_PARENT) if (g.bRestarting) RunAsExecutable(); #endif } else { printf("\rInitialization failed. (%x)\n", hr); } }
// ----------------------------------------------------------------- // // @details This is the entry point for the Win32 application. // // ----------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) { // // Create a console window for debugging and other output AllocConsole(); HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE); int hcrt = _open_osfhandle((long) hout, _O_TEXT); FILE* fout = _fdopen(hcrt, "w"); setvbuf(fout, NULL, _IONBF, 1); *stdout = *fout; HANDLE hin = GetStdHandle(STD_INPUT_HANDLE); hcrt = _open_osfhandle((long) hin, _O_TEXT); FILE* fin = _fdopen(hcrt, "r"); setvbuf(fin, NULL, _IONBF, 128); *stdin = *fin; // // Define a window class WNDCLASS wcl; wcl.hInstance = hInstance; wcl.lpszClassName = L"FaultTolerant"; wcl.lpfnWndProc = WinMessageHandler; wcl.cbClsExtra = 0; wcl.cbWndExtra = 0; wcl.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wcl.hIcon = LoadIcon(NULL, IDI_WINLOGO); wcl.hCursor = LoadCursor(NULL, IDC_ARROW); wcl.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcl.lpszMenuName=NULL; // // Register with Windows if (!RegisterClass(&wcl)) { return 0; } DWORD dwStyle = WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; DWORD dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // // Create the window HWND hwnd = CreateWindowEx( dwExStyle, L"FaultTolerant", L"FaultTolerantPriority - Demo", dwStyle, CW_USEDEFAULT,CW_USEDEFAULT, 500, 500, NULL, NULL, hInstance, NULL); SetFocus(hwnd); // // Obtain the client size of the window RECT rcClient; GetClientRect(hwnd, &rcClient); // // Initialize the application code g_app = std::make_shared<FaultTolerantApp>(hwnd, static_cast<uint16_t>(rcClient.right), static_cast<uint16_t>(rcClient.bottom)); g_app->initialize(); // // Display the window ShowWindow(hwnd, nShowCmd); // // Enter the Windows message loop MSG winMessage; while (GetMessage(&winMessage,NULL,0,0)) { TranslateMessage(&winMessage); DispatchMessage(&winMessage); g_app->pulse(); } g_app->terminate(); // // Disable a compiler warning complaining about WPARAM to int conversion. #pragma warning(push) #pragma warning(disable : 4244) return winMessage.wParam; #pragma warning(pop) }
// XXX: if this function returns <0 in rows or cols expect MAYHEM R_API int r_cons_get_size(int *rows) { #if __WINDOWS__ && !__CYGWIN__ CONSOLE_SCREEN_BUFFER_INFO csbi; GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &csbi); I.columns = csbi.srWindow.Right - csbi.srWindow.Left + 1; I.rows = csbi.srWindow.Bottom - csbi.srWindow.Top; // last row empty #elif EMSCRIPTEN I.columns = 80; I.rows = 23; #elif __UNIX__ || __CYGWIN__ struct winsize win; // use stdin as reference? //if (isatty (1) && ioctl (1, TIOCGWINSZ, &win) == 0) { if (isatty (0) && ioctl (0, TIOCGWINSZ, &win) == 0) { if (win.ws_col==0) { // TODO: use ttyname() ? int fd = open ("/dev/tty", O_RDONLY); if (fd != -1) { if (ioctl (fd, TIOCGWINSZ, &win) != 0) { I.columns = 80; I.rows = 23; } close (fd); } } I.columns = win.ws_col; I.rows = win.ws_row-1; } else { I.columns = 80; I.rows = 23; } #else char *str = r_sys_getenv ("COLUMNS"); if (str != NULL) { I.columns = atoi (str); I.rows = 23; // XXX. windows must get console size free (str); } else { I.columns = 80; I.rows = 23; } #endif #if SIMULATE_ADB_SHELL I.rows = 0; I.columns = 0; #endif #if SIMULATE_MAYHEM // expect tons of crashes I.rows = -1; I.columns = -1; #endif if (I.rows<0) I.rows = 0; if (I.columns<0) I.columns = 0; if (I.force_columns) I.columns = I.force_columns; if (I.force_rows) I.rows = I.force_rows; if (I.fix_columns) I.columns += I.fix_columns; if (I.fix_rows) I.rows += I.fix_rows; if (rows) *rows = I.rows; I.rows = R_MAX (0, I.rows); return R_MAX (0, I.columns); }
static int ConsoleCloseProc( ClientData instanceData, /* Pointer to ConsoleInfo structure. */ Tcl_Interp *interp) /* For error reporting. */ { ConsoleInfo *consolePtr = (ConsoleInfo *) instanceData; int errorCode; ConsoleInfo *infoPtr, **nextPtrPtr; ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); DWORD exitCode; errorCode = 0; /* * Clean up the background thread if necessary. Note that this * must be done before we can close the file, since the * thread may be blocking trying to read from the console. */ if (consolePtr->readThread) { /* * The thread may already have closed on it's own. Check it's * exit code. */ GetExitCodeThread(consolePtr->readThread, &exitCode); if (exitCode == STILL_ACTIVE) { /* * Set the stop event so that if the reader thread is blocked * in ConsoleReaderThread on WaitForMultipleEvents, it will exit * cleanly. */ SetEvent(consolePtr->stopReader); /* * Wait at most 20 milliseconds for the reader thread to close. */ if (WaitForSingleObject(consolePtr->readThread, 20) == WAIT_TIMEOUT) { /* * Forcibly terminate the background thread as a last * resort. Note that we need to guard against * terminating the thread while it is in the middle of * Tcl_ThreadAlert because it won't be able to release * the notifier lock. */ Tcl_MutexLock(&consoleMutex); /* BUG: this leaks memory. */ TerminateThread(consolePtr->readThread, 0); Tcl_MutexUnlock(&consoleMutex); } } CloseHandle(consolePtr->readThread); CloseHandle(consolePtr->readable); CloseHandle(consolePtr->startReader); CloseHandle(consolePtr->stopReader); consolePtr->readThread = NULL; } consolePtr->validMask &= ~TCL_READABLE; /* * Wait for the writer thread to finish the current buffer, then * terminate the thread and close the handles. If the channel is * nonblocking, there should be no pending write operations. */ if (consolePtr->writeThread) { if (consolePtr->toWrite) { /* * We only need to wait if there is something to write. * This may prevent infinite wait on exit. [python bug 216289] */ WaitForSingleObject(consolePtr->writable, INFINITE); } /* * The thread may already have closed on it's own. Check it's * exit code. */ GetExitCodeThread(consolePtr->writeThread, &exitCode); if (exitCode == STILL_ACTIVE) { /* * Set the stop event so that if the reader thread is blocked * in ConsoleWriterThread on WaitForMultipleEvents, it will * exit cleanly. */ SetEvent(consolePtr->stopWriter); /* * Wait at most 20 milliseconds for the writer thread to close. */ if (WaitForSingleObject(consolePtr->writeThread, 20) == WAIT_TIMEOUT) { /* * Forcibly terminate the background thread as a last * resort. Note that we need to guard against * terminating the thread while it is in the middle of * Tcl_ThreadAlert because it won't be able to release * the notifier lock. */ Tcl_MutexLock(&consoleMutex); /* BUG: this leaks memory. */ TerminateThread(consolePtr->writeThread, 0); Tcl_MutexUnlock(&consoleMutex); } } CloseHandle(consolePtr->writeThread); CloseHandle(consolePtr->writable); CloseHandle(consolePtr->startWriter); CloseHandle(consolePtr->stopWriter); consolePtr->writeThread = NULL; } consolePtr->validMask &= ~TCL_WRITABLE; /* * Don't close the Win32 handle if the handle is a standard channel * during the thread exit process. Otherwise, one thread may kill * the stdio of another. */ if (!TclInThreadExit() || ((GetStdHandle(STD_INPUT_HANDLE) != consolePtr->handle) && (GetStdHandle(STD_OUTPUT_HANDLE) != consolePtr->handle) && (GetStdHandle(STD_ERROR_HANDLE) != consolePtr->handle))) { if (CloseHandle(consolePtr->handle) == FALSE) { TclWinConvertError(GetLastError()); errorCode = errno; } } consolePtr->watchMask &= consolePtr->validMask; /* * Remove the file from the list of watched files. */ for (nextPtrPtr = &(tsdPtr->firstConsolePtr), infoPtr = *nextPtrPtr; infoPtr != NULL; nextPtrPtr = &infoPtr->nextPtr, infoPtr = *nextPtrPtr) { if (infoPtr == (ConsoleInfo *)consolePtr) { *nextPtrPtr = infoPtr->nextPtr; break; } } if (consolePtr->writeBuf != NULL) { ckfree(consolePtr->writeBuf); consolePtr->writeBuf = 0; } ckfree((char*) consolePtr); return errorCode; }
void Log::SetColor( const eColor background, const eColor text ) { HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE ); SetConsoleTextAttribute( hStdOut, (WORD)( ( getColorNum( background ) << 4 ) | getColorNum( text ) ) ); }
BOOL ProcessInputMessage(MSG64::MsgStr &msg, INPUT_RECORD &r) { memset(&r, 0, sizeof(r)); BOOL lbOk = FALSE; if (!UnpackInputRecord(&msg, &r)) { _ASSERT(FALSE); } else { TODO("Сделать обработку пачки сообщений, вдруг они накопились в очереди?"); //#ifdef _DEBUG //if (r.EventType == KEY_EVENT && (r.Event.KeyEvent.wVirtualKeyCode == 'C' || r.Event.KeyEvent.wVirtualKeyCode == VK_CANCEL)) //{ // DEBUGSTR(L" --- CtrlC/CtrlBreak recieved\n"); //} //#endif bool lbProcessEvent = false; bool lbIngoreKey = false; if (r.EventType == KEY_EVENT && r.Event.KeyEvent.bKeyDown && (r.Event.KeyEvent.wVirtualKeyCode == 'C' || r.Event.KeyEvent.wVirtualKeyCode == VK_CANCEL) && ( // Удерживается ТОЛЬКО Ctrl (r.Event.KeyEvent.dwControlKeyState & CTRL_MODIFIERS) && ((r.Event.KeyEvent.dwControlKeyState & ALL_MODIFIERS) == (r.Event.KeyEvent.dwControlKeyState & CTRL_MODIFIERS)) ) ) { lbProcessEvent = true; DEBUGSTR(L" --- CtrlC/CtrlBreak recieved\n"); DWORD dwMode = 0; GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &dwMode); // CTRL+C (and Ctrl+Break?) is processed by the system and is not placed in the input buffer if ((dwMode & ENABLE_PROCESSED_INPUT) == ENABLE_PROCESSED_INPUT) lbIngoreKey = lbProcessEvent = true; else lbProcessEvent = false; if (lbProcessEvent) { //BOOL lbRc = FALSE; #if 0 DWORD dwEvent = (r.Event.KeyEvent.wVirtualKeyCode == 'C') ? CTRL_C_EVENT : CTRL_BREAK_EVENT; #endif //&& (gpSrv->dwConsoleMode & ENABLE_PROCESSED_INPUT) #if 1 // Issue 590: GenerateConsoleCtrlEvent нифига не прерывает функцию ReadConsoleW SendMessage(ghConWnd, WM_KEYDOWN, r.Event.KeyEvent.wVirtualKeyCode, 0); //lbRc = TRUE; #endif #if 0 //The SetConsoleMode function can disable the ENABLE_PROCESSED_INPUT mode for a console's input buffer, //so CTRL+C is reported as keyboard input rather than as a signal. // CTRL+BREAK is always treated as a signal if ( // Удерживается ТОЛЬКО Ctrl (r.Event.KeyEvent.dwControlKeyState & CTRL_MODIFIERS) && ((r.Event.KeyEvent.dwControlKeyState & ALL_MODIFIERS) == (r.Event.KeyEvent.dwControlKeyState & CTRL_MODIFIERS)) ) { // Вроде работает, Главное не запускать процесс с флагом CREATE_NEW_PROCESS_GROUP // иначе у микрософтовской консоли (WinXP SP3) сносит крышу, и она реагирует // на Ctrl-Break, но напрочь игнорирует Ctrl-C lbRc = GenerateConsoleCtrlEvent(dwEvent, 0); // Это событие (Ctrl+C) в буфер помещается(!) иначе до фара не дойдет собственно клавиша C с нажатым Ctrl } #endif } if (lbIngoreKey) return FALSE; // CtrlBreak отсылаем СРАЗУ, мимо очереди, иначе макросы FAR нельзя стопнуть if (r.Event.KeyEvent.wVirtualKeyCode == VK_CANCEL) { // При получении CtrlBreak в реальной консоли - буфер ввода очищается // иначе фар, при попытке считать ввод получит старые, // еще не обработанные нажатия, и CtrlBreak проигнорирует FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); SendConsoleEvent(&r, 1); return FALSE; } } #ifdef _DEBUG if (r.EventType == KEY_EVENT && r.Event.KeyEvent.bKeyDown && r.Event.KeyEvent.wVirtualKeyCode == VK_F11) { DEBUGSTR(L" --- F11 recieved\n"); } #endif #ifdef _DEBUG if (r.EventType == MOUSE_EVENT) { static DWORD nLastEventTick = 0; if (nLastEventTick && (GetTickCount() - nLastEventTick) > 2000) { OutputDebugString(L".\n"); } wchar_t szDbg[60]; _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L" ConEmuC.MouseEvent(X=%i,Y=%i,Btns=0x%04x,Moved=%i)\n", r.Event.MouseEvent.dwMousePosition.X, r.Event.MouseEvent.dwMousePosition.Y, r.Event.MouseEvent.dwButtonState, (r.Event.MouseEvent.dwEventFlags & MOUSE_MOVED)); DEBUGLOGINPUT(szDbg); nLastEventTick = GetTickCount(); } #endif // Запомнить, когда была последняя активность пользователя if (r.EventType == KEY_EVENT || (r.EventType == MOUSE_EVENT && (r.Event.MouseEvent.dwButtonState || r.Event.MouseEvent.dwEventFlags || r.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK))) { gpSrv->dwLastUserTick = GetTickCount(); } lbOk = TRUE; //SendConsoleEvent(&r, 1); } return lbOk; }
/* ========================================================================= * Output a formatted unicode string. Ideally this will go to the console * and hence required WriteConsoleW to output it, however if file i/o is * redirected, it needs to be WriteFile'd using OEM (not ANSI) format * ========================================================================= */ static int __cdecl ATTRIB_wprintf(const WCHAR *format, ...) { static WCHAR *output_bufW = NULL; static char *output_bufA = NULL; static BOOL toConsole = TRUE; static BOOL traceOutput = FALSE; #define MAX_WRITECONSOLE_SIZE 65535 __ms_va_list parms; DWORD nOut; int len; DWORD res = 0; /* * Allocate buffer to use when writing to console * Note: Not freed - memory will be allocated once and released when * xcopy ends */ if (!output_bufW) output_bufW = HeapAlloc(GetProcessHeap(), 0, MAX_WRITECONSOLE_SIZE); if (!output_bufW) { WINE_FIXME("Out of memory - could not allocate 2 x 64K buffers\n"); return 0; } __ms_va_start(parms, format); SetLastError(NO_ERROR); len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, output_bufW, MAX_WRITECONSOLE_SIZE/sizeof(*output_bufW), &parms); __ms_va_end(parms); if (len == 0 && GetLastError() != NO_ERROR) { WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(format)); return 0; } /* Try to write as unicode all the time we think its a console */ if (toConsole) { res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), output_bufW, len, &nOut, NULL); } /* If writing to console has failed (ever) we assume its file i/o so convert to OEM codepage and output */ if (!res) { BOOL usedDefaultChar = FALSE; DWORD convertedChars; toConsole = FALSE; /* * Allocate buffer to use when writing to file. Not freed, as above */ if (!output_bufA) output_bufA = HeapAlloc(GetProcessHeap(), 0, MAX_WRITECONSOLE_SIZE); if (!output_bufA) { WINE_FIXME("Out of memory - could not allocate 2 x 64K buffers\n"); return 0; } /* Convert to OEM, then output */ convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, output_bufW, len, output_bufA, MAX_WRITECONSOLE_SIZE, "?", &usedDefaultChar); WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), output_bufA, convertedChars, &nOut, FALSE); } /* Trace whether screen or console */ if (!traceOutput) { WINE_TRACE("Writing to console? (%d)\n", toConsole); traceOutput = TRUE; } return nOut; }
CURLcode Curl_telnet(struct connectdata *conn) { CURLcode code; struct SessionHandle *data = conn->data; curl_socket_t sockfd = conn->sock[FIRSTSOCKET]; #ifdef WIN32 HMODULE wsock2; WSOCK2_FUNC close_event_func; WSOCK2_FUNC create_event_func; WSOCK2_FUNC event_select_func; WSOCK2_FUNC enum_netevents_func; WSAEVENT event_handle; WSANETWORKEVENTS events; HANDLE stdin_handle; HANDLE objs[2]; DWORD waitret; DWORD readfile_read; #else fd_set readfd; fd_set keepfd; #endif ssize_t nread; bool keepon = TRUE; char *buf = data->state.buffer; struct TELNET *tn; code = init_telnet(conn); if(code) return code; tn = (struct TELNET *)conn->proto.telnet; code = check_telnet_options(conn); if(code) return code; #ifdef WIN32 /* ** This functionality only works with WinSock >= 2.0. So, ** make sure have it. */ code = check_wsock2(data); if (code) return code; /* OK, so we have WinSock 2.0. We need to dynamically */ /* load ws2_32.dll and get the function pointers we need. */ wsock2 = LoadLibrary("WS2_32.DLL"); if (wsock2 == NULL) { failf(data,"failed to load WS2_32.DLL (%d)",GetLastError()); return CURLE_FAILED_INIT; } /* Grab a pointer to WSACreateEvent */ create_event_func = GetProcAddress(wsock2,"WSACreateEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACreateEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSACloseEvent */ close_event_func = GetProcAddress(wsock2,"WSACloseEvent"); if (create_event_func == NULL) { failf(data,"failed to find WSACloseEvent function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEventSelect */ event_select_func = GetProcAddress(wsock2,"WSAEventSelect"); if (event_select_func == NULL) { failf(data,"failed to find WSAEventSelect function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* And WSAEnumNetworkEvents */ enum_netevents_func = GetProcAddress(wsock2,"WSAEnumNetworkEvents"); if (enum_netevents_func == NULL) { failf(data,"failed to find WSAEnumNetworkEvents function (%d)", GetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* We want to wait for both stdin and the socket. Since ** the select() function in winsock only works on sockets ** we have to use the WaitForMultipleObjects() call. */ /* First, create a sockets event object */ event_handle = (WSAEVENT)create_event_func(); if (event_handle == WSA_INVALID_EVENT) { failf(data,"WSACreateEvent failed (%d)",WSAGetLastError()); FreeLibrary(wsock2); return CURLE_FAILED_INIT; } /* The get the Windows file handle for stdin */ stdin_handle = GetStdHandle(STD_INPUT_HANDLE); /* Create the list of objects to wait for */ objs[0] = stdin_handle; objs[1] = event_handle; /* Tell winsock what events we want to listen to */ if(event_select_func(sockfd, event_handle, FD_READ|FD_CLOSE) == SOCKET_ERROR) { close_event_func(event_handle); FreeLibrary(wsock2); return 0; } /* Keep on listening and act on events */ while(keepon) { waitret = WaitForMultipleObjects(2, objs, FALSE, INFINITE); switch(waitret - WAIT_OBJECT_0) { case 0: { unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer), &readfile_read, NULL)) { keepon = FALSE; break; } nread = readfile_read; while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } break; case 1: if(enum_netevents_func(sockfd, event_handle, &events) != SOCKET_ERROR) { if(events.lNetworkEvents & FD_READ) { /* This reallu OUGHT to check its return code. */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); telrcv(conn, (unsigned char *)buf, nread); fflush(stdout); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } if(events.lNetworkEvents & FD_CLOSE) { keepon = FALSE; } } break; } } /* We called WSACreateEvent, so call WSACloseEvent */ if (close_event_func(event_handle) == FALSE) { infof(data,"WSACloseEvent failed (%d)",WSAGetLastError()); } /* "Forget" pointers into the library we're about to free */ create_event_func = NULL; close_event_func = NULL; event_select_func = NULL; enum_netevents_func = NULL; /* We called LoadLibrary, so call FreeLibrary */ if (!FreeLibrary(wsock2)) infof(data,"FreeLibrary(wsock2) failed (%d)",GetLastError()); #else FD_ZERO (&readfd); /* clear it */ FD_SET (sockfd, &readfd); FD_SET (0, &readfd); keepfd = readfd; while (keepon) { struct timeval interval; readfd = keepfd; /* set this every lap in the loop */ interval.tv_sec = 1; interval.tv_usec = 0; switch (select (sockfd + 1, &readfd, NULL, NULL, &interval)) { case -1: /* error, stop reading */ keepon = FALSE; continue; case 0: /* timeout */ break; default: /* read! */ if(FD_ISSET(0, &readfd)) { /* read from stdin */ unsigned char outbuf[2]; int out_count = 0; ssize_t bytes_written; char *buffer = buf; nread = read(0, buf, 255); while(nread--) { outbuf[0] = *buffer++; out_count = 1; if(outbuf[0] == CURL_IAC) outbuf[out_count++] = CURL_IAC; Curl_write(conn, conn->sock[FIRSTSOCKET], outbuf, out_count, &bytes_written); } } if(FD_ISSET(sockfd, &readfd)) { /* This OUGHT to check the return code... */ (void)Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); /* if we receive 0 or less here, the server closed the connection and we bail out from this! */ if (nread <= 0) { keepon = FALSE; break; } telrcv(conn, (unsigned char *)buf, nread); /* Negotiate if the peer has started negotiating, otherwise don't. We don't want to speak telnet with non-telnet servers, like POP or SMTP. */ if(tn->please_negotiate && !tn->already_negotiated) { negotiate(conn); tn->already_negotiated = 1; } } } if(data->set.timeout) { struct timeval now; /* current time */ now = Curl_tvnow(); if(Curl_tvdiff(now, conn->created)/1000 >= data->set.timeout) { failf(data, "Time-out"); code = CURLE_OPERATION_TIMEOUTED; keepon = FALSE; } } } #endif /* mark this as "no further transfer wanted" */ Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL); return code; }
void print(std::wstring &str) { DWORD numCharsToWrite = str.length(); LPDWORD numCharsWritten = NULL; WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), str.c_str(), numCharsToWrite, numCharsWritten, NULL); }
int adb_main(int is_daemon, int server_port) { #if !ADB_HOST int port; char value[PROPERTY_VALUE_MAX]; umask(000); #endif atexit(adb_cleanup); #ifdef HAVE_WIN32_PROC SetConsoleCtrlHandler( ctrlc_handler, TRUE ); #elif defined(HAVE_FORKEXEC) // No SIGCHLD. Let the service subproc handle its children. signal(SIGPIPE, SIG_IGN); #endif init_transport_registration(); #if ADB_HOST HOST = 1; #ifdef WORKAROUND_BUG6558362 if(is_daemon) adb_set_affinity(); #endif usb_vendors_init(); usb_init(); local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); adb_auth_init(); char local_name[30]; build_local_name(local_name, sizeof(local_name), server_port); if(install_listener(local_name, "*smartsocket*", NULL, 0)) { exit(1); } #else property_get("ro.adb.secure", value, "0"); auth_enabled = !strcmp(value, "1"); if (auth_enabled) adb_auth_init(); // Our external storage path may be different than apps, since // we aren't able to bind mount after dropping root. const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); if (NULL != adb_external_storage) { setenv("EXTERNAL_STORAGE", adb_external_storage, 1); } else { D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" " unchanged.\n"); } /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ if (should_drop_privileges()) { drop_capabilities_bounding_set_if_needed(); /* add extra groups: ** AID_ADB to access the USB driver ** AID_LOG to read system logs (adb logcat) ** AID_INPUT to diagnose input issues (getevent) ** AID_INET to diagnose network issues (netcfg, ping) ** AID_GRAPHICS to access the frame buffer ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) ** AID_SDCARD_R to allow reading from the SD card ** AID_SDCARD_RW to allow writing to the SD card ** AID_NET_BW_STATS to read out qtaguid statistics */ gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS, AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_R, AID_SDCARD_RW, AID_NET_BW_STATS }; if (setgroups(sizeof(groups)/sizeof(groups[0]), groups) != 0) { exit(1); } /* then switch user and group to "shell" */ if (setgid(AID_SHELL) != 0) { exit(1); } if (setuid(AID_SHELL) != 0) { exit(1); } D("Local port disabled\n"); } else { char local_name[30]; build_local_name(local_name, sizeof(local_name), server_port); if(install_listener(local_name, "*smartsocket*", NULL, 0)) { exit(1); } } int usb = 0; if (access(USB_ADB_PATH, F_OK) == 0 || access(USB_FFS_ADB_EP0, F_OK) == 0) { // listen on USB usb_init(); usb = 1; } // If one of these properties is set, also listen on that port // If one of the properties isn't set and we couldn't listen on usb, // listen on the default port. property_get("service.adb.tcp.port", value, ""); if (!value[0]) { property_get("persist.adb.tcp.port", value, ""); } if (sscanf(value, "%d", &port) == 1 && port > 0) { printf("using port=%d\n", port); // listen on TCP port specified by service.adb.tcp.port property local_init(port); } else if (!usb) { // listen on default port local_init(DEFAULT_ADB_LOCAL_TRANSPORT_PORT); } D("adb_main(): pre init_jdwp()\n"); init_jdwp(); D("adb_main(): post init_jdwp()\n"); #endif if (is_daemon) { // inform our parent that we are up and running. #ifdef HAVE_WIN32_PROC DWORD count; WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); #elif defined(HAVE_FORKEXEC) fprintf(stderr, "OK\n"); #endif start_logging(); } D("Event loop starting\n"); fdevent_loop(); usb_cleanup(); return 0; }
int launch_server(int server_port) { #ifdef HAVE_WIN32_PROC /* we need to start the server in the background */ /* we create a PIPE that will be used to wait for the server's "OK" */ /* message since the pipe handles must be inheritable, we use a */ /* security attribute */ HANDLE pipe_read, pipe_write; HANDLE stdout_handle, stderr_handle; SECURITY_ATTRIBUTES sa; STARTUPINFO startup; PROCESS_INFORMATION pinfo; char program_path[ MAX_PATH ]; int ret; sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* create pipe, and ensure its read handle isn't inheritable */ ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); if (!ret) { fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); return -1; } SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); /* Some programs want to launch an adb command and collect its output by * calling CreateProcess with inheritable stdout/stderr handles, then * using read() to get its output. When this happens, the stdout/stderr * handles passed to the adb client process will also be inheritable. * When starting the adb server here, care must be taken to reset them * to non-inheritable. * Otherwise, something bad happens: even if the adb command completes, * the calling process is stuck while read()-ing from the stdout/stderr * descriptors, because they're connected to corresponding handles in the * adb server process (even if the latter never uses/writes to them). */ stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE ); stderr_handle = GetStdHandle( STD_ERROR_HANDLE ); if (stdout_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 ); } if (stderr_handle != INVALID_HANDLE_VALUE) { SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 ); } ZeroMemory( &startup, sizeof(startup) ); startup.cb = sizeof(startup); startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); startup.hStdOutput = pipe_write; startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); startup.dwFlags = STARTF_USESTDHANDLES; ZeroMemory( &pinfo, sizeof(pinfo) ); /* get path of current program */ GetModuleFileName( NULL, program_path, sizeof(program_path) ); ret = CreateProcess( program_path, /* program path */ "adb fork-server server", /* the fork-server argument will set the debug = 2 in the child */ NULL, /* process handle is not inheritable */ NULL, /* thread handle is not inheritable */ TRUE, /* yes, inherit some handles */ DETACHED_PROCESS, /* the new process doesn't have a console */ NULL, /* use parent's environment block */ NULL, /* use parent's starting directory */ &startup, /* startup info, i.e. std handles */ &pinfo ); CloseHandle( pipe_write ); if (!ret) { fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); CloseHandle( pipe_read ); return -1; } CloseHandle( pinfo.hProcess ); CloseHandle( pinfo.hThread ); /* wait for the "OK\n" message */ { char temp[3]; DWORD count; ret = ReadFile( pipe_read, temp, 3, &count, NULL ); CloseHandle( pipe_read ); if ( !ret ) { fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); return -1; } if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } } #elif defined(HAVE_FORKEXEC) char path[PATH_MAX]; int fd[2]; // set up a pipe so the child can tell us when it is ready. // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. if (pipe(fd)) { fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); return -1; } get_my_path(path, PATH_MAX); pid_t pid = fork(); if(pid < 0) return -1; if (pid == 0) { // child side of the fork // redirect stderr to the pipe // we use stderr instead of stdout due to stdout's buffering behavior. adb_close(fd[0]); dup2(fd[1], STDERR_FILENO); adb_close(fd[1]); char str_port[30]; snprintf(str_port, sizeof(str_port), "%d", server_port); // child process int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL); // this should not return fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); } else { // parent side of the fork char temp[3]; temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; // wait for the "OK\n" message adb_close(fd[1]); int ret = adb_read(fd[0], temp, 3); int saved_errno = errno; adb_close(fd[0]); if (ret < 0) { fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno); return -1; } if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { fprintf(stderr, "ADB server didn't ACK\n" ); return -1; } setsid(); } #else #error "cannot implement background server start on this platform" #endif return 0; }
int main() { DWORD dwRead, dwWrite; char *cmdLine; HANDLE hStdInput, hStdOutput, hStdError; HANDLE hFileInput, hFileOutput, hFileError; STARTUPINFO si; PROCESS_INFORMATION pi; char buf[8192]; DWORD result; hFileInput = INVALID_HANDLE_VALUE; hFileOutput = INVALID_HANDLE_VALUE; hFileError = INVALID_HANDLE_VALUE; result = 1; /* * Don't get command line from argc, argv, because the command line * tokenizer will have stripped off all the escape sequences needed * for quotes and backslashes, and then we'd have to put them all * back in again. Get the raw command line and parse off what we * want ourselves. The command line should be of the form: * * stub16.exe program arg1 arg2 ... */ cmdLine = strchr(GetCommandLine(), ' '); if (cmdLine == NULL) { return 1; } cmdLine++; hStdInput = GetStdHandle(STD_INPUT_HANDLE); hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); hStdError = GetStdHandle(STD_ERROR_HANDLE); if (GetFileType(hStdInput) == FILE_TYPE_PIPE) { hFileInput = CreateTempFile(); if (hFileInput == INVALID_HANDLE_VALUE) { goto cleanup; } while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) { if (dwRead == 0) { break; } if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) { goto cleanup; } } SetFilePointer(hFileInput, 0, 0, FILE_BEGIN); SetStdHandle(STD_INPUT_HANDLE, hFileInput); } if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) { hFileOutput = CreateTempFile(); if (hFileOutput == INVALID_HANDLE_VALUE) { goto cleanup; } SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput); } if (GetFileType(hStdError) == FILE_TYPE_PIPE) { hFileError = CreateTempFile(); if (hFileError == INVALID_HANDLE_VALUE) { goto cleanup; } SetStdHandle(STD_ERROR_HANDLE, hFileError); } ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == FALSE) { goto cleanup; } WaitForInputIdle(pi.hProcess, 5000); WaitForSingleObject(pi.hProcess, INFINITE); GetExitCodeProcess(pi.hProcess, &result); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); if (hFileOutput != INVALID_HANDLE_VALUE) { SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN); while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) { if (dwRead == 0) { break; } if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) { break; } } } if (hFileError != INVALID_HANDLE_VALUE) { SetFilePointer(hFileError, 0, 0, FILE_BEGIN); while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) { if (dwRead == 0) { break; } if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) { break; } } } cleanup: if (hFileInput != INVALID_HANDLE_VALUE) { CloseHandle(hFileInput); } if (hFileOutput != INVALID_HANDLE_VALUE) { CloseHandle(hFileOutput); } if (hFileError != INVALID_HANDLE_VALUE) { CloseHandle(hFileError); } CloseHandle(hStdInput); CloseHandle(hStdOutput); CloseHandle(hStdError); ExitProcess(result); return 1; }
void gotoxy(int x, int y) { COORD Pos = { x - 1, y - 1 }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), Pos); }
VOID Client( char* Server, char* Pipe ) { HANDLE *Connection; DWORD tid; MyStdInp=GetStdHandle(STD_INPUT_HANDLE); MyStdOut=GetStdHandle(STD_OUTPUT_HANDLE); WRITEF((VBuff,"**************************************\n")); WRITEF((VBuff,"*********** REMOTE ************\n")); WRITEF((VBuff,"*********** CLIENT ************\n")); WRITEF((VBuff,"**************************************\n")); if ((Connection=EstablishSession(Server,Pipe))==NULL) return; ReadPipe=Connection[0]; WritePipe=Connection[1]; SetConsoleCtrlHandler((PHANDLER_ROUTINE)Mych,TRUE); // Start Thread For Server --> Client Flow if ((iothreads[0]=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes. (DWORD)0, // Use same stack size. (LPTHREAD_START_ROUTINE)GetServerOut, // Thread procedure. (LPVOID)NULL, // Parameter to pass. (DWORD)0, // Run immediately. (LPDWORD)&tid))==NULL) // Thread identifier. { Errormsg("Could Not Create rwSrv2Cl Thread"); return; } // // Start Thread for Client --> Server Flow // if ((iothreads[1]=CreateThread((LPSECURITY_ATTRIBUTES)NULL, // No security attributes. (DWORD)0, // Use same stack size. (LPTHREAD_START_ROUTINE)SendServerInp, // Thread procedure. (LPVOID)NULL, // Parameter to pass. (DWORD)0, // Run immediately. (LPDWORD)&tid))==NULL) // Thread identifier. { Errormsg("Could Not Create rwSrv2Cl Thread"); return; } WaitForMultipleObjects(2,iothreads,FALSE,INFINITE); TerminateThread(iothreads[0],1); TerminateThread(iothreads[1],1); WRITEF((VBuff,"*** SESSION OVER ***\n")); }
HB_FHANDLE hb_fsProcessOpen( const char * pszFilename, HB_FHANDLE * phStdin, HB_FHANDLE * phStdout, HB_FHANDLE * phStderr, HB_BOOL fDetach, HB_ULONG * pulPID ) { HB_FHANDLE hPipeIn [ 2 ] = { FS_ERROR, FS_ERROR }, hPipeOut[ 2 ] = { FS_ERROR, FS_ERROR }, hPipeErr[ 2 ] = { FS_ERROR, FS_ERROR }; HB_FHANDLE hResult = FS_ERROR; HB_BOOL fError = HB_FALSE; HB_TRACE( HB_TR_DEBUG, ( "hb_fsProcessOpen(%s, %p, %p, %p, %d, %p)", pszFilename, phStdin, phStdout, phStderr, fDetach, pulPID ) ); if( phStdin != NULL ) fError = ! hb_fsPipeCreate( hPipeIn ); if( ! fError && phStdout != NULL ) fError = ! hb_fsPipeCreate( hPipeOut ); if( ! fError && phStderr != NULL ) { if( phStdout == phStderr ) { hPipeErr[ 0 ] = hPipeOut[ 0 ]; hPipeErr[ 1 ] = hPipeOut[ 1 ]; } else fError = ! hb_fsPipeCreate( hPipeErr ); } if( ! fError ) { #if defined( HB_OS_WIN ) PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwFlags = 0; LPTSTR lpCommand = HB_CHARDUP( pszFilename ); memset( &pi, 0, sizeof( pi ) ); memset( &si, 0, sizeof( si ) ); si.cb = sizeof( si ); # ifdef STARTF_USESTDHANDLES si.dwFlags = STARTF_USESTDHANDLES; # endif if( fDetach ) { # ifdef STARTF_USESHOWWINDOW si.dwFlags |= STARTF_USESHOWWINDOW; # endif si.wShowWindow = SW_HIDE; si.hStdInput = ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ); si.hStdOutput = ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ); si.hStdError = ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ); # ifdef DETACHED_PROCESS dwFlags |= DETACHED_PROCESS; # endif } else { si.hStdInput = phStdin ? ( HANDLE ) hb_fsGetOsHandle( hPipeIn [ 0 ] ) : GetStdHandle( STD_INPUT_HANDLE ); si.hStdOutput = phStdout ? ( HANDLE ) hb_fsGetOsHandle( hPipeOut[ 1 ] ) : GetStdHandle( STD_OUTPUT_HANDLE ); si.hStdError = phStderr ? ( HANDLE ) hb_fsGetOsHandle( hPipeErr[ 1 ] ) : GetStdHandle( STD_ERROR_HANDLE ); } fError = ! CreateProcess( NULL, /* lpAppName */ lpCommand, NULL, /* lpProcessAttr */ NULL, /* lpThreadAttr */ TRUE, /* bInheritHandles */ dwFlags, /* dwCreationFlags */ NULL, /* lpEnvironment */ NULL, /* lpCurrentDirectory */ &si, &pi ); hb_fsSetIOError( ! fError, 0 ); hb_xfree( lpCommand ); if( ! fError ) { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pi.dwProcessId; CloseHandle( pi.hThread ); hResult = ( HB_FHANDLE ) pi.hProcess; } #elif defined( HB_OS_UNIX ) && \ ! defined( HB_OS_VXWORKS ) && ! defined( HB_OS_SYMBIAN ) pid_t pid = fork(); if( pid == -1 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } else /* child process */ { if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "/dev/null", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) hb_fsClose( hNull ); } if( phStdin != NULL ) { dup2( hPipeIn[ 0 ], 0 ); hb_fsClose( hPipeIn[ 1 ] ); } if( phStdout != NULL ) { dup2( hPipeOut[ 1 ], 1 ); hb_fsClose( hPipeOut[ 0 ] ); } if( phStderr != NULL ) { dup2( hPipeErr[ 1 ], 2 ); if( phStdout != phStderr ) hb_fsClose( hPipeErr[ 0 ] ); } /* close all non std* handles */ { int iMaxFD, i; iMaxFD = sysconf( _SC_OPEN_MAX ); if( iMaxFD < 3 ) iMaxFD = 1024; for( i = 3; i < iMaxFD; ++i ) hb_fsClose( i ); } /* reset extended process attributes */ setuid( getuid() ); setgid( getgid() ); /* execute command */ { char ** argv; argv = hb_buildArgs( pszFilename ); # if defined( __WATCOMC__ ) execvp( argv[ 0 ], ( const char ** ) argv ); # else execvp( argv[ 0 ], argv ); # endif hb_freeArgs( argv ); exit( -1 ); } } #elif defined( HB_OS_OS2 ) || defined( HB_OS_WIN ) int hStdIn, hStdOut, hStdErr; char ** argv; int pid; hStdIn = dup( 0 ); hStdOut = dup( 1 ); hStdErr = dup( 2 ); if( fDetach && ( ! phStdin || ! phStdout || ! phStderr ) ) { HB_FHANDLE hNull = open( "NUL:", O_RDWR ); if( ! phStdin ) dup2( hNull, 0 ); if( ! phStdout ) dup2( hNull, 1 ); if( ! phStderr ) dup2( hNull, 2 ); if( hNull != FS_ERROR ) close( hNull ); } if( phStdin != NULL ) dup2( hPipeIn[ 0 ], 0 ); if( phStdout != NULL ) dup2( hPipeOut[ 1 ], 1 ); if( phStderr != NULL ) dup2( hPipeErr[ 1 ], 2 ); argv = hb_buildArgs( pszFilename ); #if defined( _MSC_VER ) || defined( __LCC__ ) || \ defined( __XCC__ ) || defined( __POCC__ ) pid = _spawnvp( _P_NOWAIT, argv[ 0 ], argv ); #elif defined( __MINGW32__ ) || defined( __WATCOMC__ ) pid = spawnvp( P_NOWAIT, argv[ 0 ], ( const char * const * ) argv ); #else pid = spawnvp( P_NOWAIT, argv[ 0 ], ( char * const * ) argv ); #endif hb_freeArgs( argv ); dup2( hStdIn, 0 ); close( hStdIn ); dup2( hStdOut, 1 ); close( hStdOut ); dup2( hStdErr, 2 ); close( hStdErr ); if( pid < 0 ) fError = HB_TRUE; else if( pid != 0 ) /* parent process */ { if( phStdin != NULL ) { *phStdin = ( HB_FHANDLE ) hPipeIn[ 1 ]; hPipeIn[ 1 ] = FS_ERROR; } if( phStdout != NULL ) { *phStdout = ( HB_FHANDLE ) hPipeOut[ 0 ]; hPipeOut[ 0 ] = FS_ERROR; } if( phStderr != NULL ) { *phStderr = ( HB_FHANDLE ) hPipeErr[ 0 ]; hPipeErr[ 0 ] = FS_ERROR; } if( pulPID ) *pulPID = pid; hResult = ( HB_FHANDLE ) pid; } #else int iTODO; /* TODO: for given platform */ HB_SYMBOL_UNUSED( pszFilename ); HB_SYMBOL_UNUSED( fDetach ); HB_SYMBOL_UNUSED( pulPID ); hb_fsSetError( ( HB_ERRCODE ) FS_ERROR ); #endif } hb_fsSetIOError( ! fError, 0 ); if( hPipeIn[ 0 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 0 ] ); if( hPipeIn[ 1 ] != FS_ERROR ) hb_fsClose( hPipeIn[ 1 ] ); if( hPipeOut[ 0 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 0 ] ); if( hPipeOut[ 1 ] != FS_ERROR ) hb_fsClose( hPipeOut[ 1 ] ); if( phStdout != phStderr ) { if( hPipeErr[ 0 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 0 ] ); if( hPipeErr[ 1 ] != FS_ERROR ) hb_fsClose( hPipeErr[ 1 ] ); } return hResult; }
void AppenderConsole::SetColor(bool stdout_stream, ColorTypes color) { #if TRINITY_PLATFORM == TRINITY_PLATFORM_WINDOWS static WORD WinColorFG[MaxColors] = { 0, // BLACK FOREGROUND_RED, // RED FOREGROUND_GREEN, // GREEN FOREGROUND_RED | FOREGROUND_GREEN, // BROWN FOREGROUND_BLUE, // BLUE FOREGROUND_RED | FOREGROUND_BLUE, // MAGENTA FOREGROUND_GREEN | FOREGROUND_BLUE, // CYAN FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // WHITE // YELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, // RED_BOLD FOREGROUND_RED | FOREGROUND_INTENSITY, // GREEN_BOLD FOREGROUND_GREEN | FOREGROUND_INTENSITY, FOREGROUND_BLUE | FOREGROUND_INTENSITY, // BLUE_BOLD // MAGENTA_BOLD FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // CYAN_BOLD FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, // WHITE_BOLD FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; HANDLE hConsole = GetStdHandle(stdout_stream ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); SetConsoleTextAttribute(hConsole, WinColorFG[color]); #else enum ANSITextAttr { TA_NORMAL = 0, TA_BOLD = 1, TA_BLINK = 5, TA_REVERSE = 7 }; enum ANSIFgTextAttr { FG_BLACK = 30, FG_RED, FG_GREEN, FG_BROWN, FG_BLUE, FG_MAGENTA, FG_CYAN, FG_WHITE, FG_YELLOW }; enum ANSIBgTextAttr { BG_BLACK = 40, BG_RED, BG_GREEN, BG_BROWN, BG_BLUE, BG_MAGENTA, BG_CYAN, BG_WHITE }; static uint8 UnixColorFG[MaxColors] = { FG_BLACK, // BLACK FG_RED, // RED FG_GREEN, // GREEN FG_BROWN, // BROWN FG_BLUE, // BLUE FG_MAGENTA, // MAGENTA FG_CYAN, // CYAN FG_WHITE, // WHITE FG_YELLOW, // YELLOW FG_RED, // LRED FG_GREEN, // LGREEN FG_BLUE, // LBLUE FG_MAGENTA, // LMAGENTA FG_CYAN, // LCYAN FG_WHITE // LWHITE }; fprintf((stdout_stream? stdout : stderr), "\x1b[%d%sm", UnixColorFG[color], (color >= YELLOW && color < MaxColors ? ";1" : "")); #endif }
BOOL SendConsoleEvent(INPUT_RECORD* pr, UINT nCount) { if (!nCount || !pr) { _ASSERTE(nCount>0 && pr!=NULL); return FALSE; } BOOL fSuccess = FALSE; //// Если сейчас идет ресайз - нежелательно помещение в буфер событий //if (gpSrv->bInSyncResize) // WaitForSingleObject(gpSrv->hAllowInputEvent, MAX_SYNCSETSIZE_WAIT); //DWORD nCurInputCount = 0, cbWritten = 0; //INPUT_RECORD irDummy[2] = {{0},{0}}; //HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); // тут был ghConIn // 02.04.2010 Maks - перенесено в WaitConsoleReady //// 27.06.2009 Maks - If input queue is not empty - wait for a while, to avoid conflicts with FAR reading queue //// 19.02.2010 Maks - замена на GetNumberOfConsoleInputEvents ////if (PeekConsoleInput(hIn, irDummy, 1, &(nCurInputCount = 0)) && nCurInputCount > 0) { //if (GetNumberOfConsoleInputEvents(hIn, &(nCurInputCount = 0)) && nCurInputCount > 0) { // DWORD dwStartTick = GetTickCount(); // WARNING("Do NOT wait, but place event in Cyclic queue"); // do { // Sleep(5); // //if (!PeekConsoleInput(hIn, irDummy, 1, &(nCurInputCount = 0))) // if (!GetNumberOfConsoleInputEvents(hIn, &(nCurInputCount = 0))) // nCurInputCount = 0; // } while ((nCurInputCount > 0) && ((GetTickCount() - dwStartTick) < MAX_INPUT_QUEUE_EMPTY_WAIT)); //} INPUT_RECORD* prNew = NULL; int nAllCount = 0; BOOL lbReqEmpty = FALSE; for (UINT n = 0; n < nCount; n++) { if (pr[n].EventType != KEY_EVENT) { nAllCount++; if (!lbReqEmpty && (pr[n].EventType == MOUSE_EVENT)) { // По всей видимости дурит консоль Windows. // Если в буфере сейчас еще есть мышиные события, то запись // в буфер возвращает ОК, но считывающее приложение получает 0-событий. // В итоге, получаем пропуск некоторых событий, что очень неприятно // при выделении кучи файлов правой кнопкой мыши (проводкой с зажатой кнопкой) if (pr[n].Event.MouseEvent.dwButtonState /*== RIGHTMOST_BUTTON_PRESSED*/) lbReqEmpty = TRUE; } } else { if (!pr[n].Event.KeyEvent.wRepeatCount) { _ASSERTE(pr[n].Event.KeyEvent.wRepeatCount!=0); pr[n].Event.KeyEvent.wRepeatCount = 1; } nAllCount += pr[n].Event.KeyEvent.wRepeatCount; } } if (nAllCount > (int)nCount) { prNew = (INPUT_RECORD*)malloc(sizeof(INPUT_RECORD)*nAllCount); if (prNew) { INPUT_RECORD* ppr = prNew; INPUT_RECORD* pprMod = NULL; for (UINT n = 0; n < nCount; n++) { *(ppr++) = pr[n]; if (pr[n].EventType == KEY_EVENT) { UINT nCurCount = pr[n].Event.KeyEvent.wRepeatCount; if (nCurCount > 1) { pprMod = (ppr-1); pprMod->Event.KeyEvent.wRepeatCount = 1; for (UINT i = 1; i < nCurCount; i++) { *(ppr++) = *pprMod; } } } else if (!lbReqEmpty && (pr[n].EventType == MOUSE_EVENT)) { // По всей видимости дурит консоль Windows. // Если в буфере сейчас еще есть мышиные события, то запись // в буфер возвращает ОК, но считывающее приложение получает 0-событий. // В итоге, получаем пропуск некоторых событий, что очень неприятно // при выделении кучи файлов правой кнопкой мыши (проводкой с зажатой кнопкой) if (pr[n].Event.MouseEvent.dwButtonState == RIGHTMOST_BUTTON_PRESSED) lbReqEmpty = TRUE; } } pr = prNew; _ASSERTE(nAllCount == (ppr-prNew)); nCount = (UINT)(ppr-prNew); } } // Если не готов - все равно запишем DEBUGTEST(BOOL bConReady = ) WaitConsoleReady(lbReqEmpty); DWORD cbWritten = 0; #ifdef _DEBUG wchar_t* pszDbgCurChars = NULL; wchar_t szDbg[255]; for (UINT i = 0; i < nCount; i++) { switch (pr[i].EventType) { case MOUSE_EVENT: _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"*** ConEmuC.MouseEvent(X=%i,Y=%i,Btns=0x%04x,Moved=%i)\n", pr[i].Event.MouseEvent.dwMousePosition.X, pr[i].Event.MouseEvent.dwMousePosition.Y, pr[i].Event.MouseEvent.dwButtonState, (pr[i].Event.MouseEvent.dwEventFlags & MOUSE_MOVED)); DEBUGSTRINPUTWRITE(szDbg); #ifdef _DEBUG { static int LastMsButton; if ((LastMsButton & 1) && (pr[i].Event.MouseEvent.dwButtonState == 0)) { // LButton was Down, now - Up LastMsButton = pr[i].Event.MouseEvent.dwButtonState; } else if (!LastMsButton && (pr[i].Event.MouseEvent.dwButtonState & 1)) { // LButton was Up, now - Down LastMsButton = pr[i].Event.MouseEvent.dwButtonState; } else { //-V523 LastMsButton = pr[i].Event.MouseEvent.dwButtonState; } } #endif break; case KEY_EVENT: { wchar_t szCh[3] = {pr[i].Event.KeyEvent.uChar.UnicodeChar}; switch (szCh[0]) { case 8: szCh[0] = L'\\'; szCh[1] = L'b'; break; case 9: szCh[0] = L'\\'; szCh[1] = L't'; break; case 10: szCh[0] = L'\\'; szCh[1] = L'r'; break; case 13: szCh[0] = L'\\'; szCh[1] = L'n'; break; case 27: szCh[0] = L'\\'; szCh[1] = L'e'; break; } _wsprintf(szDbg, SKIPLEN(countof(szDbg)) L"*** ConEmuC.KeybdEvent(%s, VK=%u, CH=%s)\n", pr[i].Event.KeyEvent.bKeyDown ? L"Dn" : L"Up", pr[i].Event.KeyEvent.wVirtualKeyCode, szCh); DEBUGSTRINPUTWRITE(szDbg); } break; } // Only for input_bug search purposes in Debug builds LONG idx = (InterlockedIncrement(&gn_LogWrittenChars) & (gn_LogWrittenCharsMax-1))*2; if (!pszDbgCurChars) pszDbgCurChars = gs_LogWrittenChars+idx; if (pr[i].EventType == KEY_EVENT) { gs_LogWrittenChars[idx++] = pr[i].Event.KeyEvent.bKeyDown ? L'\\' : L'/'; gs_LogWrittenChars[idx] = pr[i].Event.KeyEvent.uChar.UnicodeChar ? pr[i].Event.KeyEvent.uChar.UnicodeChar : L'.'; } else { gs_LogWrittenChars[idx++] = L'='; switch (pr[i].EventType) { case MOUSE_EVENT: gs_LogWrittenChars[idx] = L'm'; break; case WINDOW_BUFFER_SIZE_EVENT: gs_LogWrittenChars[idx] = L'w'; break; case MENU_EVENT: gs_LogWrittenChars[idx] = L'e'; break; case FOCUS_EVENT: gs_LogWrittenChars[idx] = L'f'; break; default: gs_LogWrittenChars[idx] = L'x'; break; } } gs_LogWrittenChars[++idx] = 0; } int nDbgSendLen = pszDbgCurChars ? lstrlen(pszDbgCurChars) : -1; SetLastError(0); #endif HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE); // тут был ghConIn // Strange VIM reaction on xterm-keypresses if ((nCount > 2) && (nCount <= 32) && (pr->EventType == KEY_EVENT) && (pr->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) { DWORD nWritten = 0; cbWritten = 0; for (UINT n = 0; n < nCount; n++) { if ((n + 1) == nCount) { DEBUGTEST(bConReady = ) WaitConsoleReady(TRUE); } fSuccess = WriteConsoleInput(hIn, pr+n, 1, &nWritten); if (fSuccess) cbWritten += nWritten; }
void setTextColor(Color color) { if (!isConsoleTty()) { return; } if (color > Color::BrightMagenta) { color = Color::Default; } #ifdef _WIN32 static WORD winColors[] = { // default FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, // main FOREGROUND_BLUE, FOREGROUND_GREEN, FOREGROUND_RED, FOREGROUND_RED | FOREGROUND_GREEN, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE, FOREGROUND_GREEN | FOREGROUND_BLUE, FOREGROUND_RED | FOREGROUND_BLUE, // bright FOREGROUND_BLUE | FOREGROUND_INTENSITY, FOREGROUND_GREEN | FOREGROUND_INTENSITY, FOREGROUND_RED | FOREGROUND_INTENSITY, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY, FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY }; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), winColors[static_cast<size_t>(color)]); #else static const char* ansiColors[] = { // default "\033[0m", // main "\033[0;34m", "\033[0;32m", "\033[0;31m", "\033[0;33m", "\033[0;37m", "\033[0;36m", "\033[0;35m", // bright "\033[1;34m", "\033[1;32m", "\033[1;31m", "\033[1;33m", "\033[1;37m", "\033[1;36m", "\033[1;35m" }; std::cout << ansiColors[static_cast<size_t>(color)]; #endif }
/// Main function int Master::Run() { BigNumber seed1; seed1.SetRand(16 * 8); sLog->outString("%s (worldserver-daemon)", _FULLVERSION); sLog->outString("<Ctrl-C> to stop.\n"); sLog->outString(" "); sLog->outString(" ______ __ __ __ __ ______ __ ______ ______ "); sLog->outString(" /\\ ___\\/\\ \\/ / /\\ \\_\\ \\/\\ ___/\\ \\/\\ == \\/\\ ___\\ "); sLog->outString(" \\ \\___ \\ \\ _'-\\ \\____ \\ \\ __\\ \\ \\ \\ __<\\ \\ __\\ "); sLog->outString(" \\/\\_____\\ \\_\\ \\_\\/\\_____\\ \\_\\ \\ \\_\\ \\_\\ \\_\\ \\_____\\ "); sLog->outString(" \\/_____/\\/_/\\/_/\\/_____/\\/_/ \\/_/\\/_/ /_/\\/_____/ "); sLog->outString(" Project SkyFireEmu 2012(c) Open-sourced Game Emulation "); sLog->outString(" <http://www.projectskyfire.org/> "); sLog->outString(" "); #ifdef USE_SFMT_FOR_RNG sLog->outString("\n"); sLog->outString("SFMT has been enabled as the random number generator, if worldserver"); sLog->outString("freezes or crashes randomly, first, try disabling SFMT in CMAKE configuration"); sLog->outString("\n"); #endif //USE_SFMT_FOR_RNG /// worldserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog->outError("Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog->outString("Daemon PID: %u\n", pid); } ///- Start the databases if (!_StartDB()) return 1; // set server offline (not connectable) LoginDatabase.DirectPExecute("UPDATE realmlist SET color = (color & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); ///- Initialize the World sWorld->SetInitialWorldSettings(); // Initialize the signal handlers WorldServerSignalHandler SignalINT, SignalTERM; #ifdef _WIN32 WorldServerSignalHandler SignalBREAK; #endif /* _WIN32 */ // Register worldserver's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #ifdef _WIN32 Handler.register_handler(SIGBREAK, &SignalBREAK); #endif /* _WIN32 */ ///- Launch WorldRunnable thread ACE_Based::Thread world_thread(new WorldRunnable); world_thread.setPriority(ACE_Based::Highest); ACE_Based::Thread* cliThread = NULL; #ifdef _WIN32 if (ConfigMgr::GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) #else if (ConfigMgr::GetBoolDefault("Console.Enable", true)) #endif { ///- Launch CliRunnable thread cliThread = new ACE_Based::Thread(new CliRunnable); } ACE_Based::Thread rar_thread(new RARunnable); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog->outError("Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) sLog->outString("Using processors (bitmask, hex): %x", curAff); else sLog->outError("Can't set used processors (hex): %x", curAff); } } sLog->outString(""); } bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false); //if (Prio && (m_ServiceStatus == -1) /* need set to default process priority class in service mode*/) if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outString("worldserver process priority class set to HIGH"); else sLog->outError("Can't set worldserver process priority class."); sLog->outString(""); } } #endif //Start soap serving thread ACE_Based::Thread* soap_thread = NULL; if (ConfigMgr::GetBoolDefault("SOAP.Enabled", false)) { TCSoapRunnable* runnable = new TCSoapRunnable(); runnable->setListenArguments(ConfigMgr::GetStringDefault("SOAP.IP", "127.0.0.1"), ConfigMgr::GetIntDefault("SOAP.Port", 7878)); soap_thread = new ACE_Based::Thread(runnable); } ///- Start up freeze catcher thread if (uint32 freeze_delay = ConfigMgr::GetIntDefault("MaxCoreStuckTime", 0)) { FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable(); fdr->SetDelayTime(freeze_delay*1000); ACE_Based::Thread freeze_thread(fdr); freeze_thread.setPriority(ACE_Based::Highest); } ///- Launch the world listener socket uint16 wsport = sWorld->getConfig(CONFIG_PORT_WORLD); std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0"); if (sWorldSocketMgr->StartNetwork(wsport, bind_ip.c_str ()) == -1) { sLog->outError("Failed to start network"); World::StopNow(ERROR_EXIT_CODE); // go down and shutdown the server } // set server online (allow connecting now) LoginDatabase.DirectPExecute("UPDATE realmlist SET color = color & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); sLog->outString("%s (worldserver-daemon) ready...", _FULLVERSION); sWorldSocketMgr->Wait(); if (soap_thread) { soap_thread->wait(); soap_thread->destroy(); delete soap_thread; } // set server offline LoginDatabase.DirectPExecute("UPDATE realmlist SET color = color | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master world_thread.wait(); rar_thread.wait(); ///- Clean database before leaving clearOnlineAccounts(); // Wait for delay threads to end CharacterDatabase.HaltDelayThread(); WorldDatabase.HaltDelayThread(); LoginDatabase.HaltDelayThread(); sLog->outString("Halting process..."); if (cliThread) { #ifdef _WIN32 // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) //_exit(1); // send keyboard input to safely unblock the CLI thread INPUT_RECORD b[5]; HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); b[0].EventType = KEY_EVENT; b[0].Event.KeyEvent.bKeyDown = TRUE; b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; b[0].Event.KeyEvent.wRepeatCount = 1; b[1].EventType = KEY_EVENT; b[1].Event.KeyEvent.bKeyDown = FALSE; b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; b[1].Event.KeyEvent.wRepeatCount = 1; b[2].EventType = KEY_EVENT; b[2].Event.KeyEvent.bKeyDown = TRUE; b[2].Event.KeyEvent.dwControlKeyState = 0; b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[2].Event.KeyEvent.wRepeatCount = 1; b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].EventType = KEY_EVENT; b[3].Event.KeyEvent.bKeyDown = FALSE; b[3].Event.KeyEvent.dwControlKeyState = 0; b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].Event.KeyEvent.wRepeatCount = 1; DWORD numb; WriteConsoleInput(hStdIn, b, 4, &numb); cliThread->wait(); #else cliThread->destroy(); #endif delete cliThread; } // for some unknown reason, unloading scripts here and not in worldrunnable // fixes a memory leak related to detaching threads from the module //UnloadScriptingModule(); // Exit the process with specified return value return World::GetExitCode(); }
void InitConProc (int argc, char **argv) { DWORD threadAddr; HANDLE hFile = NULL; HANDLE heventParent = NULL; HANDLE heventChild = NULL; int t; ccom_argc = argc; ccom_argv = argv; // give QHOST a chance to hook into the console if ((t = CCheckParm ("-HFILE")) > 0) { if (t < argc) hFile = (HANDLE)atoi (ccom_argv[t+1]); } if ((t = CCheckParm ("-HPARENT")) > 0) { if (t < argc) heventParent = (HANDLE)atoi (ccom_argv[t+1]); } if ((t = CCheckParm ("-HCHILD")) > 0) { if (t < argc) heventChild = (HANDLE)atoi (ccom_argv[t+1]); } // ignore if we don't have all the events. if (!hFile || !heventParent || !heventChild) { printf ("Qhost not present.\n"); return; } qHost = TRUE; printf ("Initializing for qhost.\n"); hfileBuffer = hFile; heventParentSend = heventParent; heventChildSend = heventChild; // so we'll know when to go away. heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); if (!heventDone) { printf ("Couldn't create heventDone\n"); return; } //if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr)) if (!CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)RequestProc, NULL, 0, &threadAddr)) { CloseHandle (heventDone); printf ("Couldn't create QHOST thread\n"); return; } // save off the input/output handles. hStdout = GetStdHandle (STD_OUTPUT_HANDLE); hStdin = GetStdHandle (STD_INPUT_HANDLE); // force 80 character width, at least 25 character height SetConsoleCXCY (hStdout, 80, 25); }