1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * ndis_events - Receive NdisMIndicateStatus() events using WMI 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi> 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define _WIN32_WINNT 0x0400 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifndef COBJMACROS 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define COBJMACROS 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* COBJMACROS */ 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include <wbemidl.h> 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wmi_refcnt = 0; 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int wmi_first = 1; 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ndis_events_data { 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemObjectSink sink; 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemObjectSinkVtbl sink_vtbl; 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc; 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemLocator *pLoc; 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HANDLE read_pipe, write_pipe, event_avail; 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt UINT ref; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int terminating; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *ifname; /* {GUID..} */ 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WCHAR *adapter_desc; 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define BstrAlloc(x) (x) ? SysAllocString(x) : NULL 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define BstrFree(x) if (x) SysFreeString(x) 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* WBEM / WMI wrapper functions, to perform in-place conversion of WCHARs to 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * BSTRs */ 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtHRESULT STDMETHODCALLTYPE call_IWbemServices_ExecQuery( 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc, LPCWSTR strQueryLanguage, LPCWSTR strQuery, 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt long lFlags, IWbemContext *pCtx, IEnumWbemClassObject **ppEnum) 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BSTR bsQueryLanguage, bsQuery; 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsQueryLanguage = BstrAlloc(strQueryLanguage); 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsQuery = BstrAlloc(strQuery); 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemServices_ExecQuery(pSvc, bsQueryLanguage, bsQuery, lFlags, 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pCtx, ppEnum); 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsQueryLanguage); 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsQuery); 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return hr; 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtHRESULT STDMETHODCALLTYPE call_IWbemServices_ExecNotificationQueryAsync( 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc, LPCWSTR strQueryLanguage, LPCWSTR strQuery, 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt long lFlags, IWbemContext *pCtx, IWbemObjectSink *pResponseHandler) 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BSTR bsQueryLanguage, bsQuery; 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsQueryLanguage = BstrAlloc(strQueryLanguage); 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsQuery = BstrAlloc(strQuery); 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemServices_ExecNotificationQueryAsync(pSvc, bsQueryLanguage, 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsQuery, lFlags, pCtx, 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pResponseHandler); 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsQueryLanguage); 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsQuery); 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return hr; 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtHRESULT STDMETHODCALLTYPE call_IWbemLocator_ConnectServer( 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemLocator *pLoc, LPCWSTR strNetworkResource, LPCWSTR strUser, 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPCWSTR strPassword, LPCWSTR strLocale, long lSecurityFlags, 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LPCWSTR strAuthority, IWbemContext *pCtx, IWbemServices **ppNamespace) 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BSTR bsNetworkResource, bsUser, bsPassword, bsLocale, bsAuthority; 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsNetworkResource = BstrAlloc(strNetworkResource); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsUser = BstrAlloc(strUser); 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsPassword = BstrAlloc(strPassword); 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsLocale = BstrAlloc(strLocale); 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsAuthority = BstrAlloc(strAuthority); 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemLocator_ConnectServer(pLoc, bsNetworkResource, bsUser, 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsPassword, bsLocale, lSecurityFlags, 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt bsAuthority, pCtx, ppNamespace); 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsNetworkResource); 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsUser); 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsPassword); 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsLocale); 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BstrFree(bsAuthority); 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return hr; 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtenum event_types { EVENT_CONNECT, EVENT_DISCONNECT, EVENT_MEDIA_SPECIFIC, 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt EVENT_ADAPTER_ARRIVAL, EVENT_ADAPTER_REMOVAL }; 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ndis_events_get_adapter(struct ndis_events_data *events, 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *ifname, const char *desc); 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ndis_events_constructor(struct ndis_events_data *events) 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->ref = 1; 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!CreatePipe(&events->read_pipe, &events->write_pipe, NULL, 512)) { 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CreatePipe() failed: %d", 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->event_avail = CreateEvent(NULL, TRUE, FALSE, NULL); 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->event_avail == NULL) { 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CreateEvent() failed: %d", 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) GetLastError()); 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(events->read_pipe); 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(events->write_pipe); 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_destructor(struct ndis_events_data *events) 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(events->read_pipe); 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(events->write_pipe); 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CloseHandle(events->event_avail); 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(events->pSvc); 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemLocator_Release(events->pLoc); 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (--wmi_refcnt == 0) 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CoUninitialize(); 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic HRESULT STDMETHODCALLTYPE 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtndis_events_query_interface(IWbemObjectSink *this, REFIID riid, void **obj) 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *obj = NULL; 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (IsEqualIID(riid, &IID_IUnknown) || 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IsEqualIID(riid, &IID_IWbemObjectSink)) { 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *obj = this; 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemObjectSink_AddRef(this); 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NOERROR; 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return E_NOINTERFACE; 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic ULONG STDMETHODCALLTYPE ndis_events_add_ref(IWbemObjectSink *this) 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ndis_events_data *events = (struct ndis_events_data *) this; 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ++events->ref; 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic ULONG STDMETHODCALLTYPE ndis_events_release(IWbemObjectSink *this) 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ndis_events_data *events = (struct ndis_events_data *) this; 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (--events->ref != 0) 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return events->ref; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_destructor(events); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: terminated"); 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->adapter_desc); 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->ifname); 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ndis_events_send_event(struct ndis_events_data *events, 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt enum event_types type, 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *data, size_t data_len) 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char buf[512], *pos, *end; 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int _type; 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DWORD written; 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt end = buf + sizeof(buf); 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _type = (int) type; 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(buf, &_type, sizeof(_type)); 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = buf + sizeof(_type); 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data) { 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (2 + data_len > (size_t) (end - pos)) { 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Not enough room for send_event " 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "data (%d)", data_len); 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = data_len >> 8; 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = data_len & 0xff; 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_memcpy(pos, data, data_len); 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos += data_len; 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (WriteFile(events->write_pipe, buf, pos - buf, &written, NULL)) { 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SetEvent(events->event_avail); 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_INFO, "WriteFile() failed: %d", (int) GetLastError()); 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_media_connect(struct ndis_events_data *events) 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaConnect"); 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_send_event(events, EVENT_CONNECT, NULL, 0); 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_media_disconnect(struct ndis_events_data *events) 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaDisconnect"); 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_send_event(events, EVENT_DISCONNECT, NULL, 0); 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_media_specific(struct ndis_events_data *events, 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject *pObj) 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VARIANT vt; 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt LONG lower, upper, k; 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt UCHAR ch; 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *data, *pos; 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t data_len; 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "MSNdis_StatusMediaSpecificIndication"); 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* This is the StatusBuffer from NdisMIndicateStatus() call */ 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"NdisStatusMediaSpecificIndication", 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0, &vt, NULL, NULL); 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Could not get " 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "NdisStatusMediaSpecificIndication from " 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "the object?!"); 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SafeArrayGetLBound(V_ARRAY(&vt), 1, &lower); 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SafeArrayGetUBound(V_ARRAY(&vt), 1, &upper); 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data_len = upper - lower + 1; 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt data = os_malloc(data_len); 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (data == NULL) { 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to allocate buffer for event " 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "data"); 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = data; 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (k = lower; k <= upper; k++) { 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt SafeArrayGetElement(V_ARRAY(&vt), &k, &ch); 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos++ = ch; 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_hexdump(MSG_DEBUG, "MediaSpecificEvent", (u8 *) data, data_len); 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_send_event(events, EVENT_MEDIA_SPECIFIC, data, data_len); 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(data); 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_adapter_arrival(struct ndis_events_data *events) 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "MSNdis_NotifyAdapterArrival"); 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_send_event(events, EVENT_ADAPTER_ARRIVAL, NULL, 0); 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void ndis_events_adapter_removal(struct ndis_events_data *events) 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "MSNdis_NotifyAdapterRemoval"); 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_send_event(events, EVENT_ADAPTER_REMOVAL, NULL, 0); 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic HRESULT STDMETHODCALLTYPE 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtndis_events_indicate(IWbemObjectSink *this, long lObjectCount, 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject __RPC_FAR *__RPC_FAR *ppObjArray) 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ndis_events_data *events = (struct ndis_events_data *) this; 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt long i; 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->terminating) { 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events_indicate: Ignore " 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "indication - terminating"); 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return WBEM_NO_ERROR; 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* wpa_printf(MSG_DEBUG, "Notification received - %d object(s)", 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt lObjectCount); */ 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < lObjectCount; i++) { 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject *pObj = ppObjArray[i]; 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VARIANT vtClass, vt; 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"__CLASS", 0, &vtClass, NULL, 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL); 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to get __CLASS from " 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "event."); 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* wpa_printf(MSG_DEBUG, "CLASS: '%S'", vtClass.bstrVal); */ 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"InstanceName", 0, &vt, NULL, 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL); 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to get InstanceName " 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "from event."); 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vtClass); 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wcscmp(vtClass.bstrVal, 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_NotifyAdapterArrival") == 0) { 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events_indicate: Try to " 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "update adapter description since it may " 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "have changed with new adapter instance"); 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_get_adapter(events, events->ifname, NULL); 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wcscmp(events->adapter_desc, vt.bstrVal) != 0) { 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events_indicate: Ignore " 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "indication for foreign adapter: " 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "InstanceName: '%S' __CLASS: '%S'", 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt vt.bstrVal, vtClass.bstrVal); 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vtClass); 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt continue; 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wcscmp(vtClass.bstrVal, 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_StatusMediaSpecificIndication") == 0) { 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_media_specific(events, pObj); 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (wcscmp(vtClass.bstrVal, 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_StatusMediaConnect") == 0) { 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_media_connect(events); 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (wcscmp(vtClass.bstrVal, 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_StatusMediaDisconnect") == 0) { 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_media_disconnect(events); 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (wcscmp(vtClass.bstrVal, 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_NotifyAdapterArrival") == 0) { 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_adapter_arrival(events); 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (wcscmp(vtClass.bstrVal, 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"MSNdis_NotifyAdapterRemoval") == 0) { 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_adapter_removal(events); 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else { 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Unepected event - __CLASS: " 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "'%S'", vtClass.bstrVal); 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vtClass); 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return WBEM_NO_ERROR; 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic HRESULT STDMETHODCALLTYPE 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtndis_events_set_status(IWbemObjectSink *this, long lFlags, HRESULT hResult, 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt BSTR strParam, IWbemClassObject __RPC_FAR *pObjParam) 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return WBEM_NO_ERROR; 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int notification_query(IWbemObjectSink *pDestSink, 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc, const char *class_name) 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WCHAR query[256]; 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _snwprintf(query, 256, 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"SELECT * FROM %S", class_name); 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query); 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemServices_ExecNotificationQueryAsync( 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSvc, L"WQL", query, 0, 0, pDestSink); 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ExecNotificationQueryAsync for %s " 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "failed with hresult of 0x%x", 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt class_name, (int) hr); 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int register_async_notification(IWbemObjectSink *pDestSink, 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc) 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int i; 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *class_list[] = { 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "MSNdis_StatusMediaConnect", 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "MSNdis_StatusMediaDisconnect", 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "MSNdis_StatusMediaSpecificIndication", 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "MSNdis_NotifyAdapterArrival", 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "MSNdis_NotifyAdapterRemoval", 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; class_list[i]; i++) { 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (notification_query(pDestSink, pSvc, class_list[i]) < 0) 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid ndis_events_deinit(struct ndis_events_data *events) 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->terminating = 1; 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_CancelAsyncCall(events->pSvc, &events->sink); 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemObjectSink_Release(&events->sink); 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Rest of deinitialization is done in ndis_events_destructor() once 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * all reference count drops to zero. 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ndis_events_use_desc(struct ndis_events_data *events, 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *desc) 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *tmp, *pos; 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t len; 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (desc == NULL) { 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Continue using old description */ 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt tmp = os_strdup(desc); 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (tmp == NULL) 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pos = os_strstr(tmp, " (Microsoft's Packet Scheduler)"); 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (pos) 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *pos = '\0'; 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = os_strlen(tmp); 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->adapter_desc = os_malloc((len + 1) * sizeof(WCHAR)); 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) { 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(tmp); 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _snwprintf(events->adapter_desc, len + 1, L"%S", tmp); 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(tmp); 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int ndis_events_get_adapter(struct ndis_events_data *events, 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *ifname, const char *desc) 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices *pSvc; 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define MAX_QUERY_LEN 256 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WCHAR query[MAX_QUERY_LEN]; 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject *pEnumerator; 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject *pObj; 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ULONG uReturned; 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VARIANT vt; 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int len, pos; 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Try to get adapter descriptor through WMI CIMv2 Win32_NetworkAdapter 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * to have better probability of matching with InstanceName from 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * MSNdis events. If this fails, use the provided description. 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->adapter_desc); 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->adapter_desc = NULL; 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemLocator_ConnectServer( 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->pLoc, L"ROOT\\CIMV2", NULL, NULL, 0, 0, 0, 0, &pSvc); 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "ndis_events: Could not connect to WMI " 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "server (ROOT\\CIMV2) - error 0x%x", (int) hr); 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Connected to ROOT\\CIMV2."); 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _snwprintf(query, MAX_QUERY_LEN, 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"SELECT Index FROM Win32_NetworkAdapterConfiguration " 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"WHERE SettingID='%S'", ifname); 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query); 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemServices_ExecQuery( 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSvc, L"WQL", query, 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, &pEnumerator); 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface " 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "GUID from Win32_NetworkAdapterConfiguration: " 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "0x%x", (int) hr); 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uReturned = 0; 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1, 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &pObj, &uReturned); 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr) || uReturned == 0) { 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface " 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "GUID from Win32_NetworkAdapterConfiguration: " 543526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "0x%x", (int) hr); 544526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantInit(&vt); 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"Index", 0, &vt, NULL, NULL); 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Index from " 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Win32_NetworkAdapterConfiguration: 0x%x", 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (int) hr); 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _snwprintf(query, MAX_QUERY_LEN, 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"SELECT Name,PNPDeviceID FROM Win32_NetworkAdapter WHERE " 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"Index=%d", 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt vt.uintVal); 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query); 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemServices_ExecQuery( 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSvc, L"WQL", query, 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, &pEnumerator); 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface " 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "from Win32_NetworkAdapter: 0x%x", (int) hr); 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uReturned = 0; 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1, 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &pObj, &uReturned); 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr) || uReturned == 0) { 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface " 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "from Win32_NetworkAdapter: 0x%x", (int) hr); 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"Name", 0, &vt, NULL, NULL); 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Name from " 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Win32_NetworkAdapter: 0x%x", (int) hr); 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Win32_NetworkAdapter::Name='%S'", 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt vt.bstrVal); 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->adapter_desc = _wcsdup(vt.bstrVal); 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Try to get even better candidate for matching with InstanceName 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * from Win32_PnPEntity. This is needed at least for some USB cards 608526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * that can change the InstanceName whenever being unplugged and 609526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * plugged again. 610526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"PNPDeviceID", 0, &vt, NULL, NULL); 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to get PNPDeviceID " 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "from Win32_NetworkAdapter: 0x%x", (int) hr); 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; /* use Win32_NetworkAdapter::Name */ 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Win32_NetworkAdapter::PNPDeviceID=" 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "'%S'", vt.bstrVal); 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt len = _snwprintf(query, MAX_QUERY_LEN, 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt L"SELECT Name FROM Win32_PnPEntity WHERE DeviceID='"); 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len < 0 || len >= MAX_QUERY_LEN - 1) { 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; /* use Win32_NetworkAdapter::Name */ 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Escape \ as \\ */ 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (pos = 0; vt.bstrVal[pos] && len < MAX_QUERY_LEN - 2; pos++) { 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (vt.bstrVal[pos] == '\\') { 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len >= MAX_QUERY_LEN - 3) 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt query[len++] = '\\'; 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt query[len++] = vt.bstrVal[pos]; 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt query[len++] = L'\''; 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt query[len] = L'\0'; 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: WMI: %S", query); 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemServices_ExecQuery( 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSvc, L"WQL", query, 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, &pEnumerator); 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to query interface " 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Name from Win32_PnPEntity: 0x%x", (int) hr); 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; /* use Win32_NetworkAdapter::Name */ 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt uReturned = 0; 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IEnumWbemClassObject_Next(pEnumerator, WBEM_INFINITE, 1, 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &pObj, &uReturned); 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr) || uReturned == 0) { 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to find interface " 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "from Win32_PnPEntity: 0x%x", (int) hr); 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; /* use Win32_NetworkAdapter::Name */ 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IEnumWbemClassObject_Release(pEnumerator); 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = IWbemClassObject_Get(pObj, L"Name", 0, &vt, NULL, NULL); 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!SUCCEEDED(hr)) { 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Failed to get Name from " 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Win32_PnPEntity: 0x%x", (int) hr); 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; /* use Win32_NetworkAdapter::Name */ 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: Win32_PnPEntity::Name='%S'", 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt vt.bstrVal); 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->adapter_desc); 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->adapter_desc = _wcsdup(vt.bstrVal); 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt VariantClear(&vt); 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemClassObject_Release(pObj); 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemServices_Release(pSvc); 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->adapter_desc == NULL) 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ndis_events_use_desc(events, desc); 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ndis_events_data * 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtndis_events_init(HANDLE *read_pipe, HANDLE *event_avail, 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *ifname, const char *desc) 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt HRESULT hr; 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt IWbemObjectSink *pSink; 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ndis_events_data *events; 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events = os_zalloc(sizeof(*events)); 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events == NULL) { 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not allocate sink for events."); 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->ifname = os_strdup(ifname); 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (events->ifname == NULL) { 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wmi_refcnt++ == 0) { 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = CoInitializeEx(0, COINIT_MULTITHREADED); 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CoInitializeEx() failed - " 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "returned 0x%x", (int) hr); 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wmi_first) { 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* CoInitializeSecurity() must be called once and only once 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * per process, so let's use wmi_first flag to protect against 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * multiple calls. */ 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wmi_first = 0; 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = CoInitializeSecurity(NULL, -1, NULL, NULL, 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RPC_C_AUTHN_LEVEL_PKT_PRIVACY, 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt RPC_C_IMP_LEVEL_IMPERSONATE, 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, EOAC_SECURE_REFS, NULL); 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CoInitializeSecurity() failed " 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "- returned 0x%x", (int) hr); 749526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 750526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 751526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 752526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 753526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 754526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, 755526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &IID_IWbemLocator, 756526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt (LPVOID *) (void *) &events->pLoc); 757526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 758526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "CoCreateInstance() failed - returned " 759526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "0x%x", (int) hr); 760526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CoUninitialize(); 761526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 762526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 763526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 764526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 765526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ndis_events_get_adapter(events, ifname, desc) < 0) { 766526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CoUninitialize(); 767526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 768526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 769526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 770526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "ndis_events: use adapter descriptor '%S'", 771526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->adapter_desc); 772526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 773526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt hr = call_IWbemLocator_ConnectServer( 774526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->pLoc, L"ROOT\\WMI", NULL, NULL, 775526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0, 0, 0, 0, &events->pSvc); 776526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (FAILED(hr)) { 777526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not connect to server - error " 778526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "0x%x", (int) hr); 779526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt CoUninitialize(); 780526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->adapter_desc); 781526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 782526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 783526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 784526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Connected to ROOT\\WMI."); 785526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 786526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_constructor(events); 787526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSink = &events->sink; 788526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt pSink->lpVtbl = &events->sink_vtbl; 789526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->sink_vtbl.QueryInterface = ndis_events_query_interface; 790526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->sink_vtbl.AddRef = ndis_events_add_ref; 791526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->sink_vtbl.Release = ndis_events_release; 792526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->sink_vtbl.Indicate = ndis_events_indicate; 793526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt events->sink_vtbl.SetStatus = ndis_events_set_status; 794526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 795526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (register_async_notification(pSink, events->pSvc) < 0) { 796526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Failed to register async " 797526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "notifications"); 798526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ndis_events_destructor(events); 799526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events->adapter_desc); 800526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt os_free(events); 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *read_pipe = events->read_pipe; 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *event_avail = events->event_avail; 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return events; 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 809