Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpipetunnel.cpp
Go to the documentation of this file.
00001 // 00002 // pipetunnel.cpp 00003 // 00004 // Martin Fuchs, 30.11.2003 00005 // 00006 00007 // 00008 // Invoke as: "pipetunnel [pipe_name]", 00009 // for example: "pipetunnel com_2" 00010 // 00011 // Then start up RectOS in VMWare, wait for the serial connect. 00012 // After that you can connect GDB using the command "target remote :9999". 00013 // 00014 00015 00016 #define WIN32_LEAN_AND_MEAN 00017 #include <windows.h> 00018 00019 #include <winsock.h> 00020 00021 #ifdef _MSC_VER 00022 #pragma comment(lib, "wsock32") 00023 #endif 00024 00025 #include <stdio.h> 00026 #include <errno.h> 00027 00028 00029 // This definition currently missing in MinGW. 00030 #ifndef FILE_FLAG_FIRST_PIPE_INSTANCE 00031 #define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000 00032 #endif 00033 00034 00035 static void print_error(DWORD win32_error) 00036 { 00037 fprintf(stderr, "WIN32 error %lu\n", win32_error); 00038 } 00039 00040 00041 #ifdef _DEBUG 00042 00043 // critical section wrapper 00044 struct CritSect : public CRITICAL_SECTION 00045 { 00046 CritSect() 00047 { 00048 InitializeCriticalSection(this); 00049 } 00050 00051 ~CritSect() 00052 { 00053 DeleteCriticalSection(this); 00054 } 00055 }; 00056 00057 static void dbg_trace(char mode, const char* buffer, int l) 00058 { 00059 static char s_mode = '\0'; 00060 static CritSect crit_sect; 00061 00062 EnterCriticalSection(&crit_sect); 00063 00064 if (l) { 00065 for(const char*p=buffer; l--; ++p) { 00066 if (mode != s_mode) { 00067 putchar('\n'); 00068 putchar(mode); 00069 putchar(' '); 00070 00071 s_mode = mode; 00072 } 00073 00074 if (*p=='\n' || !*p /*|| *p=='#'*/) { 00075 /*if (*p == '#') 00076 putchar(*p);*/ 00077 00078 s_mode = '\0'; 00079 } else 00080 putchar(*p); 00081 } 00082 } 00083 00084 LeaveCriticalSection(&crit_sect); 00085 } 00086 00087 #endif 00088 00089 00090 static SOCKET s_srv_socket = (SOCKET)-1; 00091 00092 SOCKET open_tcp_connect() 00093 { 00094 if (s_srv_socket == (SOCKET)-1) { 00095 SOCKADDR_IN srv_addr = {0}; 00096 00097 srv_addr.sin_family = AF_INET; 00098 srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); 00099 srv_addr.sin_port = htons(9999); 00100 00101 s_srv_socket = socket(PF_INET, SOCK_STREAM, 0); 00102 if (s_srv_socket == (SOCKET)-1) { 00103 perror("socket()"); 00104 return 0; 00105 } 00106 00107 if (bind(s_srv_socket, (struct sockaddr*) &srv_addr, sizeof(srv_addr)) == -1) { 00108 perror("bind()"); 00109 return 0; 00110 } 00111 00112 if (listen(s_srv_socket, 4) == -1) { 00113 perror("listen()"); 00114 return 0; 00115 } 00116 } 00117 00118 SOCKADDR_IN rem_addr; 00119 int rem_len = sizeof(rem_addr); 00120 00121 for(;;) { 00122 SOCKET sock = accept(s_srv_socket, (struct sockaddr*)&rem_addr, &rem_len); 00123 00124 if (sock < 0) { 00125 if (errno == EINTR) 00126 continue; 00127 00128 perror("accept()"); 00129 return 0; 00130 } 00131 00132 return sock; 00133 } 00134 } 00135 00136 00137 00138 struct WriterThread 00139 { 00140 WriterThread(SOCKET sock, HANDLE hPipe) 00141 : _sock(sock), 00142 _hPipe(hPipe) 00143 { 00144 DWORD tid; 00145 00146 HANDLE hThread = CreateThread(NULL, 0, WriterThreadRoutine, this, 0, &tid); 00147 00148 if (hThread) { 00149 SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST); 00150 00151 CloseHandle(hThread); 00152 } else 00153 delete this; 00154 } 00155 00156 protected: 00157 SOCKET _sock; 00158 HANDLE _hPipe; 00159 00160 static DWORD WINAPI WriterThreadRoutine(LPVOID param) 00161 { 00162 WriterThread* pThis = (WriterThread*) param; 00163 00164 DWORD ret = pThis->Run(); 00165 00166 delete pThis; 00167 00168 return ret; 00169 } 00170 00171 DWORD Run() 00172 { 00173 char buffer[1024]; 00174 00175 for(;;) { 00176 int r = recv(_sock, buffer, sizeof(buffer), 0); 00177 00178 if (r == -1) { 00179 perror("recv()"); 00180 fprintf(stderr, "debugger connection broken\n"); 00181 _sock = (SOCKET)-1; 00182 return 1; 00183 } 00184 00185 if (r) { 00186 DWORD wrote; 00187 00188 if (!WriteFile(_hPipe, buffer, r, &wrote, NULL)) 00189 break; 00190 00191 #ifdef _DEBUG 00192 dbg_trace('<', buffer, r); 00193 #endif 00194 } 00195 } 00196 00197 return 0; 00198 } 00199 }; 00200 00201 00202 LONG read_pipe(HANDLE hPipe, SOCKET sock) 00203 { 00204 for(;;) { 00205 DWORD read; 00206 char buffer[1024]; 00207 00208 // wait for input data 00209 WaitForSingleObject(hPipe, INFINITE); 00210 00211 if (!ReadFile(hPipe, buffer, sizeof(buffer), &read, NULL)) { 00212 DWORD error = GetLastError(); 00213 00214 if (error == ERROR_PIPE_LISTENING) 00215 Sleep(1000); 00216 else 00217 return error; 00218 } 00219 00220 if (read) { 00221 #ifdef _DEBUG 00222 dbg_trace('>', buffer, read); 00223 #endif 00224 00225 if (!send(sock, buffer, read, 0)) { 00226 perror("send()"); 00227 return GetLastError(); 00228 } 00229 } 00230 } 00231 } 00232 00233 00234 int main(int argc, char** argv) 00235 { 00236 char path[MAX_PATH]; 00237 const char* pipe_name; 00238 00239 if (argc > 1) 00240 pipe_name = *++argv; 00241 else 00242 pipe_name = "com_2"; 00243 00244 sprintf(path, "\\\\.\\pipe\\%s", pipe_name); 00245 00246 00247 // initialize winsock 00248 WSADATA wsa_data; 00249 00250 if (WSAStartup(MAKEWORD(2,2), &wsa_data)) { 00251 fprintf(stderr, "WSAStartup() failed\n"); 00252 return 0; 00253 } 00254 00255 00256 // increment priority to be faster than the cpu eating VMWare process 00257 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 00258 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 00259 00260 00261 HANDLE hPipe = INVALID_HANDLE_VALUE; 00262 00263 for(;;) { 00264 DWORD read; 00265 00266 if (hPipe == INVALID_HANDLE_VALUE) { 00267 hPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_WAIT|PIPE_TYPE_BYTE, 1, 4096, 4096, 30000, NULL); 00268 00269 if (hPipe == INVALID_HANDLE_VALUE) { 00270 print_error(GetLastError()); 00271 return 1; 00272 } 00273 } 00274 00275 // wait for the client side of the pipe 00276 while(!ReadFile(hPipe, NULL, 0, &read, NULL) && 00277 GetLastError()==ERROR_PIPE_LISTENING) 00278 Sleep(1000); 00279 00280 puts("\nnamed pipe connected, now waiting for TCP connection..."); 00281 00282 SOCKET sock = open_tcp_connect(); 00283 if (sock == (SOCKET)-1) 00284 break; 00285 00286 puts("TCP connection established."); 00287 00288 // launch writer thread 00289 new WriterThread(sock, hPipe); 00290 00291 // launch reader loop 00292 LONG error = read_pipe(hPipe, sock); 00293 00294 00295 // close TCP connectiom 00296 closesocket(sock); 00297 sock = (SOCKET)-1; 00298 00299 // close named pipe 00300 CloseHandle(hPipe); 00301 hPipe = INVALID_HANDLE_VALUE; 00302 00303 00304 if (error == ERROR_BROKEN_PIPE) 00305 puts("\nconnection closed."); // normal connection termination 00306 else { 00307 print_error(GetLastError()); 00308 break; 00309 } 00310 } 00311 00312 if (hPipe != INVALID_HANDLE_VALUE) 00313 if (!CloseHandle(hPipe)) 00314 print_error(GetLastError()); 00315 00316 return 0; 00317 } Generated on Sun May 27 2012 04:37:47 for ReactOS by
1.7.6.1
|