From 6353b7bcc31e1956a278aa5174c441a19bf84575 Mon Sep 17 00:00:00 2001 From: Doug MacEachern Date: Sat, 20 Nov 2004 21:01:16 +0000 Subject: [PATCH] merging in the win32bindings package --- bindings/java/src/jni/win32/eventlog.c | 301 +++++++++++++++ bindings/java/src/jni/win32/metabase.cpp | 282 ++++++++++++++ bindings/java/src/jni/win32/pdh.c | 338 ++++++++++++++++ bindings/java/src/jni/win32/registrykey.cpp | 274 +++++++++++++ bindings/java/src/jni/win32/service.cpp | 361 ++++++++++++++++++ bindings/java/src/jni/win32/util.c | 25 ++ bindings/java/src/jni/win32/win32bindings.h | 28 ++ .../src/net/hyperic/sigar/win32/EventLog.java | 86 +++++ .../sigar/win32/EventLogNotification.java | 17 + .../hyperic/sigar/win32/EventLogRecord.java | 106 +++++ .../hyperic/sigar/win32/EventLogThread.java | 139 +++++++ .../src/net/hyperic/sigar/win32/MetaBase.java | 184 +++++++++ .../java/src/net/hyperic/sigar/win32/Pdh.java | 310 +++++++++++++++ .../net/hyperic/sigar/win32/RegistryKey.java | 245 ++++++++++++ .../src/net/hyperic/sigar/win32/Service.java | 335 ++++++++++++++++ .../hyperic/sigar/win32/Win32Bindings.java | 10 + .../hyperic/sigar/win32/Win32Exception.java | 17 + .../sigar/win32/test/TestEventLog.java | 121 ++++++ .../sigar/win32/test/TestMetaBase.java | 19 + .../net/hyperic/sigar/win32/test/TestPdh.java | 29 ++ .../sigar/win32/test/TestRegistryKey.java | 33 ++ .../hyperic/sigar/win32/test/TestService.java | 29 ++ 22 files changed, 3289 insertions(+) create mode 100644 bindings/java/src/jni/win32/eventlog.c create mode 100644 bindings/java/src/jni/win32/metabase.cpp create mode 100644 bindings/java/src/jni/win32/pdh.c create mode 100644 bindings/java/src/jni/win32/registrykey.cpp create mode 100644 bindings/java/src/jni/win32/service.cpp create mode 100644 bindings/java/src/jni/win32/util.c create mode 100644 bindings/java/src/jni/win32/win32bindings.h create mode 100644 bindings/java/src/net/hyperic/sigar/win32/EventLog.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/EventLogNotification.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/EventLogRecord.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/EventLogThread.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/MetaBase.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/Pdh.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/RegistryKey.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/Service.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/Win32Bindings.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/Win32Exception.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/test/TestEventLog.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/test/TestMetaBase.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/test/TestPdh.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/test/TestRegistryKey.java create mode 100644 bindings/java/src/net/hyperic/sigar/win32/test/TestService.java diff --git a/bindings/java/src/jni/win32/eventlog.c b/bindings/java/src/jni/win32/eventlog.c new file mode 100644 index 00000000..1e4d6e93 --- /dev/null +++ b/bindings/java/src/jni/win32/eventlog.c @@ -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 */ diff --git a/bindings/java/src/jni/win32/metabase.cpp b/bindings/java/src/jni/win32/metabase.cpp new file mode 100644 index 00000000..cd67fc52 --- /dev/null +++ b/bindings/java/src/jni/win32/metabase.cpp @@ -0,0 +1,282 @@ +#ifdef WIN32 +#define UNICODE +#define _UNICODE +#define _WIN32_DCOM + +#define INITGUID + +#include // COM Interface header file. +#include // COM Interface header file. +#include // MD_ & IIS_MD_ #defines header file. +#include +#include // 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 *pIMeta; + pIMeta = (CComPtr *)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 *pIMeta; + pIMeta = (CComPtr *)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 *pIMeta; + pIMeta = (CComPtr *)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 *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 ); + 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 *pIMeta; + pIMeta = (CComPtr *)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 *pIMeta; + pIMeta = (CComPtr *)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 *pIMeta; + pIMeta = (CComPtr *)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 *pIMeta; + pIMeta = (CComPtr *)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 */ diff --git a/bindings/java/src/jni/win32/pdh.c b/bindings/java/src/jni/win32/pdh.c new file mode 100644 index 00000000..3c0acc07 --- /dev/null +++ b/bindings/java/src/jni/win32/pdh.c @@ -0,0 +1,338 @@ +#ifdef WIN32 +#include +#include + +#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 */ diff --git a/bindings/java/src/jni/win32/registrykey.cpp b/bindings/java/src/jni/win32/registrykey.cpp new file mode 100644 index 00000000..0cd7edba --- /dev/null +++ b/bindings/java/src/jni/win32/registrykey.cpp @@ -0,0 +1,274 @@ +#ifdef WIN32 +#define UNICODE +#define _UNICODE + +#include + +#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 */ diff --git a/bindings/java/src/jni/win32/service.cpp b/bindings/java/src/jni/win32/service.cpp new file mode 100644 index 00000000..18eb1fed --- /dev/null +++ b/bindings/java/src/jni/win32/service.cpp @@ -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 + * . + * + * 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 */ diff --git a/bindings/java/src/jni/win32/util.c b/bindings/java/src/jni/win32/util.c new file mode 100644 index 00000000..d4f5625b --- /dev/null +++ b/bindings/java/src/jni/win32/util.c @@ -0,0 +1,25 @@ +#ifdef WIN32 +#include +#include + +#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 */ diff --git a/bindings/java/src/jni/win32/win32bindings.h b/bindings/java/src/jni/win32/win32bindings.h new file mode 100644 index 00000000..5b2ee18f --- /dev/null +++ b/bindings/java/src/jni/win32/win32bindings.h @@ -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 + +#include + +/* Include java jni headers */ +#include + +#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 diff --git a/bindings/java/src/net/hyperic/sigar/win32/EventLog.java b/bindings/java/src/net/hyperic/sigar/win32/EventLog.java new file mode 100644 index 00000000..be6fd464 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/EventLog.java @@ -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; +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/EventLogNotification.java b/bindings/java/src/net/hyperic/sigar/win32/EventLogNotification.java new file mode 100644 index 00000000..44b89a41 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/EventLogNotification.java @@ -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); +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/EventLogRecord.java b/bindings/java/src/net/hyperic/sigar/win32/EventLogRecord.java new file mode 100644 index 00000000..93325dea --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/EventLogRecord.java @@ -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; + } +} + diff --git a/bindings/java/src/net/hyperic/sigar/win32/EventLogThread.java b/bindings/java/src/net/hyperic/sigar/win32/EventLogThread.java new file mode 100644 index 00000000..f5a163e3 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/EventLogThread.java @@ -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; + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/MetaBase.java b/bindings/java/src/net/hyperic/sigar/win32/MetaBase.java new file mode 100644 index 00000000..99dc02c0 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/MetaBase.java @@ -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"); + } + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/Pdh.java b/bindings/java/src/net/hyperic/sigar/win32/Pdh.java new file mode 100644 index 00000000..d5565c14 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/Pdh.java @@ -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; + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/RegistryKey.java b/bindings/java/src/net/hyperic/sigar/win32/RegistryKey.java new file mode 100644 index 00000000..9d092235 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/RegistryKey.java @@ -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); +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/Service.java b/bindings/java/src/net/hyperic/sigar/win32/Service.java new file mode 100644 index 00000000..62a2df1e --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/Service.java @@ -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); +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/Win32Bindings.java b/bindings/java/src/net/hyperic/sigar/win32/Win32Bindings.java new file mode 100644 index 00000000..5d7311a0 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/Win32Bindings.java @@ -0,0 +1,10 @@ +package net.hyperic.sigar.win32; + +import net.hyperic.sigar.Sigar; + +abstract class Win32Bindings { + + static { + new Sigar(); //XXX Sigar.load() + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/Win32Exception.java b/bindings/java/src/net/hyperic/sigar/win32/Win32Exception.java new file mode 100644 index 00000000..eeab9d88 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/Win32Exception.java @@ -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; + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/test/TestEventLog.java b/bindings/java/src/net/hyperic/sigar/win32/test/TestEventLog.java new file mode 100644 index 00000000..54a3383a --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/test/TestEventLog.java @@ -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(); + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/test/TestMetaBase.java b/bindings/java/src/net/hyperic/sigar/win32/test/TestMetaBase.java new file mode 100644 index 00000000..9a806fc5 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/test/TestMetaBase.java @@ -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 { + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/test/TestPdh.java b/bindings/java/src/net/hyperic/sigar/win32/test/TestPdh.java new file mode 100644 index 00000000..f1b82d37 --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/test/TestPdh.java @@ -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); + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/test/TestRegistryKey.java b/bindings/java/src/net/hyperic/sigar/win32/test/TestRegistryKey.java new file mode 100644 index 00000000..b651c1df --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/test/TestRegistryKey.java @@ -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"); + } +} diff --git a/bindings/java/src/net/hyperic/sigar/win32/test/TestService.java b/bindings/java/src/net/hyperic/sigar/win32/test/TestService.java new file mode 100644 index 00000000..f37a4b0d --- /dev/null +++ b/bindings/java/src/net/hyperic/sigar/win32/test/TestService.java @@ -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(); + } +}