Source code of Windows XP (NT5)
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.

299 lines
7.9 KiB

  1. /*
  2. * Copyright (c) Microsoft Corporation
  3. *
  4. * Module Name :
  5. * main.c
  6. *
  7. * This is the main file containing the client code.
  8. *
  9. *
  10. * Sadagopan Rajaram -- Oct 14, 1999
  11. *
  12. */
  13. // Can kill this program on a normal NT console using the
  14. // Alt - X Key combination. Just a shortcut, that is all.
  15. // Serves no useful purpose.
  16. #include "tcclnt.h"
  17. #include "tcsrvc.h"
  18. WSABUF ReceiveBuffer;
  19. CHAR RecvBuf[MAX_BUFFER_SIZE];
  20. IO_STATUS_BLOCK IoStatus;
  21. HANDLE InputHandle;
  22. DWORD bytesRecvd;
  23. WSAOVERLAPPED junk;
  24. SOCKET cli_sock;
  25. DWORD flags;
  26. #if _MSC_FULL_VER >= 13008827
  27. #pragma warning(push)
  28. #pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
  29. #endif
  30. DWORD
  31. inputUpdate(
  32. PVOID dummy
  33. )
  34. {
  35. // Runs in a single thread getting all the inputs
  36. // from the keyboard.
  37. ULONG result;
  38. // gets a multibyte string for every character
  39. // pressed on the keyboard.
  40. CHAR r[MB_CUR_MAX + 1];
  41. while(1){
  42. r[0] = _T('\0');
  43. inchar(r);
  44. // BUGBUG - Performance issues in sending a single character
  45. // at a time across the n/w
  46. if(strlen(r)){
  47. // may send a single byte or two bytes.
  48. send(cli_sock,r,strlen(r),0);
  49. }
  50. }
  51. return 1;
  52. }
  53. #if _MSC_FULL_VER >= 13008827
  54. #pragma warning(pop)
  55. #endif
  56. VOID sendUpdate(
  57. IN DWORD dwError,
  58. IN DWORD cbTransferred,
  59. IN LPWSAOVERLAPPED lpOverLapped,
  60. IN DWORD dwFlags
  61. )
  62. {
  63. int error,i;
  64. // Receives a packet and sends it through the stream parser
  65. // BUGBUG - For effeciency it can be made inline.
  66. // I am not sure of the performance increase, but it should
  67. // be substantial as we will be sending a lot of data.
  68. if(dwError != 0){
  69. exit(1);
  70. }
  71. for(i=0;i < (int)cbTransferred;i++){
  72. PrintChar(ReceiveBuffer.buf[i]);
  73. }
  74. // Repost the receive on the socket.
  75. error = WSARecv(cli_sock,
  76. &ReceiveBuffer,
  77. 1,
  78. &bytesRecvd,
  79. &flags,
  80. &junk,
  81. sendUpdate
  82. );
  83. if((error == SOCKET_ERROR)
  84. &&(WSAGetLastError()!=WSA_IO_PENDING)){
  85. // Implies something wrong with the socket.
  86. exit(1);
  87. }
  88. return;
  89. }
  90. int __cdecl
  91. main(
  92. IN int argc,
  93. char *argv[]
  94. )
  95. /*++
  96. Opens a single port, binds to the tcserver and passes information back and forth.
  97. --*/
  98. {
  99. struct sockaddr_in srv_addr,cli_addr;
  100. LPHOSTENT host_info;
  101. CLIENT_INFO SendInfo;
  102. int status;
  103. WSADATA data;
  104. #ifdef UNICODE
  105. // BUGBUG - Trying to write a code that works for
  106. // both Unicode and ASCII. Gets multi byte sequences
  107. // Confusion when the tcclnt and tcclnt are in different
  108. // modes.
  109. ANSI_STRING Src;
  110. UNICODE_STRING Dest;
  111. #endif
  112. NTSTATUS Status;
  113. HANDLE Thread;
  114. DWORD ThreadId;
  115. COORD coord;
  116. SMALL_RECT rect;
  117. int RetVal;
  118. struct hostent *ht;
  119. ULONG r;
  120. TCHAR Buffer[80];
  121. if((argc<2) || (argc >4)){
  122. // Error in running the program
  123. printf("Usage - tcclnt COMPORTNAME [ipaddress]\n");
  124. exit(0);
  125. }
  126. ThreadId = GetEnvironmentVariable(_T("TERM"),Buffer , 80);
  127. // We need to know if we have a vt100 screen or an ANSI screen.
  128. AttributeFunction = ProcessTextAttributes;
  129. if(ThreadId >0){
  130. // Terminal type exists in the environment.
  131. // Use it
  132. if((_tcsncmp(Buffer, _T("VT100"), 5) == 0)||
  133. _tcsncmp(Buffer, _T("vt100"),5) ==0 )
  134. AttributeFunction = vt100Attributes;
  135. }
  136. hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  137. coord.X = MAX_TERMINAL_WIDTH;
  138. coord.Y = MAX_TERMINAL_HEIGHT;
  139. rect.Left = rect.Top = 0;
  140. rect.Right = MAX_TERMINAL_WIDTH -1;
  141. rect.Bottom = MAX_TERMINAL_HEIGHT -1;
  142. if(hConsoleOutput == NULL){
  143. printf("Could not get current console handle %d\n", GetLastError());
  144. return 1;
  145. }
  146. RetVal = SetConsoleScreenBufferSize(hConsoleOutput,
  147. coord
  148. );
  149. RetVal = SetConsoleWindowInfo(hConsoleOutput,
  150. TRUE,
  151. &rect
  152. );
  153. if (RetVal == FALSE) {
  154. printf("Could not set window size %d\n", GetLastError());
  155. return 1;
  156. }
  157. RetVal = SetConsoleMode(hConsoleOutput,ENABLE_PROCESSED_OUTPUT);
  158. if(RetVal == FALSE){
  159. printf("Could not console mode %d\n", GetLastError());
  160. return 1;
  161. }
  162. /* Set up client socket */
  163. InputHandle = GetStdHandle(STD_INPUT_HANDLE);
  164. if(InputHandle == NULL) return 1;
  165. SetConsoleMode(InputHandle, 0);
  166. status=WSAStartup(514,&data);
  167. if(status){
  168. printf("Cannot start up %d\n",status);
  169. return(1);
  170. }
  171. cli_sock=WSASocket(PF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
  172. if (cli_sock==INVALID_SOCKET){
  173. printf("Windows Sockets error %d: Couldn't create socket.",
  174. WSAGetLastError());
  175. return(1);
  176. }
  177. cli_addr.sin_family=AF_INET;
  178. cli_addr.sin_addr.s_addr=INADDR_ANY;
  179. cli_addr.sin_port=0; /* no specific port req'd */
  180. /* Bind client socket to any local interface and port */
  181. if (bind(cli_sock,(LPSOCKADDR)&cli_addr,sizeof(cli_addr))==SOCKET_ERROR){
  182. printf("Windows Sockets error %d: Couldn't bind socket.",
  183. WSAGetLastError());
  184. return(1);
  185. }
  186. srv_addr.sin_family = AF_INET;
  187. if(argc == 3){
  188. srv_addr.sin_addr.s_addr = inet_addr(argv[2]);
  189. if (srv_addr.sin_addr.s_addr == INADDR_NONE) {
  190. ht = gethostbyname(argv[2]);
  191. if(!ht || !ht->h_addr){ // cannot resolve the name
  192. printf("Cannot resolve %s", argv[2]);
  193. exit(1);
  194. }
  195. memcpy((&(srv_addr.sin_addr.s_addr)),ht->h_addr, ht->h_length);
  196. }
  197. }
  198. else{
  199. srv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
  200. }
  201. srv_addr.sin_port=htons(SERVICE_PORT);
  202. /* Connect to FTP server at address SERVER */
  203. if (connect(cli_sock,(LPSOCKADDR)&srv_addr,sizeof(srv_addr))==SOCKET_ERROR){
  204. printf("Windows Sockets error %d: Couldn't connect socket.\n",
  205. WSAGetLastError());
  206. return(1);
  207. }
  208. SendInfo.len = sizeof(CLIENT_INFO);
  209. #ifdef UNICODE
  210. Src.Buffer = argv[1];
  211. Src.Length = (USHORT)strlen(argv[1]);
  212. Dest.Buffer = SendInfo.device;
  213. Dest.MaximumLength = MAX_BUFFER_SIZE;
  214. Status = RtlAnsiStringToUnicodeString(&Dest, &Src, FALSE);
  215. if (!NT_SUCCESS(Status)) {
  216. printf("RtlAnsiStringToUnicodeString failed, ec = 0x%08x\n",Status);
  217. exit(1);
  218. }
  219. send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0);
  220. #else
  221. // We are sending to an ANSI String
  222. strcpy(SendInfo.device, argv[1]);
  223. send(cli_sock, (PCHAR) &SendInfo, sizeof(CLIENT_INFO), 0);
  224. #endif
  225. ReceiveBuffer.len = MAX_BUFFER_SIZE;
  226. ReceiveBuffer.buf = RecvBuf;
  227. status=WSARecv(cli_sock,
  228. &ReceiveBuffer,
  229. 1,
  230. &bytesRecvd,
  231. &flags,
  232. &junk,
  233. sendUpdate
  234. );
  235. if((status == SOCKET_ERROR)
  236. &&(WSAGetLastError() != WSA_IO_PENDING)){
  237. printf("Error in recv %d\n",WSAGetLastError());
  238. exit(1);
  239. }
  240. // Create a thread that gets input from the console
  241. // to send to the bridge.
  242. Thread = CreateThread(NULL,
  243. 0,
  244. inputUpdate,
  245. NULL,
  246. 0,
  247. &ThreadId
  248. );
  249. if (Thread== NULL) {
  250. exit(1);
  251. }
  252. CloseHandle(Thread);
  253. while(1){
  254. // Put this thread in an alertable
  255. // state so that the receive calls can
  256. // asynchronously terminate within the
  257. // context of this thread.
  258. status=SleepEx(INFINITE,TRUE);
  259. }
  260. // We never return here.
  261. closesocket(cli_sock);
  262. return 0;
  263. }