616 lines
15 KiB
C++
616 lines
15 KiB
C++
/******************************************************************
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
GotNet.CPP -- WMI provider class implementation
|
|
|
|
Generated by Microsoft WMI Code Generation Engine
|
|
|
|
TO DO: - See individual function headers
|
|
- When linking, make sure you link to framedyd.lib &
|
|
msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail).
|
|
|
|
Description:
|
|
|
|
|
|
|
|
******************************************************************/
|
|
|
|
#include "stdpch.h"
|
|
#pragma hdrstop
|
|
#include "GotNet.h"
|
|
|
|
#include "host.h" // CHost
|
|
#include "output.h" // COutput
|
|
#include "diag.h"
|
|
|
|
#include "oe.h"
|
|
#include "proxy.h"
|
|
#include "connect.h" // ConnectToPort
|
|
|
|
// TO DO: Replace "NameSpace" with the appropriate namespace for your
|
|
// provider instance. For instance: "root\\default or "root\\cimv2".
|
|
//===================================================================
|
|
//CGotNet MyGotNetSet (PROVIDER_NAME_GOTNET, L"root\\default") ;
|
|
|
|
// Property names
|
|
//===============
|
|
|
|
const static WCHAR* pid = L"id" ;
|
|
const static WCHAR* pbIEProxy = L"bIEProxy" ;
|
|
const static WCHAR* pIEProxy = L"IEProxy" ;
|
|
const static WCHAR* pIEProxyPort = L"IEProxyPort" ;
|
|
|
|
// Counts the number of times the com object is referenced
|
|
//
|
|
long g_nModuleRef = 0;
|
|
|
|
void
|
|
AddRefModule()
|
|
/*++
|
|
|
|
Routine Description
|
|
This routine is counts the number of time the dll/COM is being refernce.
|
|
Increments the ref count
|
|
|
|
Arguments
|
|
none
|
|
|
|
Return Value
|
|
none
|
|
|
|
--*/
|
|
{
|
|
InterlockedIncrement(&g_nModuleRef);
|
|
}
|
|
|
|
void
|
|
ReleaseModule()
|
|
/*++
|
|
|
|
Routine Description
|
|
This routine is decrements the ref count.
|
|
|
|
Arguments
|
|
none
|
|
|
|
Return Value
|
|
none
|
|
|
|
--*/
|
|
{
|
|
InterlockedDecrement(&g_nModuleRef);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CGotNet::CGotNet
|
|
*
|
|
* DESCRIPTION : Constructor
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* RETURNS : nothing
|
|
*
|
|
* COMMENTS : Calls the Provider constructor.
|
|
*
|
|
*****************************************************************************/
|
|
CGotNet::CGotNet ()
|
|
{
|
|
AddRefModule();
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* FUNCTION : CGotNet::~CGotNet
|
|
*
|
|
* DESCRIPTION : Destructor
|
|
*
|
|
* INPUTS : none
|
|
*
|
|
* RETURNS : nothing
|
|
*
|
|
* COMMENTS :
|
|
*
|
|
*****************************************************************************/
|
|
CGotNet::~CGotNet ()
|
|
{
|
|
ReleaseModule();
|
|
}
|
|
//***************************************************************************
|
|
//
|
|
// CGotNet::QueryInterface
|
|
// CGotNet::AddRef
|
|
// CGotNet::Release
|
|
//
|
|
// Purpose: IUnknown members for CInstPro object.
|
|
//***************************************************************************
|
|
|
|
|
|
STDMETHODIMP CGotNet::QueryInterface(REFIID riid, LPVOID* ppv)
|
|
{
|
|
*ppv=NULL;
|
|
|
|
// Since we have dual inheritance, it is necessary to cast the return type
|
|
|
|
if(riid== IID_IWbemServices)
|
|
*ppv=(IWbemServices*)this;
|
|
|
|
if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
|
|
*ppv=(IWbemProviderInit*)this;
|
|
|
|
|
|
if (NULL!=*ppv) {
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
}
|
|
|
|
|
|
STDMETHODIMP_(ULONG) CGotNet::AddRef(void)
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) CGotNet::Release(void)
|
|
{
|
|
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
|
|
if (0L == nNewCount)
|
|
delete this;
|
|
|
|
return nNewCount;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* *
|
|
* CInstPro::Initialize *
|
|
* *
|
|
* Purpose: This is the implementation of IWbemProviderInit. The method *
|
|
* is need to initialize with CIMOM. *
|
|
* *
|
|
***********************************************************************/
|
|
|
|
STDMETHODIMP CGotNet::Initialize(LPWSTR pszUser, LONG lFlags,
|
|
LPWSTR pszNamespace, LPWSTR pszLocale,
|
|
IWbemServices *pNamespace,
|
|
IWbemContext *pCtx,
|
|
IWbemProviderInitSink *pInitSink)
|
|
{
|
|
if(pNamespace)
|
|
pNamespace->AddRef();
|
|
|
|
m_pNamespace = pNamespace;
|
|
|
|
//Let CIMOM know you are initialized
|
|
//==================================
|
|
|
|
pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CInstPro::CreateInstanceEnumAsync
|
|
//
|
|
// Purpose: Asynchronously enumerates the instances.
|
|
//
|
|
//***************************************************************************
|
|
|
|
SCODE CGotNet::CreateInstanceEnumAsync( const BSTR RefStr, long lFlags, IWbemContext *pCtx,
|
|
IWbemObjectSink FAR* pHandler)
|
|
{
|
|
SCODE sc;
|
|
int iCnt;
|
|
IWbemClassObject FAR* pNewInst;
|
|
HRESULT hr;
|
|
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
if(pHandler == NULL || m_pNamespace == NULL)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
hr = CoImpersonateClient();
|
|
if( hr != S_OK )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
for(iCnt=0; iCnt < 1; iCnt++)
|
|
{
|
|
sc = CreateInst(
|
|
m_pNamespace,
|
|
&pNewInst,
|
|
RefStr,
|
|
pCtx);
|
|
|
|
|
|
if(sc != S_OK)
|
|
break;
|
|
|
|
sc = AddProps(pNewInst);
|
|
|
|
if(sc != S_OK)
|
|
break;
|
|
|
|
// Send the object to the caller
|
|
|
|
pHandler->Indicate(1,&pNewInst);
|
|
pNewInst->Release();
|
|
}
|
|
|
|
// Set status
|
|
|
|
pHandler->SetStatus(0,sc,NULL, NULL);
|
|
|
|
CoRevertToSelf();
|
|
return sc;
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CGotNet::GetObjectByPath
|
|
// CGetNet::GetObjectByPathAsync
|
|
//
|
|
// Purpose: Creates an instance given a particular path value.
|
|
//
|
|
//***************************************************************************
|
|
SCODE CGotNet::GetObjectAsync(const BSTR ObjectPath, long lFlags,IWbemContext *pCtx,
|
|
IWbemObjectSink FAR* pHandler)
|
|
{
|
|
|
|
SCODE sc;
|
|
IWbemClassObject FAR* pObj;
|
|
BOOL bOK = FALSE;
|
|
|
|
// Do a check of arguments and make sure we have pointer to Namespace
|
|
|
|
if(ObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL)
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
|
|
// do the get, pass the object on to the notify
|
|
|
|
sc = GetByPath(ObjectPath,&pObj, pCtx);
|
|
if(sc == S_OK)
|
|
{
|
|
pHandler->Indicate(1,&pObj);
|
|
pObj->Release();
|
|
bOK = TRUE;
|
|
}
|
|
|
|
sc = (bOK) ? S_OK : WBEM_E_NOT_FOUND;
|
|
|
|
// Set Status
|
|
|
|
pHandler->SetStatus(0,sc, NULL, NULL);
|
|
|
|
return sc;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//
|
|
// CGotNet::GetByPath
|
|
//
|
|
// Purpose: Creates an instance given a particular Path value.
|
|
//
|
|
//***************************************************************************
|
|
|
|
SCODE
|
|
CGotNet::GetByPath(
|
|
BSTR ObjectPath,
|
|
IWbemClassObject FAR* FAR* ppObj,
|
|
IWbemContext *pCtx)
|
|
{
|
|
SCODE sc = S_OK;
|
|
|
|
if(!_wcsicmp(L"NetDiagnostics=@", ObjectPath))
|
|
{
|
|
sc = CreateInst(
|
|
m_pNamespace,
|
|
ppObj,
|
|
L"NetDiagnostics",
|
|
pCtx);
|
|
|
|
return sc;
|
|
}
|
|
|
|
return WBEM_E_NOT_FOUND;
|
|
}
|
|
|
|
HRESULT STDMETHODCALLTYPE
|
|
CGotNet::ExecMethodAsync(
|
|
const BSTR ObjectPath,
|
|
const BSTR MethodName,
|
|
long lFlags,
|
|
IWbemContext* pCtx,
|
|
IWbemClassObject* pInParams,
|
|
IWbemObjectSink* pResultSink)
|
|
{
|
|
if(0 == _wcsicmp(MethodName, L"Ping"))
|
|
{
|
|
return WMIPing(lFlags, pCtx, pInParams, pResultSink);
|
|
}
|
|
else if (0 == _wcsicmp(MethodName, L"ConnectToPort"))
|
|
{
|
|
return WMIConnectToPort(lFlags, pCtx, pInParams, pResultSink);
|
|
}
|
|
else
|
|
{
|
|
return WBEM_E_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
|
|
HRESULT CGotNet::WMIPing(
|
|
long lFlags,
|
|
IWbemContext* pCtx,
|
|
IWbemClassObject* pInParams,
|
|
IWbemObjectSink* pResultSink)
|
|
{
|
|
HRESULT hr;
|
|
IWbemClassObject * pClass = NULL;
|
|
IWbemClassObject * pOutClass = NULL;
|
|
IWbemClassObject* pOutParams = NULL;
|
|
TEST_INFO ping;
|
|
CHost host;
|
|
char buffer[100];
|
|
WSADATA wsa;
|
|
|
|
WSAStartup(MAKEWORD(2,1), &wsa);
|
|
|
|
|
|
hr = CoImpersonateClient();
|
|
if( hr != S_OK )
|
|
{
|
|
WSACleanup();
|
|
return hr;
|
|
}
|
|
|
|
|
|
// Allocate some BSTRs
|
|
|
|
BSTR ClassName = SysAllocString(L"NetDiagnostics");
|
|
BSTR InputArgName = SysAllocString(L"sInAddr");
|
|
BSTR OutputArgName = SysAllocString(L"sOutArg");
|
|
BSTR retValName = SysAllocString(L"ReturnValue");
|
|
|
|
// Get the class object, this is hard coded and matches the class
|
|
// in the MOF. A more sophisticated example would parse the
|
|
// ObjectPath to determine the class and possibly the instance.
|
|
|
|
hr = m_pNamespace->GetObject(ClassName, 0, pCtx, &pClass, NULL);
|
|
if(hr != S_OK)
|
|
{
|
|
pResultSink->SetStatus(0,hr, NULL, NULL);
|
|
WSACleanup();
|
|
CoRevertToSelf();
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
// This method returns values, and so create an instance of the
|
|
// output argument class.
|
|
|
|
hr = pClass->GetMethod(L"Ping", 0, NULL, &pOutClass);
|
|
pOutClass->SpawnInstance(0, &pOutParams);
|
|
|
|
// Copy the input argument into the output object
|
|
|
|
auto_var var;
|
|
|
|
// Get the input argument
|
|
pInParams->Get(InputArgName, 0, &var, NULL, NULL);
|
|
|
|
wcstombs(buffer, var.bstrVal, 100);
|
|
ping.host.SetHost(buffer);
|
|
CheckPing(&ping);
|
|
WaitForSingleObject(ping.hEvent, INFINITE);
|
|
|
|
|
|
// put it into the output object
|
|
_variant_t v ((bool)(ping.dwErr == S_OK));
|
|
|
|
pOutParams->Put(retValName , 0, &v, 0);
|
|
|
|
v = ping.output.Status();
|
|
pOutParams->Put(OutputArgName , 0, &v, 0);
|
|
|
|
// Send the output object back to the client via the sink. Then
|
|
// release the pointers and free the strings.
|
|
|
|
hr = pResultSink->Indicate(1, &pOutParams);
|
|
pOutParams->Release();
|
|
pOutClass->Release();
|
|
pClass->Release();
|
|
SysFreeString(ClassName);
|
|
SysFreeString(InputArgName);
|
|
SysFreeString(OutputArgName);
|
|
SysFreeString(retValName);
|
|
|
|
// all done now, set the status
|
|
hr = pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
|
|
CoRevertToSelf();
|
|
|
|
WSACleanup();
|
|
return WBEM_S_NO_ERROR;
|
|
|
|
}
|
|
|
|
HRESULT CGotNet::WMIConnectToPort(
|
|
long lFlags,
|
|
IWbemContext* pCtx,
|
|
IWbemClassObject* pInParams,
|
|
IWbemObjectSink* pResultSink)
|
|
{
|
|
HRESULT hr;
|
|
IWbemClassObject * pClass = NULL;
|
|
IWbemClassObject * pOutClass = NULL;
|
|
IWbemClassObject* pOutParams = NULL;
|
|
TEST_INFO ping;
|
|
CHost host;
|
|
char buffer[100];
|
|
bool bConnect = false;
|
|
|
|
hr = CoImpersonateClient();
|
|
if( hr != S_OK )
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// Allocate some BSTRs
|
|
|
|
BSTR ClassName = SysAllocString(L"NetDiagnostics");
|
|
BSTR AddrArgName = SysAllocString(L"sInAddr");
|
|
BSTR PortArgName = SysAllocString(L"port");
|
|
BSTR OutputArgName = SysAllocString(L"sOutArg");
|
|
BSTR retValName = SysAllocString(L"ReturnValue");
|
|
|
|
// Get the class object, this is hard coded and matches the class
|
|
// in the MOF. A more sophisticated example would parse the
|
|
// ObjectPath to determine the class and possibly the instance.
|
|
|
|
hr = m_pNamespace->GetObject(ClassName, 0, pCtx, &pClass, NULL);
|
|
if(hr != S_OK)
|
|
{
|
|
pResultSink->SetStatus(0,hr, NULL, NULL);
|
|
CoRevertToSelf();
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
// This method returns values, and so create an instance of the
|
|
// output argument class.
|
|
|
|
hr = pClass->GetMethod(L"ConnectToPort", 0, NULL, &pOutClass);
|
|
pOutClass->SpawnInstance(0, &pOutParams);
|
|
|
|
// Copy the input argument into the output object
|
|
|
|
auto_var addr;
|
|
auto_var port;
|
|
|
|
// Get the input argument
|
|
pInParams->Get(AddrArgName, 0, &addr, NULL, NULL);
|
|
pInParams->Get(PortArgName, 0, &port, NULL, NULL);
|
|
|
|
wcstombs(buffer, addr.bstrVal, 100);
|
|
|
|
host.SetHost(buffer);
|
|
|
|
Connect(host, port.lVal, bConnect);
|
|
|
|
// put it into the output object
|
|
_variant_t v (bConnect);
|
|
|
|
pOutParams->Put(retValName , 0, &v, 0);
|
|
|
|
v = ping.output.Status();
|
|
pOutParams->Put(OutputArgName , 0, &v, 0);
|
|
|
|
// Send the output object back to the client via the sink. Then
|
|
// release the pointers and free the strings.
|
|
|
|
hr = pResultSink->Indicate(1, &pOutParams);
|
|
pOutParams->Release();
|
|
pOutClass->Release();
|
|
pClass->Release();
|
|
SysFreeString(ClassName);
|
|
SysFreeString(AddrArgName);
|
|
SysFreeString(PortArgName);
|
|
SysFreeString(OutputArgName);
|
|
SysFreeString(retValName);
|
|
|
|
// all done now, set the status
|
|
hr = pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
|
|
CoRevertToSelf();
|
|
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
|
|
HRESULT CGotNet::AddProps(IWbemClassObject* pInstance)
|
|
{
|
|
HRESULT hRes = WBEM_S_NO_ERROR;
|
|
CHost host;
|
|
DWORD dwPort = 0;
|
|
DWORD dwProxyPort = 0;
|
|
DWORD dwProxyEnabled = 0;
|
|
_variant_t v;
|
|
|
|
v.Clear();
|
|
/*
|
|
//
|
|
// Grab all the mail server information
|
|
///////////////////////////////////////
|
|
|
|
CHost InBoundMailHost, OutBoundMailHost;
|
|
DWORD dwInBoundPort, dwOutBoundPort;
|
|
WCHAR wszInBoundMailType, wszOutBoundMailType;
|
|
|
|
hRes = GetOEDefaultMailServer(InBoundMailHost,
|
|
dwInBoundPort,
|
|
wszInBoundMailType,
|
|
OutBoundMailHost,
|
|
dwOutBoundPort,
|
|
wszOutBoundMailType);
|
|
if( SUCCEEDED(hRes) )
|
|
{
|
|
v = InBoundMailHost.GetHost();
|
|
pInstance->Put(pInBoundMailServer, 0, &v, 0);
|
|
|
|
v = (long)dwInBoundPort;
|
|
pInstance->Put(pInBoundMailPort, 0, &v, 0);
|
|
|
|
v = wszInBoundMailType
|
|
pInstance->Put(pInBoundMailType, 0, &v, 0);
|
|
|
|
|
|
v = OutBoundMailHost.GetHost();
|
|
pInstance->Put(pOutBoundMailServer, 0, &v, 0);
|
|
|
|
v = (long)dwOutBoundPort;
|
|
pInstance->Put(pOutBoundMailPort, 0, &v, 0);
|
|
|
|
v = wszOutBoundMailType
|
|
pInstance->Put(pOutBoundMailType, 0, &v, 0);
|
|
|
|
}
|
|
*/
|
|
//
|
|
// Grab all the news server information
|
|
///////////////////////////////////////
|
|
v.Clear();
|
|
hRes = GetOEDefaultNewsServer(host, dwPort);
|
|
v = host.GetHost();
|
|
pInstance->Put(pNewsServer, 0, &v, 0);
|
|
|
|
v = (long)dwPort;
|
|
pInstance->Put(pNewsNNTPPort, 0, &v, 0);
|
|
|
|
|
|
v.Clear();
|
|
if (FindProxy(&host, &dwProxyPort, &dwProxyEnabled))
|
|
{
|
|
v = (bool)(dwProxyEnabled == TRUE);
|
|
pInstance->Put(pbIEProxy, 0, &v, 0);
|
|
|
|
v.Clear();
|
|
v = host.GetHost();
|
|
pInstance->Put(pIEProxy, 0, &v, 0);
|
|
|
|
v.Clear();
|
|
v = (long)dwProxyPort;
|
|
pInstance->Put(pIEProxyPort, 0, &v, 0);
|
|
}
|
|
else
|
|
{
|
|
v = (bool)FALSE;
|
|
pInstance->Put(pbIEProxy, 0, &v, 0);
|
|
pInstance->Put(pIEProxy, 0, NULL, 0);
|
|
pInstance->Put(pIEProxyPort, 0, NULL, 0);
|
|
}
|
|
|
|
return hRes;
|
|
}
|