merging in the win32bindings package
This commit is contained in:
parent
3b0a6af2d2
commit
6353b7bcc3
|
@ -0,0 +1,301 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#include "javasigar.h"
|
||||||
|
#include "win32bindings.h"
|
||||||
|
|
||||||
|
#define MAX_INSERT_STRS 8
|
||||||
|
#define MAX_MSG_LENGTH 4096
|
||||||
|
#define MAX_ERROR_LENGTH 1024
|
||||||
|
|
||||||
|
#define REG_MSGFILE_ROOT "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
|
||||||
|
|
||||||
|
static void win32_set_pointer(JNIEnv *env, jobject obj, const void *ptr)
|
||||||
|
{
|
||||||
|
jfieldID pointer_field;
|
||||||
|
int pointer_int;
|
||||||
|
jclass cls;
|
||||||
|
|
||||||
|
cls = JENV->GetObjectClass(env, obj);
|
||||||
|
|
||||||
|
pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
|
||||||
|
pointer_int = (int)ptr;
|
||||||
|
|
||||||
|
JENV->SetIntField(env, obj, pointer_field, pointer_int);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE win32_get_pointer(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
jfieldID pointer_field;
|
||||||
|
HANDLE h;
|
||||||
|
jclass cls;
|
||||||
|
|
||||||
|
cls = JENV->GetObjectClass(env, obj);
|
||||||
|
|
||||||
|
pointer_field = JENV->GetFieldID(env, cls, "eventLogHandle", "I");
|
||||||
|
h = (HANDLE)JENV->GetIntField(env, obj, pointer_field);
|
||||||
|
|
||||||
|
if (!h) {
|
||||||
|
win32_throw_exception(env, "Event log not opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_messagefile_dll(char *app, char *source, char *dllfile)
|
||||||
|
{
|
||||||
|
HKEY hk;
|
||||||
|
DWORD type, data;
|
||||||
|
char buf[MAX_MSG_LENGTH];
|
||||||
|
|
||||||
|
sprintf(buf, "%s%s\\%s", REG_MSGFILE_ROOT, app, source);
|
||||||
|
|
||||||
|
if (RegOpenKey(HKEY_LOCAL_MACHINE, buf, &hk)) {
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RegQueryValueEx(hk, "EventMessageFile", NULL, &type,
|
||||||
|
(UCHAR *)buf, &data)) {
|
||||||
|
RegCloseKey(hk);
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(dllfile, buf, sizeof(dllfile));
|
||||||
|
|
||||||
|
RegCloseKey(hk);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_formatted_message(EVENTLOGRECORD *pevlr, char *dllfile,
|
||||||
|
char *msg)
|
||||||
|
{
|
||||||
|
HINSTANCE hlib;
|
||||||
|
LPTSTR msgbuf;
|
||||||
|
char msgdll[MAX_MSG_LENGTH];
|
||||||
|
char *insert_strs[MAX_INSERT_STRS], *ch;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!ExpandEnvironmentStrings(dllfile, msgdll, MAX_PATH))
|
||||||
|
return GetLastError();
|
||||||
|
|
||||||
|
if (!(hlib = LoadLibraryEx(msgdll, NULL,
|
||||||
|
LOAD_LIBRARY_AS_DATAFILE)))
|
||||||
|
return GetLastError();
|
||||||
|
|
||||||
|
ch = (char *)((LPBYTE)pevlr + pevlr->StringOffset);
|
||||||
|
for (i = 0; i < pevlr->NumStrings && i < MAX_INSERT_STRS; i++) {
|
||||||
|
insert_strs[i] = ch;
|
||||||
|
ch += strlen(ch) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FormatMessage(FORMAT_MESSAGE_FROM_HMODULE |
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
||||||
|
hlib,
|
||||||
|
pevlr->EventID,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_ENGLISH_US),
|
||||||
|
(LPTSTR) &msgbuf,
|
||||||
|
MAX_MSG_LENGTH,
|
||||||
|
insert_strs);
|
||||||
|
|
||||||
|
strncpy(msg, msgbuf, sizeof(msg));
|
||||||
|
|
||||||
|
FreeLibrary(hlib);
|
||||||
|
LocalFree((HLOCAL)msgbuf);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_EventLog_open)
|
||||||
|
(JNIEnv *env, jobject obj, jstring lpSourceName)
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
name = JENV->GetStringUTFChars(env, lpSourceName, 0);
|
||||||
|
|
||||||
|
h = OpenEventLog(NULL, name);
|
||||||
|
if (h == NULL) {
|
||||||
|
char buf[MAX_ERROR_LENGTH];
|
||||||
|
DWORD lastError = GetLastError();
|
||||||
|
|
||||||
|
sprintf(buf, "Unable to open event log: %d", lastError);
|
||||||
|
JENV->ReleaseStringUTFChars(env, lpSourceName, name);
|
||||||
|
win32_throw_exception(env, buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JENV->ReleaseStringUTFChars(env, lpSourceName, name);
|
||||||
|
|
||||||
|
/* Save the handle for later use */
|
||||||
|
win32_set_pointer(env, obj, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_EventLog_close)
|
||||||
|
(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
HANDLE h = win32_get_pointer(env, obj);
|
||||||
|
|
||||||
|
CloseEventLog(h);
|
||||||
|
|
||||||
|
win32_set_pointer(env, obj, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_EventLog_getNumberOfRecords)
|
||||||
|
(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
DWORD records;
|
||||||
|
HANDLE h = win32_get_pointer(env, obj);
|
||||||
|
|
||||||
|
GetNumberOfEventLogRecords(h, &records);
|
||||||
|
|
||||||
|
return records;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_EventLog_getOldestRecord)
|
||||||
|
(JNIEnv *env, jobject obj)
|
||||||
|
{
|
||||||
|
DWORD oldest;
|
||||||
|
HANDLE h = win32_get_pointer(env, obj);
|
||||||
|
|
||||||
|
GetOldestEventLogRecord(h, &oldest);
|
||||||
|
|
||||||
|
return oldest;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobject SIGAR_JNI(win32_EventLog_read)
|
||||||
|
(JNIEnv *env, jobject obj, jint recordOffset)
|
||||||
|
{
|
||||||
|
EVENTLOGRECORD *pevlr;
|
||||||
|
BYTE buffer[8192];
|
||||||
|
char dllfile[1024];
|
||||||
|
DWORD dwRead, dwNeeded;
|
||||||
|
LPSTR source, machineName;
|
||||||
|
HANDLE h;
|
||||||
|
BOOL rv;
|
||||||
|
jclass cls = WIN32_FIND_CLASS("EventLogRecord");
|
||||||
|
jobject eventObj; /* Actual instance of the EventLogRecord */
|
||||||
|
jfieldID id;
|
||||||
|
|
||||||
|
h = win32_get_pointer(env, obj);
|
||||||
|
|
||||||
|
pevlr = (EVENTLOGRECORD *)&buffer;
|
||||||
|
rv = ReadEventLog(h,
|
||||||
|
EVENTLOG_SEEK_READ | EVENTLOG_FORWARDS_READ,
|
||||||
|
recordOffset,
|
||||||
|
pevlr,
|
||||||
|
sizeof(buffer),
|
||||||
|
&dwRead,
|
||||||
|
&dwNeeded);
|
||||||
|
if (!rv) {
|
||||||
|
char buf[MAX_ERROR_LENGTH];
|
||||||
|
DWORD lastError = GetLastError();
|
||||||
|
|
||||||
|
sprintf(buf, "Error reading from the event log: %d", lastError);
|
||||||
|
win32_throw_exception(env, buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
eventObj = JENV->AllocObject(env, cls);
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "recordNumber", "J");
|
||||||
|
JENV->SetLongField(env, eventObj, id, pevlr->RecordNumber);
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "timeGenerated", "J");
|
||||||
|
JENV->SetLongField(env, eventObj, id, pevlr->TimeGenerated);
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "timeWritten", "J");
|
||||||
|
JENV->SetLongField(env, eventObj, id, pevlr->TimeWritten);
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "eventId", "J");
|
||||||
|
JENV->SetLongField(env, eventObj, id, pevlr->EventID);
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "eventType", "S");
|
||||||
|
JENV->SetShortField(env, eventObj, id, pevlr->EventType);
|
||||||
|
|
||||||
|
/* Extract string data from the end of the structure. Lame. */
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "source", "Ljava/lang/String;");
|
||||||
|
source = (LPSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD));
|
||||||
|
SetStringField(env, eventObj, id, source);
|
||||||
|
|
||||||
|
/* Get the formatted message */
|
||||||
|
if (!get_messagefile_dll("Application", source, dllfile)) {
|
||||||
|
char msg[MAX_MSG_LENGTH];
|
||||||
|
if (!get_formatted_message(pevlr, dllfile, msg)) {
|
||||||
|
|
||||||
|
id = JENV->GetFieldID(env, cls, "stringData",
|
||||||
|
"Ljava/lang/String;");
|
||||||
|
SetStringField(env, eventObj, id, msg);
|
||||||
|
}
|
||||||
|
} else if (pevlr->StringOffset > 0) {
|
||||||
|
/* Work around some applications not using a message file */
|
||||||
|
char *tmp = (LPSTR)((LPBYTE)pevlr + pevlr->StringOffset);
|
||||||
|
id = JENV->GetFieldID(env, cls, "stringData", "Ljava/lang/String;");
|
||||||
|
SetStringField(env, eventObj, id, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Increment up to the machine name. */
|
||||||
|
id = JENV->GetFieldID(env, cls, "computerName", "Ljava/lang/String;");
|
||||||
|
machineName = (LPSTR)((LPBYTE)pevlr + sizeof(EVENTLOGRECORD) +
|
||||||
|
strlen(source) + 1);
|
||||||
|
SetStringField(env, eventObj, id, machineName);
|
||||||
|
|
||||||
|
/* Get user id info */
|
||||||
|
if (pevlr->UserSidLength > 0) {
|
||||||
|
char name[256];
|
||||||
|
char domain[256];
|
||||||
|
DWORD namelen = sizeof(name);
|
||||||
|
DWORD domainlen = sizeof(domain);
|
||||||
|
DWORD len;
|
||||||
|
SID_NAME_USE snu;
|
||||||
|
PSID sid;
|
||||||
|
|
||||||
|
sid = (PSID)((LPBYTE)pevlr + pevlr->UserSidOffset);
|
||||||
|
if (LookupAccountSid(NULL, sid, name, &namelen, domain,
|
||||||
|
&domainlen, &snu)) {
|
||||||
|
id = JENV->GetFieldID(env, cls, "user", "Ljava/lang/String;");
|
||||||
|
SetStringField(env, eventObj, id, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return eventObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_EventLog_waitForChange)
|
||||||
|
(JNIEnv *env, jobject obj, jint timeout)
|
||||||
|
{
|
||||||
|
HANDLE h, hEvent;
|
||||||
|
DWORD millis;
|
||||||
|
|
||||||
|
h = win32_get_pointer(env, obj);
|
||||||
|
|
||||||
|
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
if (hEvent == NULL) {
|
||||||
|
win32_throw_exception(env, "Unable to create event");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout == -1)
|
||||||
|
millis = INFINITE;
|
||||||
|
else
|
||||||
|
millis = timeout;
|
||||||
|
|
||||||
|
if(!(NotifyChangeEventLog(h, hEvent))) {
|
||||||
|
char buf[MAX_ERROR_LENGTH];
|
||||||
|
sprintf(buf, "Error registering for event log to change: %d",
|
||||||
|
GetLastError());
|
||||||
|
win32_throw_exception(env, buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WaitForSingleObject(hEvent, millis) == WAIT_FAILED)
|
||||||
|
{
|
||||||
|
char buf[MAX_ERROR_LENGTH];
|
||||||
|
sprintf(buf, "Error waiting for event log change: %d",
|
||||||
|
GetLastError());
|
||||||
|
win32_throw_exception(env, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,282 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#define UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
#define _WIN32_DCOM
|
||||||
|
|
||||||
|
#define INITGUID
|
||||||
|
|
||||||
|
#include <objbase.h> // COM Interface header file.
|
||||||
|
#include <iadmw.h> // COM Interface header file.
|
||||||
|
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
|
||||||
|
#include <ks.h>
|
||||||
|
#include <atlBase.h> // ATL support header file.
|
||||||
|
|
||||||
|
#include "win32bindings.h"
|
||||||
|
#include "javasigar.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static jfieldID ptr_field = 0;
|
||||||
|
static jfieldID IMeta_field = 0;
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseClose)
|
||||||
|
(JNIEnv *env, jobject cur)
|
||||||
|
{
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
(*pIMeta)->CloseKey(MyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseRelease)
|
||||||
|
(JNIEnv *env, jobject cur)
|
||||||
|
{
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
pIMeta->Release();
|
||||||
|
delete pIMeta;
|
||||||
|
env->SetIntField(cur, ptr_field, 0);
|
||||||
|
CoUninitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_MetaBase_MetaBaseEnumKey)
|
||||||
|
(JNIEnv *env, jobject cur, jint index)
|
||||||
|
{
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
DWORD dwBufLen = 8096;
|
||||||
|
DWORD dwReqBufLen = 0;
|
||||||
|
TCHAR pbBuffer[METADATA_MAX_NAME_LEN];
|
||||||
|
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
|
||||||
|
hRes = (*pIMeta)->EnumKeys(MyHandle, TEXT(""), pbBuffer, index);
|
||||||
|
if (SUCCEEDED(hRes)) {
|
||||||
|
jstring strResult;
|
||||||
|
// Store the data identifiers in an array for future use.
|
||||||
|
// Note: declare a suitable DWORD array for names and add
|
||||||
|
// array bounds checking.
|
||||||
|
strResult = env->NewString((const jchar *)pbBuffer, lstrlen(pbBuffer));
|
||||||
|
return strResult;
|
||||||
|
} else if (hRes == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "MetaBaseEnumKey");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_MetaBase_MetaBaseInit)
|
||||||
|
(JNIEnv *env, jobject cur)
|
||||||
|
{
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||||
|
if (FAILED(hRes)) {
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "MetaBaseInit");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pIMeta = new (CComPtr <IMSAdminBase>);
|
||||||
|
hRes = CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL,
|
||||||
|
IID_IMSAdminBase, (void **)pIMeta);
|
||||||
|
if (FAILED(hRes)) {
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "MetaBaseInit: Can't CoCreateInstance");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass cls = env->GetObjectClass(cur);
|
||||||
|
ptr_field = env->GetFieldID(cls, "m_handle", "I");
|
||||||
|
IMeta_field = env->GetFieldID(cls, "pIMeta", "J");
|
||||||
|
return (jlong)pIMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MetaBaseOpenSubKey(JNIEnv *env, jobject cur,
|
||||||
|
jstring path, METADATA_HANDLE MyHandle)
|
||||||
|
{
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
// Get a handle to the Web service.
|
||||||
|
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(path, NULL);
|
||||||
|
hRes = (*pIMeta)->OpenKey(MyHandle, lpSubkey,
|
||||||
|
METADATA_PERMISSION_READ, 20, &MyHandle);
|
||||||
|
env->ReleaseStringChars(path, (const jchar *)lpSubkey);
|
||||||
|
|
||||||
|
if (FAILED(hRes)) {
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "Can't open Sub Key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
env->SetIntField(cur, ptr_field, MyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseOpenSubKey)
|
||||||
|
(JNIEnv *env, jobject cur, jstring path)
|
||||||
|
{
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
MetaBaseOpenSubKey(env, cur, path, MyHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseOpenSubKeyAbs)
|
||||||
|
(JNIEnv *env, jobject cur, jstring path)
|
||||||
|
{
|
||||||
|
MetaBaseOpenSubKey(env, cur, path, METADATA_MASTER_ROOT_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_MetaBase_MetaBaseGetIntValue)
|
||||||
|
(JNIEnv *env, jobject cur, jint key)
|
||||||
|
{
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
METADATA_RECORD MyRecord;
|
||||||
|
DWORD dwBufLen = 8096;
|
||||||
|
DWORD dwReqBufLen = 0;
|
||||||
|
TCHAR pbBuffer[8096];
|
||||||
|
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
|
||||||
|
// Initialize the input structure -
|
||||||
|
// the values specify what kind of data to enumerate.
|
||||||
|
MyRecord.dwMDIdentifier = key;
|
||||||
|
MyRecord.dwMDAttributes = 0;
|
||||||
|
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
|
||||||
|
MyRecord.dwMDDataType = DWORD_METADATA;
|
||||||
|
MyRecord.dwMDDataLen = dwBufLen;
|
||||||
|
MyRecord.pbMDData = (unsigned char *)pbBuffer;
|
||||||
|
|
||||||
|
// Enumerate the data of the first virtual Web server,
|
||||||
|
// checking to ensure that the data returned does not
|
||||||
|
// overflow the buffer.
|
||||||
|
|
||||||
|
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
|
||||||
|
if (SUCCEEDED(hRes)) {
|
||||||
|
int ret = (int)MyRecord.pbMDData;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "No such Int value");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_MetaBase_MetaBaseGetStringValue)
|
||||||
|
(JNIEnv *env, jobject cur, jint key)
|
||||||
|
{
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
METADATA_RECORD MyRecord;
|
||||||
|
DWORD dwBufLen = 8096;
|
||||||
|
DWORD dwReqBufLen = 0;
|
||||||
|
TCHAR pbBuffer[8096];
|
||||||
|
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
|
||||||
|
// Initialize the input structure -
|
||||||
|
// the values specify what kind of data to enumerate.
|
||||||
|
MyRecord.dwMDIdentifier = key;
|
||||||
|
MyRecord.dwMDAttributes = 0;
|
||||||
|
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
|
||||||
|
MyRecord.dwMDDataType = STRING_METADATA;
|
||||||
|
MyRecord.dwMDDataLen = dwBufLen;
|
||||||
|
MyRecord.pbMDData = (unsigned char *)pbBuffer;
|
||||||
|
|
||||||
|
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
|
||||||
|
if (SUCCEEDED(hRes)) {
|
||||||
|
jstring strResult;
|
||||||
|
// Store the data identifiers in an array for future use.
|
||||||
|
// Note: declare a suitable DWORD array for names and add
|
||||||
|
// array bounds checking.
|
||||||
|
strResult = env->NewString((const jchar *)MyRecord.pbMDData,
|
||||||
|
lstrlen(pbBuffer));
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "No Such string value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray SIGAR_JNI(win32_MetaBase_MetaBaseGetMultiStringValue)
|
||||||
|
(JNIEnv *env, jobject cur, jint key)
|
||||||
|
{
|
||||||
|
HRESULT hRes = 0;
|
||||||
|
METADATA_HANDLE MyHandle;
|
||||||
|
METADATA_RECORD MyRecord;
|
||||||
|
DWORD dwBufLen = 8096;
|
||||||
|
DWORD dwReqBufLen = 0;
|
||||||
|
TCHAR pbBuffer[8096];
|
||||||
|
|
||||||
|
CComPtr <IMSAdminBase> *pIMeta;
|
||||||
|
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
|
||||||
|
|
||||||
|
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
|
||||||
|
|
||||||
|
// Initialize the input structure -
|
||||||
|
// the values specify what kind of data to enumerate.
|
||||||
|
MyRecord.dwMDIdentifier = key;
|
||||||
|
MyRecord.dwMDAttributes = 0;
|
||||||
|
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
|
||||||
|
MyRecord.dwMDDataType = MULTISZ_METADATA;
|
||||||
|
MyRecord.dwMDDataLen = dwBufLen;
|
||||||
|
MyRecord.pbMDData = (unsigned char *)pbBuffer;
|
||||||
|
|
||||||
|
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
|
||||||
|
if (SUCCEEDED(hRes)) {
|
||||||
|
TCHAR *szThisInstance = NULL;
|
||||||
|
jobjectArray ret = NULL;
|
||||||
|
int i;
|
||||||
|
// Start at -1 to account for the \0 at the end of the
|
||||||
|
// list.
|
||||||
|
int count = -1;
|
||||||
|
|
||||||
|
// Count # of objects in dwInstanceList
|
||||||
|
for (i = 0; i < MyRecord.dwMDDataLen; i+=2) {
|
||||||
|
if ((TCHAR)MyRecord.pbMDData[i] == '\0') {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = (jobjectArray)env->
|
||||||
|
NewObjectArray(count,
|
||||||
|
env->FindClass("java/lang/String"),
|
||||||
|
env->NewString((const jchar *)"", 1));
|
||||||
|
|
||||||
|
// Walk the return instance list, creating an array
|
||||||
|
for (szThisInstance = (TCHAR *)MyRecord.pbMDData, i = 0;
|
||||||
|
*szThisInstance != 0;
|
||||||
|
szThisInstance += lstrlen(szThisInstance) + 1, i++)
|
||||||
|
{
|
||||||
|
env->SetObjectArrayElement(ret,i,env->NewString(
|
||||||
|
(const jchar *)(LPCTSTR)szThisInstance,
|
||||||
|
lstrlen(szThisInstance)));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "No Such string value");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,338 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <pdh.h>
|
||||||
|
#include <pdhmsg.h>
|
||||||
|
|
||||||
|
#include "win32bindings.h"
|
||||||
|
#include "javasigar.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack around not being able to format error codes using
|
||||||
|
* FORMAT_MESSAGE_FROM_HMODULE. We only define the error
|
||||||
|
* codes that could be possibly returned.
|
||||||
|
*/
|
||||||
|
static char *get_error_message(PDH_STATUS status) {
|
||||||
|
switch (status) {
|
||||||
|
case PDH_CSTATUS_NO_MACHINE:
|
||||||
|
return "The computer is unavailable";
|
||||||
|
case PDH_CSTATUS_NO_OBJECT:
|
||||||
|
return "The specified object could not be found on the computer";
|
||||||
|
case PDH_INVALID_ARGUMENT:
|
||||||
|
return "A required argument is invalid";
|
||||||
|
case PDH_MEMORY_ALLOCATION_FAILURE:
|
||||||
|
return "A required temporary buffer could not be allocated";
|
||||||
|
case PDH_INVALID_HANDLE:
|
||||||
|
return "The query handle is not valid";
|
||||||
|
case PDH_NO_DATA:
|
||||||
|
return "The query does not currently have any counters";
|
||||||
|
case PDH_CSTATUS_BAD_COUNTERNAME:
|
||||||
|
return "The counter name path string could not be parsed or "
|
||||||
|
"interpreted";
|
||||||
|
case PDH_CSTATUS_NO_COUNTER:
|
||||||
|
return "The specified counter was not found";
|
||||||
|
case PDH_CSTATUS_NO_COUNTERNAME:
|
||||||
|
return "An empty counter name path string was passed in";
|
||||||
|
case PDH_FUNCTION_NOT_FOUND:
|
||||||
|
return "The calculation function for this counter could not "
|
||||||
|
"be determined";
|
||||||
|
default:
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL SIGAR_JNI(win32_Pdh_pdhOpenQuery)
|
||||||
|
(JNIEnv *env, jobject cur)
|
||||||
|
{
|
||||||
|
HQUERY h_query;
|
||||||
|
PDH_STATUS status;
|
||||||
|
|
||||||
|
status = PdhOpenQuery(NULL, 0, &h_query);
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (jlong)h_query;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_Pdh_pdhCloseQuery)
|
||||||
|
(JNIEnv *env, jclass cur, jlong query)
|
||||||
|
{
|
||||||
|
HQUERY h_query = (HQUERY)query;
|
||||||
|
PDH_STATUS status;
|
||||||
|
|
||||||
|
// Close the query and the log file.
|
||||||
|
status = PdhCloseQuery(h_query);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_Pdh_pdhAddCounter)
|
||||||
|
(JNIEnv *env, jclass cur, jlong query, jstring cp)
|
||||||
|
{
|
||||||
|
HCOUNTER h_counter;
|
||||||
|
HQUERY h_query = (HQUERY)query;
|
||||||
|
PDH_STATUS status;
|
||||||
|
LPCTSTR counter_path = JENV->GetStringUTFChars(env, cp, NULL);
|
||||||
|
|
||||||
|
/* Add the counter that created the data in the log file. */
|
||||||
|
status = PdhAddCounter(h_query, counter_path, 0, &h_counter);
|
||||||
|
JENV->ReleaseStringUTFChars(env, cp, counter_path);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (jlong)h_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void SIGAR_JNI(win32_Pdh_pdhRemoveCounter)
|
||||||
|
(JNIEnv *env, jclass cur, jlong counter)
|
||||||
|
{
|
||||||
|
HCOUNTER h_counter = (HCOUNTER)counter;
|
||||||
|
PDH_STATUS status;
|
||||||
|
|
||||||
|
status = PdhRemoveCounter(h_counter);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jdouble SIGAR_JNI(win32_Pdh_pdhGetSingleValue)
|
||||||
|
(JNIEnv *env, jclass cur, jlong query, jlong counter)
|
||||||
|
{
|
||||||
|
HCOUNTER h_counter = (HCOUNTER)counter;
|
||||||
|
HQUERY h_query = (HQUERY)query;
|
||||||
|
PDH_FMT_COUNTERVALUE pdh_value;
|
||||||
|
PDH_STATUS status;
|
||||||
|
|
||||||
|
status = PdhCollectQueryData(h_query);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Format the performance data record.
|
||||||
|
status = PdhGetFormattedCounterValue(h_counter,
|
||||||
|
PDH_FMT_DOUBLE,
|
||||||
|
(LPDWORD)NULL,
|
||||||
|
&pdh_value);
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pdh_value.doubleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetInstances)
|
||||||
|
(JNIEnv *env, jclass cur, jstring cp)
|
||||||
|
{
|
||||||
|
PDH_STATUS status = ERROR_SUCCESS;
|
||||||
|
DWORD counter_list_size = 0;
|
||||||
|
DWORD instance_list_size = 8096;
|
||||||
|
LPTSTR instance_list_buf =
|
||||||
|
(LPTSTR)malloc ((instance_list_size * sizeof (TCHAR)));
|
||||||
|
LPTSTR cur_object = NULL;
|
||||||
|
LPCTSTR counter_path =
|
||||||
|
(LPCTSTR)JENV->GetStringUTFChars(env, cp, 0);
|
||||||
|
jobjectArray array = NULL;
|
||||||
|
|
||||||
|
status = PdhEnumObjectItems(NULL, NULL, counter_path, NULL,
|
||||||
|
&counter_list_size, instance_list_buf,
|
||||||
|
&instance_list_size, PERF_DETAIL_WIZARD,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
|
if (status == PDH_MORE_DATA && instance_list_size > 0) {
|
||||||
|
// Allocate the buffers and try the call again.
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
instance_list_buf = (LPTSTR)malloc((instance_list_size *
|
||||||
|
sizeof (TCHAR)));
|
||||||
|
counter_list_size = 0;
|
||||||
|
status = PdhEnumObjectItems (NULL, NULL, counter_path,
|
||||||
|
NULL, &counter_list_size,
|
||||||
|
instance_list_buf,
|
||||||
|
&instance_list_size,
|
||||||
|
PERF_DETAIL_WIZARD, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
JENV->ReleaseStringUTFChars(env, cp, counter_path);
|
||||||
|
|
||||||
|
// Still may get PDH_ERROR_MORE data after the first reallocation,
|
||||||
|
// but that is OK for just browsing the instances
|
||||||
|
if (status == ERROR_SUCCESS || status == PDH_MORE_DATA) {
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
for (cur_object = instance_list_buf, count = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, count++);
|
||||||
|
|
||||||
|
array = JENV->NewObjectArray(env, count,
|
||||||
|
JENV->FindClass(env,
|
||||||
|
"java/lang/String"),
|
||||||
|
JENV->NewStringUTF(env, ""));
|
||||||
|
|
||||||
|
/* Walk the return instance list, creating an array */
|
||||||
|
for (cur_object = instance_list_buf, i = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, i++)
|
||||||
|
{
|
||||||
|
jstring s = JENV->NewStringUTF(env, cur_object);
|
||||||
|
JENV->SetObjectArrayElement(env, array, i, s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
// An error occured
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetKeys)
|
||||||
|
(JNIEnv *env, jclass cur, jstring cp)
|
||||||
|
{
|
||||||
|
PDH_STATUS status = ERROR_SUCCESS;
|
||||||
|
DWORD counter_list_size = 8096;
|
||||||
|
DWORD instance_list_size = 0;
|
||||||
|
LPTSTR instance_list_buf =
|
||||||
|
(LPTSTR)malloc (counter_list_size * sizeof(TCHAR));
|
||||||
|
LPTSTR cur_object = NULL;
|
||||||
|
LPCTSTR counter_path = JENV->GetStringUTFChars(env, cp, 0);
|
||||||
|
jobjectArray array = NULL;
|
||||||
|
|
||||||
|
status = PdhEnumObjectItems(NULL, NULL, counter_path,
|
||||||
|
instance_list_buf, &counter_list_size,
|
||||||
|
NULL, &instance_list_size,
|
||||||
|
PERF_DETAIL_WIZARD, FALSE);
|
||||||
|
|
||||||
|
if (status == PDH_MORE_DATA) {
|
||||||
|
/* Allocate the buffers and try the call again. */
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
instance_list_buf = (LPTSTR)malloc(counter_list_size *
|
||||||
|
sizeof(TCHAR));
|
||||||
|
instance_list_size = 0;
|
||||||
|
status = PdhEnumObjectItems (NULL, NULL, counter_path,
|
||||||
|
instance_list_buf,
|
||||||
|
&counter_list_size, NULL,
|
||||||
|
&instance_list_size,
|
||||||
|
PERF_DETAIL_WIZARD, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
JENV->ReleaseStringUTFChars(env, cp, counter_path);
|
||||||
|
|
||||||
|
if (status == ERROR_SUCCESS || status == PDH_MORE_DATA) {
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
for (cur_object = instance_list_buf, count = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, count++);
|
||||||
|
|
||||||
|
array = JENV->NewObjectArray(env, count,
|
||||||
|
JENV->FindClass(env,
|
||||||
|
"java/lang/String"),
|
||||||
|
JENV->NewStringUTF(env, ""));
|
||||||
|
|
||||||
|
/* Walk the return instance list, creating an array */
|
||||||
|
for (cur_object = instance_list_buf, i = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, i++)
|
||||||
|
{
|
||||||
|
jstring s = JENV->NewStringUTF(env, cur_object);
|
||||||
|
JENV->SetObjectArrayElement(env, array, i, s);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// An error occured
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
// An error occured
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance_list_buf != NULL)
|
||||||
|
free(instance_list_buf);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetObjects)
|
||||||
|
(JNIEnv *env, jclass cur)
|
||||||
|
{
|
||||||
|
PDH_STATUS status;
|
||||||
|
DWORD list_size = 8096;
|
||||||
|
LPTSTR list_buf = (LPTSTR)malloc(list_size * sizeof(TCHAR));
|
||||||
|
LPTSTR cur_object;
|
||||||
|
DWORD i, num_objects = 0;
|
||||||
|
jobjectArray array = NULL;
|
||||||
|
|
||||||
|
status = PdhEnumObjects(NULL, NULL, list_buf, &list_size,
|
||||||
|
PERF_DETAIL_WIZARD, FALSE);
|
||||||
|
|
||||||
|
if (status == PDH_MORE_DATA) {
|
||||||
|
// Re-try call with a larger buffer
|
||||||
|
if (list_buf != NULL)
|
||||||
|
free(list_buf);
|
||||||
|
|
||||||
|
list_buf = (LPTSTR)malloc(list_size * sizeof(TCHAR));
|
||||||
|
status = PdhEnumObjects(NULL, NULL, list_buf, &list_size,
|
||||||
|
PERF_DETAIL_WIZARD, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != ERROR_SUCCESS) {
|
||||||
|
if (list_buf != NULL)
|
||||||
|
free(list_buf);
|
||||||
|
|
||||||
|
win32_throw_exception(env, get_error_message(status));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Walk the return buffer counting the number of objects
|
||||||
|
for (cur_object = list_buf, num_objects = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, num_objects++);
|
||||||
|
|
||||||
|
array = JENV->NewObjectArray(env, num_objects,
|
||||||
|
JENV->FindClass(env,
|
||||||
|
"java/lang/String"),
|
||||||
|
JENV->NewStringUTF(env, ""));
|
||||||
|
|
||||||
|
for (cur_object = list_buf, i = 0;
|
||||||
|
*cur_object != 0;
|
||||||
|
cur_object += lstrlen(cur_object) + 1, i++)
|
||||||
|
{
|
||||||
|
jstring s = JENV->NewStringUTF(env, cur_object);
|
||||||
|
JENV->SetObjectArrayElement(env, array, i, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list_buf != NULL)
|
||||||
|
free(list_buf);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,274 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#define UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "win32bindings.h"
|
||||||
|
#include "javasigar.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
|
||||||
|
(JNIEnv *, jclass, jlong hkey)
|
||||||
|
{
|
||||||
|
return RegCloseKey((HKEY)hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
|
||||||
|
{
|
||||||
|
HKEY hkeyResult = NULL;
|
||||||
|
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
|
||||||
|
|
||||||
|
RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
|
||||||
|
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
|
||||||
|
NULL, &hkeyResult, NULL);
|
||||||
|
|
||||||
|
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
|
||||||
|
|
||||||
|
return (jlong)hkeyResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
|
||||||
|
{
|
||||||
|
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
|
||||||
|
LONG lResult = RegDeleteKey((HKEY)hkey, lpSubkey);
|
||||||
|
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
|
||||||
|
{
|
||||||
|
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
|
||||||
|
LONG lResult = RegDeleteValue((HKEY)hkey, lpValueName);
|
||||||
|
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jint index)
|
||||||
|
{
|
||||||
|
jstring strResult;
|
||||||
|
TCHAR szBuffer[MAX_PATH + 1];
|
||||||
|
|
||||||
|
if(RegEnumKey((HKEY)hkey, index, szBuffer,
|
||||||
|
sizeof(szBuffer)) == ERROR_SUCCESS)
|
||||||
|
strResult = env->NewString((const jchar *)szBuffer,
|
||||||
|
lstrlen(szBuffer));
|
||||||
|
else
|
||||||
|
strResult = NULL;
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jint index)
|
||||||
|
{
|
||||||
|
jstring strResult;
|
||||||
|
TCHAR szValueName[MAX_PATH + 1];
|
||||||
|
DWORD cbValueName = sizeof(szValueName);
|
||||||
|
|
||||||
|
if(RegEnumValue((HKEY)hkey, index, szValueName,
|
||||||
|
&cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
|
||||||
|
strResult = env->NewString((const jchar *)szValueName,
|
||||||
|
lstrlen(szValueName));
|
||||||
|
else
|
||||||
|
strResult = NULL;
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
|
||||||
|
(JNIEnv *env, jclass, long hkey)
|
||||||
|
{
|
||||||
|
return RegFlushKey((HKEY)hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
|
||||||
|
{
|
||||||
|
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
|
||||||
|
LPCTSTR lpFile = (LPCTSTR)env->GetStringChars(file, NULL);
|
||||||
|
|
||||||
|
LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);
|
||||||
|
|
||||||
|
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
|
||||||
|
env->ReleaseStringChars(file, (const jchar *)lpFile);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
|
||||||
|
{
|
||||||
|
HKEY hkeyResult = NULL;
|
||||||
|
|
||||||
|
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
|
||||||
|
RegOpenKey((HKEY)hkey, lpSubkey, &hkeyResult);
|
||||||
|
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
|
||||||
|
|
||||||
|
return (jlong)hkeyResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
|
||||||
|
{
|
||||||
|
DWORD dwResult;
|
||||||
|
DWORD dwType;
|
||||||
|
LPBYTE lpValue;
|
||||||
|
DWORD cbValue;
|
||||||
|
|
||||||
|
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
|
||||||
|
LONG lErr = RegQueryValueEx((HKEY)hkey, lpValueName,
|
||||||
|
NULL, (LPDWORD)&dwType,
|
||||||
|
NULL, &cbValue);
|
||||||
|
|
||||||
|
if(lErr == ERROR_SUCCESS) {
|
||||||
|
lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, cbValue);
|
||||||
|
|
||||||
|
if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL,
|
||||||
|
NULL, lpValue, &cbValue) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
switch(dwType) {
|
||||||
|
case REG_DWORD:
|
||||||
|
dwResult = *(LPDWORD)lpValue;
|
||||||
|
break;
|
||||||
|
case REG_SZ:
|
||||||
|
dwResult = _ttol((LPCTSTR)lpValue);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
lErr = ERROR_SUCCESS - 1; // Make an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpValue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// Make an error out of not seeing a REG_DWORD
|
||||||
|
lErr = ERROR_SUCCESS - 1;
|
||||||
|
|
||||||
|
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
|
||||||
|
|
||||||
|
if(lErr != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
jclass cls =
|
||||||
|
env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return dwResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring name)
|
||||||
|
{
|
||||||
|
jstring strResult;
|
||||||
|
DWORD dwType;
|
||||||
|
LPBYTE lpValue;
|
||||||
|
DWORD cbValue;
|
||||||
|
|
||||||
|
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
|
||||||
|
LONG lErr = RegQueryValueEx((HKEY)hkey,
|
||||||
|
lpValueName, NULL,
|
||||||
|
(LPDWORD)&dwType, NULL, &cbValue);
|
||||||
|
|
||||||
|
if(lErr == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY, cbValue);
|
||||||
|
|
||||||
|
if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL, NULL,
|
||||||
|
lpValue, &cbValue) == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
switch(dwType) {
|
||||||
|
case REG_DWORD:
|
||||||
|
TCHAR szBuf[20];
|
||||||
|
_ltot(*(LPDWORD)lpValue, szBuf, 10);
|
||||||
|
strResult = env->NewString((const jchar *)szBuf,
|
||||||
|
lstrlen(szBuf));
|
||||||
|
break;
|
||||||
|
case REG_SZ:
|
||||||
|
case REG_EXPAND_SZ: {
|
||||||
|
DWORD len;
|
||||||
|
LPTSTR dest = NULL;
|
||||||
|
len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
|
||||||
|
dest = (LPTSTR)malloc(len * sizeof(TCHAR));
|
||||||
|
ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
|
||||||
|
strResult = env->NewString((const jchar *)dest, len);
|
||||||
|
free(dest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
lErr = ERROR_SUCCESS - 1; // Make an error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, lpValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
env->ReleaseStringChars(name, (const jchar *)lpValueName);
|
||||||
|
|
||||||
|
if(lErr == ERROR_SUCCESS)
|
||||||
|
return strResult;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
|
||||||
|
env->ThrowNew(cls, "");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
|
||||||
|
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
|
||||||
|
{
|
||||||
|
LPCTSTR lpValueName;
|
||||||
|
|
||||||
|
if(valueName != NULL)
|
||||||
|
lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
|
||||||
|
else
|
||||||
|
lpValueName = NULL;
|
||||||
|
|
||||||
|
int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
|
||||||
|
REG_DWORD, (LPBYTE)&value, sizeof(value));
|
||||||
|
|
||||||
|
if(valueName != NULL)
|
||||||
|
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
|
||||||
|
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
|
||||||
|
{
|
||||||
|
LPCTSTR lpValueName;
|
||||||
|
|
||||||
|
if(name != NULL)
|
||||||
|
lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
|
||||||
|
else
|
||||||
|
lpValueName = NULL;
|
||||||
|
|
||||||
|
LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);
|
||||||
|
|
||||||
|
int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
|
||||||
|
REG_SZ, (LPBYTE)lpValue,
|
||||||
|
(lstrlen(lpValue) + 1) * sizeof(TCHAR));
|
||||||
|
|
||||||
|
if(name != NULL)
|
||||||
|
env->ReleaseStringChars(name, (const jchar *)lpValueName);
|
||||||
|
env->ReleaseStringChars(value, (const jchar *)lpValue);
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,361 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#define UNICODE
|
||||||
|
#define _UNICODE
|
||||||
|
|
||||||
|
#include "win32bindings.h"
|
||||||
|
#include "javasigar.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This code is stolen from misc/win32/misc.c and apr_private.h
|
||||||
|
* This helper code resolves late bound entry points
|
||||||
|
* missing from one or more releases of the Win32 API...
|
||||||
|
* This is covered under the Apache Software License
|
||||||
|
*
|
||||||
|
* ====================================================================
|
||||||
|
* The Apache Software License, Version 1.1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights
|
||||||
|
* reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
*
|
||||||
|
* 3. The end-user documentation included with the redistribution,
|
||||||
|
* if any, must include the following acknowledgment:
|
||||||
|
* "This product includes software developed by the
|
||||||
|
* Apache Software Foundation (http://www.apache.org/)."
|
||||||
|
* Alternately, this acknowledgment may appear in the software itself,
|
||||||
|
* if and wherever such third-party acknowledgments normally appear.
|
||||||
|
*
|
||||||
|
* 4. The names "Apache" and "Apache Software Foundation" must
|
||||||
|
* not be used to endorse or promote products derived from this
|
||||||
|
* software without prior written permission. For written
|
||||||
|
* permission, please contact apache@apache.org.
|
||||||
|
*
|
||||||
|
* 5. Products derived from this software may not be called "Apache",
|
||||||
|
* nor may "Apache" appear in their name, without prior written
|
||||||
|
* permission of the Apache Software Foundation.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
|
||||||
|
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||||
|
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
* ====================================================================
|
||||||
|
*
|
||||||
|
* This software consists of voluntary contributions made by many
|
||||||
|
* individuals on behalf of the Apache Software Foundation. For more
|
||||||
|
* information on the Apache Software Foundation, please see
|
||||||
|
* <http://www.apache.org/>.
|
||||||
|
*
|
||||||
|
* Portions of this software are based upon public domain software
|
||||||
|
* originally written at the National Center for Supercomputing Applications,
|
||||||
|
* University of Illinois, Urbana-Champaign.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DLL_WINBASEAPI = 0, // kernel32 From WinBase.h
|
||||||
|
DLL_WINADVAPI = 1, // advapi32 From WinBase.h
|
||||||
|
DLL_WINSOCKAPI = 2, // mswsock From WinSock.h
|
||||||
|
DLL_WINSOCK2API = 3, // ws2_32 From WinSock2.h
|
||||||
|
DLL_SHSTDAPI = 4, // shell32 From ShellAPI.h
|
||||||
|
DLL_NTDLL = 5, // shell32 From our real kernel
|
||||||
|
DLL_defined = 6 // must define as last idx_ + 1
|
||||||
|
} dlltoken_e;
|
||||||
|
|
||||||
|
FARPROC load_dll_func(dlltoken_e fnLib, TCHAR* fnName, int ordinal);
|
||||||
|
|
||||||
|
#define DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \
|
||||||
|
typedef rettype (calltype *winapi_fpt_##fn) args; \
|
||||||
|
static winapi_fpt_##fn winapi_pfn_##fn = NULL; \
|
||||||
|
__inline rettype winapi_##fn args \
|
||||||
|
{ if (!winapi_pfn_##fn) \
|
||||||
|
winapi_pfn_##fn = (winapi_fpt_##fn) load_dll_func(lib, (wchar_t *)#fn, ord); \
|
||||||
|
return (*(winapi_pfn_##fn)) names; }; \
|
||||||
|
|
||||||
|
/* Win2K kernel only */
|
||||||
|
DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI,
|
||||||
|
ChangeServiceConfig2W, 0,
|
||||||
|
(SC_HANDLE hService,
|
||||||
|
DWORD dwInfoLevel,
|
||||||
|
LPVOID lpInfo),
|
||||||
|
(hService, dwInfoLevel, lpInfo));
|
||||||
|
#undef ChangeServiceConfig2
|
||||||
|
#define ChangeServiceConfig2 winapi_ChangeServiceConfig2W
|
||||||
|
|
||||||
|
/* End Apache licensed code */
|
||||||
|
|
||||||
|
static TCHAR* lateDllName[] = {
|
||||||
|
L"kernel32", L"advapi32", L"mswsock", L"ws2_32" };
|
||||||
|
static HMODULE lateDllHandle[] = {
|
||||||
|
NULL, NULL, NULL, NULL };
|
||||||
|
|
||||||
|
FARPROC load_dll_func(dlltoken_e fnLib, TCHAR* fnName, int ordinal)
|
||||||
|
{
|
||||||
|
if (!lateDllHandle[fnLib]) {
|
||||||
|
lateDllHandle[fnLib] = LoadLibrary(lateDllName[fnLib]);
|
||||||
|
if (!lateDllHandle[fnLib]) {
|
||||||
|
DWORD err = GetLastError();
|
||||||
|
fprintf(stderr, "GetLastError(): %d %s\r\n",
|
||||||
|
err, lateDllName[fnLib]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ordinal)
|
||||||
|
return GetProcAddress(lateDllHandle[fnLib], (char *)ordinal);
|
||||||
|
else
|
||||||
|
return GetProcAddress(lateDllHandle[fnLib], (char *)fnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*End ASF licensed code */
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_ChangeServiceDescription)
|
||||||
|
(JNIEnv *env, jclass, jlong handle, jstring description)
|
||||||
|
{
|
||||||
|
jboolean bResult = TRUE;
|
||||||
|
SERVICE_DESCRIPTION servdesc;
|
||||||
|
|
||||||
|
OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */
|
||||||
|
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||||
|
GetVersionEx(&osver);
|
||||||
|
|
||||||
|
if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
||||||
|
&& (osver.dwMajorVersion > 4)
|
||||||
|
&& (ChangeServiceConfig2 != NULL)) {
|
||||||
|
servdesc.lpDescription = (LPTSTR)env->GetStringChars(description,
|
||||||
|
NULL);
|
||||||
|
bResult = ChangeServiceConfig2((SC_HANDLE)handle,
|
||||||
|
SERVICE_CONFIG_DESCRIPTION, &servdesc);
|
||||||
|
env->ReleaseStringChars(description,
|
||||||
|
(const jchar *)servdesc.lpDescription);
|
||||||
|
}
|
||||||
|
return bResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_CloseServiceHandle)
|
||||||
|
(JNIEnv *, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
return CloseServiceHandle((SC_HANDLE)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_ControlService)
|
||||||
|
(JNIEnv *, jclass, jlong handle, jint control)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
return ControlService((SC_HANDLE)handle, control, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_Service_CreateService)
|
||||||
|
(JNIEnv *env,
|
||||||
|
jclass,
|
||||||
|
jlong handle,
|
||||||
|
jstring serviceName,
|
||||||
|
jstring displayName,
|
||||||
|
jint serviceType,
|
||||||
|
jint startType,
|
||||||
|
jint errorControl,
|
||||||
|
jstring path,
|
||||||
|
jobjectArray dependencies,
|
||||||
|
jstring startName,
|
||||||
|
jstring password)
|
||||||
|
{
|
||||||
|
TCHAR szBuf[4048];
|
||||||
|
LPCTSTR lpDepend = NULL;
|
||||||
|
jlong lResult;
|
||||||
|
LPCTSTR lpStartName;
|
||||||
|
|
||||||
|
LPCTSTR lpServiceName = (LPCTSTR)env->GetStringChars(serviceName, NULL);
|
||||||
|
LPCTSTR lpDisplayName = (LPCTSTR)env->GetStringChars(displayName, NULL);
|
||||||
|
LPCTSTR lpPath = (LPCTSTR)env->GetStringChars(path, NULL);
|
||||||
|
LPCTSTR lpPassword = (LPCTSTR)env->GetStringChars(password, NULL);
|
||||||
|
|
||||||
|
if(startName != NULL)
|
||||||
|
lpStartName = (LPCTSTR)env->GetStringChars(path, NULL);
|
||||||
|
else
|
||||||
|
lpStartName = NULL;
|
||||||
|
|
||||||
|
if(dependencies != NULL)
|
||||||
|
{
|
||||||
|
// Build a buffer of a double null terminated array of
|
||||||
|
// null terminated service names
|
||||||
|
lpDepend = szBuf;
|
||||||
|
|
||||||
|
LPTSTR lpBuf = szBuf;
|
||||||
|
size_t cbLen = 0;
|
||||||
|
jsize cSize = env->GetArrayLength(dependencies);
|
||||||
|
|
||||||
|
for(int i = 0;i < cSize;i ++)
|
||||||
|
{
|
||||||
|
jstring str = (jstring)env->GetObjectArrayElement(dependencies, i);
|
||||||
|
|
||||||
|
LPCTSTR lpStr = (LPCTSTR)env->GetStringChars(str, NULL);
|
||||||
|
cbLen = lstrlen(lpStr);
|
||||||
|
|
||||||
|
// If we're going to overrun the buffer then break out of the loop
|
||||||
|
if((lpBuf + cbLen + 1) >= (szBuf + sizeof(szBuf) / sizeof(TCHAR)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
lstrcpy(lpBuf, lpStr);
|
||||||
|
env->ReleaseStringChars(str, (const jchar *)lpStr);
|
||||||
|
|
||||||
|
// Move the buffer to the byte beyond the current string
|
||||||
|
// null terminator
|
||||||
|
lpBuf = lpBuf + cbLen + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpBuf = 0; // Double null terminate the string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the Service
|
||||||
|
lResult = (jlong)CreateService((SC_HANDLE)handle, lpServiceName,
|
||||||
|
lpDisplayName, SERVICE_ALL_ACCESS,
|
||||||
|
serviceType,
|
||||||
|
startType, errorControl, lpPath,
|
||||||
|
NULL, NULL, lpDepend, lpStartName,
|
||||||
|
lpPassword);
|
||||||
|
|
||||||
|
if(lpStartName != NULL)
|
||||||
|
env->ReleaseStringChars(path, (const jchar *)lpStartName);
|
||||||
|
|
||||||
|
env->ReleaseStringChars(password, (const jchar *)lpPassword);
|
||||||
|
env->ReleaseStringChars(path, (const jchar *)lpPath);
|
||||||
|
env->ReleaseStringChars(displayName, (const jchar *)lpDisplayName);
|
||||||
|
env->ReleaseStringChars(serviceName, (const jchar *)lpServiceName);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_DeleteService)
|
||||||
|
(JNIEnv *env, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
return DeleteService((SC_HANDLE)handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring SIGAR_JNI(win32_Service_GetErrorMessage)
|
||||||
|
(JNIEnv *env, jclass, jint error)
|
||||||
|
{
|
||||||
|
LPTSTR lpMsg;
|
||||||
|
|
||||||
|
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
|
||||||
|
FORMAT_MESSAGE_IGNORE_INSERTS|
|
||||||
|
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
NULL, error,
|
||||||
|
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
|
||||||
|
(LPTSTR)&lpMsg, 0, NULL);
|
||||||
|
return env->NewString((const jchar *)lpMsg, lstrlen(lpMsg));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XXX: this should probablly be moved into a util class
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_Service_GetLastError)
|
||||||
|
(JNIEnv *, jclass)
|
||||||
|
{
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_Service_OpenSCManager)
|
||||||
|
(JNIEnv *env, jclass, jstring machine, jint access)
|
||||||
|
{
|
||||||
|
jlong lResult;
|
||||||
|
|
||||||
|
LPCTSTR lpMachine = (LPCTSTR)env->GetStringChars(machine, NULL);
|
||||||
|
lResult = (jlong)OpenSCManager(lpMachine, NULL, access);
|
||||||
|
env->ReleaseStringChars(machine, (const jchar *)lpMachine);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jlong SIGAR_JNI(win32_Service_OpenService)
|
||||||
|
(JNIEnv *env,
|
||||||
|
jclass,
|
||||||
|
jlong handle,
|
||||||
|
jstring service,
|
||||||
|
jint access)
|
||||||
|
{
|
||||||
|
jlong lResult;
|
||||||
|
|
||||||
|
LPCTSTR lpService = (LPCTSTR)env->GetStringChars(service, NULL);
|
||||||
|
lResult = (jlong)OpenService((SC_HANDLE)handle,
|
||||||
|
lpService, access);
|
||||||
|
env->ReleaseStringChars(service, (const jchar *)lpService);
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint
|
||||||
|
SIGAR_JNI(win32_Service_QueryServiceStatus)
|
||||||
|
(JNIEnv *, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
int iResult;
|
||||||
|
|
||||||
|
if(QueryServiceStatus((SC_HANDLE)handle, &status) == TRUE) {
|
||||||
|
iResult = status.dwCurrentState;
|
||||||
|
} else
|
||||||
|
iResult = -1;
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint SIGAR_JNI(win32_Service_QueryServiceStartType)
|
||||||
|
(JNIEnv *, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
LPQUERY_SERVICE_CONFIG config;
|
||||||
|
int iResult;
|
||||||
|
DWORD dwBytesNeeded;
|
||||||
|
|
||||||
|
config = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
|
||||||
|
if (config == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Get the configuration information. */
|
||||||
|
|
||||||
|
if (QueryServiceConfig((SC_HANDLE)handle, config, 4096,
|
||||||
|
&dwBytesNeeded) == 0) {
|
||||||
|
iResult = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
iResult = config->dwStartType;
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_StartService)
|
||||||
|
(JNIEnv *, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
return StartService((SC_HANDLE)handle, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jboolean SIGAR_JNI(win32_Service_StopService)
|
||||||
|
(JNIEnv *, jclass, jlong handle)
|
||||||
|
{
|
||||||
|
SERVICE_STATUS status;
|
||||||
|
|
||||||
|
return ControlService((SC_HANDLE)handle, SERVICE_CONTROL_STOP, &status);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifdef WIN32
|
||||||
|
#include <pdh.h>
|
||||||
|
#include <pdhmsg.h>
|
||||||
|
|
||||||
|
#include "win32bindings.h"
|
||||||
|
#include "javasigar.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set of common utilities for all win32bindings objects
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void win32_throw_exception(JNIEnv *env, char *msg)
|
||||||
|
{
|
||||||
|
jclass exceptionClass = WIN32_FIND_CLASS("Win32Exception");
|
||||||
|
JENV->ThrowNew(env, exceptionClass, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* WIN32 */
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef WIN32_BINDINGS_H
|
||||||
|
#define WIN32_BINDINGS_H
|
||||||
|
|
||||||
|
/* Exclude rarely-used stuff from windows headers */
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
/* Windows Header Files */
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
/* Include java jni headers */
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#define WIN32_PACKAGE "net/covalent/win32bindings/"
|
||||||
|
|
||||||
|
#define WIN32_FIND_CLASS(name) \
|
||||||
|
JENV->FindClass(env, WIN32_PACKAGE name)
|
||||||
|
|
||||||
|
#define WIN32_ALLOC_OBJECT(name) \
|
||||||
|
JENV->AllocObject(env, WIN32_FIND_CLASS(name))
|
||||||
|
|
||||||
|
#define SetStringField(env, obj, fieldID, val) \
|
||||||
|
JENV->SetObjectField(env, obj, fieldID, JENV->NewStringUTF(env, val))
|
||||||
|
|
||||||
|
void win32_throw_exception(JNIEnv *env, char *msg);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,86 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
public class EventLog extends Win32Bindings {
|
||||||
|
|
||||||
|
int eventLogHandle = 0; // holds the event log HANDLE
|
||||||
|
|
||||||
|
// Event log types as defined in WINNT.H
|
||||||
|
public static final int EVENTLOG_SUCCESS = 0x0000;
|
||||||
|
public static final int EVENTLOG_ERROR_TYPE = 0x0001;
|
||||||
|
public static final int EVENTLOG_WARNING_TYPE = 0x0002;
|
||||||
|
public static final int EVENTLOG_INFORMATION_TYPE = 0x0004;
|
||||||
|
public static final int EVENTLOG_AUDIT_SUCCESS = 0x0008;
|
||||||
|
public static final int EVENTLOG_AUDIT_FAILURE = 0x0010;
|
||||||
|
|
||||||
|
// Event log timeouts
|
||||||
|
public static final int EVENTLOG_WAIT_INFINITE = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an event log.
|
||||||
|
*/
|
||||||
|
public EventLog() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the event log. This must be done before any other operation.
|
||||||
|
* @param lpSourceName The event log to open. Should be one of
|
||||||
|
* Application, System or Security.
|
||||||
|
* @exception Win32Exception If opening the event log fails.
|
||||||
|
*/
|
||||||
|
public native void open(String lpSourceName) throws Win32Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the event log.
|
||||||
|
* @exception Win32Excepion If closing of the event log fails.
|
||||||
|
*/
|
||||||
|
public native void close() throws Win32Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of records for this event log
|
||||||
|
* @exception Win32Exception If the event log is not open
|
||||||
|
*/
|
||||||
|
public native int getNumberOfRecords() throws Win32Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the oldest event log record
|
||||||
|
* @exception Win32Exception If the event log is not open
|
||||||
|
*/
|
||||||
|
public native int getOldestRecord() throws Win32Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the newest event log record.
|
||||||
|
* @exception Win32Exception If the event log is not open
|
||||||
|
*/
|
||||||
|
public int getNewestRecord()
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
return getOldestRecord() + getNumberOfRecords() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an event log record. This method only support the
|
||||||
|
* EVENTLOG_SEEK_READ flag, no sequential reading is currently
|
||||||
|
* supported.
|
||||||
|
*
|
||||||
|
* @param recordOffset The record offset to read.
|
||||||
|
* @exception Win32Exception If the event log is not open, or
|
||||||
|
* if the specified record could not be
|
||||||
|
* found
|
||||||
|
*/
|
||||||
|
public native EventLogRecord read(int recordOffset)
|
||||||
|
throws Win32Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wait for a change to the event log. This function will
|
||||||
|
* return on event log change, or when the timeout pops.
|
||||||
|
*
|
||||||
|
* Windows PulseEvent will fire no more than once per 5 seconds,
|
||||||
|
* so multiple events may occur before the application is notified.
|
||||||
|
*
|
||||||
|
* @param timeout Time to wait in milliseconds.
|
||||||
|
* @exception Win32Exception If the event log is not open, or
|
||||||
|
* there is an error waiting for the
|
||||||
|
* the event.
|
||||||
|
*/
|
||||||
|
public native void waitForChange(int timeout)
|
||||||
|
throws Win32Exception;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register for event log notifications.
|
||||||
|
*/
|
||||||
|
public interface EventLogNotification {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if we want to handle this event.
|
||||||
|
*/
|
||||||
|
public abstract boolean matches(EventLogRecord event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if matches() returns true
|
||||||
|
*/
|
||||||
|
public abstract void handleNotification(EventLogRecord event);
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to represent event log records
|
||||||
|
*/
|
||||||
|
public class EventLogRecord {
|
||||||
|
|
||||||
|
public long recordNumber;
|
||||||
|
public long timeGenerated;
|
||||||
|
public long timeWritten;
|
||||||
|
public long eventId;
|
||||||
|
|
||||||
|
public short eventType;
|
||||||
|
|
||||||
|
public String source;
|
||||||
|
public String computerName;
|
||||||
|
public String user;
|
||||||
|
public String stringData;
|
||||||
|
|
||||||
|
/* Get the record number for this event entry */
|
||||||
|
public long getRecordNumber() {
|
||||||
|
return recordNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time at which this entry was submitted. This time is
|
||||||
|
* measured in the number of seconds elapsed since 00:00:00
|
||||||
|
* January 1, 1970, Universal Coordinated Time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public long getTimeGenerated() {
|
||||||
|
return this.timeGenerated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time at which this entry was received by the service to be
|
||||||
|
* written to the logfile. This time is measured in the number of
|
||||||
|
* seconds elapsed since 00:00:00 January 1, 1970, Universal
|
||||||
|
* Coordinated Time.
|
||||||
|
*/
|
||||||
|
public long getTimeWritten() {
|
||||||
|
return this.timeWritten;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event identifier. The value is specific to the event source
|
||||||
|
* for the event, and is used with source name to locate a
|
||||||
|
* description string in the message file for the event source.
|
||||||
|
*
|
||||||
|
* XXX: This is probably not needed
|
||||||
|
*/
|
||||||
|
public long getEventId() {
|
||||||
|
return this.eventId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the event type.
|
||||||
|
* See the EVENTLOG_* constants in the EventLog class
|
||||||
|
*/
|
||||||
|
public short getEventType() {
|
||||||
|
return this.eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the application which triggered the event
|
||||||
|
*/
|
||||||
|
public String getSource() {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the machine name where the event was generated
|
||||||
|
*/
|
||||||
|
public String getComputerName() {
|
||||||
|
return this.computerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user who generated the event. May be null if no user is
|
||||||
|
* associated with the event.
|
||||||
|
*/
|
||||||
|
public String getUser() {
|
||||||
|
return this.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the string data for the event. (The message)
|
||||||
|
*/
|
||||||
|
public String getStringData() {
|
||||||
|
return this.stringData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For debugging
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
"recordNumber=" + recordNumber + " " +
|
||||||
|
"source=" + source + " " +
|
||||||
|
"computerName=" + computerName + " " +
|
||||||
|
"user=" + user + " " +
|
||||||
|
"stringData=" + stringData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple thread that runs forever monitoring the event log.
|
||||||
|
*/
|
||||||
|
public class EventLogThread implements Runnable {
|
||||||
|
|
||||||
|
public static final int DEFAULT_INTERVAL = 60 * 1000;
|
||||||
|
|
||||||
|
private static Logger logger =
|
||||||
|
Logger.getLogger(EventLogThread.class.getName());
|
||||||
|
|
||||||
|
private Thread thread = null;
|
||||||
|
private static EventLogThread instance = null;
|
||||||
|
private boolean shouldDie = false;
|
||||||
|
private Set notifiers = Collections.synchronizedSet(new HashSet());
|
||||||
|
|
||||||
|
private String logName = "Application";
|
||||||
|
private long interval = 10 * 1000; // Default to 10 seconds
|
||||||
|
|
||||||
|
public static synchronized EventLogThread getInstance() {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new EventLogThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInterval(long interval) {
|
||||||
|
this.interval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLogName(String logName) {
|
||||||
|
this.logName = logName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void doStart() {
|
||||||
|
if (this.thread != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.thread = new Thread(this, "EventLogThread");
|
||||||
|
this.thread.setDaemon(true);
|
||||||
|
this.thread.start();
|
||||||
|
|
||||||
|
logger.debug(this.thread.getName() + " started");
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void doStop() {
|
||||||
|
if (this.thread == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
die();
|
||||||
|
this.thread.interrupt();
|
||||||
|
logger.debug(this.thread.getName() + " stopped");
|
||||||
|
this.thread = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(EventLogNotification notifier) {
|
||||||
|
this.notifiers.add(notifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(EventLogNotification notifier) {
|
||||||
|
this.notifiers.remove(notifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleEvents(EventLog log, int curEvent, int lastEvent)
|
||||||
|
{
|
||||||
|
for (int i = curEvent + 1; i <= lastEvent; i++) {
|
||||||
|
|
||||||
|
EventLogRecord record;
|
||||||
|
|
||||||
|
try {
|
||||||
|
record = log.read(i);
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
logger.error("Unable to read event id " + i + ": " + e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (this.notifiers) {
|
||||||
|
for (Iterator it = this.notifiers.iterator(); it.hasNext();)
|
||||||
|
{
|
||||||
|
EventLogNotification notification =
|
||||||
|
(EventLogNotification)it.next();
|
||||||
|
if (notification.matches(record))
|
||||||
|
notification.handleNotification(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
int curEvent;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Open the event log
|
||||||
|
log.open(this.logName);
|
||||||
|
|
||||||
|
curEvent = log.getNewestRecord();
|
||||||
|
|
||||||
|
while (!shouldDie) {
|
||||||
|
// XXX: Using the waitForChange() method would be a
|
||||||
|
// cleaner way to go, but we cannot interrupt
|
||||||
|
// a native system call.
|
||||||
|
int lastEvent = log.getNewestRecord();
|
||||||
|
if (lastEvent > curEvent) {
|
||||||
|
handleEvents(log, curEvent, lastEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
curEvent = lastEvent;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(this.interval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.close();
|
||||||
|
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
logger.error("Unable to monitor event log:", e);
|
||||||
|
} finally {
|
||||||
|
try { log.close(); }
|
||||||
|
catch (Win32Exception e) {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void die() {
|
||||||
|
this.shouldDie = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,184 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class MetaBase extends Win32Bindings
|
||||||
|
{
|
||||||
|
static private int IIS_MD_SERVER_BASE = 1000;
|
||||||
|
static private int IIS_MD_HTTP_BASE = 2000;
|
||||||
|
|
||||||
|
/* NOTE: This is only a partial list of the information that can
|
||||||
|
* get from the metabase.
|
||||||
|
*
|
||||||
|
* These properties are applicable to both HTTP and FTP virtual
|
||||||
|
* servers
|
||||||
|
*/
|
||||||
|
public static int MD_SERVER_COMMAND = IIS_MD_SERVER_BASE+12;
|
||||||
|
public static int MD_CONNECTION_TIMEOUT = IIS_MD_SERVER_BASE+13;
|
||||||
|
public static int MD_MAX_CONNECTIONS = IIS_MD_SERVER_BASE+14;
|
||||||
|
public static int MD_SERVER_COMMENT = IIS_MD_SERVER_BASE+15;
|
||||||
|
public static int MD_SERVER_STATE = IIS_MD_SERVER_BASE+16;
|
||||||
|
public static int MD_SERVER_AUTOSTART = IIS_MD_SERVER_BASE+17;
|
||||||
|
public static int MD_SERVER_SIZE = IIS_MD_SERVER_BASE+18;
|
||||||
|
public static int MD_SERVER_LISTEN_BACKLOG = IIS_MD_SERVER_BASE+19;
|
||||||
|
public static int MD_SERVER_LISTEN_TIMEOUT = IIS_MD_SERVER_BASE+20;
|
||||||
|
public static int MD_DOWNLEVEL_ADMIN_INSTANCE = IIS_MD_SERVER_BASE+21;
|
||||||
|
public static int MD_LEVELS_TO_SCAN = IIS_MD_SERVER_BASE+22;
|
||||||
|
public static int MD_SERVER_BINDINGS = IIS_MD_SERVER_BASE+23;
|
||||||
|
public static int MD_MAX_ENDPOINT_CONNECTIONS = IIS_MD_SERVER_BASE+24;
|
||||||
|
public static int MD_SERVER_CONFIGURATION_INFO = IIS_MD_SERVER_BASE+27;
|
||||||
|
public static int MD_IISADMIN_EXTENSIONS = IIS_MD_SERVER_BASE+28;
|
||||||
|
|
||||||
|
public static int MD_LOGFILEDIRECTORY = 4001;
|
||||||
|
|
||||||
|
// These properties are specific to HTTP and belong to the website
|
||||||
|
public static int MD_SECURE_BINDINGS = IIS_MD_HTTP_BASE+21;
|
||||||
|
|
||||||
|
protected int m_handle;
|
||||||
|
protected long pIMeta;
|
||||||
|
|
||||||
|
public MetaBase()
|
||||||
|
{
|
||||||
|
pIMeta = MetaBaseInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
MetaBaseClose();
|
||||||
|
MetaBaseRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenSubKey(String subkey)
|
||||||
|
{
|
||||||
|
if (subkey.startsWith("/")) {
|
||||||
|
MetaBaseOpenSubKeyAbs(subkey);
|
||||||
|
} else {
|
||||||
|
MetaBaseOpenSubKey(subkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntValue(int datakey) throws Win32Exception
|
||||||
|
{
|
||||||
|
int iResult = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
iResult = MetaBaseGetIntValue(datakey);
|
||||||
|
} catch(Throwable t) {
|
||||||
|
throw new Win32Exception("Error getting int value");
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntValue(int datakey, int defaultValue)
|
||||||
|
{
|
||||||
|
int iResult;
|
||||||
|
|
||||||
|
try {
|
||||||
|
iResult = this.getIntValue(datakey);
|
||||||
|
} catch(Win32Exception e) {
|
||||||
|
iResult = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringValue(int datakey) throws Win32Exception
|
||||||
|
{
|
||||||
|
String strResult = MetaBaseGetStringValue(datakey);
|
||||||
|
|
||||||
|
if(strResult == null)
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error getting string value");
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringValue(int datakey, String defaultValue)
|
||||||
|
{
|
||||||
|
String strResult;
|
||||||
|
|
||||||
|
try {
|
||||||
|
strResult = this.getStringValue(datakey);
|
||||||
|
} catch(Win32Exception e) {
|
||||||
|
strResult = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMultiStringValue(int datakey)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
String[] strResult = MetaBaseGetMultiStringValue(datakey);
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getSubKeyNames()
|
||||||
|
{
|
||||||
|
Collection coll = new Vector();
|
||||||
|
String strName;
|
||||||
|
|
||||||
|
for(int i = 0;(strName = MetaBaseEnumKey(i)) != null;i ++)
|
||||||
|
coll.add(strName);
|
||||||
|
|
||||||
|
return (String[])coll.toArray(new String[coll.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final native long MetaBaseInit();
|
||||||
|
protected final native void MetaBaseClose();
|
||||||
|
protected final native void MetaBaseRelease();
|
||||||
|
protected final native String MetaBaseEnumKey(int index);
|
||||||
|
protected final native void MetaBaseOpenSubKey(String subkey);
|
||||||
|
protected final native void MetaBaseOpenSubKeyAbs(String subkey);
|
||||||
|
protected final native int MetaBaseGetIntValue(int datakey);
|
||||||
|
protected final native String MetaBaseGetStringValue(int datakey);
|
||||||
|
protected final native String[] MetaBaseGetMultiStringValue(int datakey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main method for dumping out IIS websites from the MetaBase
|
||||||
|
*/
|
||||||
|
public static void main(String args[]) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
MetaBase mb = new MetaBase();
|
||||||
|
|
||||||
|
mb.OpenSubKey("/LM/W3SVC");
|
||||||
|
String keys[] = mb.getSubKeyNames();
|
||||||
|
|
||||||
|
System.out.println("Listing IIS Web Sites");
|
||||||
|
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
int serverNum;
|
||||||
|
try {
|
||||||
|
serverNum = Integer.parseInt(keys[i]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaBase vhost = new MetaBase();
|
||||||
|
vhost.OpenSubKey("/LM/W3SVC/" + serverNum);
|
||||||
|
|
||||||
|
String[] bindings =
|
||||||
|
vhost.getMultiStringValue(MD_SERVER_BINDINGS);
|
||||||
|
|
||||||
|
String hostname = vhost.getStringValue(MD_SERVER_COMMENT);
|
||||||
|
|
||||||
|
System.out.println("");
|
||||||
|
System.out.println("Host: " + hostname);
|
||||||
|
for (int j = 0; j < bindings.length; j++) {
|
||||||
|
System.out.println("Bindings: " + bindings[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
vhost.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
mb.close();
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
System.out.println("Unable to query MetaBase for IIS Web Sites");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,310 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Pdh extends Win32Bindings {
|
||||||
|
|
||||||
|
protected long h_query; // Handle to the query
|
||||||
|
protected String hostname; // Not yet supported
|
||||||
|
|
||||||
|
private String counterPath;
|
||||||
|
private long h_counter = -1l; // Handle to the counter
|
||||||
|
|
||||||
|
public Pdh() throws Win32Exception {
|
||||||
|
h_query = pdhOpenQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pdh(String hostName) throws Win32Exception {
|
||||||
|
this();
|
||||||
|
this.hostname = hostName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void finalize() throws Throwable {
|
||||||
|
try {
|
||||||
|
this.close();
|
||||||
|
} finally {
|
||||||
|
super.finalize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws Win32Exception {
|
||||||
|
if (h_counter != -1l) {
|
||||||
|
pdhRemoveCounter(h_counter);
|
||||||
|
h_counter = -1l;
|
||||||
|
}
|
||||||
|
|
||||||
|
pdhCloseQuery(h_query);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSingleValue(String cp) throws Win32Exception {
|
||||||
|
setCounterPath(cp);
|
||||||
|
return getSingleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getSingleValue() throws Win32Exception {
|
||||||
|
if (h_counter != -1l) {
|
||||||
|
pdhRemoveCounter(h_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
h_counter = pdhAddCounter(h_query, getCounterPath());
|
||||||
|
|
||||||
|
return pdhGetSingleValue(h_query, h_counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getInstances(String cp) throws Win32Exception {
|
||||||
|
return pdhGetInstances(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getKeys(String cp) throws Win32Exception {
|
||||||
|
return pdhGetKeys(cp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getObjects() throws Win32Exception {
|
||||||
|
return pdhGetObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCounterPath() {
|
||||||
|
return counterPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCounterPath(String cp) {
|
||||||
|
this.counterPath = cp;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final native long pdhOpenQuery();
|
||||||
|
protected static final native void pdhCloseQuery(long query);
|
||||||
|
protected static final native long pdhAddCounter(long query, String cp);
|
||||||
|
protected static final native void pdhRemoveCounter(long counter);
|
||||||
|
protected static final native double pdhGetSingleValue(long query,
|
||||||
|
long counter);
|
||||||
|
protected static final native String[] pdhGetInstances(String cp);
|
||||||
|
protected static final native String[] pdhGetKeys(String cp);
|
||||||
|
protected static final native String[] pdhGetObjects();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main method for dumping the entire PDH
|
||||||
|
*
|
||||||
|
* Usage: Pdh [OPTION]
|
||||||
|
* Show information from the Windows PDH
|
||||||
|
*
|
||||||
|
* -v, --values include key values [default=no]
|
||||||
|
* --object=NAME only print info on this object
|
||||||
|
* --contains=NAME only print info on objects that contain
|
||||||
|
this substring
|
||||||
|
* -i, --instance show instances [default=no]
|
||||||
|
* -k, --keys show keys [default=no]
|
||||||
|
* -h, --help display help and exit
|
||||||
|
*/
|
||||||
|
public static void main(String args[]) {
|
||||||
|
|
||||||
|
Pdh pdh = null;
|
||||||
|
String objectName = null;
|
||||||
|
String partialName = null;
|
||||||
|
boolean showValues = false;
|
||||||
|
boolean showInstances = false;
|
||||||
|
boolean showKeys = false;
|
||||||
|
|
||||||
|
// Parse command line arguments
|
||||||
|
if (args.length > 0) {
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i].equals("-h") ||
|
||||||
|
args[i].equals("-help") ||
|
||||||
|
args[i].equals("--help")) {
|
||||||
|
System.out.println("Usage: Pdh [OPTION]");
|
||||||
|
System.out.println("Show information from the Windows " +
|
||||||
|
"PDH");
|
||||||
|
System.out.println("");
|
||||||
|
System.out.println(" --object=NAME " +
|
||||||
|
"only print info on this object");
|
||||||
|
System.out.println(" --contains=NAME " +
|
||||||
|
"only print info on objects that");
|
||||||
|
System.out.println(" " +
|
||||||
|
"contain this substring");
|
||||||
|
System.out.println("-i, --instance " +
|
||||||
|
"show instances [default=no]");
|
||||||
|
System.out.println("-k, --keys " +
|
||||||
|
"show keys [default=no]");
|
||||||
|
System.out.println("-v, --values " +
|
||||||
|
"include key values [default=no]");
|
||||||
|
System.out.println("-h, --help " +
|
||||||
|
"display help and exit");
|
||||||
|
return;
|
||||||
|
} else if (args[i].equals("-v") ||
|
||||||
|
args[i].equals("--values")) {
|
||||||
|
showKeys = true; // Assume -k when -v is used.
|
||||||
|
showValues = true;
|
||||||
|
} else if (args[i].equals("-i") ||
|
||||||
|
args[i].equals("--instances")) {
|
||||||
|
showInstances = true;
|
||||||
|
} else if (args[i].equals("-k") ||
|
||||||
|
args[i].equals("--keys")) {
|
||||||
|
showKeys = true;
|
||||||
|
} else if (args[i].startsWith("--contains=")) {
|
||||||
|
int idx = args[i].indexOf("=");
|
||||||
|
partialName = args[i].substring(idx + 1);
|
||||||
|
} else if (args[i].startsWith("--object=")) {
|
||||||
|
int idx = args[i].indexOf("=");
|
||||||
|
objectName = args[i].substring(idx + 1);
|
||||||
|
} else {
|
||||||
|
System.out.println("Unknown option: " + args[i]);
|
||||||
|
System.out.println("Use --help for usage information");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
pdh = new Pdh();
|
||||||
|
|
||||||
|
String[] objects; // The list of objects to inspect.
|
||||||
|
|
||||||
|
if (partialName != null) {
|
||||||
|
// Check list of object names for a user defined
|
||||||
|
// substring. (e.g. --contains=PLUMTREE for example)
|
||||||
|
List matching = new ArrayList();
|
||||||
|
String[] allObjects = Pdh.getObjects();
|
||||||
|
|
||||||
|
for (int i = 0; i < allObjects.length; i++) {
|
||||||
|
if (allObjects[i].toUpperCase().
|
||||||
|
indexOf(partialName.toUpperCase()) != -1) {
|
||||||
|
matching.add(allObjects[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
objects = (String[])matching.toArray(new String[0]);
|
||||||
|
|
||||||
|
} else if (objectName != null) {
|
||||||
|
// Query for a single object
|
||||||
|
objects = new String[] { objectName };
|
||||||
|
} else {
|
||||||
|
objects = Pdh.getObjects();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int o = 0; o < objects.length; o++) {
|
||||||
|
System.out.println(objects[o]);
|
||||||
|
|
||||||
|
// Get the query keys for this object
|
||||||
|
String[] keys;
|
||||||
|
try {
|
||||||
|
keys = Pdh.getKeys(objects[o]);
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
System.err.println("Unable to get keys for object=" +
|
||||||
|
objects[o] + " Reason: " +
|
||||||
|
e.getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pad = getLongestKey(keys);
|
||||||
|
|
||||||
|
// Get the instances for this object
|
||||||
|
String[] instances = Pdh.getInstances(objects[o]);
|
||||||
|
if (instances.length == 0) {
|
||||||
|
// No instances, dump the keys and values for the
|
||||||
|
// top level object
|
||||||
|
|
||||||
|
if (showKeys == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int k = 0; k < keys.length; k++) {
|
||||||
|
if (showValues) {
|
||||||
|
String query =
|
||||||
|
"\\" + objects[o] + "\\" + keys[k];
|
||||||
|
double val;
|
||||||
|
|
||||||
|
try {
|
||||||
|
val = pdh.getSingleValue(query);
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
System.err.println("Unable to get value for " +
|
||||||
|
" key=" + query +
|
||||||
|
" Reason: " + e.getMessage());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String out = pad(keys[k], pad, ' ');
|
||||||
|
System.out.println(" " + out + " = " + val);
|
||||||
|
} else {
|
||||||
|
System.out.println(" " + keys[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Only show instance level info if asked.
|
||||||
|
if (showInstances == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// For each instance, print it along with the keys
|
||||||
|
for (int i = 0; i < instances.length; i++) {
|
||||||
|
System.out.println(" " + instances[i]);
|
||||||
|
// Dump the keys for this instance
|
||||||
|
|
||||||
|
if (showKeys == false)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int k = 0; k < keys.length; k++) {
|
||||||
|
if (showValues) {
|
||||||
|
String query =
|
||||||
|
"\\" + objects[o] +
|
||||||
|
"(" + instances[i] + ")" +
|
||||||
|
"\\" + keys[k];
|
||||||
|
|
||||||
|
double val;
|
||||||
|
|
||||||
|
try {
|
||||||
|
val = pdh.getSingleValue(query);
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
System.err.println("Unable to get value " +
|
||||||
|
"for key=" + query +
|
||||||
|
" Reason: " +
|
||||||
|
e.getMessage());
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String out = pad(keys[k], pad, ' ');
|
||||||
|
System.out.println(" " + out + " = " +
|
||||||
|
val);
|
||||||
|
} else {
|
||||||
|
System.out.println(" " + keys[k]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pdh.close();
|
||||||
|
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
// Should never happen
|
||||||
|
System.err.println("Unable to dump PDH data: " +
|
||||||
|
e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String padder yanked from java-util's StringUtil.java
|
||||||
|
*/
|
||||||
|
private static String pad(String value, int length, char ch) {
|
||||||
|
StringBuffer padder = new StringBuffer(value);
|
||||||
|
if (value.length() < length) {
|
||||||
|
for (int i=0; i < (length - value.length()); i++) {
|
||||||
|
padder.append(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return padder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the length of the longest string in an array
|
||||||
|
*/
|
||||||
|
private static int getLongestKey(String[] keys) {
|
||||||
|
int longest = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < keys.length; i++) {
|
||||||
|
int len = keys[i].length();
|
||||||
|
if (len > longest)
|
||||||
|
longest = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return longest;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,245 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
public class RegistryKey extends Win32Bindings
|
||||||
|
{
|
||||||
|
protected static final int HKEY_CLASSES_ROOT = 0x80000000;
|
||||||
|
protected static final int HKEY_CURRENT_USER = 0x80000001;
|
||||||
|
protected static final int HKEY_LOCAL_MACHINE = 0x80000002;
|
||||||
|
protected static final int HKEY_USERS = 0x80000003;
|
||||||
|
protected static final int HKEY_PERFORMANCE_DATA = 0x80000004;
|
||||||
|
protected static final int HKEY_CURRENT_CONFIG = 0x80000005;
|
||||||
|
protected static final int HKEY_DYN_DATA = 0x80000006;
|
||||||
|
|
||||||
|
public static final RegistryKey ClassesRoot
|
||||||
|
= new RegistryKey(RegistryKey.HKEY_CLASSES_ROOT);
|
||||||
|
public static final RegistryKey CurrentUser
|
||||||
|
= new RegistryKey(RegistryKey.HKEY_CURRENT_USER);
|
||||||
|
public static final RegistryKey LocalMachine
|
||||||
|
= new RegistryKey(RegistryKey.HKEY_LOCAL_MACHINE);
|
||||||
|
|
||||||
|
protected long m_hkey;
|
||||||
|
private String subkey;
|
||||||
|
|
||||||
|
protected RegistryKey(long hkey)
|
||||||
|
{
|
||||||
|
this.m_hkey = hkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
RegCloseKey(this.m_hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegistryKey createSubKey(String subkey)
|
||||||
|
{
|
||||||
|
return new RegistryKey(RegCreateKey(this.m_hkey, subkey));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSubKeyName() {
|
||||||
|
return this.subkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegistryKey createSubKey(String subkey, String value)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
RegistryKey keyResult = null;
|
||||||
|
long hkey = RegCreateKey(this.m_hkey, subkey);
|
||||||
|
|
||||||
|
if(hkey != 0)
|
||||||
|
{
|
||||||
|
keyResult = new RegistryKey(hkey);
|
||||||
|
|
||||||
|
if(keyResult != null)
|
||||||
|
keyResult.setStringValue(null, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error creating subkey");
|
||||||
|
|
||||||
|
return keyResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegistryKey createSubKey(String subkey, int value)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
RegistryKey keyResult = null;
|
||||||
|
long hkey = RegCreateKey(this.m_hkey, subkey);
|
||||||
|
|
||||||
|
if(hkey != 0)
|
||||||
|
{
|
||||||
|
keyResult = new RegistryKey(hkey);
|
||||||
|
|
||||||
|
if(keyResult != null)
|
||||||
|
keyResult.setIntValue(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error creating subkey");
|
||||||
|
|
||||||
|
return keyResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteSubKey(String subkey)
|
||||||
|
{
|
||||||
|
RegDeleteKey(this.m_hkey, subkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteSubKeyTree(String subkey)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deleteValue(String name)
|
||||||
|
{
|
||||||
|
RegDeleteValue(this.m_hkey, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush()
|
||||||
|
{
|
||||||
|
RegFlushKey(this.m_hkey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntValue(String name)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
int iResult = 0;
|
||||||
|
|
||||||
|
try {
|
||||||
|
iResult = RegQueryIntValue(this.m_hkey, name);
|
||||||
|
} catch(Throwable t) {
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error getting int value");
|
||||||
|
}
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntValue(String name, int defaultValue)
|
||||||
|
{
|
||||||
|
int iResult;
|
||||||
|
|
||||||
|
try {
|
||||||
|
iResult = this.getIntValue(name);
|
||||||
|
} catch(Win32Exception e) {
|
||||||
|
iResult = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return iResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringValue(String name) throws Win32Exception
|
||||||
|
{
|
||||||
|
String strResult = RegQueryStringValue(this.m_hkey, name);
|
||||||
|
|
||||||
|
if(strResult == null)
|
||||||
|
// W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error getting string value");
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStringValue(String name, String defaultValue)
|
||||||
|
{
|
||||||
|
String strResult;
|
||||||
|
|
||||||
|
try {
|
||||||
|
strResult = this.getStringValue(name);
|
||||||
|
} catch(Win32Exception e) {
|
||||||
|
strResult = defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return strResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getSubKeyNames()
|
||||||
|
{
|
||||||
|
Collection coll = new Vector();
|
||||||
|
String strName;
|
||||||
|
|
||||||
|
for(int i = 0; (strName = RegEnumKey(this.m_hkey, i)) != null; i++)
|
||||||
|
coll.add(strName);
|
||||||
|
|
||||||
|
return (String[])coll.toArray(new String[coll.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getValueNames()
|
||||||
|
{
|
||||||
|
Collection coll = new Vector();
|
||||||
|
String strName;
|
||||||
|
|
||||||
|
for(int i = 0; (strName = RegEnumValueName(this.m_hkey, i)) != null;
|
||||||
|
i ++)
|
||||||
|
coll.add(strName);
|
||||||
|
|
||||||
|
return (String[])coll.toArray(new String[coll.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RegistryKey openSubKey(String subkey) throws Win32Exception
|
||||||
|
{
|
||||||
|
long hkey = RegOpenKey(this.m_hkey, subkey);
|
||||||
|
|
||||||
|
if(hkey == 0)
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error opening subkey");
|
||||||
|
|
||||||
|
RegistryKey key = new RegistryKey(hkey);
|
||||||
|
key.subkey = subkey;
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIntValue(String name, int value) throws Win32Exception
|
||||||
|
{
|
||||||
|
int iResult = RegSetIntValue(this.m_hkey, name, value);
|
||||||
|
|
||||||
|
if(iResult != 0)
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error setting int value");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStringValue(String name, String value) throws Win32Exception
|
||||||
|
{
|
||||||
|
int iResult = RegSetStringValue(this.m_hkey, name, value);
|
||||||
|
|
||||||
|
if(iResult != 0)
|
||||||
|
//W32Service.throwLastErrorException();
|
||||||
|
throw new Win32Exception("Error setting string value");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void finalize()
|
||||||
|
{
|
||||||
|
if(this.m_hkey != 0)
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final native int RegCloseKey(long hkey);
|
||||||
|
protected static final native long RegCreateKey(long hkey,
|
||||||
|
String subkey);
|
||||||
|
protected static final native int RegDeleteKey(long hkey,
|
||||||
|
String subkey);
|
||||||
|
protected static final native int RegDeleteValue(long hkey,
|
||||||
|
String valueName);
|
||||||
|
protected static final native String RegEnumKey(long hkey,
|
||||||
|
int index);
|
||||||
|
protected static final native String RegEnumValueName(long hkey,
|
||||||
|
int index);
|
||||||
|
protected static final native int RegFlushKey(long hkey);
|
||||||
|
protected static final native int RegLoadKey(long hkey,
|
||||||
|
String subkey,
|
||||||
|
String filename);
|
||||||
|
protected static final native long RegOpenKey(long hkey, String subkey);
|
||||||
|
protected static final native byte[] RegQueryBufferValue(long hkey,
|
||||||
|
String valueName);
|
||||||
|
protected static final native int RegQueryIntValue(long hkey,
|
||||||
|
String valueName);
|
||||||
|
protected static final native String RegQueryStringValue(long hkey,
|
||||||
|
String valueName);
|
||||||
|
protected static final native int RegSetIntValue(long hkey,
|
||||||
|
String valueName,
|
||||||
|
int value);
|
||||||
|
protected static final native int RegSetStringValue(long hkey,
|
||||||
|
String valueName,
|
||||||
|
String value);
|
||||||
|
}
|
|
@ -0,0 +1,335 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
public class Service extends Win32Bindings implements java.io.Serializable
|
||||||
|
{
|
||||||
|
// Service State
|
||||||
|
public static final int SERVICE_STOPPED = 0x00000001;
|
||||||
|
public static final int SERVICE_START_PENDING = 0x00000002;
|
||||||
|
public static final int SERVICE_STOP_PENDING = 0x00000003;
|
||||||
|
public static final int SERVICE_RUNNING = 0x00000004;
|
||||||
|
public static final int SERVICE_CONTINUE_PENDING = 0x00000005;
|
||||||
|
public static final int SERVICE_PAUSE_PENDING = 0x00000006;
|
||||||
|
public static final int SERVICE_PAUSED = 0x00000007;
|
||||||
|
|
||||||
|
// Start Type
|
||||||
|
public static final int SERVICE_BOOT_START = 0x00000000;
|
||||||
|
public static final int SERVICE_SYSTEM_START = 0x00000001;
|
||||||
|
public static final int SERVICE_AUTO_START = 0x00000002;
|
||||||
|
public static final int SERVICE_DEMAND_START = 0x00000003;
|
||||||
|
public static final int SERVICE_DISABLED = 0x00000004;
|
||||||
|
|
||||||
|
// Service Controls
|
||||||
|
protected static final int SERVICE_CONTROL_STOP = 0x00000001;
|
||||||
|
protected static final int SERVICE_CONTROL_PAUSE = 0x00000002;
|
||||||
|
protected static final int SERVICE_CONTROL_CONTINUE = 0x00000003;
|
||||||
|
protected static final int SERVICE_CONTROL_INTERROGATE = 0x00000004;
|
||||||
|
protected static final int SERVICE_CONTROL_SHUTDOWN = 0x00000005;
|
||||||
|
protected static final int SERVICE_CONTROL_PARAMCHANGE = 0x00000006;
|
||||||
|
protected static final int SERVICE_CONTROL_NETBINDADD = 0x00000007;
|
||||||
|
protected static final int SERVICE_CONTROL_NETBINDREMOVE = 0x00000008;
|
||||||
|
protected static final int SERVICE_CONTROL_NETBINDENABLE = 0x00000009;
|
||||||
|
protected static final int SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A;
|
||||||
|
protected static final int SERVICE_CONTROL_DEVICEEVENT = 0x0000000B;
|
||||||
|
protected static final int SERVICE_CONTROL_HARDWAREPROFILECHANGE
|
||||||
|
= 0x0000000C;
|
||||||
|
protected static final int SERVICE_CONTROL_POWEREVENT = 0x0000000D;
|
||||||
|
protected static final int SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E;
|
||||||
|
|
||||||
|
// Service Control Manager object specific access types
|
||||||
|
protected static final int STANDARD_RIGHTS_REQUIRED = (int)0x000F0000L;
|
||||||
|
|
||||||
|
protected static final int SC_MANAGER_CONNECT = 0x0001;
|
||||||
|
protected static final int SC_MANAGER_CREATE_SERVICE = 0x0002;
|
||||||
|
protected static final int SC_MANAGER_ENUMERATE_SERVICE = 0x0004;
|
||||||
|
protected static final int SC_MANAGER_LOCK = 0x0008;
|
||||||
|
protected static final int SC_MANAGER_QUERY_LOCK_STATUS = 0x0010;
|
||||||
|
protected static final int SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020;
|
||||||
|
|
||||||
|
protected static final int SC_MANAGER_ALL_ACCESS =
|
||||||
|
(STANDARD_RIGHTS_REQUIRED |
|
||||||
|
SC_MANAGER_CONNECT |
|
||||||
|
SC_MANAGER_CREATE_SERVICE |
|
||||||
|
SC_MANAGER_ENUMERATE_SERVICE |
|
||||||
|
SC_MANAGER_LOCK |
|
||||||
|
SC_MANAGER_QUERY_LOCK_STATUS |
|
||||||
|
SC_MANAGER_MODIFY_BOOT_CONFIG);
|
||||||
|
|
||||||
|
// Service object specific access type
|
||||||
|
protected static final int SERVICE_QUERY_CONFIG = 0x0001;
|
||||||
|
protected static final int SERVICE_CHANGE_CONFIG = 0x0002;
|
||||||
|
protected static final int SERVICE_QUERY_STATUS = 0x0004;
|
||||||
|
protected static final int SERVICE_ENUMERATE_DEPENDENTS = 0x0008;
|
||||||
|
protected static final int SERVICE_START = 0x0010;
|
||||||
|
protected static final int SERVICE_STOP = 0x0020;
|
||||||
|
protected static final int SERVICE_PAUSE_CONTINUE = 0x0040;
|
||||||
|
protected static final int SERVICE_INTERROGATE = 0x0080;
|
||||||
|
protected static final int SERVICE_USER_DEFINED_CONTROL = 0x0100;
|
||||||
|
|
||||||
|
protected static final int SERVICE_ALL_ACCESS =
|
||||||
|
(STANDARD_RIGHTS_REQUIRED |
|
||||||
|
SERVICE_QUERY_CONFIG |
|
||||||
|
SERVICE_CHANGE_CONFIG |
|
||||||
|
SERVICE_QUERY_STATUS |
|
||||||
|
SERVICE_ENUMERATE_DEPENDENTS |
|
||||||
|
SERVICE_START |
|
||||||
|
SERVICE_STOP |
|
||||||
|
SERVICE_PAUSE_CONTINUE |
|
||||||
|
SERVICE_INTERROGATE |
|
||||||
|
SERVICE_USER_DEFINED_CONTROL);
|
||||||
|
|
||||||
|
// Service Types (Bit Mask)
|
||||||
|
protected static final int SERVICE_KERNEL_DRIVER = 0x00000001;
|
||||||
|
protected static final int SERVICE_FILE_SYSTEM_DRIVER = 0x00000002;
|
||||||
|
protected static final int SERVICE_ADAPTER = 0x00000004;
|
||||||
|
protected static final int SERVICE_RECOGNIZER_DRIVER = 0x00000008;
|
||||||
|
protected static final int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
|
||||||
|
protected static final int SERVICE_WIN32_SHARE_PROCESS = 0x00000020;
|
||||||
|
protected static final int SERVICE_INTERACTIVE_PROCESS = 0x00000100;
|
||||||
|
|
||||||
|
// Error control type
|
||||||
|
protected static final int SERVICE_ERROR_IGNORE = 0x00000000;
|
||||||
|
protected static final int SERVICE_ERROR_NORMAL = 0x00000001;
|
||||||
|
protected static final int SERVICE_ERROR_SEVERE = 0x00000002;
|
||||||
|
protected static final int SERVICE_ERROR_CRITICAL = 0x00000003;
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////
|
||||||
|
// Object Variables
|
||||||
|
protected long m_hMgr;
|
||||||
|
protected long m_hService;
|
||||||
|
|
||||||
|
protected Service() throws Win32Exception
|
||||||
|
{
|
||||||
|
this.m_hMgr = OpenSCManager("", SC_MANAGER_ALL_ACCESS);
|
||||||
|
|
||||||
|
if(this.m_hMgr == 0)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Service(String serviceName) throws Win32Exception
|
||||||
|
{
|
||||||
|
this();
|
||||||
|
|
||||||
|
this.m_hService = OpenService(this.m_hMgr, serviceName,
|
||||||
|
SERVICE_ALL_ACCESS);
|
||||||
|
|
||||||
|
if(this.m_hService == 0)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finalize()
|
||||||
|
{
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void close()
|
||||||
|
{
|
||||||
|
if(this.m_hService != 0) {
|
||||||
|
CloseServiceHandle(this.m_hService);
|
||||||
|
this.m_hService = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.m_hMgr != 0) {
|
||||||
|
CloseServiceHandle(this.m_hMgr);
|
||||||
|
this.m_hService = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Service create(String serviceName,
|
||||||
|
String displayName,
|
||||||
|
String description,
|
||||||
|
String path)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
return Service.create(serviceName, displayName,
|
||||||
|
description, SERVICE_WIN32_OWN_PROCESS,
|
||||||
|
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
||||||
|
path, null, null, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Service create(String serviceName, String displayName,
|
||||||
|
String description, int serviceType,
|
||||||
|
int startType, int errorControl,
|
||||||
|
String path, String[] dependicies,
|
||||||
|
String startName, String password)
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
if(serviceName == null)
|
||||||
|
throw new IllegalArgumentException("The serviceName argument " +
|
||||||
|
"cannot be null.");
|
||||||
|
if(displayName == null)
|
||||||
|
throw new IllegalArgumentException("The displayName argument " +
|
||||||
|
"cannot be null.");
|
||||||
|
if(path == null)
|
||||||
|
throw new IllegalArgumentException("The displayName argument " +
|
||||||
|
"cannot be null.");
|
||||||
|
|
||||||
|
Service service = new Service();
|
||||||
|
service.m_hService = Service.CreateService(service.m_hMgr,
|
||||||
|
serviceName,
|
||||||
|
displayName,
|
||||||
|
serviceType,
|
||||||
|
startType,
|
||||||
|
errorControl,
|
||||||
|
path,
|
||||||
|
dependicies,
|
||||||
|
startName,
|
||||||
|
password);
|
||||||
|
if(service.m_hService == 0)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
|
||||||
|
service.setDescription(description);
|
||||||
|
|
||||||
|
return service;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() throws Win32Exception
|
||||||
|
{
|
||||||
|
DeleteService(this.m_hService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description)
|
||||||
|
{
|
||||||
|
Service.ChangeServiceDescription(this.m_hService, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void start() throws Win32Exception
|
||||||
|
{
|
||||||
|
if(Service.StartService(this.m_hService) == false)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startAndWait() throws Win32Exception
|
||||||
|
{
|
||||||
|
// Wait indefinitely
|
||||||
|
this.startAndWait(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startAndWait(long timeout) throws Win32Exception
|
||||||
|
{
|
||||||
|
this.start();
|
||||||
|
this.waitForStart(timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int status()
|
||||||
|
{
|
||||||
|
return QueryServiceStatus(this.m_hService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int startType()
|
||||||
|
{
|
||||||
|
return QueryServiceStartType(this.m_hService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() throws Win32Exception
|
||||||
|
{
|
||||||
|
if(StopService(this.m_hService) == false)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopAndWait() throws Win32Exception
|
||||||
|
{
|
||||||
|
// Wait indefinitely
|
||||||
|
this.stopAndWait(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopAndWait(long timeout) throws Win32Exception
|
||||||
|
{
|
||||||
|
long lStatus;
|
||||||
|
|
||||||
|
this.stop();
|
||||||
|
|
||||||
|
long lStart = System.currentTimeMillis();
|
||||||
|
|
||||||
|
while((lStatus = this.status()) != SERVICE_STOPPED) {
|
||||||
|
if(lStatus == SERVICE_STOP_PENDING) {
|
||||||
|
// The start hasn't completed yet. Keep trying up to
|
||||||
|
// the timeout.
|
||||||
|
if((System.currentTimeMillis() - lStart) <
|
||||||
|
timeout || timeout <= 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lStatus != SERVICE_STOPPED)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitForStart(long timeout) throws Win32Exception
|
||||||
|
{
|
||||||
|
long lStatus;
|
||||||
|
boolean bResult = true;
|
||||||
|
long lStart = System.currentTimeMillis();
|
||||||
|
|
||||||
|
while((lStatus = this.status()) != SERVICE_RUNNING)
|
||||||
|
{
|
||||||
|
if(lStatus == SERVICE_START_PENDING)
|
||||||
|
{
|
||||||
|
// The start hasn't completed yet. Keep trying up to
|
||||||
|
// the timeout.
|
||||||
|
if((System.currentTimeMillis() - lStart) <
|
||||||
|
timeout || timeout <= 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch(InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bResult = false;
|
||||||
|
} else if(lStatus == SERVICE_STOPPED) {
|
||||||
|
// Start failed
|
||||||
|
bResult = false;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// Hrm.
|
||||||
|
bResult = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bResult == false)
|
||||||
|
Service.throwLastErrorException();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final void throwLastErrorException()
|
||||||
|
throws Win32Exception
|
||||||
|
{
|
||||||
|
int iErr = Service.GetLastError();
|
||||||
|
throw new Win32Exception(iErr, "Win32 Error Code: " +
|
||||||
|
iErr + ": " + Service.GetErrorMessage(iErr));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final native boolean
|
||||||
|
ChangeServiceDescription(long handle,
|
||||||
|
String description);
|
||||||
|
protected static final native boolean CloseServiceHandle(long handle);
|
||||||
|
protected static final native long CreateService(long handle,
|
||||||
|
String serviceName,
|
||||||
|
String displayName,
|
||||||
|
int serviceType,
|
||||||
|
int startType,
|
||||||
|
int errorControl,
|
||||||
|
String path,
|
||||||
|
String[] dependicies,
|
||||||
|
String startName,
|
||||||
|
String password);
|
||||||
|
protected static final native boolean ControlService(long handle,
|
||||||
|
int control);
|
||||||
|
protected static final native boolean DeleteService(long handle);
|
||||||
|
protected static final native String GetErrorMessage(int error);
|
||||||
|
protected static final native int GetLastError();
|
||||||
|
protected static final native long OpenSCManager(String machine,
|
||||||
|
int access);
|
||||||
|
protected static final native long OpenService(long handle,
|
||||||
|
String service,
|
||||||
|
int access);
|
||||||
|
protected static final native int QueryServiceStatus(long handle);
|
||||||
|
protected static final native int QueryServiceStartType(long handle);
|
||||||
|
protected static final native boolean StartService(long handle);
|
||||||
|
protected static final native boolean StopService(long handle);
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
import net.hyperic.sigar.Sigar;
|
||||||
|
|
||||||
|
abstract class Win32Bindings {
|
||||||
|
|
||||||
|
static {
|
||||||
|
new Sigar(); //XXX Sigar.load()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package net.hyperic.sigar.win32;
|
||||||
|
|
||||||
|
public class Win32Exception extends Exception {
|
||||||
|
|
||||||
|
private int errorCode;
|
||||||
|
|
||||||
|
public Win32Exception (String s) { super(s); }
|
||||||
|
|
||||||
|
public Win32Exception (int error, String s) {
|
||||||
|
super(s);
|
||||||
|
this.errorCode = error;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getErrorCode() {
|
||||||
|
return this.errorCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package net.hyperic.sigar.win32.test;
|
||||||
|
|
||||||
|
import net.hyperic.sigar.win32.EventLog;
|
||||||
|
import net.hyperic.sigar.win32.EventLogNotification;
|
||||||
|
import net.hyperic.sigar.win32.EventLogRecord;
|
||||||
|
import net.hyperic.sigar.win32.EventLogThread;
|
||||||
|
import net.hyperic.sigar.win32.Win32Exception;
|
||||||
|
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class TestEventLog extends TestCase {
|
||||||
|
|
||||||
|
public TestEventLog(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testOpenClose() throws Exception {
|
||||||
|
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
|
||||||
|
// Try to close an event log that isn't open
|
||||||
|
try {
|
||||||
|
log.close();
|
||||||
|
fail("Closing an unopened event log succeeded");
|
||||||
|
} catch (Win32Exception e) {
|
||||||
|
// OK
|
||||||
|
}
|
||||||
|
|
||||||
|
log.open("Application");
|
||||||
|
log.close();
|
||||||
|
|
||||||
|
// Try to reopen using the System log
|
||||||
|
log.open("System");
|
||||||
|
log.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetNumberOfRecords() throws Exception {
|
||||||
|
int numRecords;
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
|
||||||
|
log.open("Application");
|
||||||
|
try {
|
||||||
|
numRecords = log.getNumberOfRecords();
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Unable to get the number of records");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetOldestRecord() throws Exception {
|
||||||
|
int oldestRecord;
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
|
||||||
|
log.open("Application");
|
||||||
|
try {
|
||||||
|
oldestRecord = log.getOldestRecord();
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Unable to get the oldest event record");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testGetNewestRecord() throws Exception {
|
||||||
|
int newestRecord;
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
|
||||||
|
log.open("Application");
|
||||||
|
try {
|
||||||
|
newestRecord = log.getNewestRecord();
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Unable to get the newest event record");
|
||||||
|
}
|
||||||
|
|
||||||
|
log.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test reading all records
|
||||||
|
public void testRead() throws Exception {
|
||||||
|
EventLogRecord record;
|
||||||
|
EventLog log = new EventLog();
|
||||||
|
|
||||||
|
log.open("Application");
|
||||||
|
int oldestRecord = log.getOldestRecord();
|
||||||
|
int numRecords = log.getNumberOfRecords();
|
||||||
|
|
||||||
|
for (int i = oldestRecord; i < oldestRecord + numRecords; i++) {
|
||||||
|
record = log.read(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SSHEventLogNotification
|
||||||
|
implements EventLogNotification {
|
||||||
|
|
||||||
|
public boolean matches(EventLogRecord record) {
|
||||||
|
return record.getSource().equals("sshd");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handleNotification(EventLogRecord record) {
|
||||||
|
System.out.println(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test event log thread
|
||||||
|
public void testEventLogThread() throws Exception {
|
||||||
|
|
||||||
|
EventLogThread thread = EventLogThread.getInstance();
|
||||||
|
|
||||||
|
thread.doStart();
|
||||||
|
|
||||||
|
SSHEventLogNotification notification =
|
||||||
|
new SSHEventLogNotification();
|
||||||
|
thread.add(notification);
|
||||||
|
|
||||||
|
thread.doStop();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package net.hyperic.sigar.win32.test;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
public class TestMetaBase extends TestCase {
|
||||||
|
|
||||||
|
public TestMetaBase(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: This test shouldn't fail if IIS is not installed. If
|
||||||
|
* the exceptions thrown from the native code were actually
|
||||||
|
* useful, we could do this. Re-add this test when the
|
||||||
|
* exceptions are cleaned up.
|
||||||
|
**/
|
||||||
|
public void testMetaBase() throws Exception {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package net.hyperic.sigar.win32.test;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import net.hyperic.sigar.win32.Pdh;
|
||||||
|
|
||||||
|
public class TestPdh extends TestCase {
|
||||||
|
|
||||||
|
public TestPdh(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPdhSingleValue() throws Exception {
|
||||||
|
|
||||||
|
Pdh pdh = new Pdh();
|
||||||
|
String key = "\\Memory\\Available Bytes";
|
||||||
|
double val = pdh.getSingleValue(key);
|
||||||
|
|
||||||
|
assertTrue(val > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testPdh () throws Exception {
|
||||||
|
|
||||||
|
Pdh pdh = new Pdh();
|
||||||
|
|
||||||
|
String[] iface = Pdh.getKeys("Thread");
|
||||||
|
|
||||||
|
assertTrue(iface.length > 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package net.hyperic.sigar.win32.test;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import net.hyperic.sigar.win32.RegistryKey;
|
||||||
|
|
||||||
|
public class TestRegistryKey extends TestCase {
|
||||||
|
|
||||||
|
public TestRegistryKey(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testRegistryKey() throws Exception {
|
||||||
|
|
||||||
|
RegistryKey key = RegistryKey.LocalMachine.
|
||||||
|
createSubKey("SOFTWARE\\Covalent\\Test", "Covalent Test");
|
||||||
|
|
||||||
|
key.setStringValue("TestString", "Hello World");
|
||||||
|
key.setIntValue("Test Int", 100);
|
||||||
|
|
||||||
|
String[] astrNames = key.getValueNames();
|
||||||
|
String strValue = key.getStringValue(astrNames[0]);
|
||||||
|
//assertTrue(strValue.equals("Covalent Test"));
|
||||||
|
|
||||||
|
int iValue = key.getIntValue(astrNames[1]);
|
||||||
|
//assertTrue(iValue == 100);
|
||||||
|
|
||||||
|
key = RegistryKey.LocalMachine.openSubKey("SOFTWARE\\Covalent");
|
||||||
|
astrNames = key.getSubKeyNames();
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
key.deleteSubKey("Test");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package net.hyperic.sigar.win32.test;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import net.hyperic.sigar.win32.Service;
|
||||||
|
|
||||||
|
public class TestService extends TestCase {
|
||||||
|
|
||||||
|
public TestService(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testServiceCreateDelete() throws Exception {
|
||||||
|
|
||||||
|
Service service =
|
||||||
|
Service.create("MyTestService",
|
||||||
|
"My Test Service",
|
||||||
|
"This is a great service.",
|
||||||
|
"C:\\oracle\\ora90\\bin\\agntsrvc.exe");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testServiceOpen() throws Exception {
|
||||||
|
Service service = new Service("MyTestService");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testDeleteService() throws Exception {
|
||||||
|
Service service = new Service("MyTestService");
|
||||||
|
service.delete();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue