⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndis_events.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ndis_events - Receive NdisMIndicateStatus() events using WMI * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Alternatively, this software may be distributed under the terms of BSD * license. * * See README and COPYING for more details. */#define _WIN32_WINNT    0x0400#include "includes.h"#ifndef COBJMACROS#define COBJMACROS#endif /* COBJMACROS */#include <wbemidl.h>#include "common.h"static int wmi_refcnt = 0;static int wmi_first = 1;struct ndis_events_data {	IWbemObjectSink sink;	IWbemObjectSinkVtbl sink_vtbl;	IWbemServices *pSvc;	IWbemLocator *pLoc;	HANDLE read_pipe, write_pipe, event_avail;	UINT ref;	int terminating;	char *ifname; /* {GUID..} */	WCHAR *adapter_desc;};#define BstrAlloc(x) (x) ? SysAllocString(x) : NULL#define BstrFree(x) if (x) SysFreeString(x)/* WBEM / WMI wrapper functions, to perform in-place conversion of WCHARs to * BSTRs */HRESULT STDMETHODCALLTYPE call_IWbemServices_ExecQuery(	IWbemServices *pSvc, LPCWSTR strQueryLanguage, LPCWSTR strQuery,	long lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum){	BSTR bsQueryLanguage, bsQuery;	HRESULT hr;	bsQueryLanguage = BstrAlloc(strQueryLanguage);	bsQuery = BstrAlloc(strQuery);	hr = IWbemServices_ExecQuery(pSvc, bsQueryLanguage, bsQuery, lFlags,				     pCtx, ppEnum);	BstrFree(bsQueryLanguage);	BstrFree(bsQuery);	return hr;}HRESULT STDMETHODCALLTYPE call_IWbemServices_ExecNotificationQueryAsync(	IWbemServices *pSvc, LPCWSTR strQueryLanguage, LPCWSTR strQuery,	long lFlags, IWbemContext *pCtx, IWbemObjectSink *pResponseHandler){	BSTR bsQueryLanguage, bsQuery;	HRESULT hr;	bsQueryLanguage = BstrAlloc(strQueryLanguage);	bsQuery = BstrAlloc(strQuery);	hr = IWbemServices_ExecNotificationQueryAsync(pSvc, bsQueryLanguage,						      bsQuery, lFlags, pCtx,						      pResponseHandler);	BstrFree(bsQueryLanguage);	BstrFree(bsQuery);	return hr;}HRESULT STDMETHODCALLTYPE call_IWbemLocator_ConnectServer(	IWbemLocator *pLoc, LPCWSTR strNetworkResource, LPCWSTR strUser,	LPCWSTR strPassword, LPCWSTR strLocale, long lSecurityFlags,	LPCWSTR strAuthority, IWbemContext *pCtx, IWbemServices **ppNamespace){	BSTR bsNetworkResource, bsUser, bsPassword, bsLocale, bsAuthority;	HRESULT hr;	bsNetworkResource = BstrAlloc(strNetworkResource);	bsUser = BstrAlloc(strUser);	bsPassword = BstrAlloc(strPassword);	bsLocale = BstrAlloc(strLocale);	bsAuthority = BstrAlloc(strAuthority);	hr = IWbemLocator_ConnectServer(pLoc, bsNetworkResource, bsUser,					bsPassword, bsLocale, lSecurityFlags,					bsAuthority, pCtx, ppNamespace);	BstrFree(bsNetworkResource);	BstrFree(bsUser);	BstrFree(bsPassword);	BstrFree(bsLocale);	BstrFree(bsAuthority);	return hr;}enum event_types { EVENT_CONNECT, EVENT_DISCONNECT, EVENT_MEDIA_SPECIFIC,		   EVENT_ADAPTER_ARRIVAL, EVENT_ADAPTER_REMOVAL };static int ndis_events_get_adapter(struct ndis_events_data *events,				   const char *ifname, const char *desc);static int ndis_events_constructor(struct ndis_events_data *events){	events->ref = 1;	if (!CreatePipe(&events->read_pipe, &events->write_pipe, NULL, 512)) {		wpa_printf(MSG_ERROR, "CreatePipe() failed: %d",			   (int) GetLastError());		return -1;	}	events->event_avail = CreateEvent(NULL, TRUE, FALSE, NULL);	if (events->event_avail == NULL) {		wpa_printf(MSG_ERROR, "CreateEvent() failed: %d",			   (int) GetLastError());		CloseHandle(events->read_pipe);		CloseHandle(events->write_pipe);		return -1;	}	return 0;}static void ndis_events_destructor(struct ndis_events_data *events){	CloseHandle(events->read_pipe);	CloseHandle(events->write_pipe);	CloseHandle(events->event_avail);	IWbemServices_Release(events->pSvc);	IWbemLocator_Release(events->pLoc);	if (--wmi_refcnt == 0)		CoUninitialize();}static HRESULT STDMETHODCALLTYPEndis_events_query_interface(IWbemObjectSink *this, REFIID riid, void **obj){	*obj = NULL;	if (IsEqualIID(riid, &IID_IUnknown) ||	    IsEqualIID(riid, &IID_IWbemObjectSink)) {		*obj = this;		IWbemObjectSink_AddRef(this);		return NOERROR;	}	return E_NOINTERFACE;}static ULONG STDMETHODCALLTYPE ndis_events_add_ref(IWbemObjectSink *this){	struct ndis_events_data *events = (struct ndis_events_data *) this;	return ++events->ref;}static ULONG STDMETHODCALLTYPE ndis_events_release(IWbemObjectSink *this){	struct ndis_events_data *events = (struct ndis_events_data *) this;	if (--events->ref != 0)		return events->ref;	ndis_events_destructor(events);	wpa_printf(MSG_DEBUG, "ndis_events: terminated");	os_free(events->adapter_desc);	os_free(events->ifname);	os_free(events);	return 0;}static int ndis_events_send_event(struct ndis_events_data *events,				  enum event_types type,				  char *data, size_t data_len){	char buf[512], *pos, *end;	int _type;	DWORD written;	end = buf + sizeof(buf);	_type = (int) type;	os_memcpy(buf, &_type, sizeof(_type));	pos = buf + sizeof(_type);	if (data) {		if (2 + data_len > (size_t) (end - pos)) {			wpa_printf(MSG_DEBUG, "Not enough room for send_event "				   "data (%d)", data_len);			return -1;		}		*pos++ = data_len >> 8;		*pos++ = data_len & 0xff;		os_memcpy(pos, data, data_len);		pos += data_len;	}	if (WriteFile(events->write_pipe, buf, pos - buf, &written, NULL)) {		SetEvent(events->event_avail);		return 0;	}	wpa_printf(MSG_INFO, "WriteFile() failed: %d", (int) GetLastError());	return -1;}static void ndis_events_media_connect(struct ndis_events_data *events){	wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaConnect");	ndis_events_send_event(events, EVENT_CONNECT, NULL, 0);}static void ndis_events_media_disconnect(struct ndis_events_data *events){	wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaDisconnect");	ndis_events_send_event(events, EVENT_DISCONNECT, NULL, 0);}static void ndis_events_media_specific(struct ndis_events_data *events,				       IWbemClassObject *pObj){	VARIANT vt;	HRESULT hr;	LONG lower, upper, k;	UCHAR ch;	char *data, *pos;	size_t data_len;	wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaSpecificIndication");	/* This is the StatusBuffer from NdisMIndicateStatus() call */	hr = IWbemClassObject_Get(pObj, L"NdisStatusMediaSpecificIndication",				  0, &vt, NULL, NULL);	if (FAILED(hr)) {		wpa_printf(MSG_DEBUG, "Could not get "			   "NdisStatusMediaSpecificIndication from "			   "the object?!");		return;	}	SafeArrayGetLBound(V_ARRAY(&vt), 1, &lower);	SafeArrayGetUBound(V_ARRAY(&vt), 1, &upper);	data_len = upper - lower + 1;	data = os_malloc(data_len);	if (data == NULL) {		wpa_printf(MSG_DEBUG, "Failed to allocate buffer for event "			   "data");		VariantClear(&vt);		return;	}	pos = data;	for (k = lower; k <= upper; k++) {		SafeArrayGetElement(V_ARRAY(&vt), &k, &ch);		*pos++ = ch;	}	wpa_hexdump(MSG_DEBUG, "MediaSpecificEvent", data, data_len);	VariantClear(&vt);	ndis_events_send_event(events, EVENT_MEDIA_SPECIFIC, data, data_len);	os_free(data);}static void ndis_events_adapter_arrival(struct ndis_events_data *events){	wpa_printf(MSG_DEBUG, "MSNdis_NotifyAdapterArrival");	ndis_events_send_event(events, EVENT_ADAPTER_ARRIVAL, NULL, 0);}static void ndis_events_adapter_removal(struct ndis_events_data *events){	wpa_printf(MSG_DEBUG, "MSNdis_NotifyAdapterRemoval");	ndis_events_send_event(events, EVENT_ADAPTER_REMOVAL, NULL, 0);}static HRESULT STDMETHODCALLTYPEndis_events_indicate(IWbemObjectSink *this, long lObjectCount,		     IWbemClassObject __RPC_FAR *__RPC_FAR *ppObjArray){	struct ndis_events_data *events = (struct ndis_events_data *) this;	long i;	if (events->terminating) {		wpa_printf(MSG_DEBUG, "ndis_events_indicate: Ignore "			   "indication - terminating");		return WBEM_NO_ERROR;	}	/* wpa_printf(MSG_DEBUG, "Notification received - %d object(s)",	   lObjectCount); */	for (i = 0; i < lObjectCount; i++) {		IWbemClassObject *pObj = ppObjArray[i];		HRESULT hr;		VARIANT vtClass, vt;		hr = IWbemClassObject_Get(pObj, L"__CLASS", 0, &vtClass, NULL,					  NULL);		if (FAILED(hr)) {			wpa_printf(MSG_DEBUG, "Failed to get __CLASS from "				   "event.");			break;		}		/* wpa_printf(MSG_DEBUG, "CLASS: '%S'", vtClass.bstrVal); */		hr = IWbemClassObject_Get(pObj, L"InstanceName", 0, &vt, NULL,					  NULL);		if (FAILED(hr)) {			wpa_printf(MSG_DEBUG, "Failed to get InstanceName "				   "from event.");			VariantClear(&vtClass);			break;		}		if (wcscmp(vtClass.bstrVal,			   L"MSNdis_NotifyAdapterArrival") == 0) {			wpa_printf(MSG_DEBUG, "ndis_events_indicate: Try to "				   "update adapter description since it may "				   "have changed with new adapter instance");			ndis_events_get_adapter(events, events->ifname, NULL);		}		if (wcscmp(events->adapter_desc, vt.bstrVal) != 0) {			wpa_printf(MSG_DEBUG, "ndis_events_indicate: Ignore "				   "indication for foreign adapter: "				   "InstanceName: '%S' __CLASS: '%S'",				   vt.bstrVal, vtClass.bstrVal);			VariantClear(&vtClass);			VariantClear(&vt);			continue;		}		VariantClear(&vt);		if (wcscmp(vtClass.bstrVal,			   L"MSNdis_StatusMediaSpecificIndication") == 0) {			ndis_events_media_specific(events, pObj);		} else if (wcscmp(vtClass.bstrVal,				  L"MSNdis_StatusMediaConnect") == 0) {			ndis_events_media_connect(events);		} else if (wcscmp(vtClass.bstrVal,				  L"MSNdis_StatusMediaDisconnect") == 0) {			ndis_events_media_disconnect(events);		} else if (wcscmp(vtClass.bstrVal,				  L"MSNdis_NotifyAdapterArrival") == 0) {			ndis_events_adapter_arrival(events);		} else if (wcscmp(vtClass.bstrVal,				  L"MSNdis_NotifyAdapterRemoval") == 0) {			ndis_events_adapter_removal(events);		} else {			wpa_printf(MSG_DEBUG, "Unepected event - __CLASS: "				   "'%S'", vtClass.bstrVal);		}		VariantClear(&vtClass);	}	return WBEM_NO_ERROR;}static HRESULT STDMETHODCALLTYPEndis_events_set_status(IWbemObjectSink *this, long lFlags, HRESULT hResult,		       BSTR strParam, IWbemClassObject __RPC_FAR *pObjParam){	return WBEM_NO_ERROR;}static int notification_query(IWbemObjectSink *pDestSink,			      IWbemServices *pSvc, const char *class_name){	HRESULT hr;	WCHAR query[256];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -