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

📄 ndis_events.c

📁 WLAN无线网络管理的最新程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	_snwprintf(query, 256,		  L"SELECT * FROM %S", class_name);	wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query);	hr = call_IWbemServices_ExecNotificationQueryAsync(		pSvc, L"WQL", query, 0, 0, pDestSink);	if (FAILED(hr)) {		wpa_printf(MSG_DEBUG, "ExecNotificationQueryAsync for %s "			   "failed with hresult of 0x%x",			   class_name, (int) hr);		return -1;	}	return 0;}static int register_async_notification(IWbemObjectSink *pDestSink,				       IWbemServices *pSvc){	int i;	const char *class_list[] = {		"MSNdis_StatusMediaConnect",		"MSNdis_StatusMediaDisconnect",		"MSNdis_StatusMediaSpecificIndication",		"MSNdis_NotifyAdapterArrival",		"MSNdis_NotifyAdapterRemoval",		NULL	};	for (i = 0; class_list[i]; i++) {		if (notification_query(pDestSink, pSvc, class_list[i]) < 0)			return -1;	}	return 0;}void ndis_events_deinit(struct ndis_events_data *events){	events->terminating = 1;	IWbemServices_CancelAsyncCall(events->pSvc, &events->sink);	IWbemObjectSink_Release(&events->sink);	/*	 * Rest of deinitialization is done in ndis_events_destructor() once	 * all reference count drops to zero.	 */}static int ndis_events_use_desc(struct ndis_events_data *events,				const char *desc){	char *tmp, *pos;	size_t len;	if (desc == NULL) {		if (events->adapter_desc == NULL)			return -1;		/* Continue using old description */		return 0;	}	tmp = os_strdup(desc);	if (tmp == NULL)		return -1;	pos = os_strstr(tmp, " (Microsoft's Packet Scheduler)");	if (pos)		*pos = '\0';	len = os_strlen(tmp);	events->adapter_desc = os_malloc((len + 1) * sizeof(WCHAR));	if (events->adapter_desc == NULL) {		os_free(tmp);		return -1;	}	_snwprintf(events->adapter_desc, len + 1, L"%S", tmp);	os_free(tmp);	return 0;}static int ndis_events_get_adapter(struct ndis_events_data *events,				   const char *ifname, const char *desc){	HRESULT hr;	IWbemServices *pSvc;#define MAX_QUERY_LEN 256	WCHAR query[MAX_QUERY_LEN];	IEnumWbemClassObject *pEnumerator;	IWbemClassObject *pObj;	ULONG uReturned;	VARIANT vt;	int len, pos;	/*	 * Try to get adapter descriptor through WMI CIMv2 Win32_NetworkAdapter	 * to have better probability of matching with InstanceName from	 * MSNdis events. If this fails, use the provided description.	 */	os_free(events->adapter_desc);	events->adapter_desc = NULL;	hr = call_IWbemLocator_ConnectServer(		events->pLoc, L"ROOT\\CIMV2", NULL, NULL, 0, 0, 0, 0, &pSvc);	if (FAILED(hr)) {		wpa_printf(MSG_ERROR, "ndis_events: Could not connect to WMI "			   "server (ROOT\\CIMV2) - error 0x%x", (int) hr);		return ndis_events_use_desc(events, desc);	}	wpa_printf(MSG_DEBUG, "ndis_events: Connected to ROOT\\CIMV2.");	_snwprintf(query, MAX_QUERY_LEN,		  L"SELECT Index FROM Win32_NetworkAdapterConfiguration "		  L"WHERE SettingID='%S'", ifname);	wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query);	hr = call_IWbemServices_ExecQuery(		pSvc, L"WQL", query,		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,		NULL, &pEnumerator);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface "			   "GUID from Win32_NetworkAdapterConfiguration: "			   "0x%x", (int) hr);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	uReturned = 0;	hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1,				       &pObj, &uReturned);	if (!SUCCEEDED(hr) || uReturned == 0) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface "			   "GUID from Win32_NetworkAdapterConfiguration: "			   "0x%x", (int) hr);		IEnumWbemClassObject_Release(pEnumerator);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	IEnumWbemClassObject_Release(pEnumerator);	VariantInit(&vt);	hr = IWbemClassObject_Get(pObj, L"Index", 0, &vt, NULL, NULL);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Index from "			   "Win32_NetworkAdapterConfiguration: 0x%x",			   (int) hr);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	_snwprintf(query, MAX_QUERY_LEN,		  L"SELECT Name,PNPDeviceID FROM Win32_NetworkAdapter WHERE "		  L"Index=%d",		  vt.uintVal);	wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query);	VariantClear(&vt);	IWbemClassObject_Release(pObj);	hr = call_IWbemServices_ExecQuery(		pSvc, L"WQL", query,		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,		NULL, &pEnumerator);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface "			   "from Win32_NetworkAdapter: 0x%x", (int) hr);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	uReturned = 0;	hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1,				       &pObj, &uReturned);	if (!SUCCEEDED(hr) || uReturned == 0) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface "			   "from Win32_NetworkAdapter: 0x%x", (int) hr);		IEnumWbemClassObject_Release(pEnumerator);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	IEnumWbemClassObject_Release(pEnumerator);	hr = IWbemClassObject_Get(pObj, L"Name", 0, &vt, NULL, NULL);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Name from "			   "Win32_NetworkAdapter: 0x%x", (int) hr);		IWbemClassObject_Release(pObj);		IWbemServices_Release(pSvc);		return ndis_events_use_desc(events, desc);	}	wpa_printf(MSG_DEBUG, "ndis_events: Win32_NetworkAdapter::Name='%S'",		   vt.bstrVal);	events->adapter_desc = _wcsdup(vt.bstrVal);	VariantClear(&vt);	/*	 * Try to get even better candidate for matching with InstanceName	 * from Win32_PnPEntity. This is needed at least for some USB cards	 * that can change the InstanceName whenever being unplugged and	 * plugged again.	 */	hr = IWbemClassObject_Get(pObj, L"PNPDeviceID", 0, &vt, NULL, NULL);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to get PNPDeviceID "			   "from Win32_NetworkAdapter: 0x%x", (int) hr);		IWbemClassObject_Release(pObj);		IWbemServices_Release(pSvc);		if (events->adapter_desc == NULL)			return ndis_events_use_desc(events, desc);		return 0; /* use Win32_NetworkAdapter::Name */	}	wpa_printf(MSG_DEBUG, "ndis_events: Win32_NetworkAdapter::PNPDeviceID="		   "'%S'", vt.bstrVal);	len = _snwprintf(query, MAX_QUERY_LEN,			L"SELECT Name FROM Win32_PnPEntity WHERE DeviceID='");	if (len < 0 || len >= MAX_QUERY_LEN - 1) {		VariantClear(&vt);		IWbemClassObject_Release(pObj);		IWbemServices_Release(pSvc);		if (events->adapter_desc == NULL)			return ndis_events_use_desc(events, desc);		return 0; /* use Win32_NetworkAdapter::Name */	}	/* Escape \ as \\ */	for (pos = 0; vt.bstrVal[pos] && len < MAX_QUERY_LEN - 2; pos++) {		if (vt.bstrVal[pos] == '\\') {			if (len >= MAX_QUERY_LEN - 3)				break;			query[len++] = '\\';		}		query[len++] = vt.bstrVal[pos];	}	query[len++] = L'\'';	query[len] = L'\0';	VariantClear(&vt);	IWbemClassObject_Release(pObj);	wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query);	hr = call_IWbemServices_ExecQuery(		pSvc, L"WQL", query,		WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,		NULL, &pEnumerator);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface "			   "Name from Win32_PnPEntity: 0x%x", (int) hr);		IWbemServices_Release(pSvc);		if (events->adapter_desc == NULL)			return ndis_events_use_desc(events, desc);		return 0; /* use Win32_NetworkAdapter::Name */	}	uReturned = 0;	hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1,				       &pObj, &uReturned);	if (!SUCCEEDED(hr) || uReturned == 0) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface "			   "from Win32_PnPEntity: 0x%x", (int) hr);		IEnumWbemClassObject_Release(pEnumerator);		IWbemServices_Release(pSvc);		if (events->adapter_desc == NULL)			return ndis_events_use_desc(events, desc);		return 0; /* use Win32_NetworkAdapter::Name */	}	IEnumWbemClassObject_Release(pEnumerator);	hr = IWbemClassObject_Get(pObj, L"Name", 0, &vt, NULL, NULL);	if (!SUCCEEDED(hr)) {		wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Name from "			   "Win32_PnPEntity: 0x%x", (int) hr);		IWbemClassObject_Release(pObj);		IWbemServices_Release(pSvc);		if (events->adapter_desc == NULL)			return ndis_events_use_desc(events, desc);		return 0; /* use Win32_NetworkAdapter::Name */	}	wpa_printf(MSG_DEBUG, "ndis_events: Win32_PnPEntity::Name='%S'",		   vt.bstrVal);	os_free(events->adapter_desc);	events->adapter_desc = _wcsdup(vt.bstrVal);	VariantClear(&vt);	IWbemClassObject_Release(pObj);	IWbemServices_Release(pSvc);	if (events->adapter_desc == NULL)		return ndis_events_use_desc(events, desc);	return 0;}struct ndis_events_data *ndis_events_init(HANDLE *read_pipe, HANDLE *event_avail,		 const char *ifname, const char *desc){	HRESULT hr;	IWbemObjectSink *pSink;	struct ndis_events_data *events;	events = os_zalloc(sizeof(*events));	if (events == NULL) {		wpa_printf(MSG_ERROR, "Could not allocate sink for events.");		return NULL;	}	events->ifname = os_strdup(ifname);	if (events->ifname == NULL) {		os_free(events);		return NULL;	}	if (wmi_refcnt++ == 0) {		hr = CoInitializeEx(0, COINIT_MULTITHREADED);		if (FAILED(hr)) {			wpa_printf(MSG_ERROR, "CoInitializeEx() failed - "				   "returned 0x%x", (int) hr);			os_free(events);			return NULL;		}	}	if (wmi_first) {		/* CoInitializeSecurity() must be called once and only once		 * per process, so let's use wmi_first flag to protect against		 * multiple calls. */		wmi_first = 0;		hr = CoInitializeSecurity(NULL, -1, NULL, NULL,					  RPC_C_AUTHN_LEVEL_PKT_PRIVACY,					  RPC_C_IMP_LEVEL_IMPERSONATE,					  NULL, EOAC_SECURE_REFS, NULL);		if (FAILED(hr)) {			wpa_printf(MSG_ERROR, "CoInitializeSecurity() failed "				   "- returned 0x%x", (int) hr);			os_free(events);			return NULL;		}	}	hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,			      &IID_IWbemLocator, (LPVOID *) &events->pLoc);	if (FAILED(hr)) {		wpa_printf(MSG_ERROR, "CoCreateInstance() failed - returned "			   "0x%x", (int) hr);		CoUninitialize();		os_free(events);		return NULL;	}	if (ndis_events_get_adapter(events, ifname, desc) < 0) {		CoUninitialize();		os_free(events);		return NULL;	}	wpa_printf(MSG_DEBUG, "ndis_events: use adapter descriptor '%S'",		   events->adapter_desc);	hr = call_IWbemLocator_ConnectServer(		events->pLoc, L"ROOT\\WMI", NULL, NULL,		0, 0, 0, 0, &events->pSvc);	if (FAILED(hr)) {		wpa_printf(MSG_ERROR, "Could not connect to server - error "			   "0x%x", (int) hr);		CoUninitialize();		os_free(events->adapter_desc);		os_free(events);		return NULL;	}	wpa_printf(MSG_DEBUG, "Connected to ROOT\\WMI.");	ndis_events_constructor(events);	pSink = &events->sink;	pSink->lpVtbl = &events->sink_vtbl;	events->sink_vtbl.QueryInterface = ndis_events_query_interface;	events->sink_vtbl.AddRef = ndis_events_add_ref;	events->sink_vtbl.Release = ndis_events_release;	events->sink_vtbl.Indicate = ndis_events_indicate;	events->sink_vtbl.SetStatus = ndis_events_set_status;	if (register_async_notification(pSink, events->pSvc) < 0) {		wpa_printf(MSG_DEBUG, "Failed to register async "			   "notifications");		ndis_events_destructor(events);		os_free(events->adapter_desc);		os_free(events);		return NULL;	}	*read_pipe = events->read_pipe;	*event_avail = events->event_avail;	return events;}

⌨️ 快捷键说明

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