annotate agent/src/os/win32/SwDbgSrv.cpp @ 1552:c18cbe5936b8

6941466: Oracle rebranding changes for Hotspot repositories Summary: Change all the Sun copyrights to Oracle copyright Reviewed-by: ohair
author trims
date Thu, 27 May 2010 19:08:38 -0700
parents a61af66fc99e
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
2 * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 0
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // A Simple Windows Debug Server.
a61af66fc99e Initial load
duke
parents:
diff changeset
26 //
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // This software provides a socket-based debug server which uses
a61af66fc99e Initial load
duke
parents:
diff changeset
28 // mostly ASCII protocols to communicate with its clients. Since the
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Windows security model is largely based around being able to run
a61af66fc99e Initial load
duke
parents:
diff changeset
30 // programs on the machine, this server only accepts connections
a61af66fc99e Initial load
duke
parents:
diff changeset
31 // coming from localhost.
a61af66fc99e Initial load
duke
parents:
diff changeset
32 //
a61af66fc99e Initial load
duke
parents:
diff changeset
33 // When run as a service (under Windows NT), this software provides
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // clients the ability to attach to and detach from processes without
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // killing those processes. Ordinarily this is forbidden by the
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // Windows debugging APIs (although more recent debugging environments
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // from Microsoft seem to have circumvented this restriction, perhaps
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // in a different way). This is achieved by forking a persistent
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // subprocess for each debugging session which remains alive as long
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // as the target process is.
a61af66fc99e Initial load
duke
parents:
diff changeset
41 //
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // At this point the client can read information out of the target
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // process's address space. Future work includes exposing more
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // functionality like writing to the remote address space and
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // suspending and resuming threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 #include <iostream>
a61af66fc99e Initial load
duke
parents:
diff changeset
48 #include <vector>
a61af66fc99e Initial load
duke
parents:
diff changeset
49 #include <stdlib.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Must come before everything else
a61af66fc99e Initial load
duke
parents:
diff changeset
51 #include <winsock2.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
52 #include <assert.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
53 #include "Dispatcher.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
54 #include "Handler.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
55 #include "initWinsock.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
56 #include "ioUtils.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
57 #include "isNT4.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
58 #include "Message.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
59 #include "nt4internals.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
60 #include "ports.h"
a61af66fc99e Initial load
duke
parents:
diff changeset
61 #include "procList.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
62 #include "serverLists.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
63 #include "Reaper.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
64
a61af66fc99e Initial load
duke
parents:
diff changeset
65 // Uncomment the #define below to get messages on stderr
a61af66fc99e Initial load
duke
parents:
diff changeset
66 // #define DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 using namespace std;
a61af66fc99e Initial load
duke
parents:
diff changeset
69
a61af66fc99e Initial load
duke
parents:
diff changeset
70 static ChildList childList;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 static ClientList clientList;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 static Reaper* reaper = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Needed prototypes
a61af66fc99e Initial load
duke
parents:
diff changeset
75 void shutdownChild(ChildInfo* childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
76 void detachClient(ClientInfo* clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void shutdownClient(ClientInfo* clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 char *
a61af66fc99e Initial load
duke
parents:
diff changeset
80 longToDotFormat(long addr)
a61af66fc99e Initial load
duke
parents:
diff changeset
81 {
a61af66fc99e Initial load
duke
parents:
diff changeset
82 char *temp_s = new char[20];
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 sprintf(temp_s, "%d.%d.%d.%d", ((addr & 0xff000000) >> 24),
a61af66fc99e Initial load
duke
parents:
diff changeset
85 ((addr & 0x00ff0000) >> 16), ((addr & 0x0000ff00) >> 8),
a61af66fc99e Initial load
duke
parents:
diff changeset
86 (addr & 0x000000ff));
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 return temp_s;
a61af66fc99e Initial load
duke
parents:
diff changeset
89 }
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 // NOTE that we do this query every time. It is a bad idea to cache IP
a61af66fc99e Initial load
duke
parents:
diff changeset
92 // addresses. For example, we might be hosted on a machine using DHCP
a61af66fc99e Initial load
duke
parents:
diff changeset
93 // and the connection addresses might change over time. (Yes, this
a61af66fc99e Initial load
duke
parents:
diff changeset
94 // actually happened.)
a61af66fc99e Initial load
duke
parents:
diff changeset
95 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
96 isConnectionOkay(ULONG connAddr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 if (connAddr == INADDR_LOOPBACK) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 const int MAXNAME = 1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
102 char myname[MAXNAME];
a61af66fc99e Initial load
duke
parents:
diff changeset
103 gethostname(myname, MAXNAME);
a61af66fc99e Initial load
duke
parents:
diff changeset
104 struct hostent* myInfo = gethostbyname(myname);
a61af66fc99e Initial load
duke
parents:
diff changeset
105 if (myInfo == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
107 cerr << "My host information was null" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
108 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
109 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // Run down the list of IP addresses for myself
a61af66fc99e Initial load
duke
parents:
diff changeset
111 assert(myInfo->h_length == sizeof(ULONG));
a61af66fc99e Initial load
duke
parents:
diff changeset
112 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
113 cerr << "My known IP addresses: " << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
115 for (char** pp = myInfo->h_addr_list; *pp != NULL; pp++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 char* p = *pp;
a61af66fc99e Initial load
duke
parents:
diff changeset
117 ULONG altAddr = ntohl(*((ULONG*) p));
a61af66fc99e Initial load
duke
parents:
diff changeset
118 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
119 char* name = longToDotFormat(altAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
120 cerr << name << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 delete[] name;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (altAddr == connAddr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
125 cerr << "FOUND" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
126 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
127 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
131 cerr << "Done." << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 }
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 SOCKET
a61af66fc99e Initial load
duke
parents:
diff changeset
139 setupListeningSocket(short port) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 SOCKET listening = socket(AF_INET, SOCK_STREAM, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
141 if (listening == INVALID_SOCKET) {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 cerr << "Error creating listening socket" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 int reuseAddress = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 if (setsockopt(listening, SOL_SOCKET, SO_REUSEADDR,
a61af66fc99e Initial load
duke
parents:
diff changeset
148 (char *)&reuseAddress, sizeof(reuseAddress)) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 cerr << "Error reusing address" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 struct sockaddr_in serverInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 memset((char *)&serverInfo, 0, sizeof(serverInfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
156 serverInfo.sin_addr.s_addr = INADDR_ANY;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 serverInfo.sin_family = AF_INET;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 serverInfo.sin_port = htons(port);
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 if (bind(listening, (struct sockaddr *) &serverInfo, sizeof(serverInfo)) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 cerr << "Error binding socket" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (listen(listening, 5) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 cerr << "Error listening" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 return listening;
a61af66fc99e Initial load
duke
parents:
diff changeset
171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
172
a61af66fc99e Initial load
duke
parents:
diff changeset
173 /** Accepts a connection from the given listening socket, but only if
a61af66fc99e Initial load
duke
parents:
diff changeset
174 the connection came from localhost. Returns INVALID_SOCKET if the
a61af66fc99e Initial load
duke
parents:
diff changeset
175 connection came from any other IP address or if an error occurred
a61af66fc99e Initial load
duke
parents:
diff changeset
176 during the call to accept(). */
a61af66fc99e Initial load
duke
parents:
diff changeset
177 SOCKET
a61af66fc99e Initial load
duke
parents:
diff changeset
178 acceptFromLocalhost(SOCKET listening) {
a61af66fc99e Initial load
duke
parents:
diff changeset
179 struct sockaddr_in peerAddr;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int peerAddrLen = sizeof(peerAddr);
a61af66fc99e Initial load
duke
parents:
diff changeset
181 SOCKET fd = accept(listening, (sockaddr*) &peerAddr, &peerAddrLen);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 if (fd == INVALID_SOCKET) {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 return fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if (!isConnectionOkay(ntohl(peerAddr.sin_addr.s_addr))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Reject connections from other machines for security purposes.
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // The Windows security model seems to assume one user per
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // machine, and that security is compromised if another user is
a61af66fc99e Initial load
duke
parents:
diff changeset
190 // able to run executables on the given host. (If these
a61af66fc99e Initial load
duke
parents:
diff changeset
191 // assumptions are not strict enough, we will have to change
a61af66fc99e Initial load
duke
parents:
diff changeset
192 // this.)
a61af66fc99e Initial load
duke
parents:
diff changeset
193 shutdown(fd, SD_BOTH);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 closesocket(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 return INVALID_SOCKET;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 // Disable TCP buffering on all sockets. We send small amounts of
a61af66fc99e Initial load
duke
parents:
diff changeset
199 // data back and forth and don't want buffering.
a61af66fc99e Initial load
duke
parents:
diff changeset
200 int buffer_val = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (setsockopt(fd, IPPROTO_IP, TCP_NODELAY,
a61af66fc99e Initial load
duke
parents:
diff changeset
202 (char *) &buffer_val, sizeof(buffer_val)) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 shutdown(fd, SD_BOTH);
a61af66fc99e Initial load
duke
parents:
diff changeset
204 closesocket(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 return fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 void
a61af66fc99e Initial load
duke
parents:
diff changeset
211 reapCB(void* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 ChildInfo* info = (ChildInfo*) arg;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 DWORD pid = info->getPid();
a61af66fc99e Initial load
duke
parents:
diff changeset
215 shutdownChild(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
217 cerr << "Reaped child for process " << pid << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 /** Starts a child process with stdin and stdout redirected to pipes,
a61af66fc99e Initial load
duke
parents:
diff changeset
222 handles to which are returned. auxHandle1 and auxHandle2 should be
a61af66fc99e Initial load
duke
parents:
diff changeset
223 closed as well when the child process exits. Returns false if
a61af66fc99e Initial load
duke
parents:
diff changeset
224 process creation failed. */
a61af66fc99e Initial load
duke
parents:
diff changeset
225 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
226 startChildProcess(DWORD pidToDebug,
a61af66fc99e Initial load
duke
parents:
diff changeset
227 DWORD childStdinBufSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
228 DWORD childStdoutBufSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
229 LPHANDLE childProcessHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
230 LPHANDLE writeToStdinHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
231 LPHANDLE readFromStdoutHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
232 LPHANDLE auxHandle1,
a61af66fc99e Initial load
duke
parents:
diff changeset
233 LPHANDLE auxHandle2) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 // Code adapted from Microsoft example
a61af66fc99e Initial load
duke
parents:
diff changeset
235 // "Creating a Child Process with Redirected Input and Output"
a61af66fc99e Initial load
duke
parents:
diff changeset
236
a61af66fc99e Initial load
duke
parents:
diff changeset
237 SECURITY_ATTRIBUTES saAttr;
a61af66fc99e Initial load
duke
parents:
diff changeset
238 BOOL fSuccess;
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
a61af66fc99e Initial load
duke
parents:
diff changeset
241 hChildStdoutRd, hChildStdoutWr, hChildStdoutRdDup,
a61af66fc99e Initial load
duke
parents:
diff changeset
242 hSaveStdin, hSaveStdout;
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 // Set the bInheritHandle flag so pipe handles are inherited.
a61af66fc99e Initial load
duke
parents:
diff changeset
245 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
a61af66fc99e Initial load
duke
parents:
diff changeset
246 saAttr.bInheritHandle = TRUE;
a61af66fc99e Initial load
duke
parents:
diff changeset
247 saAttr.lpSecurityDescriptor = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 // The steps for redirecting child process's STDOUT:
a61af66fc99e Initial load
duke
parents:
diff changeset
250 // 1. Save current STDOUT, to be restored later.
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // 2. Create anonymous pipe to be STDOUT for child process.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // 3. Set STDOUT of the parent process to be write handle to
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // the pipe, so it is inherited by the child process.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // 4. Create a noninheritable duplicate of the read handle and
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // close the inheritable read handle.
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Save the handle to the current STDOUT.
a61af66fc99e Initial load
duke
parents:
diff changeset
258 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // Create a pipe for the child process's STDOUT.
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, childStdoutBufSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // Set a write handle to the pipe to be STDOUT.
a61af66fc99e Initial load
duke
parents:
diff changeset
264 if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
265 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267 // Create noninheritable read handle and close the inheritable read
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // handle.
a61af66fc99e Initial load
duke
parents:
diff changeset
269 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
a61af66fc99e Initial load
duke
parents:
diff changeset
270 GetCurrentProcess(), &hChildStdoutRdDup,
a61af66fc99e Initial load
duke
parents:
diff changeset
271 0, FALSE,
a61af66fc99e Initial load
duke
parents:
diff changeset
272 DUPLICATE_SAME_ACCESS);
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if( !fSuccess ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
274 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
276 CloseHandle(hChildStdoutRd);
a61af66fc99e Initial load
duke
parents:
diff changeset
277
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // The steps for redirecting child process's STDIN:
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // 1. Save current STDIN, to be restored later.
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // 2. Create anonymous pipe to be STDIN for child process.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 // 3. Set STDIN of the parent to be the read handle to the
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // pipe, so it is inherited by the child process.
a61af66fc99e Initial load
duke
parents:
diff changeset
283 // 4. Create a noninheritable duplicate of the write handle,
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // and close the inheritable write handle.
a61af66fc99e Initial load
duke
parents:
diff changeset
285 // Save the handle to the current STDIN.
a61af66fc99e Initial load
duke
parents:
diff changeset
286 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
287 // Create a pipe for the child process's STDIN.
a61af66fc99e Initial load
duke
parents:
diff changeset
288 if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, childStdinBufSize)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
289 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291 // Set a read handle to the pipe to be STDIN.
a61af66fc99e Initial load
duke
parents:
diff changeset
292 if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 // Duplicate the write handle to the pipe so it is not inherited.
a61af66fc99e Initial load
duke
parents:
diff changeset
296 fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr,
a61af66fc99e Initial load
duke
parents:
diff changeset
297 GetCurrentProcess(), &hChildStdinWrDup, 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
298 FALSE, // not inherited
a61af66fc99e Initial load
duke
parents:
diff changeset
299 DUPLICATE_SAME_ACCESS);
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (! fSuccess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 CloseHandle(hChildStdinWr);
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // Create the child process
a61af66fc99e Initial load
duke
parents:
diff changeset
306 char cmdLine[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
307 sprintf(cmdLine, "SwDbgSub.exe %u", pidToDebug);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 PROCESS_INFORMATION procInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
309 STARTUPINFO startInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 memset((char*) &startInfo, 0, sizeof(startInfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
311 startInfo.cb = sizeof(startInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
312 BOOL res = CreateProcess(NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
313 cmdLine,
a61af66fc99e Initial load
duke
parents:
diff changeset
314 NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
315 NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
316 TRUE, // inherit handles: important
a61af66fc99e Initial load
duke
parents:
diff changeset
317 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
318 NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
319 NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
320 &startInfo,
a61af66fc99e Initial load
duke
parents:
diff changeset
321 &procInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
322 if (!res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
323 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
325 // After process creation, restore the saved STDIN and STDOUT.
a61af66fc99e Initial load
duke
parents:
diff changeset
326 if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
327 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329 if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 // hChildStdinWrDup can be used to write to the child's stdin
a61af66fc99e Initial load
duke
parents:
diff changeset
334 // hChildStdoutRdDup can be used to read from the child's stdout
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // NOTE: example code closes hChildStdoutWr before reading from
a61af66fc99e Initial load
duke
parents:
diff changeset
337 // hChildStdoutRdDup. "Close the write end of the pipe before
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // reading from the read end of the pipe"??? Looks like this is
a61af66fc99e Initial load
duke
parents:
diff changeset
339 // example-specific.
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Set up return arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
342 // hChildStdoutRd and hChildStdinWr are already closed at this point
a61af66fc99e Initial load
duke
parents:
diff changeset
343 *childProcessHandle = procInfo.hProcess;
a61af66fc99e Initial load
duke
parents:
diff changeset
344 *writeToStdinHandle = hChildStdinWrDup;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 *readFromStdoutHandle = hChildStdoutRdDup;
a61af66fc99e Initial load
duke
parents:
diff changeset
346 *auxHandle1 = hChildStdinRd;
a61af66fc99e Initial load
duke
parents:
diff changeset
347 *auxHandle2 = hChildStdoutWr;
a61af66fc99e Initial load
duke
parents:
diff changeset
348 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 /** Clears the event and writes the message to the child process */
a61af66fc99e Initial load
duke
parents:
diff changeset
352 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
353 sendMessage(ChildInfo* child, Message* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 DWORD numBytesWritten;
a61af66fc99e Initial load
duke
parents:
diff changeset
355 if (!WriteFile(child->getWriteToStdinHandle(),
a61af66fc99e Initial load
duke
parents:
diff changeset
356 message, sizeof(Message), &numBytesWritten, NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if (numBytesWritten != sizeof(Message)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // Follow up "poke" messages with the raw data
a61af66fc99e Initial load
duke
parents:
diff changeset
363 if (message->type == Message::POKE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
364 if (!WriteFile(child->getWriteToStdinHandle(),
a61af66fc99e Initial load
duke
parents:
diff changeset
365 message->pokeArg.data, message->pokeArg.numBytes, &numBytesWritten, NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 if (numBytesWritten != message->pokeArg.numBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
369 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 /** Copies data from child's stdout to the client's IOBuf and sends it
a61af66fc99e Initial load
duke
parents:
diff changeset
376 along */
a61af66fc99e Initial load
duke
parents:
diff changeset
377 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
378 forwardReplyToClient(ChildInfo* child, ClientInfo* client) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 DWORD total = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 IOBuf::FillState ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
383 DWORD temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
384 ret = client->getIOBuf()->fillFromFileHandle(child->getReadFromStdoutHandle(),
a61af66fc99e Initial load
duke
parents:
diff changeset
385 &temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 if (ret == IOBuf::DONE || ret == IOBuf::MORE_DATA_PENDING) {
a61af66fc99e Initial load
duke
parents:
diff changeset
387 if (!client->getIOBuf()->flush()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
388 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
389 cerr << "Forward failed because flush failed" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
390 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
391 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
393 total += temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
395 } while (ret == IOBuf::MORE_DATA_PENDING);
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 return (ret == IOBuf::FAILED) ? false : true;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 }
a61af66fc99e Initial load
duke
parents:
diff changeset
399
a61af66fc99e Initial load
duke
parents:
diff changeset
400 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
401 // Server Handler
a61af66fc99e Initial load
duke
parents:
diff changeset
402 //
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 class ServerHandler : public Handler {
a61af66fc99e Initial load
duke
parents:
diff changeset
405 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
406 ServerHandler();
a61af66fc99e Initial load
duke
parents:
diff changeset
407
a61af66fc99e Initial load
duke
parents:
diff changeset
408 // Starts up in Unicode mode by default
a61af66fc99e Initial load
duke
parents:
diff changeset
409 bool getASCII();
a61af66fc99e Initial load
duke
parents:
diff changeset
410
a61af66fc99e Initial load
duke
parents:
diff changeset
411 void setIOBuf(IOBuf* ioBuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
412
a61af66fc99e Initial load
duke
parents:
diff changeset
413 void procList(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // Must be called before calling one of the routines below
a61af66fc99e Initial load
duke
parents:
diff changeset
416 void setClientInfo(ClientInfo* info);
a61af66fc99e Initial load
duke
parents:
diff changeset
417
a61af66fc99e Initial load
duke
parents:
diff changeset
418 // Indicates to outer loop that exit was called or that an error
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // occurred and that the client exited.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 bool exited();
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // Clears this state
a61af66fc99e Initial load
duke
parents:
diff changeset
422 void clearExited();
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424 void ascii(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void unicode(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
426 void attach(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 void detach(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 void libInfo(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 void peek(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
430 void poke(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
431 void threadList(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 void dupHandle(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 void closeHandle(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 void getContext(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
435 void setContext(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
436 void selectorEntry(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
437 void suspend(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 void resume(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
439 void pollEvent(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
440 void continueEvent(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
441 void exit(char* arg);
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // This is pretty gross. Needed to make the target process know
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // about clients that have disconnected unexpectedly while attached.
a61af66fc99e Initial load
duke
parents:
diff changeset
445 friend void shutdownClient(ClientInfo*);
a61af66fc99e Initial load
duke
parents:
diff changeset
446 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
447 // Writes: charSize <space> numChars <space> <binary string>
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // Handles both ASCII and UNICODE modes
a61af66fc99e Initial load
duke
parents:
diff changeset
449 void writeString(USHORT len, WCHAR* str);
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // Handles only ASCII mode
a61af66fc99e Initial load
duke
parents:
diff changeset
452 void writeString(USHORT len, char* str);
a61af66fc99e Initial load
duke
parents:
diff changeset
453
a61af66fc99e Initial load
duke
parents:
diff changeset
454 ClientInfo* clientInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
455 IOBuf* ioBuf;
a61af66fc99e Initial load
duke
parents:
diff changeset
456 bool _exited;
a61af66fc99e Initial load
duke
parents:
diff changeset
457 bool _ascii;
a61af66fc99e Initial load
duke
parents:
diff changeset
458 };
a61af66fc99e Initial load
duke
parents:
diff changeset
459
a61af66fc99e Initial load
duke
parents:
diff changeset
460 static ServerHandler* handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 ServerHandler::ServerHandler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 _exited = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 _ascii = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 ioBuf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
469 ServerHandler::getASCII() {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 return _ascii;
a61af66fc99e Initial load
duke
parents:
diff changeset
471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 void
a61af66fc99e Initial load
duke
parents:
diff changeset
474 ServerHandler::setIOBuf(IOBuf* buf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 ioBuf = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 void
a61af66fc99e Initial load
duke
parents:
diff changeset
479 ServerHandler::setClientInfo(ClientInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 clientInfo = info;
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 bool
a61af66fc99e Initial load
duke
parents:
diff changeset
484 ServerHandler::exited() {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 return _exited;
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 void
a61af66fc99e Initial load
duke
parents:
diff changeset
489 ServerHandler::clearExited() {
a61af66fc99e Initial load
duke
parents:
diff changeset
490 _exited = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493 void
a61af66fc99e Initial load
duke
parents:
diff changeset
494 ServerHandler::ascii(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
495 _ascii = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 void
a61af66fc99e Initial load
duke
parents:
diff changeset
499 ServerHandler::unicode(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 _ascii = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502
a61af66fc99e Initial load
duke
parents:
diff changeset
503 void
a61af66fc99e Initial load
duke
parents:
diff changeset
504 ServerHandler::procList(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
505 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
506 cerr << "proclist" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
508
a61af66fc99e Initial load
duke
parents:
diff changeset
509 ProcEntryList processes;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 ::procList(processes);
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512 ioBuf->writeInt(processes.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 for (ProcEntryList::iterator iter = processes.begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
515 iter != processes.end(); iter++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 ProcEntry& entry = *iter;
a61af66fc99e Initial load
duke
parents:
diff changeset
517 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
518 ioBuf->writeUnsignedInt(entry.getPid());
a61af66fc99e Initial load
duke
parents:
diff changeset
519 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
520 writeString(entry.getNameLength(), entry.getName());
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
524 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 void
a61af66fc99e Initial load
duke
parents:
diff changeset
528 ServerHandler::attach(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // If the client is already attached to a process, fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
530 if (clientInfo->getTarget() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
531 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
533 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
534 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // Try to get pid
a61af66fc99e Initial load
duke
parents:
diff changeset
538 DWORD pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
539 if (!scanUnsignedLong(&arg, &pid)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
541 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
542 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
543 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // See whether this pid is already forked
a61af66fc99e Initial load
duke
parents:
diff changeset
547 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
548 ChildInfo* childInfo = childList.getChildByPid(pid);
a61af66fc99e Initial load
duke
parents:
diff changeset
549 if (childInfo != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // If this child already has a client, return false
a61af66fc99e Initial load
duke
parents:
diff changeset
551 if (childInfo->getClient() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
552 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
553 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
554 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
555 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Otherwise, can associate this client with this child process
a61af66fc99e Initial load
duke
parents:
diff changeset
559 childInfo->setClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
560 clientInfo->setTarget(childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // Tell the child we are attaching so it can suspend the target
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // process
a61af66fc99e Initial load
duke
parents:
diff changeset
564 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 msg.type = Message::ATTACH;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 sendMessage(childInfo, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 ioBuf->writeBoolAsInt(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
570 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
571 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
572 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // Have to fork a new child subprocess
a61af66fc99e Initial load
duke
parents:
diff changeset
574 HANDLE childProcessHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 HANDLE writeToStdinHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
576 HANDLE readFromStdoutHandle;
a61af66fc99e Initial load
duke
parents:
diff changeset
577 HANDLE auxHandle1;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 HANDLE auxHandle2;
a61af66fc99e Initial load
duke
parents:
diff changeset
579 if (!startChildProcess(pid,
a61af66fc99e Initial load
duke
parents:
diff changeset
580 32768,
a61af66fc99e Initial load
duke
parents:
diff changeset
581 131072,
a61af66fc99e Initial load
duke
parents:
diff changeset
582 &childProcessHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
583 &writeToStdinHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
584 &readFromStdoutHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
585 &auxHandle1,
a61af66fc99e Initial load
duke
parents:
diff changeset
586 &auxHandle2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
588 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
589 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
590 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 // See whether the child succeeded in attaching to the process
a61af66fc99e Initial load
duke
parents:
diff changeset
594 char res;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 DWORD numRead;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 if (!ReadFile(readFromStdoutHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
597 &res,
a61af66fc99e Initial load
duke
parents:
diff changeset
598 sizeof(char),
a61af66fc99e Initial load
duke
parents:
diff changeset
599 &numRead,
a61af66fc99e Initial load
duke
parents:
diff changeset
600 NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
602 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
603 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
604 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606
a61af66fc99e Initial load
duke
parents:
diff changeset
607 if (!res) {
a61af66fc99e Initial load
duke
parents:
diff changeset
608 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
610 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
611 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // OK, success.
a61af66fc99e Initial load
duke
parents:
diff changeset
615 childInfo = new ChildInfo(pid, childProcessHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
616 writeToStdinHandle, readFromStdoutHandle,
a61af66fc99e Initial load
duke
parents:
diff changeset
617 auxHandle1, auxHandle2);
a61af66fc99e Initial load
duke
parents:
diff changeset
618 childList.addChild(childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
619 reaper->registerProcess(childProcessHandle, childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Associate this client with this child process
a61af66fc99e Initial load
duke
parents:
diff changeset
621 childInfo->setClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
622 clientInfo->setTarget(childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 // Tell the child process to actually suspend the target process
a61af66fc99e Initial load
duke
parents:
diff changeset
625 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
626 msg.type = Message::ATTACH;
a61af66fc99e Initial load
duke
parents:
diff changeset
627 sendMessage(childInfo, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
628
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // Write result to client
a61af66fc99e Initial load
duke
parents:
diff changeset
630 ioBuf->writeBoolAsInt(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
632 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
633 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 void
a61af66fc99e Initial load
duke
parents:
diff changeset
638 ServerHandler::detach(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // If the client is not attached, fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
640 if (clientInfo->getTarget() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
641 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
642 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
643 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
644 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 detachClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649 ioBuf->writeBoolAsInt(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
650 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
651 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
652 }
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 void
a61af66fc99e Initial load
duke
parents:
diff changeset
655 ServerHandler::libInfo(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
656 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
657 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
658 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
659 ioBuf->writeInt(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
660 ioBuf->writeEOL();
a61af66fc99e Initial load
duke
parents:
diff changeset
661 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
662 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
666 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
667 msg.type = Message::LIBINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
668 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
669
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
671 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 void
a61af66fc99e Initial load
duke
parents:
diff changeset
675 ServerHandler::peek(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
676 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
677 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
678 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
679 ioBuf->writeString("B");
a61af66fc99e Initial load
duke
parents:
diff changeset
680 ioBuf->writeBinChar(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
681 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
682 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 // Try to get address
a61af66fc99e Initial load
duke
parents:
diff changeset
686 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
688 ioBuf->writeString("B");
a61af66fc99e Initial load
duke
parents:
diff changeset
689 ioBuf->writeBinChar(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
690 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
691 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
693
a61af66fc99e Initial load
duke
parents:
diff changeset
694 // Try to get number of bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
695 DWORD numBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
696 if (!scanUnsignedLong(&arg, &numBytes)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
697 ioBuf->writeString("B");
a61af66fc99e Initial load
duke
parents:
diff changeset
698 ioBuf->writeBinChar(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
700 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
702
a61af66fc99e Initial load
duke
parents:
diff changeset
703 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
704 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
705 msg.type = Message::PEEK;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 msg.peekArg.address = address;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 msg.peekArg.numBytes = numBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
711 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
712 }
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 void
a61af66fc99e Initial load
duke
parents:
diff changeset
715 ServerHandler::poke(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
717 cerr << "ServerHandler::poke" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
718 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
719 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
723 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
724 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
726
a61af66fc99e Initial load
duke
parents:
diff changeset
727 // Try to get address
a61af66fc99e Initial load
duke
parents:
diff changeset
728 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
729 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
732 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734
a61af66fc99e Initial load
duke
parents:
diff changeset
735 // Try to get number of bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
736 if (!scanAndSkipBinEscapeChar(&arg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
737 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
738 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
739 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
740 }
a61af66fc99e Initial load
duke
parents:
diff changeset
741 DWORD numBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
742 if (!scanBinUnsignedLong(&arg, &numBytes)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
743 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
745 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
746 }
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // Raw data is now in "arg"
a61af66fc99e Initial load
duke
parents:
diff changeset
749 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
750 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 msg.type = Message::POKE;
a61af66fc99e Initial load
duke
parents:
diff changeset
752 msg.pokeArg.address = address;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 msg.pokeArg.numBytes = numBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 msg.pokeArg.data = arg;
a61af66fc99e Initial load
duke
parents:
diff changeset
755 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
756
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
758 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 void
a61af66fc99e Initial load
duke
parents:
diff changeset
762 ServerHandler::threadList(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
765 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
766 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
767 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
768 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
770
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
772 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 msg.type = Message::THREADLIST;
a61af66fc99e Initial load
duke
parents:
diff changeset
774 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
777 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 void
a61af66fc99e Initial load
duke
parents:
diff changeset
781 ServerHandler::dupHandle(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
782 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
784 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
785 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
786 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
787 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // Try to get handle
a61af66fc99e Initial load
duke
parents:
diff changeset
791 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
793 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
794 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
798 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
799 msg.type = Message::DUPHANDLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
800 msg.handleArg.handle = (HANDLE) address;
a61af66fc99e Initial load
duke
parents:
diff changeset
801 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
804 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
805 }
a61af66fc99e Initial load
duke
parents:
diff changeset
806
a61af66fc99e Initial load
duke
parents:
diff changeset
807 void
a61af66fc99e Initial load
duke
parents:
diff changeset
808 ServerHandler::closeHandle(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
811 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
812 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // Try to get handle
a61af66fc99e Initial load
duke
parents:
diff changeset
816 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
817 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
818 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
822 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
823 msg.type = Message::CLOSEHANDLE;
a61af66fc99e Initial load
duke
parents:
diff changeset
824 msg.handleArg.handle = (HANDLE) address;
a61af66fc99e Initial load
duke
parents:
diff changeset
825 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
826
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // No reply
a61af66fc99e Initial load
duke
parents:
diff changeset
828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
829
a61af66fc99e Initial load
duke
parents:
diff changeset
830 void
a61af66fc99e Initial load
duke
parents:
diff changeset
831 ServerHandler::getContext(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
833 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
834 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
835 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
836 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
837 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // Try to get handle
a61af66fc99e Initial load
duke
parents:
diff changeset
841 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
842 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
843 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
844 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
845 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
849 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 msg.type = Message::GETCONTEXT;
a61af66fc99e Initial load
duke
parents:
diff changeset
851 msg.handleArg.handle = (HANDLE) address;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
853
a61af66fc99e Initial load
duke
parents:
diff changeset
854 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
855 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
856 }
a61af66fc99e Initial load
duke
parents:
diff changeset
857
a61af66fc99e Initial load
duke
parents:
diff changeset
858 void
a61af66fc99e Initial load
duke
parents:
diff changeset
859 ServerHandler::setContext(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
861 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
862 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
863 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
864 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
865 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // Try to get handle
a61af66fc99e Initial load
duke
parents:
diff changeset
869 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
870 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
872 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
873 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // Try to get context
a61af66fc99e Initial load
duke
parents:
diff changeset
877 DWORD regs[NUM_REGS_IN_CONTEXT];
a61af66fc99e Initial load
duke
parents:
diff changeset
878 for (int i = 0; i < NUM_REGS_IN_CONTEXT; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 if (!scanAddress(&arg, &regs[i])) {
a61af66fc99e Initial load
duke
parents:
diff changeset
880 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
881 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
882 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
887 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
888 msg.type = Message::SETCONTEXT;
a61af66fc99e Initial load
duke
parents:
diff changeset
889 msg.setContextArg.handle = (HANDLE) address;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 msg.setContextArg.Eax = regs[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
891 msg.setContextArg.Ebx = regs[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
892 msg.setContextArg.Ecx = regs[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
893 msg.setContextArg.Edx = regs[3];
a61af66fc99e Initial load
duke
parents:
diff changeset
894 msg.setContextArg.Esi = regs[4];
a61af66fc99e Initial load
duke
parents:
diff changeset
895 msg.setContextArg.Edi = regs[5];
a61af66fc99e Initial load
duke
parents:
diff changeset
896 msg.setContextArg.Ebp = regs[6];
a61af66fc99e Initial load
duke
parents:
diff changeset
897 msg.setContextArg.Esp = regs[7];
a61af66fc99e Initial load
duke
parents:
diff changeset
898 msg.setContextArg.Eip = regs[8];
a61af66fc99e Initial load
duke
parents:
diff changeset
899 msg.setContextArg.Ds = regs[9];
a61af66fc99e Initial load
duke
parents:
diff changeset
900 msg.setContextArg.Es = regs[10];
a61af66fc99e Initial load
duke
parents:
diff changeset
901 msg.setContextArg.Fs = regs[11];
a61af66fc99e Initial load
duke
parents:
diff changeset
902 msg.setContextArg.Gs = regs[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
903 msg.setContextArg.Cs = regs[13];
a61af66fc99e Initial load
duke
parents:
diff changeset
904 msg.setContextArg.Ss = regs[14];
a61af66fc99e Initial load
duke
parents:
diff changeset
905 msg.setContextArg.EFlags = regs[15];
a61af66fc99e Initial load
duke
parents:
diff changeset
906 msg.setContextArg.Dr0 = regs[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
907 msg.setContextArg.Dr1 = regs[17];
a61af66fc99e Initial load
duke
parents:
diff changeset
908 msg.setContextArg.Dr2 = regs[18];
a61af66fc99e Initial load
duke
parents:
diff changeset
909 msg.setContextArg.Dr3 = regs[19];
a61af66fc99e Initial load
duke
parents:
diff changeset
910 msg.setContextArg.Dr6 = regs[20];
a61af66fc99e Initial load
duke
parents:
diff changeset
911 msg.setContextArg.Dr7 = regs[21];
a61af66fc99e Initial load
duke
parents:
diff changeset
912 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
913
a61af66fc99e Initial load
duke
parents:
diff changeset
914 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
915 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 void
a61af66fc99e Initial load
duke
parents:
diff changeset
919 ServerHandler::selectorEntry(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
921 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
922 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
924 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
925 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // Try to get thread handle
a61af66fc99e Initial load
duke
parents:
diff changeset
929 DWORD address;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 if (!scanAddress(&arg, &address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
931 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
933 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 // Try to get selector
a61af66fc99e Initial load
duke
parents:
diff changeset
937 DWORD selector;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 if (!scanUnsignedLong(&arg, &selector)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
939 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
940 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
941 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 }
a61af66fc99e Initial load
duke
parents:
diff changeset
943
a61af66fc99e Initial load
duke
parents:
diff changeset
944 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
945 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
946 msg.type = Message::SELECTORENTRY;
a61af66fc99e Initial load
duke
parents:
diff changeset
947 msg.selectorArg.handle = (HANDLE) address;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 msg.selectorArg.selector = selector;
a61af66fc99e Initial load
duke
parents:
diff changeset
949 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
950
a61af66fc99e Initial load
duke
parents:
diff changeset
951 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
952 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
953 }
a61af66fc99e Initial load
duke
parents:
diff changeset
954
a61af66fc99e Initial load
duke
parents:
diff changeset
955 void
a61af66fc99e Initial load
duke
parents:
diff changeset
956 ServerHandler::suspend(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
957 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
959 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 }
a61af66fc99e Initial load
duke
parents:
diff changeset
962
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
964 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 msg.type = Message::SUSPEND;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968 // No reply
a61af66fc99e Initial load
duke
parents:
diff changeset
969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 void
a61af66fc99e Initial load
duke
parents:
diff changeset
972 ServerHandler::resume(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
973 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
974 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
975 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
976 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
980 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
981 msg.type = Message::RESUME;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
983
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // No reply
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 void
a61af66fc99e Initial load
duke
parents:
diff changeset
988 ServerHandler::pollEvent(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
990 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
991 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
993 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
994 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
998 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
999 msg.type = Message::POLLEVENT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1001
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 ServerHandler::continueEvent(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 ChildInfo* child = clientInfo->getTarget();
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 if (child == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // Try to get bool arg
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 int passEventToClient;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 if (!scanInt(&arg, &passEventToClient)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 ioBuf->writeBoolAsInt(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 ioBuf->flush();
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1023
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 // Send message to child
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 msg.type = Message::CONTINUEEVENT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 msg.boolArg.val = ((passEventToClient != 0) ? true : false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 sendMessage(child, &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1029
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 // Forward reply to client
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 forwardReplyToClient(child, clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 ServerHandler::exit(char* arg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 shutdownClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 _exited = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 ServerHandler::writeString(USHORT len, WCHAR* str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 if (_ascii) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 char* cStr = new char[len + 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 sprintf(cStr, "%.*ls", len, str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 writeString(len, cStr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 delete[] cStr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 ioBuf->writeInt(sizeof(unsigned short));
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 ioBuf->writeInt(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 ioBuf->writeBinUnsignedShort(str[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 ServerHandler::writeString(USHORT len, char* str) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 ioBuf->writeInt(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 ioBuf->writeInt(len);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 ioBuf->writeSpace();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 ioBuf->writeString(str);
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1069
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 // Shutdown routines
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 shutdownChild(ChildInfo* childInfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 childList.removeChild(childInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 childInfo->closeAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 if (childInfo->getClient() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 shutdownClient(childInfo->getClient());
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 delete childInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 detachClient(ClientInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 ListsLocker ll;
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // May have been dissociated while not under cover of lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 if (info->getTarget() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // Tell the child that we have detached to let the target process
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 // continue running
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 Message msg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 msg.type = Message::DETACH;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 sendMessage(info->getTarget(), &msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // Dissociate the client and the target
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 info->getTarget()->setClient(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 info->setTarget(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 shutdownClient(ClientInfo* clientInfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 cerr << "Shutting down client" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1108
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // If we're connected, inform the target process that we're
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 // disconnecting
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 detachClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // Remove this client from the list and delete it
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 clientList.removeClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 if (clientInfo->getTarget() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 clientInfo->getTarget()->setClient(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 clientInfo->closeAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 delete clientInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1121
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 /** Main dispatcher for client commands. NOTE: do not refer to this
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 clientInfo data structure after calling this routine, as it may be
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 deleted internally. */
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 void
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 readAndDispatch(ClientInfo* clientInfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 IOBuf::ReadLineResult res;
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 IOBuf* ioBuf = clientInfo->getIOBuf();
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 unsigned long howMany;
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 ioctlsocket(clientInfo->getDataSocket(), FIONREAD, &howMany);
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 if (howMany == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Client closed down.
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 shutdownClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 // Read and process as much data as possible
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 res = ioBuf->tryReadLine();
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 if (res == IOBuf::RL_ERROR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 cerr << "Error while reading line" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 shutdownClient(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 } else if (res == IOBuf::RL_GOT_DATA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 cerr << "Got data: \"" << ioBuf->getLine() << "\"" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 handler->setIOBuf(ioBuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 handler->setClientInfo(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 handler->clearExited();
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 Dispatcher::dispatch(ioBuf->getLine(), handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 } while (res == IOBuf::RL_GOT_DATA && (!handler->exited()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 cerr << "Exiting readAndDispatch" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1163
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 int
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 main(int argc, char **argv)
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 initWinsock();
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 if (isNT4()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 loadPSAPIDLL(); // Will exit if not present
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 SOCKET clientListeningSock = setupListeningSocket(CLIENT_PORT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 handler = new ServerHandler();
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 Lists::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
1177
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 reaper = new Reaper(&reapCB);
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 if (!reaper->start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1182
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // Select on all sockets:
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 // - client listening socket
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // - sockets for all client connections
a61af66fc99e Initial load
duke
parents:
diff changeset
1187
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 // When one of the client connections closes, close its socket
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // handles.
a61af66fc99e Initial load
duke
parents:
diff changeset
1190
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 fd_set set;
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 SOCKET maxSock = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Set up fd_set
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 FD_ZERO(&set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 FD_SET(clientListeningSock, &set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 if (clientListeningSock > maxSock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 maxSock = clientListeningSock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 for (i = 0; i < clientList.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 ClientInfo* info = clientList.get(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 if (info->getDataSocket() > maxSock) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 maxSock = info->getDataSocket();
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 FD_SET(info->getDataSocket(), &set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 struct timeval timeout;
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 timeout.tv_sec = 300; // 5 minutes
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 timeout.tv_usec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 int res = select(maxSock, &set, NULL, NULL, &timeout);
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if (res > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 ////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // New client //
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 ////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 if (FD_ISSET(clientListeningSock, &set)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 SOCKET fd = acceptFromLocalhost(clientListeningSock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 if (fd != INVALID_SOCKET) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 // Create new client information object
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 ClientInfo* info = new ClientInfo(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 // Add to list of clients
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 clientList.addClient(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 #ifdef DEBUGGING
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 cerr << "New client" << endl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1231
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 ///////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 // Commands from clients //
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 ///////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 ClientInfo* clientInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 if (clientList.isAnyDataSocketSet(&set, &clientInfo)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 readAndDispatch(clientInfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 } else if (res < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // Looks like one of the clients was killed. Try to figure out which one.
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 bool found = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 fd_set set;
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 struct timeval timeout;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 timeout.tv_sec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 timeout.tv_usec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 for (int i = 0; i < clientList.size(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 ClientInfo* info = clientList.get(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 FD_ZERO(&set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 FD_SET(info->getDataSocket(), &set);
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 if (select(1 + info->getDataSocket(), &set, NULL, NULL, &timeout) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 found = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 clientList.removeClient(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 info->closeAll();
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 delete info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 if (!found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 // This indicates trouble -- one of our listening sockets died.
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1264
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 }