|
|
1.1 ! root 1: // conproc.c -- support for qhost ! 2: #include <stdio.h> ! 3: #include <process.h> ! 4: #include <windows.h> ! 5: #include "conproc.h" ! 6: ! 7: #define CCOM_WRITE_TEXT 0x2 ! 8: // Param1 : Text ! 9: ! 10: #define CCOM_GET_TEXT 0x3 ! 11: // Param1 : Begin line ! 12: // Param2 : End line ! 13: ! 14: #define CCOM_GET_SCR_LINES 0x4 ! 15: // No params ! 16: ! 17: #define CCOM_SET_SCR_LINES 0x5 ! 18: // Param1 : Number of lines ! 19: ! 20: ! 21: HANDLE heventDone; ! 22: HANDLE hfileBuffer; ! 23: HANDLE heventChildSend; ! 24: HANDLE heventParentSend; ! 25: HANDLE hStdout; ! 26: HANDLE hStdin; ! 27: ! 28: unsigned _stdcall RequestProc (void *arg); ! 29: LPVOID GetMappedBuffer (HANDLE hfileBuffer); ! 30: void ReleaseMappedBuffer (LPVOID pBuffer); ! 31: BOOL GetScreenBufferLines (int *piLines); ! 32: BOOL SetScreenBufferLines (int iLines); ! 33: BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine); ! 34: BOOL WriteText (LPCTSTR szText); ! 35: int CharToCode (char c); ! 36: BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy); ! 37: ! 38: int ccom_argc; ! 39: char **ccom_argv; ! 40: ! 41: /* ! 42: ================ ! 43: CCheckParm ! 44: ! 45: Returns the position (1 to argc-1) in the program's argument list ! 46: where the given parameter apears, or 0 if not present ! 47: ================ ! 48: */ ! 49: int CCheckParm (char *parm) ! 50: { ! 51: int i; ! 52: ! 53: for (i=1 ; i<ccom_argc ; i++) ! 54: { ! 55: if (!ccom_argv[i]) ! 56: continue; ! 57: if (!strcmp (parm,ccom_argv[i])) ! 58: return i; ! 59: } ! 60: ! 61: return 0; ! 62: } ! 63: ! 64: ! 65: void InitConProc (int argc, char **argv) ! 66: { ! 67: unsigned threadAddr; ! 68: HANDLE hFile; ! 69: HANDLE heventParent; ! 70: HANDLE heventChild; ! 71: int t; ! 72: ! 73: ccom_argc = argc; ! 74: ccom_argv = argv; ! 75: ! 76: // give QHOST a chance to hook into the console ! 77: if ((t = CCheckParm ("-HFILE")) > 0) ! 78: { ! 79: if (t < argc) ! 80: hFile = (HANDLE)atoi (ccom_argv[t+1]); ! 81: } ! 82: ! 83: if ((t = CCheckParm ("-HPARENT")) > 0) ! 84: { ! 85: if (t < argc) ! 86: heventParent = (HANDLE)atoi (ccom_argv[t+1]); ! 87: } ! 88: ! 89: if ((t = CCheckParm ("-HCHILD")) > 0) ! 90: { ! 91: if (t < argc) ! 92: heventChild = (HANDLE)atoi (ccom_argv[t+1]); ! 93: } ! 94: ! 95: ! 96: // ignore if we don't have all the events. ! 97: if (!hFile || !heventParent || !heventChild) ! 98: { ! 99: printf ("Qhost not present.\n"); ! 100: return; ! 101: } ! 102: ! 103: printf ("Initializing for qhost.\n"); ! 104: ! 105: hfileBuffer = hFile; ! 106: heventParentSend = heventParent; ! 107: heventChildSend = heventChild; ! 108: ! 109: // so we'll know when to go away. ! 110: heventDone = CreateEvent (NULL, FALSE, FALSE, NULL); ! 111: ! 112: if (!heventDone) ! 113: { ! 114: printf ("Couldn't create heventDone\n"); ! 115: return; ! 116: } ! 117: ! 118: if (!_beginthreadex (NULL, 0, RequestProc, NULL, 0, &threadAddr)) ! 119: { ! 120: CloseHandle (heventDone); ! 121: printf ("Couldn't create QHOST thread\n"); ! 122: return; ! 123: } ! 124: ! 125: // save off the input/output handles. ! 126: hStdout = GetStdHandle (STD_OUTPUT_HANDLE); ! 127: hStdin = GetStdHandle (STD_INPUT_HANDLE); ! 128: ! 129: // force 80 character width, at least 25 character height ! 130: SetConsoleCXCY (hStdout, 80, 25); ! 131: } ! 132: ! 133: ! 134: void DeinitConProc (void) ! 135: { ! 136: if (heventDone) ! 137: SetEvent (heventDone); ! 138: } ! 139: ! 140: ! 141: unsigned _stdcall RequestProc (void *arg) ! 142: { ! 143: int *pBuffer; ! 144: DWORD dwRet; ! 145: HANDLE heventWait[2]; ! 146: int iBeginLine, iEndLine; ! 147: ! 148: heventWait[0] = heventParentSend; ! 149: heventWait[1] = heventDone; ! 150: ! 151: while (1) ! 152: { ! 153: dwRet = WaitForMultipleObjects (2, heventWait, FALSE, INFINITE); ! 154: ! 155: // heventDone fired, so we're exiting. ! 156: if (dwRet == WAIT_OBJECT_0 + 1) ! 157: break; ! 158: ! 159: pBuffer = (int *) GetMappedBuffer (hfileBuffer); ! 160: ! 161: // hfileBuffer is invalid. Just leave. ! 162: if (!pBuffer) ! 163: { ! 164: printf ("Invalid hfileBuffer\n"); ! 165: break; ! 166: } ! 167: ! 168: switch (pBuffer[0]) ! 169: { ! 170: case CCOM_WRITE_TEXT: ! 171: // Param1 : Text ! 172: pBuffer[0] = WriteText ((LPCTSTR) (pBuffer + 1)); ! 173: break; ! 174: ! 175: case CCOM_GET_TEXT: ! 176: // Param1 : Begin line ! 177: // Param2 : End line ! 178: iBeginLine = pBuffer[1]; ! 179: iEndLine = pBuffer[2]; ! 180: pBuffer[0] = ReadText ((LPTSTR) (pBuffer + 1), iBeginLine, ! 181: iEndLine); ! 182: break; ! 183: ! 184: case CCOM_GET_SCR_LINES: ! 185: // No params ! 186: pBuffer[0] = GetScreenBufferLines (&pBuffer[1]); ! 187: break; ! 188: ! 189: case CCOM_SET_SCR_LINES: ! 190: // Param1 : Number of lines ! 191: pBuffer[0] = SetScreenBufferLines (pBuffer[1]); ! 192: break; ! 193: } ! 194: ! 195: ReleaseMappedBuffer (pBuffer); ! 196: SetEvent (heventChildSend); ! 197: } ! 198: ! 199: _endthreadex (0); ! 200: return 0; ! 201: } ! 202: ! 203: ! 204: LPVOID GetMappedBuffer (HANDLE hfileBuffer) ! 205: { ! 206: LPVOID pBuffer; ! 207: ! 208: pBuffer = MapViewOfFile (hfileBuffer, ! 209: FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); ! 210: ! 211: return pBuffer; ! 212: } ! 213: ! 214: ! 215: void ReleaseMappedBuffer (LPVOID pBuffer) ! 216: { ! 217: UnmapViewOfFile (pBuffer); ! 218: } ! 219: ! 220: ! 221: BOOL GetScreenBufferLines (int *piLines) ! 222: { ! 223: CONSOLE_SCREEN_BUFFER_INFO info; ! 224: BOOL bRet; ! 225: ! 226: bRet = GetConsoleScreenBufferInfo (hStdout, &info); ! 227: ! 228: if (bRet) ! 229: *piLines = info.dwSize.Y; ! 230: ! 231: return bRet; ! 232: } ! 233: ! 234: ! 235: BOOL SetScreenBufferLines (int iLines) ! 236: { ! 237: ! 238: return SetConsoleCXCY (hStdout, 80, iLines); ! 239: } ! 240: ! 241: ! 242: BOOL ReadText (LPTSTR pszText, int iBeginLine, int iEndLine) ! 243: { ! 244: COORD coord; ! 245: DWORD dwRead; ! 246: BOOL bRet; ! 247: ! 248: coord.X = 0; ! 249: coord.Y = iBeginLine; ! 250: ! 251: bRet = ReadConsoleOutputCharacter( ! 252: hStdout, ! 253: pszText, ! 254: 80 * (iEndLine - iBeginLine + 1), ! 255: coord, ! 256: &dwRead); ! 257: ! 258: // Make sure it's null terminated. ! 259: if (bRet) ! 260: pszText[dwRead] = '\0'; ! 261: ! 262: return bRet; ! 263: } ! 264: ! 265: ! 266: BOOL WriteText (LPCTSTR szText) ! 267: { ! 268: DWORD dwWritten; ! 269: INPUT_RECORD rec; ! 270: char upper, *sz; ! 271: ! 272: sz = (LPTSTR) szText; ! 273: ! 274: while (*sz) ! 275: { ! 276: // 13 is the code for a carriage return (\n) instead of 10. ! 277: if (*sz == 10) ! 278: *sz = 13; ! 279: ! 280: upper = toupper(*sz); ! 281: ! 282: rec.EventType = KEY_EVENT; ! 283: rec.Event.KeyEvent.bKeyDown = TRUE; ! 284: rec.Event.KeyEvent.wRepeatCount = 1; ! 285: rec.Event.KeyEvent.wVirtualKeyCode = upper; ! 286: rec.Event.KeyEvent.wVirtualScanCode = CharToCode (*sz); ! 287: rec.Event.KeyEvent.uChar.AsciiChar = *sz; ! 288: rec.Event.KeyEvent.uChar.UnicodeChar = *sz; ! 289: rec.Event.KeyEvent.dwControlKeyState = isupper(*sz) ? 0x80 : 0x0; ! 290: ! 291: WriteConsoleInput( ! 292: hStdin, ! 293: &rec, ! 294: 1, ! 295: &dwWritten); ! 296: ! 297: rec.Event.KeyEvent.bKeyDown = FALSE; ! 298: ! 299: WriteConsoleInput( ! 300: hStdin, ! 301: &rec, ! 302: 1, ! 303: &dwWritten); ! 304: ! 305: sz++; ! 306: } ! 307: ! 308: return TRUE; ! 309: } ! 310: ! 311: ! 312: int CharToCode (char c) ! 313: { ! 314: char upper; ! 315: ! 316: upper = toupper(c); ! 317: ! 318: switch (c) ! 319: { ! 320: case 13: ! 321: return 28; ! 322: ! 323: default: ! 324: break; ! 325: } ! 326: ! 327: if (isalpha(c)) ! 328: return (30 + upper - 65); ! 329: ! 330: if (isdigit(c)) ! 331: return (1 + upper - 47); ! 332: ! 333: return c; ! 334: } ! 335: ! 336: ! 337: BOOL SetConsoleCXCY(HANDLE hStdout, int cx, int cy) ! 338: { ! 339: CONSOLE_SCREEN_BUFFER_INFO info; ! 340: COORD coordMax; ! 341: ! 342: coordMax = GetLargestConsoleWindowSize(hStdout); ! 343: ! 344: if (cy > coordMax.Y) ! 345: cy = coordMax.Y; ! 346: ! 347: if (cx > coordMax.X) ! 348: cx = coordMax.X; ! 349: ! 350: if (!GetConsoleScreenBufferInfo(hStdout, &info)) ! 351: return FALSE; ! 352: ! 353: // height ! 354: info.srWindow.Left = 0; ! 355: info.srWindow.Right = info.dwSize.X - 1; ! 356: info.srWindow.Top = 0; ! 357: info.srWindow.Bottom = cy - 1; ! 358: ! 359: if (cy < info.dwSize.Y) ! 360: { ! 361: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) ! 362: return FALSE; ! 363: ! 364: info.dwSize.Y = cy; ! 365: ! 366: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) ! 367: return FALSE; ! 368: } ! 369: else if (cy > info.dwSize.Y) ! 370: { ! 371: info.dwSize.Y = cy; ! 372: ! 373: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) ! 374: return FALSE; ! 375: ! 376: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) ! 377: return FALSE; ! 378: } ! 379: ! 380: if (!GetConsoleScreenBufferInfo(hStdout, &info)) ! 381: return FALSE; ! 382: ! 383: // width ! 384: info.srWindow.Left = 0; ! 385: info.srWindow.Right = cx - 1; ! 386: info.srWindow.Top = 0; ! 387: info.srWindow.Bottom = info.dwSize.Y - 1; ! 388: ! 389: if (cx < info.dwSize.X) ! 390: { ! 391: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) ! 392: return FALSE; ! 393: ! 394: info.dwSize.X = cx; ! 395: ! 396: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) ! 397: return FALSE; ! 398: } ! 399: else if (cx > info.dwSize.X) ! 400: { ! 401: info.dwSize.X = cx; ! 402: ! 403: if (!SetConsoleScreenBufferSize(hStdout, info.dwSize)) ! 404: return FALSE; ! 405: ! 406: if (!SetConsoleWindowInfo(hStdout, TRUE, &info.srWindow)) ! 407: return FALSE; ! 408: } ! 409: ! 410: return TRUE; ! 411: } ! 412:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.