295 lines
7.1 KiB
C++
295 lines
7.1 KiB
C++
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
|
|
//==============================================================================
|
|
//
|
|
// NDISSTAT.CPP
|
|
//
|
|
// This contains two classes which implement a temporary event consumer for
|
|
// the NDIS connect status events.
|
|
//
|
|
//==============================================================================
|
|
|
|
#include "stdafx.h"
|
|
#include "ndisstat.h"
|
|
|
|
// Query list to NdisStatus notifications
|
|
WCHAR *Queries[] =
|
|
{
|
|
L"select * from NdisStatusMediaConnect",
|
|
L"select * from NdisStatusMediaDisconnect"
|
|
};
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
STDMETHODIMP CEventSink::QueryInterface(REFIID riid, LPVOID * ppv)
|
|
{
|
|
*ppv = 0;
|
|
|
|
if ( IID_IUnknown == riid || IID_IWbemObjectSink == riid )
|
|
{
|
|
*ppv = (IWbemEventProvider *) this;
|
|
AddRef( );
|
|
return NOERROR;
|
|
}
|
|
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
ULONG CEventSink::AddRef( )
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
ULONG CEventSink::Release( )
|
|
{
|
|
if (0 != --m_cRef)
|
|
return m_cRef;
|
|
|
|
delete this;
|
|
return 0;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
HRESULT CEventSink::Indicate(
|
|
long lObjectCount,
|
|
IWbemClassObject __RPC_FAR *__RPC_FAR *ppObjArray
|
|
)
|
|
{
|
|
if ( lObjectCount > 0 )
|
|
{
|
|
// Only expecting one, if more ignore them
|
|
IWbemClassObject *pObj = ppObjArray[0];
|
|
|
|
PostMessage( (HWND) m_ulContext1, WM_COMMAND, MAKELONG( 0, (WORD) m_ulContext2 ), m_ulContext3 );
|
|
}
|
|
|
|
return WBEM_NO_ERROR;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
HRESULT CEventSink::SetStatus(
|
|
long lFlags,
|
|
HRESULT hResult,
|
|
BSTR strParam,
|
|
IWbemClassObject __RPC_FAR *pObjParam
|
|
)
|
|
{
|
|
// Not called during event delivery.
|
|
|
|
return WBEM_NO_ERROR;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
CEventNotify::CEventNotify( )
|
|
{
|
|
long i;
|
|
|
|
m_pSvc = NULL;
|
|
for ( i = 0; i < MAX_EVENTS; i++ )
|
|
{
|
|
m_pSink[i] = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
CEventNotify::~CEventNotify( )
|
|
{
|
|
long i;
|
|
|
|
for ( i = 0; i < MAX_EVENTS; i++ )
|
|
{
|
|
DisableWbemEvent( i );
|
|
}
|
|
if ( m_pSvc )
|
|
{
|
|
m_pSvc->Release( );
|
|
}
|
|
|
|
CoUninitialize( );
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
HRESULT CEventNotify::EnableWbemEvent( ULONG ulEventId, ULONG ulContext1, ULONG ulContext2 )
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if ( m_pSvc && ulEventId < MAX_EVENTS )
|
|
{
|
|
m_pSink[ulEventId] = new CEventSink( ulContext1, ulContext2, ulEventId );
|
|
if ( m_pSink[ulEventId] )
|
|
{
|
|
BSTR query = SysAllocString( Queries[ulEventId] );
|
|
BSTR lang = SysAllocString( L"WQL" );
|
|
|
|
hr = m_pSvc->ExecNotificationQueryAsync(
|
|
lang,
|
|
query,
|
|
0L,
|
|
NULL,
|
|
m_pSink[ulEventId]
|
|
);
|
|
|
|
SysFreeString( lang );
|
|
SysFreeString( query );
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
HRESULT CEventNotify::DisableWbemEvent( ULONG ulEventId )
|
|
{
|
|
HRESULT hr = WBEM_E_FAILED;
|
|
|
|
if ( m_pSvc && ulEventId < MAX_EVENTS )
|
|
{
|
|
if ( m_pSink[ulEventId] )
|
|
{
|
|
hr = m_pSvc->CancelAsyncCall( m_pSink[ulEventId] );
|
|
m_pSink[ulEventId]->Release( );
|
|
m_pSink[ulEventId] = NULL;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
HRESULT CEventNotify::InitWbemServices( BSTR Namespace )
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
|
|
|
|
if ( hr == S_OK )
|
|
{
|
|
IWbemLocator *pLoc = NULL;
|
|
|
|
InitSecurity( );
|
|
|
|
DWORD dwRes = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator, (LPVOID *) &pLoc );
|
|
|
|
if ( pLoc )
|
|
{
|
|
hr = pLoc->ConnectServer(
|
|
Namespace,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
&m_pSvc
|
|
);
|
|
|
|
pLoc->Release( );
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
//
|
|
//==============================================================================
|
|
|
|
void CEventNotify::InitSecurity( void )
|
|
{
|
|
UINT uSize;
|
|
BOOL bRetCode = FALSE;
|
|
|
|
// find the system directory.
|
|
LPTSTR pszSysDir = new TCHAR[MAX_PATH + 10];
|
|
|
|
if(pszSysDir == NULL)
|
|
return;
|
|
|
|
uSize = GetSystemDirectory(pszSysDir, MAX_PATH);
|
|
|
|
if(uSize > MAX_PATH)
|
|
{
|
|
delete[] pszSysDir;
|
|
pszSysDir = new TCHAR[ uSize +10 ];
|
|
if(pszSysDir == NULL)
|
|
return;
|
|
uSize = GetSystemDirectory(pszSysDir, uSize);
|
|
}
|
|
|
|
// manually load the ole32.dll
|
|
lstrcat(pszSysDir, TEXT("\\ole32.dll"));
|
|
|
|
HINSTANCE hOle32 = LoadLibraryEx(pszSysDir, NULL, 0);
|
|
HRESULT (STDAPICALLTYPE *g_pfnCoInitializeSecurity)(PSECURITY_DESCRIPTOR pVoid,
|
|
DWORD cAuthSvc,
|
|
SOLE_AUTHENTICATION_SERVICE * asAuthSvc,
|
|
void * pReserved1,
|
|
DWORD dwAuthnLevel,
|
|
DWORD dwImpLevel,
|
|
RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
|
|
DWORD dwCapabilities,
|
|
void * pvReserved2 );
|
|
|
|
delete[] pszSysDir;
|
|
|
|
if(hOle32 != NULL)
|
|
{
|
|
(FARPROC&)g_pfnCoInitializeSecurity = GetProcAddress(hOle32, "CoInitializeSecurity");
|
|
|
|
// if it exports CoInitializeSecurity then DCOM is installed.
|
|
if(g_pfnCoInitializeSecurity != NULL)
|
|
{
|
|
// NOTE: This is needed to work around a security problem
|
|
// when using IWBEMObjectSink. The sink wont normally accept
|
|
// calls when the caller wont identify themselves. This
|
|
// adjusts that process.
|
|
HRESULT hres = g_pfnCoInitializeSecurity(NULL, -1, NULL, NULL,
|
|
RPC_C_AUTHN_LEVEL_CONNECT,
|
|
RPC_C_IMP_LEVEL_IDENTIFY,
|
|
NULL, 0, 0);
|
|
}
|
|
FreeLibrary(hOle32);
|
|
}
|
|
}
|