ReactOS  0.4.12-dev-375-g61fed54
pipespy.cpp
Go to the documentation of this file.
1 /*
2  * PipeSpy
3  * Copyright (c) 2004, Skywing (skywing@valhallalegends.com)
4  * Released under the GNU GPL for the ReactOS project
5  *
6  * This program can be used to spy on a named pipe in Windows NT(+)
7  * or ReactOS. It is particularly intended to be used for
8  * understanding the remote kernel debugging protocol used
9  * by windows kd.
10  *
11  * USE:
12  *
13  * PipeSpy \\.\pipe\debug_server \\.\pipe\debug_client > PipeSpy.log
14  *
15  * VMware: act as client, connect to \\.\pipe\debug_server, pipe is connected
16  * to application
17  *
18  * WinDbg -k com:pipe,port=\\.\pipe\debug_client,resets=0
19  *
20  * NOTE:
21  *
22  * This program hasn't really been tested against ReactOS, and has only
23  * been built with Visual Studio .NET 2003.
24  */
25 #include <process.h>
26 #include <windows.h>
27 #include <stdio.h>
28 
31 
32 void dumphex(const char *buf, int len, int pos)
33 {
34  int i, j;
35  for(j = 0; j < len; j += 16) {
36  for(i = 0; i < 16; i++) {
37  if(i + j < len)
38  printf("%02x%c", (unsigned char)buf[i + j], j + i + 1 == pos ? '*' : ' ');
39  else
40  printf(" ");
41  }
42  for(i = 0; i < 16; i++) {
43  if(i + j < len)
44  printf("%c", buf[i + j] >= ' ' ? buf[i + j] : '.');
45  else
46  printf(" ");
47  }
48  printf("\n");
49  }
50 }
51 
52 enum {
55 };
56 
57 typedef struct _READ_OVERLAPPED {
59  char* Buffer;
61  bool Server;
62  bool Connected;
64 
65 VOID WINAPI WritePipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
66 {
67  if(dwErrorCode) {
69  printf(lpOverlapped->hEvent ? "Server> Error %u writing to client pipe\n" : "Client> Error %u writing to server pipe\n", dwErrorCode);
71  }
72 
73  free((void*)lpOverlapped);
74 }
75 
76 VOID WINAPI ReadPipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
77 {
78  READ_OVERLAPPED* ReadOverlapped = (READ_OVERLAPPED*)lpOverlapped;
79  LPOVERLAPPED WriteOverlapped;
80 
82 
83  if(dwErrorCode) {
84  printf(ReadOverlapped->Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", dwErrorCode);
85  ReadOverlapped->Connected = false;
86  } else {
87  SYSTEMTIME SystemTime;
88 
89  GetLocalTime(&SystemTime);
90  printf(ReadOverlapped->Server ? "Server> [%02u:%02u:%02u.%03u] Received %u byte message:\n" : "Client> [%02u:%02u:%02u.%03u] Received %u byte message:\n",
91  SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, dwNumberOfBytesTransferred);
92  dumphex(ReadOverlapped->Buffer, (int)dwNumberOfBytesTransferred, -1);
93  printf("\n");
94  }
95 
97 
98  WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+dwNumberOfBytesTransferred);
99 
100  if(!WriteOverlapped)
101  printf(ReadOverlapped->Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
102  else {
103  ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
104  WriteOverlapped->hEvent = (HANDLE)ReadOverlapped->Server;
105  memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), ReadOverlapped->Buffer, dwNumberOfBytesTransferred);
106  WriteFileEx(ReadOverlapped->OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), dwNumberOfBytesTransferred, WriteOverlapped,
108  }
109 
110  if(!dwErrorCode) {
111  ZeroMemory(ReadOverlapped, sizeof(OVERLAPPED));
112  ReadFileEx(ReadOverlapped->Pipe, ReadOverlapped->Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped->ReadOverlapped, ReadPipeCompletion);
113  }
114 }
115 
117 {
118  READ_OVERLAPPED ReadOverlapped;
119 
120  ReadOverlapped.Pipe = (HANDLE)param, ReadOverlapped.OtherPipe = ReadOverlapped.Pipe == g_DebugServerPipe ? g_DebugClientPipe : g_DebugServerPipe;
121  ReadOverlapped.Server = ReadOverlapped.Pipe == g_DebugServerPipe;
122  ReadOverlapped.Buffer = (char*)malloc(PIPEBUF_INITIAL_SIZE);
123 
124  for(;;) {
125  if(!ConnectNamedPipe(ReadOverlapped.Pipe, 0) && GetLastError() != ERROR_PIPE_CONNECTED) {
126  printf(ReadOverlapped.Server ? "Server> Error %u accepting pipe connection\n" : "Client> Error %u accepting pipe connection\n",
127  GetLastError());
128  break;
129  }
130 
131  ReadOverlapped.Connected = true;
132  printf(ReadOverlapped.Server ? "Server> Connected\n" : "Client> Connected\n");
133 
134  ZeroMemory(&ReadOverlapped.ReadOverlapped, sizeof(OVERLAPPED));
135  ReadFileEx(ReadOverlapped.Pipe, ReadOverlapped.Buffer, PIPEBUF_INITIAL_SIZE, &ReadOverlapped.ReadOverlapped, ReadPipeCompletion);
136 
137  do {
139  } while(ReadOverlapped.Connected) ;
140 
141  DisconnectNamedPipe(ReadOverlapped.Pipe);
142  printf(ReadOverlapped.Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
143  }
144 
145  printf(ReadOverlapped.Server ? "Server> Shutting down\n" : "Client> Shutting down\n");
146 
147  free(ReadOverlapped.Buffer);
148  CloseHandle(ReadOverlapped.Pipe);
149  SleepEx(0, TRUE);
150 }
151 
152 int main(int ac, char **av)
153 {
154  if(ac != 3) {
155  printf("syntax: pipespy serverpipe clientpipe\n");
156  return 0;
157  }
158 
160  1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
161 
163  printf("Error %u creating server pipe\n", GetLastError());
164  return 0;
165  }
166 
168  1, 4096, 4096, NMPWAIT_WAIT_FOREVER, 0);
169 
171  printf("Error %u creating client pipe\n", GetLastError());
173  return 0;
174  }
175 
180  return 0;
181 }
182 
183 
184 /*
185  while(!Error) {
186  SleepEx(0, TRUE);
187  BufferPos = 0;
188 
189  if(BufferSize > PIPEBUF_MAX_SIZE) {
190  char* NewBuf = (char*)realloc(Buffer, PIPEBUF_MAX_SIZE);
191 
192  if(NewBuf) {
193  Buffer = NewBuf;
194  BufferSize = PIPEBUF_MAX_SIZE;
195  }
196  }
197 
198  for(;;) {
199  char* NewBuf;
200 
201  if(ReadFile(Pipe, Buffer+BufferPos, BufferSize-BufferPos, &Read, 0)) {
202  BufferPos += Read;
203  Error = 0;
204  break;
205  }
206 
207  Error = GetLastError();
208 
209  printf("Error=%u read=%u\n", Error, Read);
210 
211  if(Error != ERROR_MORE_DATA) {
212  printf(Server ? "Server> Error %u reading from pipe\n" : "Client> Error %u reading from pipe\n", GetLastError());
213  break;
214  }
215 
216  NewBuf = (char*)realloc(Buffer, BufferSize << 1);
217 
218  if(!NewBuf) {
219  printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
220  break;
221  }
222 
223  BufferSize <<= 1;
224  BufferPos += Read;
225  Error = 0;
226  }
227 
228  if(Error)
229  break;
230 
231  WriteOverlapped = (LPOVERLAPPED)malloc(sizeof(OVERLAPPED)+BufferPos);
232 
233  if(!WriteOverlapped)
234  printf(Server ? "Server> Out of memory\n" : "Client> Out of memory\n");
235  else {
236  ZeroMemory(WriteOverlapped, sizeof(OVERLAPPED));
237  memcpy(((char*)WriteOverlapped)+sizeof(OVERLAPPED), Buffer, BufferPos);
238  WriteFileEx(OtherPipe, ((char*)WriteOverlapped)+sizeof(OVERLAPPED), BufferPos, WriteOverlapped, WritePipeCompletion);
239  }
240 
241  EnterCriticalSection(&g_OutputLock);
242  printf(Server ? "Server> Received %u byte message:\n" : "Client> Received %u byte message:\n", BufferPos);
243  dumphex(Buffer, (int)BufferPos, -1);
244  printf("\n");
245  LeaveCriticalSection(&g_OutputLock);
246  }
247 
248  DisconnectNamedPipe(Pipe);
249  printf(Server ? "Server> Disconnected\n" : "Client> Disconnected\n");
250 
251  */
#define CreateNamedPipe
Definition: winbase.h:3571
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
struct _OVERLAPPED OVERLAPPED
#define __cdecl
Definition: accygwin.h:79
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
struct _OVERLAPPED * LPOVERLAPPED
#define free
Definition: debug_ros.c:5
#define PIPE_WAIT
Definition: winbase.h:171
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1635
HANDLE g_DebugServerPipe
Definition: pipespy.cpp:29
void __cdecl pipeserver(void *param)
Definition: pipespy.cpp:116
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
struct _READ_OVERLAPPED READ_OVERLAPPED
VOID WINAPI WritePipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
Definition: pipespy.cpp:65
HANDLE g_DebugClientPipe
Definition: pipespy.cpp:29
GLenum GLclampf GLint i
Definition: glfuncs.h:14
BOOL WINAPI ReadFileEx(IN HANDLE hFile, IN LPVOID lpBuffer, IN DWORD nNumberOfBytesToRead OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:299
int main(int ac, char **av)
Definition: pipespy.cpp:152
#define NMPWAIT_WAIT_FOREVER
Definition: winbase.h:133
#define PIPE_TYPE_BYTE
Definition: winbase.h:167
HANDLE hEvent
Definition: winbase.h:792
WORD wMinute
Definition: winbase.h:875
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
VOID WINAPI GetLocalTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:276
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:748
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:164
GLfloat param
Definition: glext.h:5796
PVOID HANDLE
Definition: typedefs.h:71
unsigned long DWORD
Definition: ntddk_ex.h:95
WORD wSecond
Definition: winbase.h:876
WORD wMilliseconds
Definition: winbase.h:877
#define ERROR_PIPE_CONNECTED
Definition: winerror.h:352
BOOL WINAPI DisconnectNamedPipe(HANDLE hNamedPipe)
Definition: npipe.c:961
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
#define WINAPI
Definition: msvc.h:20
VOID WINAPI ReadPipeCompletion(DWORD dwErrorCode, DWORD dwNumberOfBytesTransferred, LPOVERLAPPED lpOverlapped)
Definition: pipespy.cpp:76
void dumphex(const char *buf, int len, int pos)
Definition: pipespy.cpp:32
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:90
CRITICAL_SECTION g_OutputLock
Definition: pipespy.cpp:30
WORD wHour
Definition: winbase.h:874
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
HANDLE OtherPipe
Definition: pipespy.cpp:60
#define malloc
Definition: debug_ros.c:4
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define INFINITE
Definition: serial.h:102
BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:262
BOOL WINAPI ConnectNamedPipe(IN HANDLE hNamedPipe, IN LPOVERLAPPED lpOverlapped)
Definition: npipe.c:701
OVERLAPPED ReadOverlapped
Definition: pipespy.cpp:58
#define printf
Definition: config.h:203
#define PIPE_READMODE_BYTE
Definition: winbase.h:169