add experiment win32-only extension for ptql to map windows service name to pid
This commit is contained in:
parent
a79bb600b9
commit
bd8ecac6c5
|
@ -1025,3 +1025,107 @@ JNIEXPORT void SIGAR_JNI(SigarLog_setLevel)
|
|||
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue