ReactOS 0.4.15-dev-7918-g2a2556c
gdb2.cpp
Go to the documentation of this file.
1/*
2 * gdb2 - gdb output splitter
3 *
4 * Copyright (C) 2000,2001 Nedko Arnaoudov <nedkohome@atia.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; see the file COPYING. If not, write to
18 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include "ph.h"
23
24#define GDB_INITIAL_COMMAND "gdb.exe"
25#define PARAMS_SEPARATOR " "
26#define PARAMS_SEPARATOR_LEN strlen(PARAMS_SEPARATOR);
27
28void DisplayError(const char *pszAPI);
29void ReadAndHandleOutput(HANDLE hPipeRead);
30void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut,
31 HANDLE hChildStdIn,
32 HANDLE hChildStdErr,
33 char *pchCommandLine);
34
37HANDLE hStdIn = NULL; // Handle to parents std input.
39
40int main(int argc, char* argv[])
41{
42 HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
43 HANDLE hInputWriteTmp,hInputRead,hInputWrite;
44 HANDLE hErrorWrite;
46 DWORD ThreadId;
48
49 // Set up the security attributes struct.
50 sa.nLength= sizeof(SECURITY_ATTRIBUTES);
51 sa.lpSecurityDescriptor = NULL;
52 sa.bInheritHandle = TRUE;
53
54
55 // Create the child output pipe.
56 if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
57 DisplayError("CreatePipe");
58
59
60 // Create a duplicate of the output write handle for the std error
61 // write handle. This is necessary in case the child application
62 // closes one of its std output handles.
63 if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
64 GetCurrentProcess(),&hErrorWrite,0,
66 DisplayError("DuplicateHandle");
67
68
69 // Create the child input pipe.
70 if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
71 DisplayError("CreatePipe");
72
73
74 // Create new output read handle and the input write handles. Set
75 // the Properties to FALSE. Otherwise, the child inherits the
76 // properties and, as a result, non-closeable handles to the pipes
77 // are created.
78 if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
80 &hOutputRead, // Address of new handle.
81 0,FALSE, // Make it uninheritable.
83 DisplayError("DupliateHandle");
84
85 if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
87 &hInputWrite, // Address of new handle.
88 0,FALSE, // Make it uninheritable.
90 DisplayError("DupliateHandle");
91
92
93 // Close inheritable copies of the handles you do not want to be
94 // inherited.
95 if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
96 if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");
97
98
99 // Get std input handle so you can close it and force the ReadFile to
100 // fail when you want the input thread to exit.
103 DisplayError("GetStdHandle");
104
105 SetConsoleTitle("gdb control console");
106
108
109 // get parameters length
110 for (int i = 1 ; i < argc ; i++)
112
113 size++; // terminating null
114
115 char *pszCommandLine = new char [size];
116 if (!pszCommandLine)
117 {
118 printf("out of memory.\n");
119 return -1;
120 }
121
122 strcpy(pszCommandLine,GDB_INITIAL_COMMAND);
123 for (int i = 1 ; i < argc ; i++)
124 {
125 strcat(pszCommandLine,PARAMS_SEPARATOR);
126 strcat(pszCommandLine,argv[i]);
127 }
128
129 PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite,pszCommandLine);
130
131
132 // Close pipe handles (do not continue to modify the parent).
133 // You need to make sure that no handles to the write end of the
134 // output pipe are maintained in this process or else the pipe will
135 // not close when the child process exits and the ReadFile will hang.
136 if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
137 if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
138 if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");
139
140
141 // Launch the thread that gets the input and sends it to the child.
143 (LPVOID)hInputWrite,0,&ThreadId);
144 if (hThread == NULL) DisplayError("CreateThread");
145
146
147 // Read the child's output.
148 ReadAndHandleOutput(hOutputRead);
149 // Redirection is complete
150
151
152 // Force the read on the input to return by closing the stdin handle.
153 if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");
154
155
156 // Tell the thread to exit and wait for thread to die.
158
160 DisplayError("WaitForSingleObject");
161
162 if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
163 if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
164
165 return 0;
166}
167
169// PrepAndLaunchRedirectedChild
170// Sets up STARTUPINFO structure, and launches redirected child.
173 HANDLE hChildStdIn,
174 HANDLE hChildStdErr,
175 char *pchCommandLine)
176{
178 STARTUPINFO si;
179 static CHAR Title[] = "debugged program console";
180
181 // Set up the start up info struct.
182 ZeroMemory(&si,sizeof(STARTUPINFO));
183 si.cb = sizeof(STARTUPINFO);
185 si.hStdOutput = hChildStdOut;
186 si.hStdInput = hChildStdIn;
187 si.hStdError = hChildStdErr;
188 si.lpTitle = Title;
189 // Use this if you want to hide the child:
190 // si.wShowWindow = SW_HIDE;
191 // Note that dwFlags must include STARTF_USESHOWWINDOW if you want to
192 // use the wShowWindow flags.
193
194
195 // Launch the process that you want to redirect (in this case,
196 // Child.exe). Make sure Child.exe is in the same directory as
197 // redirect.c launch redirect from a command line to prevent location
198 // confusion.
199 if (!CreateProcess(NULL,pchCommandLine,NULL,NULL,TRUE,
201 DisplayError("CreateProcess");
202
203
204 // Set global child process handle to cause threads to exit.
205 hChildProcess = pi.hProcess;
206
207
208 // Close any unnecessary handles.
209 if (!CloseHandle(pi.hThread)) DisplayError("CloseHandle");
210}
211
213// ReadAndHandleOutput
214// Monitors handle for input. Exits when child exits or pipe breaks.
217{
218 CHAR lpBuffer[256];
219 DWORD nBytesRead;
220 DWORD nCharsWritten;
221
222 while(TRUE)
223 {
224 if (!ReadFile(hPipeRead,lpBuffer,sizeof(lpBuffer),
225 &nBytesRead,NULL) || !nBytesRead)
226 {
228 break; // pipe done - normal exit path.
229 else
230 DisplayError("ReadFile"); // Something bad happened.
231 }
232
233 // Display the character read on the screen.
235 nBytesRead,&nCharsWritten,NULL))
236 DisplayError("WriteConsole");
237 }
238}
239
240
242// GetAndSendInputThread
243// Thread procedure that monitors the console for input and sends input
244// to the child process through the input pipe.
245// This thread ends when the child application exits.
248{
249 CHAR read_buff[256];
250 DWORD nBytesRead,nBytesWrote;
251 HANDLE hPipeWrite = (HANDLE)lpvThreadParam;
252
253 // Get input from our console and send it to child through the pipe.
254 while (bRunThread)
255 {
256 if(!ReadConsole(hStdIn,read_buff,1,&nBytesRead,NULL))
257 DisplayError("ReadConsole");
258
259 read_buff[nBytesRead] = '\0'; // Follow input with a NULL.
260
261 if (!WriteFile(hPipeWrite,read_buff,nBytesRead,&nBytesWrote,NULL))
262 {
264 break; // Pipe was closed (normal exit path).
265 else
266 DisplayError("WriteFile");
267 }
268 }
269
270 return 1;
271}
272
274// DisplayError
275// Displays the error number and corresponding message.
277void DisplayError(const char *pszAPI)
278{
279 LPVOID lpvMessageBuffer;
280 CHAR szPrintBuffer[512];
281 DWORD nCharsWritten;
282
287 (LPTSTR)&lpvMessageBuffer, 0, NULL);
288
289 wsprintf(szPrintBuffer,
290 "ERROR: API = %s.\n error code = %d.\n message = %s.\n",
291 pszAPI, GetLastError(), (char *)lpvMessageBuffer);
292
294 lstrlen(szPrintBuffer),&nCharsWritten,NULL);
295
296 LocalFree(lpvMessageBuffer);
298}
static int argc
Definition: ServiceArgs.c:12
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR Title[]
Definition: oid.c:1259
#define CloseHandle
Definition: compat.h:739
struct _SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GetCurrentProcess()
Definition: compat.h:759
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1487
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
int main()
Definition: test.c:6
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:93
void PrepAndLaunchRedirectedChild(HANDLE hChildStdOut, HANDLE hChildStdIn, HANDLE hChildStdErr, char *pchCommandLine)
Definition: gdb2.cpp:172
DWORD WINAPI GetAndSendInputThread(LPVOID lpvThreadParam)
Definition: gdb2.cpp:247
void ReadAndHandleOutput(HANDLE hPipeRead)
Definition: gdb2.cpp:216
#define GDB_INITIAL_COMMAND
Definition: gdb2.cpp:24
HANDLE hChildProcess
Definition: gdb2.cpp:36
HANDLE hStdIn
Definition: gdb2.cpp:37
#define PARAMS_SEPARATOR
Definition: gdb2.cpp:25
#define PARAMS_SEPARATOR_LEN
Definition: gdb2.cpp:26
void DisplayError(const char *pszAPI)
Definition: gdb2.cpp:277
BOOL bRunThread
Definition: gdb2.cpp:38
GLsizeiptr size
Definition: glext.h:5919
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HLOCAL NTAPI LocalFree(HLOCAL hMem)
Definition: heapmem.c:1594
static refpint_t pi[]
Definition: server.c:96
#define argv
Definition: mplay32.c:18
HANDLE hThread
Definition: wizard.c:28
BOOL WINAPI CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
Definition: npipe.c:117
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
HANDLE hStdOutput
Definition: winbase.h:847
LPSTR lpTitle
Definition: winbase.h:834
HANDLE hStdError
Definition: winbase.h:848
DWORD dwFlags
Definition: winbase.h:842
DWORD cb
Definition: winbase.h:831
HANDLE hStdInput
Definition: winbase.h:846
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
PVOID HANDLE
Definition: typedefs.h:73
#define FormatMessage
Definition: winbase.h:3795
#define CreateProcess
Definition: winbase.h:3758
#define ZeroMemory
Definition: winbase.h:1712
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
STARTUPINFOA STARTUPINFO
Definition: winbase.h:3719
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:419
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
#define WAIT_FAILED
Definition: winbase.h:413
#define lstrlen
Definition: winbase.h:3876
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180
#define SetConsoleTitle
Definition: wincon.h:783
#define ReadConsole
Definition: wincon.h:777
#define WriteConsole
Definition: wincon.h:784
#define WINAPI
Definition: msvc.h:6
#define ERROR_NO_DATA
Definition: winerror.h:284
#define ERROR_BROKEN_PIPE
Definition: winerror.h:183
#define wsprintf
Definition: winuser.h:5865
#define DUPLICATE_SAME_ACCESS
CHAR * LPTSTR
Definition: xmlstorage.h:192
char CHAR
Definition: xmlstorage.h:175