2025-04-27 07:49:33 -04:00

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);
}
}