Mercurial > hg > truffle
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); +}