/****************************************************************** 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; }