Reactos
at master 317 lines 6.7 kB view raw
1// 2// pipetunnel.cpp 3// 4// Martin Fuchs, 30.11.2003 5// 6 7// 8// Invoke as: "pipetunnel [pipe_name]", 9// for example: "pipetunnel com_2" 10// 11// Then start up RectOS in VMWare, wait for the serial connect. 12// After that you can connect GDB using the command "target remote :9999". 13// 14 15 16#define WIN32_LEAN_AND_MEAN 17#include <windows.h> 18 19#include <winsock.h> 20 21#ifdef _MSC_VER 22#pragma comment(lib, "wsock32") 23#endif 24 25#include <stdio.h> 26#include <errno.h> 27 28 29 // This definition currently missing in MinGW. 30#ifndef FILE_FLAG_FIRST_PIPE_INSTANCE 31#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000 32#endif 33 34 35static void print_error(DWORD win32_error) 36{ 37 fprintf(stderr, "WIN32 error %lu\n", win32_error); 38} 39 40 41#ifdef _DEBUG 42 43 // critical section wrapper 44struct CritSect : public CRITICAL_SECTION 45{ 46 CritSect() 47 { 48 InitializeCriticalSection(this); 49 } 50 51 ~CritSect() 52 { 53 DeleteCriticalSection(this); 54 } 55}; 56 57static void dbg_trace(char mode, const char* buffer, int l) 58{ 59 static char s_mode = '\0'; 60 static CritSect crit_sect; 61 62 EnterCriticalSection(&crit_sect); 63 64 if (l) { 65 for(const char*p=buffer; l--; ++p) { 66 if (mode != s_mode) { 67 putchar('\n'); 68 putchar(mode); 69 putchar(' '); 70 71 s_mode = mode; 72 } 73 74 if (*p=='\n' || !*p /*|| *p=='#'*/) { 75 /*if (*p == '#') 76 putchar(*p);*/ 77 78 s_mode = '\0'; 79 } else 80 putchar(*p); 81 } 82 } 83 84 LeaveCriticalSection(&crit_sect); 85} 86 87#endif 88 89 90static SOCKET s_srv_socket = (SOCKET)-1; 91 92SOCKET open_tcp_connect() 93{ 94 if (s_srv_socket == (SOCKET)-1) { 95 SOCKADDR_IN srv_addr = {0}; 96 97 srv_addr.sin_family = AF_INET; 98 srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 99 srv_addr.sin_port = htons(9999); 100 101 s_srv_socket = socket(PF_INET, SOCK_STREAM, 0); 102 if (s_srv_socket == (SOCKET)-1) { 103 perror("socket()"); 104 return 0; 105 } 106 107 if (bind(s_srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { 108 perror("bind()"); 109 return 0; 110 } 111 112 if (listen(s_srv_socket, 4) == -1) { 113 perror("listen()"); 114 return 0; 115 } 116 } 117 118 SOCKADDR_IN rem_addr; 119 int rem_len = sizeof(rem_addr); 120 121 for(;;) { 122 SOCKET sock = accept(s_srv_socket, (struct sockaddr*)&rem_addr, &rem_len); 123 124 if (sock < 0) { 125 if (errno == EINTR) 126 continue; 127 128 perror("accept()"); 129 return 0; 130 } 131 132 return sock; 133 } 134} 135 136 137 138struct WriterThread 139{ 140 WriterThread(SOCKET sock, HANDLE hPipe) 141 : _sock(sock), 142 _hPipe(hPipe) 143 { 144 DWORD tid; 145 146 HANDLE hThread = CreateThread(NULL, 0, WriterThreadRoutine, this, 0, &tid); 147 148 if (hThread) { 149 SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); 150 151 CloseHandle(hThread); 152 } else 153 delete this; 154 } 155 156protected: 157 SOCKET _sock; 158 HANDLE _hPipe; 159 160 static DWORD WINAPI WriterThreadRoutine(LPVOID param) 161 { 162 WriterThread* pThis = (WriterThread*) param; 163 164 DWORD ret = pThis->Run(); 165 166 delete pThis; 167 168 return ret; 169 } 170 171 DWORD Run() 172 { 173 char buffer[1024]; 174 175 for(;;) { 176 int r = recv(_sock, buffer, sizeof(buffer), 0); 177 178 if (r == -1) { 179 perror("recv()"); 180 fprintf(stderr, "debugger connection broken\n"); 181 _sock = (SOCKET)-1; 182 return 1; 183 } 184 185 if (r) { 186 DWORD wrote; 187 188 if (!WriteFile(_hPipe, buffer, r, &wrote, NULL)) 189 break; 190 191#ifdef _DEBUG 192 dbg_trace('<', buffer, r); 193#endif 194 } 195 } 196 197 return 0; 198 } 199}; 200 201 202LONG read_pipe(HANDLE hPipe, SOCKET sock) 203{ 204 for(;;) { 205 DWORD read; 206 char buffer[1024]; 207 208 // wait for input data 209 WaitForSingleObject(hPipe, INFINITE); 210 211 if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) { 212 DWORD error = GetLastError(); 213 214 if (error == ERROR_PIPE_LISTENING) 215 Sleep(1000); 216 else 217 return error; 218 } 219 220 if (read) { 221#ifdef _DEBUG 222 dbg_trace('>', buffer, read); 223#endif 224 225 if (!send(sock, buffer, read, 0)) { 226 perror("send()"); 227 return GetLastError(); 228 } 229 } 230 } 231} 232 233 234int main(int argc, char** argv) 235{ 236 char path[MAX_PATH]; 237 const char* pipe_name; 238 239 if (argc > 1) 240 pipe_name = *++argv; 241 else 242 pipe_name = "com_2"; 243 244 sprintf(path, "\\\\.\\pipe\\%s", pipe_name); 245 246 247 // initialize winsock 248 WSADATA wsa_data; 249 250 if (WSAStartup(MAKEWORD(2,2), &wsa_data)) { 251 fprintf(stderr, "WSAStartup() failed\n"); 252 return 0; 253 } 254 255 256 // increment priority to be faster than the cpu eating VMWare process 257 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 258 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 259 260 261 HANDLE hPipe = INVALID_HANDLE_VALUE; 262 263 for(;;) { 264 DWORD read; 265 266 if (hPipe == INVALID_HANDLE_VALUE) { 267 hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL); 268 269 if (hPipe == INVALID_HANDLE_VALUE) { 270 print_error(GetLastError()); 271 return 1; 272 } 273 } 274 275 // wait for the client side of the pipe 276 while(!ReadFile(hPipe, NULL, 0, &read, NULL) && 277 GetLastError()==ERROR_PIPE_LISTENING) 278 Sleep(1000); 279 280 puts("\nnamed pipe connected, now waiting for TCP connection..."); 281 282 SOCKET sock = open_tcp_connect(); 283 if (sock == (SOCKET)-1) 284 break; 285 286 puts("TCP connection established."); 287 288 // launch writer thread 289 new WriterThread(sock, hPipe); 290 291 // launch reader loop 292 LONG error = read_pipe(hPipe, sock); 293 294 295 // close TCP connectiom 296 closesocket(sock); 297 sock = (SOCKET)-1; 298 299 // close named pipe 300 CloseHandle(hPipe); 301 hPipe = INVALID_HANDLE_VALUE; 302 303 304 if (error == ERROR_BROKEN_PIPE) 305 puts("\nconnection closed."); // normal connection termination 306 else { 307 print_error(GetLastError()); 308 break; 309 } 310 } 311 312 if (hPipe != INVALID_HANDLE_VALUE) 313 if (!CloseHandle(hPipe)) 314 print_error(GetLastError()); 315 316 return 0; 317}