hotspot/agent/src/os/win32/procList.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-2001 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
#include "procList.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
#include "nt4internals.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
#include "isNT4.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
#include "toolHelp.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
#include <assert.h>
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
using namespace std;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
using namespace NT4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
typedef void ProcListImplFunc(ProcEntryList& processes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
void procListImplNT4(ProcEntryList& processes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
void procListImplToolHelp(ProcEntryList& processes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, WCHAR* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  this->pid = pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  this->nameLength = nameLength;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  this->name = new WCHAR[nameLength];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  memcpy(this->name, name, nameLength * sizeof(WCHAR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, char* name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  this->pid = pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  this->nameLength = nameLength;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  this->name = new WCHAR[nameLength];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  int j = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  for (int i = 0; i < nameLength; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    // FIXME: what is the proper promotion from ASCII to UNICODE?
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
    this->name[i] = name[i] & 0xFF;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
ProcEntry::ProcEntry(const ProcEntry& arg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  name = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  copyFrom(arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
ProcEntry&
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
ProcEntry::operator=(const ProcEntry& arg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  copyFrom(arg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  return *this;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
ProcEntry::~ProcEntry() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  delete[] name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
ProcEntry::copyFrom(const ProcEntry& arg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
  if (name != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
    delete[] name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  pid = arg.pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  nameLength = arg.nameLength;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  name = new WCHAR[nameLength];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
  memcpy(name, arg.name, nameLength * sizeof(WCHAR));
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
ULONG
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
ProcEntry::getPid() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  return pid;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
USHORT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
ProcEntry::getNameLength() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
  return nameLength;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
WCHAR*
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
ProcEntry::getName() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  return name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
procList(ProcEntryList& processes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
  static ProcListImplFunc* impl = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  if (impl == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
    // See which operating system we're on
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
    impl = (isNT4() ? &procListImplNT4 : &procListImplToolHelp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  assert(impl != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  (*impl)(processes);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
procListImplNT4(ProcEntryList& processes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  using namespace NT4;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  static ZwQuerySystemInformationFunc* query = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  if (query == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    HMODULE ntDLL = loadNTDLL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    query =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
      (ZwQuerySystemInformationFunc*) GetProcAddress(ntDLL,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
                                                     "ZwQuerySystemInformation");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    assert(query != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  ULONG n = 0x100;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  PSYSTEM_PROCESSES sp = new SYSTEM_PROCESSES[n];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  while ((*query)(SystemProcessesAndThreadsInformation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
                  sp, n * sizeof(SYSTEM_PROCESSES), 0) == STATUS_INFO_LENGTH_MISMATCH) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
    delete[] sp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
    n *= 2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
    sp = new SYSTEM_PROCESSES[n];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  bool done = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
  for (PSYSTEM_PROCESSES p = sp; !done;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
       p = PSYSTEM_PROCESSES(PCHAR(p) + p->NextEntryDelta)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    processes.push_back(ProcEntry(p->ProcessId,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
                                  p->ProcessName.Length / 2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
                                  p->ProcessName.Buffer));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
    done = p->NextEntryDelta == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
void
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
procListImplToolHelp(ProcEntryList& processes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  using namespace ToolHelp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  static CreateToolhelp32SnapshotFunc* snapshotFunc = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
  static Process32FirstFunc*           firstFunc    = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  static Process32NextFunc*            nextFunc     = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
  if (snapshotFunc == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
    HMODULE dll = loadDLL();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    snapshotFunc =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      (CreateToolhelp32SnapshotFunc*) GetProcAddress(dll,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
                                                     "CreateToolhelp32Snapshot");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
    firstFunc = (Process32FirstFunc*) GetProcAddress(dll,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
                                                     "Process32First");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
    nextFunc = (Process32NextFunc*) GetProcAddress(dll,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
                                                   "Process32Next");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
    assert(snapshotFunc != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
    assert(firstFunc    != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
    assert(nextFunc     != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  HANDLE snapshot = (*snapshotFunc)(TH32CS_SNAPPROCESS, 0 /* ignored */);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  if (snapshot == (HANDLE) -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    // Error occurred during snapshot
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
  // Iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
  PROCESSENTRY32 proc;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  if ((*firstFunc)(snapshot, &proc)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
      // FIXME: could make this uniform to the NT version by cutting
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
      // off the path name just before the executable name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
      processes.push_back(ProcEntry(proc.th32ProcessID,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
                                    strlen(proc.szExeFile),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
                                    proc.szExeFile));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    } while ((*nextFunc)(snapshot, &proc));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  CloseHandle(snapshot);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
}