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