ext/winevt/winevt_subscribe.c in winevt_c-0.8.1 vs ext/winevt/winevt_subscribe.c in winevt_c-0.9.0

- old
+ new

@@ -55,10 +55,13 @@ if (winevtSubscribe->hEvents[i]) { EvtClose(winevtSubscribe->hEvents[i]); } } + if (winevtSubscribe->remoteHandle) + EvtClose(winevtSubscribe->remoteHandle); + xfree(ptr); } static VALUE rb_winevt_subscribe_alloc(VALUE klass) @@ -130,35 +133,39 @@ } /* * Subscribe into a Windows EventLog channel. * - * @overload subscribe(path, query, options={}) + * @overload subscribe(path, query, bookmark=nil, session=nil) * @param path [String] Subscribe Channel * @param query [String] Query string for channel - * @option options [Bookmark] bookmark Bookmark class instance. + * @param bookmark [Bookmark] bookmark Bookmark class instance. + * @param session [Session] Session information for remoting access. * @return [Boolean] * */ static VALUE rb_winevt_subscribe_subscribe(int argc, VALUE* argv, VALUE self) { - VALUE rb_path, rb_query, rb_bookmark; + VALUE rb_path, rb_query, rb_bookmark, rb_session; EVT_HANDLE hSubscription = NULL, hBookmark = NULL; HANDLE hSignalEvent; + EVT_HANDLE hRemoteHandle = NULL; DWORD len, flags = 0L; + DWORD err = ERROR_SUCCESS; VALUE wpathBuf, wqueryBuf, wBookmarkBuf; PWSTR path, query, bookmarkXml; DWORD status = ERROR_SUCCESS; + struct WinevtSession* winevtSession; struct WinevtSubscribe* winevtSubscribe; hSignalEvent = CreateEvent(NULL, FALSE, FALSE, NULL); TypedData_Get_Struct( self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe); - rb_scan_args(argc, argv, "21", &rb_path, &rb_query, &rb_bookmark); + rb_scan_args(argc, argv, "22", &rb_path, &rb_query, &rb_bookmark, &rb_session); Check_Type(rb_path, T_STRING); Check_Type(rb_query, T_STRING); if (rb_obj_is_kind_of(rb_bookmark, rb_cString)) { // bookmarkXml : To wide char @@ -177,11 +184,24 @@ if (hBookmark == NULL) { status = GetLastError(); raise_system_error(rb_eWinevtQueryError, status); } } + if (rb_obj_is_kind_of(rb_session, rb_cSession)) { + winevtSession = EventSession(rb_session); + hRemoteHandle = connect_to_remote(winevtSession->server, + winevtSession->domain, + winevtSession->username, + winevtSession->password, + winevtSession->flags); + err = GetLastError(); + if (err != ERROR_SUCCESS) { + raise_system_error(rb_eRuntimeError, err); + } + } + // path : To wide char len = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), NULL, 0); path = ALLOCV_N(WCHAR, wpathBuf, len + 1); MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(rb_path), RSTRING_LEN(rb_path), path, len); @@ -202,20 +222,24 @@ } else { flags |= EvtSubscribeToFutureEvents; } hSubscription = - EvtSubscribe(NULL, hSignalEvent, path, query, hBookmark, NULL, NULL, flags); + EvtSubscribe(hRemoteHandle, hSignalEvent, path, query, hBookmark, NULL, NULL, flags); if (!hSubscription) { if (hBookmark != NULL) { EvtClose(hBookmark); } if (hSignalEvent != NULL) { CloseHandle(hSignalEvent); } status = GetLastError(); - raise_system_error(rb_eWinevtQueryError, status); + if (rb_obj_is_kind_of(rb_session, rb_cSession)) { + rb_raise(rb_eRemoteHandlerError, "Remoting subscription is not working. errCode: %ld\n", status); + } else { + raise_system_error(rb_eWinevtQueryError, status); + } } if (winevtSubscribe->subscription != NULL) { // should be disgarded the old event subscription handle. EvtClose(winevtSubscribe->subscription); @@ -224,10 +248,11 @@ ALLOCV_END(wpathBuf); ALLOCV_END(wqueryBuf); winevtSubscribe->signalEvent = hSignalEvent; winevtSubscribe->subscription = hSubscription; + winevtSubscribe->remoteHandle = hRemoteHandle; if (hBookmark) { winevtSubscribe->bookmark = hBookmark; } else { winevtSubscribe->bookmark = EvtCreateBookmark(NULL); if (winevtSubscribe->bookmark == NULL) { @@ -344,16 +369,16 @@ return render_system_event(event, winevtSubscribe->preserveQualifiers); } } static VALUE -rb_winevt_subscribe_message(EVT_HANDLE event, LocaleInfo* localeInfo) +rb_winevt_subscribe_message(EVT_HANDLE event, LocaleInfo* localeInfo, EVT_HANDLE hRemote) { WCHAR* wResult; VALUE utf8str; - wResult = get_description(event, localeInfo->langID); + wResult = get_description(event, localeInfo->langID, hRemote); utf8str = wstr_to_rb_str(CP_UTF8, wResult, -1); free(wResult); return utf8str; } @@ -392,11 +417,12 @@ self, struct WinevtSubscribe, &rb_winevt_subscribe_type, winevtSubscribe); for (int i = 0; i < winevtSubscribe->count; i++) { rb_yield_values(3, rb_winevt_subscribe_render(self, winevtSubscribe->hEvents[i]), - rb_winevt_subscribe_message(winevtSubscribe->hEvents[i], winevtSubscribe->localeInfo), + rb_winevt_subscribe_message(winevtSubscribe->hEvents[i], winevtSubscribe->localeInfo, + winevtSubscribe->remoteHandle), rb_winevt_subscribe_string_inserts(winevtSubscribe->hEvents[i])); } return Qnil; } @@ -521,10 +547,10 @@ /* * This method specifies whether preserving qualifiers key or not. * * @since 0.7.3 - * @param rb_render_as_xml [Boolean] + * @param rb_preserve_qualifiers [Boolean] */ static VALUE rb_winevt_subscribe_set_preserve_qualifiers(VALUE self, VALUE rb_preserve_qualifiers) { struct WinevtSubscribe* winevtSubscribe;