windows-nt/Source/XPSP1/NT/net/diagnostics/wmi/dgnet/dgnet.cpp
2020-09-26 16:20:57 +08:00

651 lines
16 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 "stdpch.h"
#include "dgnet.h"
GUID CLSID_Dgnet = { 0x8dabe793,0x23d9,0x45df, {0xa3,0xdb,0xf4,0x42,0x88,0x3b,0xb4,0x79} };
#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* pInBoundMailServer = L"InBoundMailServer" ;
const static WCHAR* pInBoundMailPort = L"InBoundMailPort" ;
const static WCHAR* pInBoundMailType = L"InBoundMailType" ;
const static WCHAR* pOutBoundMailServer = L"OutBoundMailServer" ;
const static WCHAR* pOutBoundMailPort = L"OutBoundMailPort" ;
const static WCHAR* pOutBoundMailType = L"OutBoundMailType" ;
*/
const static WCHAR* pNewsServer = L"NewsServer" ;
const static WCHAR* pNewsNNTPPort = L"NewsNNTPPort" ;
const static WCHAR* pbIEProxy = L"bIEProxy" ;
const static WCHAR* pIEProxy = L"IEProxy" ;
const static WCHAR* pIEProxyPort = L"IEProxyPort" ;
#if 0
// 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);
}
#endif
/*****************************************************************************
*
* 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.
//***************************************************************************
#if 0
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;
}
#endif
/***********************************************************************
* *
* 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 * pNewInst = NULL;
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;
TCHAR buffer[100];
WSADATA wsa;
DWORD err = WSAStartup(MAKEWORD(2,1), &wsa);
if( err != 0 )
{
err = WSAGetLastError();
}
hr = CoImpersonateClient();
if( hr != S_OK )
{
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);
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);
lstrcpyn(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;
TCHAR buffer[100];
bool bConnect = false;
WSADATA wsa;
DWORD err = WSAStartup(MAKEWORD(2,1), &wsa);
if( err != 0 )
{
err = WSAGetLastError();
}
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);
lstrcpyn(buffer, addr.bstrVal, 100);
//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();
WSACleanup();
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;
TCHAR wszInBoundMailType[MAX_PATH], wszOutBoundMailType[MAX_PATH];
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;
}