add experiment win32-only extension for ptql to map windows service name to pid

This commit is contained in:
Doug MacEachern 2004-08-13 01:21:39 +00:00
parent a79bb600b9
commit bd8ecac6c5
1 changed files with 104 additions and 0 deletions

View File

@ -1025,3 +1025,107 @@ JNIEXPORT void SIGAR_JNI(SigarLog_setLevel)
sigar_log_level_set(sigar, level); sigar_log_level_set(sigar, level);
} }
/*
* XXX temporary function for ptql to map windows service to pid.
* in the future would better to integrate win32bindings w/ sigar.
*/
#ifdef WIN32
typedef struct _SERVICE_STATUS_PROCESS {
DWORD dwServiceType;
DWORD dwCurrentState;
DWORD dwControlsAccepted;
DWORD dwWin32ExitCode;
DWORD dwServiceSpecificExitCode;
DWORD dwCheckPoint;
DWORD dwWaitHint;
DWORD dwProcessId;
DWORD dwServiceFlags;
} SERVICE_STATUS_PROCESS;
typedef enum {
SC_STATUS_PROCESS_INFO = 0
} SC_STATUS_TYPE;
typedef BOOL (CALLBACK *QueryServiceStatusExFunc)(SC_HANDLE,
SC_STATUS_TYPE,
LPBYTE,
DWORD,
LPDWORD);
#endif
JNIEXPORT jlong SIGAR_JNI(ptql_WindowsServiceQuery_getServicePid)
(JNIEnv *env, jclass classinstance, jstring jname)
{
#ifdef WIN32
const char *name;
jboolean is_copy;
jlong pid = 0;
DWORD err = ERROR_SUCCESS;
SC_HANDLE mgr;
name = JENV->GetStringUTFChars(env, jname, &is_copy);
mgr = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE,
SC_MANAGER_ALL_ACCESS);
if (mgr) {
HANDLE svc = OpenService(mgr, name, SERVICE_ALL_ACCESS);
if (svc) {
SERVICE_STATUS_PROCESS status;
DWORD bytes;
HANDLE lib;
if ((lib = LoadLibrary("advapi32.dll"))) {
QueryServiceStatusExFunc status_query;
status_query =
(QueryServiceStatusExFunc)
GetProcAddress(lib, "QueryServiceStatusEx");
if (!status_query) {
err = SIGAR_ENOTIMPL;
}
else if (status_query(svc,
SC_STATUS_PROCESS_INFO,
(LPBYTE)&status, sizeof(status), &bytes))
{
pid = status.dwProcessId;
}
else {
err = GetLastError();
}
FreeLibrary(lib);
}
else {
err = GetLastError();
}
CloseServiceHandle(svc);
}
else {
err = GetLastError();
}
CloseServiceHandle(mgr);
}
else {
err = GetLastError();
}
if (is_copy) {
JENV->ReleaseStringUTFChars(env, jname, name);
}
if (err != ERROR_SUCCESS) {
/* XXX need sigar for sigar_strerror */
char msg[256];
sprintf(msg, "error=%d", err);
sigar_throw_exception(env, msg);
}
return pid;
#else
sigar_throw_notimpl(env, "Win32 only");
#endif
}