Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
6.1 KiB

  1. //
  2. // ConsoleCom.cpp : Defines the entry point for the console application.
  3. //
  4. #include "stdafx.h"
  5. #include "ConsoleCom.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. //
  10. // The one and only application object
  11. //
  12. CWinApp theApp;
  13. HANDLE coutPipe, cinPipe, cerrPipe;
  14. #define CONNECTIMEOUT 1000
  15. //
  16. // Create named pipes for stdin, stdout and stderr
  17. // Parameter: process id
  18. //
  19. BOOL CreateNamedPipes(DWORD pid)
  20. {
  21. TCHAR name[256];
  22. _stprintf(name, _T("\\\\.\\pipe\\%dcout"), pid);
  23. if (INVALID_HANDLE_VALUE == (coutPipe = CreateNamedPipe(name,
  24. PIPE_ACCESS_INBOUND,
  25. PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
  26. 1,
  27. 1024,
  28. 1024,
  29. CONNECTIMEOUT,
  30. NULL)))
  31. return 0;
  32. _stprintf(name, _T("\\\\.\\pipe\\%dcin"), pid);
  33. if (INVALID_HANDLE_VALUE == (cinPipe = CreateNamedPipe(name,
  34. PIPE_ACCESS_OUTBOUND,
  35. PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
  36. 1,
  37. 1024,
  38. 1024,
  39. CONNECTIMEOUT,
  40. NULL)))
  41. return 0;
  42. _stprintf(name, _T("\\\\.\\pipe\\%dcerr"), pid);
  43. if (INVALID_HANDLE_VALUE == (cerrPipe = CreateNamedPipe(name,
  44. PIPE_ACCESS_INBOUND,
  45. PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
  46. 1,
  47. 1024,
  48. 1024,
  49. CONNECTIMEOUT,
  50. NULL)))
  51. return 0;
  52. return 1;
  53. }
  54. //
  55. // Close all named pipes
  56. //
  57. void CloseNamedPipes()
  58. {
  59. CloseHandle(coutPipe);
  60. CloseHandle(cerrPipe);
  61. CloseHandle(cinPipe);
  62. }
  63. //
  64. // Thread function that handles incoming bytesreams to be outputed
  65. // on stdout
  66. //
  67. void __cdecl OutPipeTh(void*)
  68. {
  69. TCHAR buffer[1024];
  70. DWORD count = 0;
  71. ConnectNamedPipe(coutPipe, NULL);
  72. while(ReadFile(coutPipe, buffer, 1024, &count, NULL))
  73. {
  74. buffer[count] = 0;
  75. cout << buffer << flush;
  76. }
  77. }
  78. //
  79. // Thread function that handles incoming bytesreams to be outputed
  80. // on stderr
  81. //
  82. void __cdecl ErrPipeTh(void*)
  83. {
  84. TCHAR buffer[1024];
  85. DWORD count = 0;
  86. ConnectNamedPipe(cerrPipe, NULL);
  87. while(ReadFile(cerrPipe, buffer, 1024, &count, NULL))
  88. {
  89. buffer[count] = 0;
  90. cerr << buffer << flush;
  91. }
  92. }
  93. //
  94. // Thread function that handles incoming bytesreams from stdin
  95. //
  96. void __cdecl InPipeTh(void*)
  97. {
  98. TCHAR buffer[1024];
  99. DWORD countr = 0;
  100. DWORD countw = 0;
  101. ConnectNamedPipe(cinPipe, NULL);
  102. for(;;)
  103. {
  104. if (!ReadFile(GetStdHandle(STD_INPUT_HANDLE),
  105. buffer,
  106. 1024,
  107. &countr,
  108. NULL))
  109. break;
  110. if (!WriteFile(cinPipe,
  111. buffer,
  112. countr,
  113. &countw,
  114. NULL))
  115. break;
  116. }
  117. }
  118. //
  119. // Start handler pipe handler threads
  120. //
  121. void RunPipeThreads()
  122. {
  123. _beginthread(InPipeTh, 0, NULL);
  124. _beginthread(OutPipeTh, 0, NULL);
  125. _beginthread(ErrPipeTh, 0, NULL);
  126. }
  127. int __cdecl _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
  128. {
  129. ULONG nRetCode = 0;
  130. //
  131. // initialize MFC and print and error on failure
  132. //
  133. if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
  134. {
  135. _tprintf(_T("Fatal Error: MFC initialization failed\n"));
  136. nRetCode = 1;
  137. } else {
  138. //
  139. // create command line string based on program name
  140. //
  141. TCHAR drive[_MAX_DRIVE];
  142. TCHAR dir[_MAX_DIR];
  143. TCHAR fname[_MAX_FNAME];
  144. TCHAR ext[_MAX_EXT];
  145. _tsplitpath(argv[0], drive, dir, fname, ext);
  146. TCHAR cParams[1024];
  147. _tcscpy(cParams, GetCommandLine() + _tcslen(argv[0]) + 1);
  148. TCHAR cLine[2028];
  149. _stprintf(cLine, _T("%s%s%s.exe %s"), drive, dir, fname, cParams);
  150. //
  151. // create process in suspended mode
  152. //
  153. PROCESS_INFORMATION pInfo;
  154. STARTUPINFO sInfo;
  155. memset(&sInfo, 0, sizeof(STARTUPINFO));
  156. sInfo.cb = sizeof(STARTUPINFO);
  157. //cout << "Calling " << cLine << endl;
  158. if (!CreateProcess(NULL,
  159. cLine,
  160. NULL,
  161. NULL,
  162. FALSE,
  163. CREATE_SUSPENDED,
  164. NULL,
  165. NULL,
  166. &sInfo,
  167. &pInfo))
  168. {
  169. cerr << _T("ERROR: Could not create process.") << endl;
  170. return 1;
  171. }
  172. if (!CreateNamedPipes(pInfo.dwProcessId))
  173. {
  174. cerr << _T("ERROR: Could not create named pipes.") << endl;
  175. return 1;
  176. }
  177. RunPipeThreads();
  178. //
  179. // resume process
  180. //
  181. ResumeThread(pInfo.hThread);
  182. WaitForSingleObject(pInfo.hProcess, INFINITE);
  183. CloseNamedPipes();
  184. GetExitCodeProcess(pInfo.hProcess, (ULONG*)&nRetCode);
  185. }
  186. return (int)nRetCode;
  187. }