merging in the win32bindings package

This commit is contained in:
Doug MacEachern 2004-11-20 21:01:16 +00:00
parent 3b0a6af2d2
commit 6353b7bcc3
22 changed files with 3289 additions and 0 deletions

View File

@ -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 */

View File

@ -0,0 +1,282 @@
#ifdef WIN32
#define UNICODE
#define _UNICODE
#define _WIN32_DCOM
#define INITGUID
#include <objbase.h> // COM Interface header file.
#include <iadmw.h> // COM Interface header file.
#include <iiscnfg.h> // MD_ & IIS_MD_ #defines header file.
#include <ks.h>
#include <atlBase.h> // ATL support header file.
#include "win32bindings.h"
#include "javasigar.h"
#ifdef __cplusplus
extern "C" {
#endif
static jfieldID ptr_field = 0;
static jfieldID IMeta_field = 0;
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseClose)
(JNIEnv *env, jobject cur)
{
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
METADATA_HANDLE MyHandle;
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
(*pIMeta)->CloseKey(MyHandle);
}
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseRelease)
(JNIEnv *env, jobject cur)
{
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
pIMeta->Release();
delete pIMeta;
env->SetIntField(cur, ptr_field, 0);
CoUninitialize();
}
JNIEXPORT jstring SIGAR_JNI(win32_MetaBase_MetaBaseEnumKey)
(JNIEnv *env, jobject cur, jint index)
{
HRESULT hRes = 0;
METADATA_HANDLE MyHandle;
DWORD dwBufLen = 8096;
DWORD dwReqBufLen = 0;
TCHAR pbBuffer[METADATA_MAX_NAME_LEN];
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
hRes = (*pIMeta)->EnumKeys(MyHandle, TEXT(""), pbBuffer, index);
if (SUCCEEDED(hRes)) {
jstring strResult;
// Store the data identifiers in an array for future use.
// Note: declare a suitable DWORD array for names and add
// array bounds checking.
strResult = env->NewString((const jchar *)pbBuffer, lstrlen(pbBuffer));
return strResult;
} else if (hRes == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) {
return NULL;
}
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "MetaBaseEnumKey");
return NULL;
}
JNIEXPORT jlong SIGAR_JNI(win32_MetaBase_MetaBaseInit)
(JNIEnv *env, jobject cur)
{
CComPtr <IMSAdminBase> *pIMeta;
HRESULT hRes = 0;
hRes = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hRes)) {
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "MetaBaseInit");
return 0;
}
pIMeta = new (CComPtr <IMSAdminBase>);
hRes = CoCreateInstance(CLSID_MSAdminBase, NULL, CLSCTX_ALL,
IID_IMSAdminBase, (void **)pIMeta);
if (FAILED(hRes)) {
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "MetaBaseInit: Can't CoCreateInstance");
return 0;
}
jclass cls = env->GetObjectClass(cur);
ptr_field = env->GetFieldID(cls, "m_handle", "I");
IMeta_field = env->GetFieldID(cls, "pIMeta", "J");
return (jlong)pIMeta;
}
static void MetaBaseOpenSubKey(JNIEnv *env, jobject cur,
jstring path, METADATA_HANDLE MyHandle)
{
HRESULT hRes = 0;
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
// Get a handle to the Web service.
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(path, NULL);
hRes = (*pIMeta)->OpenKey(MyHandle, lpSubkey,
METADATA_PERMISSION_READ, 20, &MyHandle);
env->ReleaseStringChars(path, (const jchar *)lpSubkey);
if (FAILED(hRes)) {
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "Can't open Sub Key");
return;
}
env->SetIntField(cur, ptr_field, MyHandle);
}
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseOpenSubKey)
(JNIEnv *env, jobject cur, jstring path)
{
METADATA_HANDLE MyHandle;
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
MetaBaseOpenSubKey(env, cur, path, MyHandle);
}
JNIEXPORT void SIGAR_JNI(win32_MetaBase_MetaBaseOpenSubKeyAbs)
(JNIEnv *env, jobject cur, jstring path)
{
MetaBaseOpenSubKey(env, cur, path, METADATA_MASTER_ROOT_HANDLE);
}
JNIEXPORT jint SIGAR_JNI(win32_MetaBase_MetaBaseGetIntValue)
(JNIEnv *env, jobject cur, jint key)
{
HRESULT hRes = 0;
METADATA_HANDLE MyHandle;
METADATA_RECORD MyRecord;
DWORD dwBufLen = 8096;
DWORD dwReqBufLen = 0;
TCHAR pbBuffer[8096];
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
// Initialize the input structure -
// the values specify what kind of data to enumerate.
MyRecord.dwMDIdentifier = key;
MyRecord.dwMDAttributes = 0;
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
MyRecord.dwMDDataType = DWORD_METADATA;
MyRecord.dwMDDataLen = dwBufLen;
MyRecord.pbMDData = (unsigned char *)pbBuffer;
// Enumerate the data of the first virtual Web server,
// checking to ensure that the data returned does not
// overflow the buffer.
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
if (SUCCEEDED(hRes)) {
int ret = (int)MyRecord.pbMDData;
return ret;
}
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "No such Int value");
return 0;
}
JNIEXPORT jstring SIGAR_JNI(win32_MetaBase_MetaBaseGetStringValue)
(JNIEnv *env, jobject cur, jint key)
{
HRESULT hRes = 0;
METADATA_HANDLE MyHandle;
METADATA_RECORD MyRecord;
DWORD dwBufLen = 8096;
DWORD dwReqBufLen = 0;
TCHAR pbBuffer[8096];
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
// Initialize the input structure -
// the values specify what kind of data to enumerate.
MyRecord.dwMDIdentifier = key;
MyRecord.dwMDAttributes = 0;
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
MyRecord.dwMDDataType = STRING_METADATA;
MyRecord.dwMDDataLen = dwBufLen;
MyRecord.pbMDData = (unsigned char *)pbBuffer;
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
if (SUCCEEDED(hRes)) {
jstring strResult;
// Store the data identifiers in an array for future use.
// Note: declare a suitable DWORD array for names and add
// array bounds checking.
strResult = env->NewString((const jchar *)MyRecord.pbMDData,
lstrlen(pbBuffer));
return strResult;
}
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "No Such string value");
return NULL;
}
JNIEXPORT jobjectArray SIGAR_JNI(win32_MetaBase_MetaBaseGetMultiStringValue)
(JNIEnv *env, jobject cur, jint key)
{
HRESULT hRes = 0;
METADATA_HANDLE MyHandle;
METADATA_RECORD MyRecord;
DWORD dwBufLen = 8096;
DWORD dwReqBufLen = 0;
TCHAR pbBuffer[8096];
CComPtr <IMSAdminBase> *pIMeta;
pIMeta = (CComPtr <IMSAdminBase> *)env->GetLongField(cur, IMeta_field);
MyHandle = (METADATA_HANDLE)env->GetIntField(cur, ptr_field);
// Initialize the input structure -
// the values specify what kind of data to enumerate.
MyRecord.dwMDIdentifier = key;
MyRecord.dwMDAttributes = 0;
MyRecord.dwMDUserType = IIS_MD_UT_SERVER;
MyRecord.dwMDDataType = MULTISZ_METADATA;
MyRecord.dwMDDataLen = dwBufLen;
MyRecord.pbMDData = (unsigned char *)pbBuffer;
hRes = (*pIMeta)->GetData(MyHandle, TEXT(""), &MyRecord, &dwReqBufLen);
if (SUCCEEDED(hRes)) {
TCHAR *szThisInstance = NULL;
jobjectArray ret = NULL;
int i;
// Start at -1 to account for the \0 at the end of the
// list.
int count = -1;
// Count # of objects in dwInstanceList
for (i = 0; i < MyRecord.dwMDDataLen; i+=2) {
if ((TCHAR)MyRecord.pbMDData[i] == '\0') {
count++;
}
}
ret = (jobjectArray)env->
NewObjectArray(count,
env->FindClass("java/lang/String"),
env->NewString((const jchar *)"", 1));
// Walk the return instance list, creating an array
for (szThisInstance = (TCHAR *)MyRecord.pbMDData, i = 0;
*szThisInstance != 0;
szThisInstance += lstrlen(szThisInstance) + 1, i++)
{
env->SetObjectArrayElement(ret,i,env->NewString(
(const jchar *)(LPCTSTR)szThisInstance,
lstrlen(szThisInstance)));
}
return ret;
}
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "No Such string value");
return NULL;
}
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */

View File

@ -0,0 +1,338 @@
#ifdef WIN32
#include <pdh.h>
#include <pdhmsg.h>
#include "win32bindings.h"
#include "javasigar.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Hack around not being able to format error codes using
* FORMAT_MESSAGE_FROM_HMODULE. We only define the error
* codes that could be possibly returned.
*/
static char *get_error_message(PDH_STATUS status) {
switch (status) {
case PDH_CSTATUS_NO_MACHINE:
return "The computer is unavailable";
case PDH_CSTATUS_NO_OBJECT:
return "The specified object could not be found on the computer";
case PDH_INVALID_ARGUMENT:
return "A required argument is invalid";
case PDH_MEMORY_ALLOCATION_FAILURE:
return "A required temporary buffer could not be allocated";
case PDH_INVALID_HANDLE:
return "The query handle is not valid";
case PDH_NO_DATA:
return "The query does not currently have any counters";
case PDH_CSTATUS_BAD_COUNTERNAME:
return "The counter name path string could not be parsed or "
"interpreted";
case PDH_CSTATUS_NO_COUNTER:
return "The specified counter was not found";
case PDH_CSTATUS_NO_COUNTERNAME:
return "An empty counter name path string was passed in";
case PDH_FUNCTION_NOT_FOUND:
return "The calculation function for this counter could not "
"be determined";
default:
return "Unknown error";
}
}
JNIEXPORT jlong JNICALL SIGAR_JNI(win32_Pdh_pdhOpenQuery)
(JNIEnv *env, jobject cur)
{
HQUERY h_query;
PDH_STATUS status;
status = PdhOpenQuery(NULL, 0, &h_query);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return 0;
}
return (jlong)h_query;
}
JNIEXPORT void SIGAR_JNI(win32_Pdh_pdhCloseQuery)
(JNIEnv *env, jclass cur, jlong query)
{
HQUERY h_query = (HQUERY)query;
PDH_STATUS status;
// Close the query and the log file.
status = PdhCloseQuery(h_query);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return;
}
}
JNIEXPORT jlong SIGAR_JNI(win32_Pdh_pdhAddCounter)
(JNIEnv *env, jclass cur, jlong query, jstring cp)
{
HCOUNTER h_counter;
HQUERY h_query = (HQUERY)query;
PDH_STATUS status;
LPCTSTR counter_path = JENV->GetStringUTFChars(env, cp, NULL);
/* Add the counter that created the data in the log file. */
status = PdhAddCounter(h_query, counter_path, 0, &h_counter);
JENV->ReleaseStringUTFChars(env, cp, counter_path);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return 0;
}
return (jlong)h_counter;
}
JNIEXPORT void SIGAR_JNI(win32_Pdh_pdhRemoveCounter)
(JNIEnv *env, jclass cur, jlong counter)
{
HCOUNTER h_counter = (HCOUNTER)counter;
PDH_STATUS status;
status = PdhRemoveCounter(h_counter);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return;
}
}
JNIEXPORT jdouble SIGAR_JNI(win32_Pdh_pdhGetSingleValue)
(JNIEnv *env, jclass cur, jlong query, jlong counter)
{
HCOUNTER h_counter = (HCOUNTER)counter;
HQUERY h_query = (HQUERY)query;
PDH_FMT_COUNTERVALUE pdh_value;
PDH_STATUS status;
status = PdhCollectQueryData(h_query);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return 0;
}
// Format the performance data record.
status = PdhGetFormattedCounterValue(h_counter,
PDH_FMT_DOUBLE,
(LPDWORD)NULL,
&pdh_value);
if (status != ERROR_SUCCESS) {
win32_throw_exception(env, get_error_message(status));
return 0;
}
return pdh_value.doubleValue;
}
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetInstances)
(JNIEnv *env, jclass cur, jstring cp)
{
PDH_STATUS status = ERROR_SUCCESS;
DWORD counter_list_size = 0;
DWORD instance_list_size = 8096;
LPTSTR instance_list_buf =
(LPTSTR)malloc ((instance_list_size * sizeof (TCHAR)));
LPTSTR cur_object = NULL;
LPCTSTR counter_path =
(LPCTSTR)JENV->GetStringUTFChars(env, cp, 0);
jobjectArray array = NULL;
status = PdhEnumObjectItems(NULL, NULL, counter_path, NULL,
&counter_list_size, instance_list_buf,
&instance_list_size, PERF_DETAIL_WIZARD,
FALSE);
if (status == PDH_MORE_DATA && instance_list_size > 0) {
// Allocate the buffers and try the call again.
if (instance_list_buf != NULL)
free(instance_list_buf);
instance_list_buf = (LPTSTR)malloc((instance_list_size *
sizeof (TCHAR)));
counter_list_size = 0;
status = PdhEnumObjectItems (NULL, NULL, counter_path,
NULL, &counter_list_size,
instance_list_buf,
&instance_list_size,
PERF_DETAIL_WIZARD, FALSE);
}
JENV->ReleaseStringUTFChars(env, cp, counter_path);
// Still may get PDH_ERROR_MORE data after the first reallocation,
// but that is OK for just browsing the instances
if (status == ERROR_SUCCESS || status == PDH_MORE_DATA) {
int i, count;
for (cur_object = instance_list_buf, count = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, count++);
array = JENV->NewObjectArray(env, count,
JENV->FindClass(env,
"java/lang/String"),
JENV->NewStringUTF(env, ""));
/* Walk the return instance list, creating an array */
for (cur_object = instance_list_buf, i = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, i++)
{
jstring s = JENV->NewStringUTF(env, cur_object);
JENV->SetObjectArrayElement(env, array, i, s);
}
} else {
if (instance_list_buf != NULL)
free(instance_list_buf);
// An error occured
win32_throw_exception(env, get_error_message(status));
return NULL;
}
if (instance_list_buf != NULL)
free(instance_list_buf);
return array;
}
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetKeys)
(JNIEnv *env, jclass cur, jstring cp)
{
PDH_STATUS status = ERROR_SUCCESS;
DWORD counter_list_size = 8096;
DWORD instance_list_size = 0;
LPTSTR instance_list_buf =
(LPTSTR)malloc (counter_list_size * sizeof(TCHAR));
LPTSTR cur_object = NULL;
LPCTSTR counter_path = JENV->GetStringUTFChars(env, cp, 0);
jobjectArray array = NULL;
status = PdhEnumObjectItems(NULL, NULL, counter_path,
instance_list_buf, &counter_list_size,
NULL, &instance_list_size,
PERF_DETAIL_WIZARD, FALSE);
if (status == PDH_MORE_DATA) {
/* Allocate the buffers and try the call again. */
if (instance_list_buf != NULL)
free(instance_list_buf);
instance_list_buf = (LPTSTR)malloc(counter_list_size *
sizeof(TCHAR));
instance_list_size = 0;
status = PdhEnumObjectItems (NULL, NULL, counter_path,
instance_list_buf,
&counter_list_size, NULL,
&instance_list_size,
PERF_DETAIL_WIZARD, 0);
}
JENV->ReleaseStringUTFChars(env, cp, counter_path);
if (status == ERROR_SUCCESS || status == PDH_MORE_DATA) {
int i, count;
for (cur_object = instance_list_buf, count = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, count++);
array = JENV->NewObjectArray(env, count,
JENV->FindClass(env,
"java/lang/String"),
JENV->NewStringUTF(env, ""));
/* Walk the return instance list, creating an array */
for (cur_object = instance_list_buf, i = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, i++)
{
jstring s = JENV->NewStringUTF(env, cur_object);
JENV->SetObjectArrayElement(env, array, i, s);
}
} else {
// An error occured
if (instance_list_buf != NULL)
free(instance_list_buf);
// An error occured
win32_throw_exception(env, get_error_message(status));
return NULL;
}
if (instance_list_buf != NULL)
free(instance_list_buf);
return array;
}
JNIEXPORT jobjectArray SIGAR_JNI(win32_Pdh_pdhGetObjects)
(JNIEnv *env, jclass cur)
{
PDH_STATUS status;
DWORD list_size = 8096;
LPTSTR list_buf = (LPTSTR)malloc(list_size * sizeof(TCHAR));
LPTSTR cur_object;
DWORD i, num_objects = 0;
jobjectArray array = NULL;
status = PdhEnumObjects(NULL, NULL, list_buf, &list_size,
PERF_DETAIL_WIZARD, FALSE);
if (status == PDH_MORE_DATA) {
// Re-try call with a larger buffer
if (list_buf != NULL)
free(list_buf);
list_buf = (LPTSTR)malloc(list_size * sizeof(TCHAR));
status = PdhEnumObjects(NULL, NULL, list_buf, &list_size,
PERF_DETAIL_WIZARD, FALSE);
}
if (status != ERROR_SUCCESS) {
if (list_buf != NULL)
free(list_buf);
win32_throw_exception(env, get_error_message(status));
return NULL;
}
// Walk the return buffer counting the number of objects
for (cur_object = list_buf, num_objects = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, num_objects++);
array = JENV->NewObjectArray(env, num_objects,
JENV->FindClass(env,
"java/lang/String"),
JENV->NewStringUTF(env, ""));
for (cur_object = list_buf, i = 0;
*cur_object != 0;
cur_object += lstrlen(cur_object) + 1, i++)
{
jstring s = JENV->NewStringUTF(env, cur_object);
JENV->SetObjectArrayElement(env, array, i, s);
}
if (list_buf != NULL)
free(list_buf);
return array;
}
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */

View File

@ -0,0 +1,274 @@
#ifdef WIN32
#define UNICODE
#define _UNICODE
#include <stdlib.h>
#include "win32bindings.h"
#include "javasigar.h"
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL SIGAR_JNI(win32_RegistryKey_RegCloseKey)
(JNIEnv *, jclass, jlong hkey)
{
return RegCloseKey((HKEY)hkey);
}
JNIEXPORT jlong JNICALL SIGAR_JNI(win32_RegistryKey_RegCreateKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
HKEY hkeyResult = NULL;
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
RegCreateKeyEx((HKEY)hkey, lpSubkey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS,
NULL, &hkeyResult, NULL);
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
return (jlong)hkeyResult;
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
LONG lResult = RegDeleteKey((HKEY)hkey, lpSubkey);
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
return lResult;
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegDeleteValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
LONG lResult = RegDeleteValue((HKEY)hkey, lpValueName);
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
return lResult;
}
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumKey)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
jstring strResult;
TCHAR szBuffer[MAX_PATH + 1];
if(RegEnumKey((HKEY)hkey, index, szBuffer,
sizeof(szBuffer)) == ERROR_SUCCESS)
strResult = env->NewString((const jchar *)szBuffer,
lstrlen(szBuffer));
else
strResult = NULL;
return strResult;
}
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegEnumValueName)
(JNIEnv *env, jclass, jlong hkey, jint index)
{
jstring strResult;
TCHAR szValueName[MAX_PATH + 1];
DWORD cbValueName = sizeof(szValueName);
if(RegEnumValue((HKEY)hkey, index, szValueName,
&cbValueName, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
strResult = env->NewString((const jchar *)szValueName,
lstrlen(szValueName));
else
strResult = NULL;
return strResult;
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegFlushKey)
(JNIEnv *env, jclass, long hkey)
{
return RegFlushKey((HKEY)hkey);
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegLoadKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey, jstring file)
{
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
LPCTSTR lpFile = (LPCTSTR)env->GetStringChars(file, NULL);
LONG lResult = RegLoadKey((HKEY)hkey, lpSubkey, lpFile);
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
env->ReleaseStringChars(file, (const jchar *)lpFile);
return lResult;
}
JNIEXPORT jlong SIGAR_JNI(win32_RegistryKey_RegOpenKey)
(JNIEnv *env, jclass, jlong hkey, jstring subkey)
{
HKEY hkeyResult = NULL;
LPCTSTR lpSubkey = (LPCTSTR)env->GetStringChars(subkey, NULL);
RegOpenKey((HKEY)hkey, lpSubkey, &hkeyResult);
env->ReleaseStringChars(subkey, (const jchar *)lpSubkey);
return (jlong)hkeyResult;
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegQueryIntValue)
(JNIEnv *env, jclass, jlong hkey, jstring valueName)
{
DWORD dwResult;
DWORD dwType;
LPBYTE lpValue;
DWORD cbValue;
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
LONG lErr = RegQueryValueEx((HKEY)hkey, lpValueName,
NULL, (LPDWORD)&dwType,
NULL, &cbValue);
if(lErr == ERROR_SUCCESS) {
lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, cbValue);
if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL,
NULL, lpValue, &cbValue) == ERROR_SUCCESS)
{
switch(dwType) {
case REG_DWORD:
dwResult = *(LPDWORD)lpValue;
break;
case REG_SZ:
dwResult = _ttol((LPCTSTR)lpValue);
break;
default:
lErr = ERROR_SUCCESS - 1; // Make an error
}
}
HeapFree(GetProcessHeap(), 0, lpValue);
}
else
// Make an error out of not seeing a REG_DWORD
lErr = ERROR_SUCCESS - 1;
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
if(lErr != ERROR_SUCCESS)
{
jclass cls =
env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, NULL);
}
return dwResult;
}
JNIEXPORT jstring SIGAR_JNI(win32_RegistryKey_RegQueryStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name)
{
jstring strResult;
DWORD dwType;
LPBYTE lpValue;
DWORD cbValue;
LPCTSTR lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
LONG lErr = RegQueryValueEx((HKEY)hkey,
lpValueName, NULL,
(LPDWORD)&dwType, NULL, &cbValue);
if(lErr == ERROR_SUCCESS)
{
lpValue = (LPBYTE)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, cbValue);
if(RegQueryValueEx((HKEY)hkey, lpValueName, NULL, NULL,
lpValue, &cbValue) == ERROR_SUCCESS)
{
switch(dwType) {
case REG_DWORD:
TCHAR szBuf[20];
_ltot(*(LPDWORD)lpValue, szBuf, 10);
strResult = env->NewString((const jchar *)szBuf,
lstrlen(szBuf));
break;
case REG_SZ:
case REG_EXPAND_SZ: {
DWORD len;
LPTSTR dest = NULL;
len = ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, 0);
dest = (LPTSTR)malloc(len * sizeof(TCHAR));
ExpandEnvironmentStrings((LPCTSTR)lpValue, dest, len);
strResult = env->NewString((const jchar *)dest, len);
free(dest);
break;
}
default:
lErr = ERROR_SUCCESS - 1; // Make an error
}
}
HeapFree(GetProcessHeap(), 0, lpValue);
}
env->ReleaseStringChars(name, (const jchar *)lpValueName);
if(lErr == ERROR_SUCCESS)
return strResult;
else
{
jclass cls = env->FindClass(WIN32_PACKAGE "Win32Exception");
env->ThrowNew(cls, "");
return NULL;
}
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetIntValue)
(JNIEnv * env, jclass, jlong hkey, jstring valueName, jint value)
{
LPCTSTR lpValueName;
if(valueName != NULL)
lpValueName = (LPCTSTR)env->GetStringChars(valueName, NULL);
else
lpValueName = NULL;
int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
REG_DWORD, (LPBYTE)&value, sizeof(value));
if(valueName != NULL)
env->ReleaseStringChars(valueName, (const jchar *)lpValueName);
return iResult;
}
JNIEXPORT jint SIGAR_JNI(win32_RegistryKey_RegSetStringValue)
(JNIEnv *env, jclass, jlong hkey, jstring name, jstring value)
{
LPCTSTR lpValueName;
if(name != NULL)
lpValueName = (LPCTSTR)env->GetStringChars(name, NULL);
else
lpValueName = NULL;
LPCTSTR lpValue = (LPCTSTR)env->GetStringChars(value, NULL);
int iResult = RegSetValueEx((HKEY)hkey, lpValueName, 0,
REG_SZ, (LPBYTE)lpValue,
(lstrlen(lpValue) + 1) * sizeof(TCHAR));
if(name != NULL)
env->ReleaseStringChars(name, (const jchar *)lpValueName);
env->ReleaseStringChars(value, (const jchar *)lpValue);
return iResult;
}
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */

View File

@ -0,0 +1,361 @@
#ifdef WIN32
#define UNICODE
#define _UNICODE
#include "win32bindings.h"
#include "javasigar.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* This code is stolen from misc/win32/misc.c and apr_private.h
* This helper code resolves late bound entry points
* missing from one or more releases of the Win32 API...
* This is covered under the Apache Software License
*
* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* Portions of this software are based upon public domain software
* originally written at the National Center for Supercomputing Applications,
* University of Illinois, Urbana-Champaign.
*/
typedef enum {
DLL_WINBASEAPI = 0, // kernel32 From WinBase.h
DLL_WINADVAPI = 1, // advapi32 From WinBase.h
DLL_WINSOCKAPI = 2, // mswsock From WinSock.h
DLL_WINSOCK2API = 3, // ws2_32 From WinSock2.h
DLL_SHSTDAPI = 4, // shell32 From ShellAPI.h
DLL_NTDLL = 5, // shell32 From our real kernel
DLL_defined = 6 // must define as last idx_ + 1
} dlltoken_e;
FARPROC load_dll_func(dlltoken_e fnLib, TCHAR* fnName, int ordinal);
#define DECLARE_LATE_DLL_FUNC(lib, rettype, calltype, fn, ord, args, names) \
typedef rettype (calltype *winapi_fpt_##fn) args; \
static winapi_fpt_##fn winapi_pfn_##fn = NULL; \
__inline rettype winapi_##fn args \
{ if (!winapi_pfn_##fn) \
winapi_pfn_##fn = (winapi_fpt_##fn) load_dll_func(lib, (wchar_t *)#fn, ord); \
return (*(winapi_pfn_##fn)) names; }; \
/* Win2K kernel only */
DECLARE_LATE_DLL_FUNC(DLL_WINADVAPI, BOOL, WINAPI,
ChangeServiceConfig2W, 0,
(SC_HANDLE hService,
DWORD dwInfoLevel,
LPVOID lpInfo),
(hService, dwInfoLevel, lpInfo));
#undef ChangeServiceConfig2
#define ChangeServiceConfig2 winapi_ChangeServiceConfig2W
/* End Apache licensed code */
static TCHAR* lateDllName[] = {
L"kernel32", L"advapi32", L"mswsock", L"ws2_32" };
static HMODULE lateDllHandle[] = {
NULL, NULL, NULL, NULL };
FARPROC load_dll_func(dlltoken_e fnLib, TCHAR* fnName, int ordinal)
{
if (!lateDllHandle[fnLib]) {
lateDllHandle[fnLib] = LoadLibrary(lateDllName[fnLib]);
if (!lateDllHandle[fnLib]) {
DWORD err = GetLastError();
fprintf(stderr, "GetLastError(): %d %s\r\n",
err, lateDllName[fnLib]);
return NULL;
}
}
if (ordinal)
return GetProcAddress(lateDllHandle[fnLib], (char *)ordinal);
else
return GetProcAddress(lateDllHandle[fnLib], (char *)fnName);
}
/*End ASF licensed code */
JNIEXPORT jboolean SIGAR_JNI(win32_Service_ChangeServiceDescription)
(JNIEnv *env, jclass, jlong handle, jstring description)
{
jboolean bResult = TRUE;
SERVICE_DESCRIPTION servdesc;
OSVERSIONINFO osver; /* VER_PLATFORM_WIN32_NT */
osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osver);
if ((osver.dwPlatformId == VER_PLATFORM_WIN32_NT)
&& (osver.dwMajorVersion > 4)
&& (ChangeServiceConfig2 != NULL)) {
servdesc.lpDescription = (LPTSTR)env->GetStringChars(description,
NULL);
bResult = ChangeServiceConfig2((SC_HANDLE)handle,
SERVICE_CONFIG_DESCRIPTION, &servdesc);
env->ReleaseStringChars(description,
(const jchar *)servdesc.lpDescription);
}
return bResult;
}
JNIEXPORT jboolean SIGAR_JNI(win32_Service_CloseServiceHandle)
(JNIEnv *, jclass, jlong handle)
{
return CloseServiceHandle((SC_HANDLE)handle);
}
JNIEXPORT jboolean SIGAR_JNI(win32_Service_ControlService)
(JNIEnv *, jclass, jlong handle, jint control)
{
SERVICE_STATUS status;
return ControlService((SC_HANDLE)handle, control, &status);
}
JNIEXPORT jlong SIGAR_JNI(win32_Service_CreateService)
(JNIEnv *env,
jclass,
jlong handle,
jstring serviceName,
jstring displayName,
jint serviceType,
jint startType,
jint errorControl,
jstring path,
jobjectArray dependencies,
jstring startName,
jstring password)
{
TCHAR szBuf[4048];
LPCTSTR lpDepend = NULL;
jlong lResult;
LPCTSTR lpStartName;
LPCTSTR lpServiceName = (LPCTSTR)env->GetStringChars(serviceName, NULL);
LPCTSTR lpDisplayName = (LPCTSTR)env->GetStringChars(displayName, NULL);
LPCTSTR lpPath = (LPCTSTR)env->GetStringChars(path, NULL);
LPCTSTR lpPassword = (LPCTSTR)env->GetStringChars(password, NULL);
if(startName != NULL)
lpStartName = (LPCTSTR)env->GetStringChars(path, NULL);
else
lpStartName = NULL;
if(dependencies != NULL)
{
// Build a buffer of a double null terminated array of
// null terminated service names
lpDepend = szBuf;
LPTSTR lpBuf = szBuf;
size_t cbLen = 0;
jsize cSize = env->GetArrayLength(dependencies);
for(int i = 0;i < cSize;i ++)
{
jstring str = (jstring)env->GetObjectArrayElement(dependencies, i);
LPCTSTR lpStr = (LPCTSTR)env->GetStringChars(str, NULL);
cbLen = lstrlen(lpStr);
// If we're going to overrun the buffer then break out of the loop
if((lpBuf + cbLen + 1) >= (szBuf + sizeof(szBuf) / sizeof(TCHAR)))
break;
lstrcpy(lpBuf, lpStr);
env->ReleaseStringChars(str, (const jchar *)lpStr);
// Move the buffer to the byte beyond the current string
// null terminator
lpBuf = lpBuf + cbLen + 1;
}
*lpBuf = 0; // Double null terminate the string
}
// Create the Service
lResult = (jlong)CreateService((SC_HANDLE)handle, lpServiceName,
lpDisplayName, SERVICE_ALL_ACCESS,
serviceType,
startType, errorControl, lpPath,
NULL, NULL, lpDepend, lpStartName,
lpPassword);
if(lpStartName != NULL)
env->ReleaseStringChars(path, (const jchar *)lpStartName);
env->ReleaseStringChars(password, (const jchar *)lpPassword);
env->ReleaseStringChars(path, (const jchar *)lpPath);
env->ReleaseStringChars(displayName, (const jchar *)lpDisplayName);
env->ReleaseStringChars(serviceName, (const jchar *)lpServiceName);
return lResult;
}
JNIEXPORT jboolean SIGAR_JNI(win32_Service_DeleteService)
(JNIEnv *env, jclass, jlong handle)
{
return DeleteService((SC_HANDLE)handle);
}
JNIEXPORT jstring SIGAR_JNI(win32_Service_GetErrorMessage)
(JNIEnv *env, jclass, jint error)
{
LPTSTR lpMsg;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_IGNORE_INSERTS|
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, error,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(LPTSTR)&lpMsg, 0, NULL);
return env->NewString((const jchar *)lpMsg, lstrlen(lpMsg));
}
/**
* XXX: this should probablly be moved into a util class
*/
JNIEXPORT jint SIGAR_JNI(win32_Service_GetLastError)
(JNIEnv *, jclass)
{
return GetLastError();
}
JNIEXPORT jlong SIGAR_JNI(win32_Service_OpenSCManager)
(JNIEnv *env, jclass, jstring machine, jint access)
{
jlong lResult;
LPCTSTR lpMachine = (LPCTSTR)env->GetStringChars(machine, NULL);
lResult = (jlong)OpenSCManager(lpMachine, NULL, access);
env->ReleaseStringChars(machine, (const jchar *)lpMachine);
return lResult;
}
JNIEXPORT jlong SIGAR_JNI(win32_Service_OpenService)
(JNIEnv *env,
jclass,
jlong handle,
jstring service,
jint access)
{
jlong lResult;
LPCTSTR lpService = (LPCTSTR)env->GetStringChars(service, NULL);
lResult = (jlong)OpenService((SC_HANDLE)handle,
lpService, access);
env->ReleaseStringChars(service, (const jchar *)lpService);
return lResult;
}
JNIEXPORT jint
SIGAR_JNI(win32_Service_QueryServiceStatus)
(JNIEnv *, jclass, jlong handle)
{
SERVICE_STATUS status;
int iResult;
if(QueryServiceStatus((SC_HANDLE)handle, &status) == TRUE) {
iResult = status.dwCurrentState;
} else
iResult = -1;
return iResult;
}
JNIEXPORT jint SIGAR_JNI(win32_Service_QueryServiceStartType)
(JNIEnv *, jclass, jlong handle)
{
LPQUERY_SERVICE_CONFIG config;
int iResult;
DWORD dwBytesNeeded;
config = (LPQUERY_SERVICE_CONFIG) LocalAlloc(LPTR, 4096);
if (config == NULL)
return -1;
/* Get the configuration information. */
if (QueryServiceConfig((SC_HANDLE)handle, config, 4096,
&dwBytesNeeded) == 0) {
iResult = -1;
}
else
iResult = config->dwStartType;
return iResult;
}
JNIEXPORT jboolean SIGAR_JNI(win32_Service_StartService)
(JNIEnv *, jclass, jlong handle)
{
return StartService((SC_HANDLE)handle, 0, NULL);
}
JNIEXPORT jboolean SIGAR_JNI(win32_Service_StopService)
(JNIEnv *, jclass, jlong handle)
{
SERVICE_STATUS status;
return ControlService((SC_HANDLE)handle, SERVICE_CONTROL_STOP, &status);
}
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */

View File

@ -0,0 +1,25 @@
#ifdef WIN32
#include <pdh.h>
#include <pdhmsg.h>
#include "win32bindings.h"
#include "javasigar.h"
/**
* Set of common utilities for all win32bindings objects
*/
#ifdef __cplusplus
extern "C" {
#endif
void win32_throw_exception(JNIEnv *env, char *msg)
{
jclass exceptionClass = WIN32_FIND_CLASS("Win32Exception");
JENV->ThrowNew(env, exceptionClass, msg);
}
#ifdef __cplusplus
}
#endif
#endif /* WIN32 */

View File

@ -0,0 +1,28 @@
#ifndef WIN32_BINDINGS_H
#define WIN32_BINDINGS_H
/* Exclude rarely-used stuff from windows headers */
#define WIN32_LEAN_AND_MEAN
/* Windows Header Files */
#include <windows.h>
#include <tchar.h>
/* Include java jni headers */
#include <jni.h>
#define WIN32_PACKAGE "net/covalent/win32bindings/"
#define WIN32_FIND_CLASS(name) \
JENV->FindClass(env, WIN32_PACKAGE name)
#define WIN32_ALLOC_OBJECT(name) \
JENV->AllocObject(env, WIN32_FIND_CLASS(name))
#define SetStringField(env, obj, fieldID, val) \
JENV->SetObjectField(env, obj, fieldID, JENV->NewStringUTF(env, val))
void win32_throw_exception(JNIEnv *env, char *msg);
#endif

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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");
}
}
}

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -0,0 +1,10 @@
package net.hyperic.sigar.win32;
import net.hyperic.sigar.Sigar;
abstract class Win32Bindings {
static {
new Sigar(); //XXX Sigar.load()
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}

View File

@ -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 {
}
}

View File

@ -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);
}
}

View File

@ -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");
}
}

View File

@ -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();
}
}