diff agent/src/os/win32/procList.cpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children c18cbe5936b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/os/win32/procList.cpp	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2000-2001 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+#include "procList.hpp"
+#include "nt4internals.hpp"
+#include "isNT4.hpp"
+#include "toolHelp.hpp"
+#include <assert.h>
+
+using namespace std;
+using namespace NT4;
+
+typedef void ProcListImplFunc(ProcEntryList& processes);
+
+void procListImplNT4(ProcEntryList& processes);
+void procListImplToolHelp(ProcEntryList& processes);
+
+ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, WCHAR* name) {
+  this->pid = pid;
+  this->nameLength = nameLength;
+  this->name = new WCHAR[nameLength];
+  memcpy(this->name, name, nameLength * sizeof(WCHAR));
+}
+
+ProcEntry::ProcEntry(ULONG pid, USHORT nameLength, char* name) {
+  this->pid = pid;
+  this->nameLength = nameLength;
+  this->name = new WCHAR[nameLength];
+  int j = 0;
+  for (int i = 0; i < nameLength; i++) {
+    // FIXME: what is the proper promotion from ASCII to UNICODE?
+    this->name[i] = name[i] & 0xFF;
+  }
+}
+
+ProcEntry::ProcEntry(const ProcEntry& arg) {
+  name = NULL;
+  copyFrom(arg);
+}
+
+ProcEntry&
+ProcEntry::operator=(const ProcEntry& arg) {
+  copyFrom(arg);
+  return *this;
+}
+
+ProcEntry::~ProcEntry() {
+  delete[] name;
+}
+
+void
+ProcEntry::copyFrom(const ProcEntry& arg) {
+  if (name != NULL) {
+    delete[] name;
+  }
+  pid = arg.pid;
+  nameLength = arg.nameLength;
+  name = new WCHAR[nameLength];
+  memcpy(name, arg.name, nameLength * sizeof(WCHAR));
+}
+
+ULONG
+ProcEntry::getPid() {
+  return pid;
+}
+
+USHORT
+ProcEntry::getNameLength() {
+  return nameLength;
+}
+
+WCHAR*
+ProcEntry::getName() {
+  return name;
+}
+
+void
+procList(ProcEntryList& processes) {
+  static ProcListImplFunc* impl = NULL;
+
+  if (impl == NULL) {
+    // See which operating system we're on
+    impl = (isNT4() ? &procListImplNT4 : &procListImplToolHelp);
+  }
+
+  assert(impl != NULL);
+
+  (*impl)(processes);
+}
+
+void
+procListImplNT4(ProcEntryList& processes) {
+  using namespace NT4;
+
+  static ZwQuerySystemInformationFunc* query = NULL;
+
+  if (query == NULL) {
+    HMODULE ntDLL = loadNTDLL();
+    query =
+      (ZwQuerySystemInformationFunc*) GetProcAddress(ntDLL,
+                                                     "ZwQuerySystemInformation");
+    assert(query != NULL);
+  }
+
+  ULONG n = 0x100;
+  PSYSTEM_PROCESSES sp = new SYSTEM_PROCESSES[n];
+  while ((*query)(SystemProcessesAndThreadsInformation,
+                  sp, n * sizeof(SYSTEM_PROCESSES), 0) == STATUS_INFO_LENGTH_MISMATCH) {
+    delete[] sp;
+    n *= 2;
+    sp = new SYSTEM_PROCESSES[n];
+  }
+
+  bool done = false;
+  for (PSYSTEM_PROCESSES p = sp; !done;
+       p = PSYSTEM_PROCESSES(PCHAR(p) + p->NextEntryDelta)) {
+    processes.push_back(ProcEntry(p->ProcessId,
+                                  p->ProcessName.Length / 2,
+                                  p->ProcessName.Buffer));
+    done = p->NextEntryDelta == 0;
+  }
+}
+
+void
+procListImplToolHelp(ProcEntryList& processes) {
+  using namespace ToolHelp;
+
+  static CreateToolhelp32SnapshotFunc* snapshotFunc = NULL;
+  static Process32FirstFunc*           firstFunc    = NULL;
+  static Process32NextFunc*            nextFunc     = NULL;
+
+  if (snapshotFunc == NULL) {
+    HMODULE dll = loadDLL();
+
+    snapshotFunc =
+      (CreateToolhelp32SnapshotFunc*) GetProcAddress(dll,
+                                                     "CreateToolhelp32Snapshot");
+
+    firstFunc = (Process32FirstFunc*) GetProcAddress(dll,
+                                                     "Process32First");
+
+    nextFunc = (Process32NextFunc*) GetProcAddress(dll,
+                                                   "Process32Next");
+
+    assert(snapshotFunc != NULL);
+    assert(firstFunc    != NULL);
+    assert(nextFunc     != NULL);
+  }
+
+  HANDLE snapshot = (*snapshotFunc)(TH32CS_SNAPPROCESS, 0 /* ignored */);
+  if (snapshot == (HANDLE) -1) {
+    // Error occurred during snapshot
+    return;
+  }
+
+  // Iterate
+  PROCESSENTRY32 proc;
+  if ((*firstFunc)(snapshot, &proc)) {
+    do {
+      // FIXME: could make this uniform to the NT version by cutting
+      // off the path name just before the executable name
+      processes.push_back(ProcEntry(proc.th32ProcessID,
+                                    strlen(proc.szExeFile),
+                                    proc.szExeFile));
+    } while ((*nextFunc)(snapshot, &proc));
+  }
+
+  CloseHandle(snapshot);
+}