////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1999-2003 Microsoft Corporation // // Module Name: // InstanceProv.cpp // // Description: // Implementation of CInstanceProv class // ////////////////////////////////////////////////////////////////////////////// #pragma once #include "Pch.h" #include "InstanceProv.h" #include "VdsNasClasses.h" #include "msg.h" BOOL MapVdsErrorToMsgAndWMIStatus( IN HRESULT hr, OUT LONG* plMsgNum, OUT HRESULT* pHr ); ////////////////////////////////////////////////////////////////////////////// // Global Variables ////////////////////////////////////////////////////////////////////////////// long g_lNumInst = 0; ClassMap g_ClassMap; //**************************************************************************** // // CInstanceProv // //**************************************************************************** ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::DoCreateInstanceEnumAsync // // Description: // Enumerate instance for a given class. // // Arguments: // bstrRefStr -- Name the class to enumerate // lFlags -- WMI flag // pCtx -- WMI context // pHandler -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // WBEM_E_INVALID_PARAMETER // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::DoCreateInstanceEnumAsync( IN BSTR bstrRefStr, IN long lFlags, IN IWbemContext* pCtx, IN IWbemObjectSink* pHandler ) { HRESULT hr = WBEM_S_NO_ERROR; if (bstrRefStr == NULL || pHandler == NULL || m_pNamespace == NULL) { return WBEM_E_INVALID_PARAMETER; } try { auto_ptr pProvBase; CreateClass(bstrRefStr, m_pNamespace, pProvBase); hr = pProvBase->EnumInstance( lFlags, pCtx, pHandler ); if (FAILED(hr)) { CProvException exception(hr); hr = SetExtendedStatus(exception, &pHandler); } else // Set status OK { pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0); } } catch (CProvException& prove) { hr = SetExtendedStatus(prove, &pHandler); } catch (_com_error& err) { CProvException exception(err.Error()); hr = SetExtendedStatus(exception, &pHandler); } catch ( ... ) { hr = WBEM_E_FAILED; } return hr; } //*** CInstanceProv::DoCreateInstanceEnumAsync() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::DoGetObjectAsync // // Description: // Creates an instance given a particular path value. // // Arguments: // bstrObjectPath -- Object path to an object // lFlags -- WMI flag // pCtx -- WMI context // pHandler -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // WBEM_E_INVALID_PARAMETER // WBEM_E_FAILED // Win32 error // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::DoGetObjectAsync( IN BSTR bstrObjectPath, IN long lFlags, IN IWbemContext* pCtx, IN IWbemObjectSink* pHandler ) { HRESULT hr = S_OK; if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL) { return WBEM_E_INVALID_PARAMETER; } try { CObjPath ObjPath; _bstr_t bstrClass; auto_ptr pProvBase; if (!ObjPath.Init( bstrObjectPath)) { return WBEM_E_INVALID_PARAMETER; } bstrClass = ObjPath.GetClassName(); CreateClass(bstrClass, m_pNamespace, pProvBase); hr = pProvBase->GetObject( ObjPath, lFlags, pCtx, pHandler ); if (FAILED(hr)) { CProvException exception(hr); hr = SetExtendedStatus(exception, &pHandler); } else // Set status OK { pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0); } } catch (CProvException& prove) { hr = SetExtendedStatus(prove, &pHandler); } catch (_com_error& err) { CProvException exception(err.Error()); hr = SetExtendedStatus(exception, &pHandler); } catch ( ... ) { hr = WBEM_E_FAILED; } return hr; } //*** CInstanceProv::DoGetObjectAsync() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::DoPutInstanceAsync // // Description: // Save this instance. // // Arguments: // pInst -- WMI object to be saved // lFlags -- WMI flag // pCtx -- WMI context // pHandler -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // WBEM_E_INVALID_PARAMETER // WBEM_E_FAILED // Win32 error // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::DoPutInstanceAsync( IN IWbemClassObject* pInst, IN long lFlags, IN IWbemContext* pCtx, IN IWbemObjectSink* pHandler ) { HRESULT hr = S_OK; if (pInst == NULL || pHandler == NULL || m_pNamespace == NULL) { return WBEM_E_INVALID_PARAMETER; } try { _variant_t varClass; auto_ptr pProvBase; CWbemClassObject wcoSrc(pInst); hr = pInst->Get(L"__CLASS", 0, &varClass, 0, 0); CreateClass(varClass.bstrVal, m_pNamespace, pProvBase); hr = pProvBase->PutInstance( wcoSrc, lFlags, pCtx, pHandler ); if (FAILED(hr)) { CProvException exception(hr); hr = SetExtendedStatus(exception, &pHandler); } else // Set status OK { pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0); } } catch (CProvException& prove) { hr = SetExtendedStatus(prove, &pHandler); } catch (_com_error& err) { CProvException exception(err.Error()); hr = SetExtendedStatus(exception, &pHandler); } catch ( ... ) { hr = WBEM_E_FAILED; } return hr; } //*** CInstanceProv::DoPutInstanceAsync() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::DoDeleteInstanceAsync // // Description: // Delete this instance. // // Arguments: // bstrObjectPath -- ObjPath for the instance to be deleted // lFlags -- WMI flag // pCtx -- WMI context // pHandler -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // WBEM_E_INVALID_PARAMETER // WBEM_E_FAILED // Win32 error // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::DoDeleteInstanceAsync( IN BSTR bstrObjectPath, IN long lFlags, IN IWbemContext* pCtx, IN IWbemObjectSink* pHandler ) { HRESULT hr = S_OK; if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL) { return WBEM_E_INVALID_PARAMETER; } try { CObjPath ObjPath; _bstr_t bstrClass; auto_ptr pProvBase; if (!ObjPath.Init(bstrObjectPath)) { return WBEM_E_INVALID_PARAMETER; } bstrClass = ObjPath.GetClassName(); CreateClass(bstrClass, m_pNamespace, pProvBase); hr = pProvBase->DeleteInstance( ObjPath, lFlags, pCtx, pHandler ); if (FAILED(hr)) { CProvException exception( hr ); hr = SetExtendedStatus(exception, &pHandler); } else // Set status OK { pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0); } } catch (CProvException& prove) { hr = SetExtendedStatus(prove, &pHandler); } catch (_com_error& err) { CProvException exception(err.Error()); hr = SetExtendedStatus(exception, &pHandler); } catch ( ... ) { hr = WBEM_E_FAILED; } return hr; } //*** CInstanceProv::DoDeleteInstanceAsync() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::DoExecMethodAsync // // Description: // Execute methods for the given object. // // Arguments: // bstrObjectPath -- Object path to a given object // bstrMethodName -- Name of the method to be invoked // lFlags -- WMI flag // pCtx -- WMI context // pInParams -- Input parameters for the method // pHandler -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::DoExecMethodAsync( IN BSTR bstrObjectPath, IN BSTR bstrMethodName, IN long lFlags, IN IWbemContext* pCtx, IN IWbemClassObject* pInParams, IN IWbemObjectSink* pHandler ) { HRESULT hr = S_OK; if (bstrObjectPath == NULL || pHandler == NULL || m_pNamespace == NULL || bstrMethodName == NULL) { return WBEM_E_INVALID_PARAMETER; } try { CObjPath ObjPath; _bstr_t bstrClass; auto_ptr pProvBase; if (!ObjPath.Init(bstrObjectPath)) { return WBEM_E_INVALID_PARAMETER; } bstrClass = ObjPath.GetClassName(); CreateClass(bstrClass, m_pNamespace, pProvBase); hr = pProvBase->ExecuteMethod( bstrObjectPath, bstrMethodName, lFlags, pInParams, pHandler ); if ( FAILED( hr ) ) { CProvException exception(hr); hr = SetExtendedStatus(exception, &pHandler); } else // Set status OK { pHandler->SetStatus(WBEM_STATUS_COMPLETE, WBEM_S_NO_ERROR, 0, 0); } } catch (CProvException& prove) { hr = SetExtendedStatus(prove, &pHandler); } catch (_com_error& err) { CProvException exception(err.Error()); hr = SetExtendedStatus(exception, &pHandler); } catch ( ... ) { hr = WBEM_E_FAILED; } return hr; } //*** CInstanceProv::DoExecMethodAsync() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::SetExtendedStatus // // Description: // Create and set extended error status. // // Arguments: // rpeIn -- Exception object. // rwcoInstOut -- Reference to WMI instance. // // Return Values: // WBEM_S_NO_ERROR // // Note: // Do not allow CProvException, _com_error or HRESULT exceptions through // this function is called to handle these exceptions. //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::SetExtendedStatus( IN CProvException & rpe, IN IWbemObjectSink ** ppHandler ) { HRESULT hr = WBEM_S_NO_ERROR; HRESULT hrStatus = WBEM_S_NO_ERROR; CComPtr spStatus; WCHAR* pwszErrorMsg = NULL; try { hr = m_pNamespace->GetObject( _bstr_t(PVD_WBEM_EXTENDEDSTATUS), 0, NULL, &spStatus, NULL ); if (SUCCEEDED(hr)) { CWbemClassObject wcoInst; hr = spStatus->SpawnInstance(0, &wcoInst); if (SUCCEEDED(hr)) { _bstr_t bstrError; LONG lMsg = 0; if (MapVdsErrorToMsgAndWMIStatus(rpe.hrGetError(), &lMsg, &hrStatus)) { // Auto-delete string LPWSTR lpwszMsg; lpwszMsg = GetMsg(lMsg); // The following may throw CProvException wcoInst.SetProperty(lpwszMsg, PVD_WBEM_DESCRIPTION); SAFE_FREE(lpwszMsg); } else { if (rpe.PwszErrorMessage()) { bstrError = rpe.PwszErrorMessage(); if (rpe.PwszGetErrorHelpInfo()) { bstrError += L" "; bstrError += rpe.PwszGetErrorHelpInfo(); } } else if (rpe.PwszGetErrorHelpInfo()) { bstrError = rpe.PwszGetErrorHelpInfo(); } // The following may throw CProvException wcoInst.SetProperty((WCHAR*)bstrError, PVD_WBEM_DESCRIPTION); } wcoInst.SetProperty(rpe.hrGetError(), PVD_WBEM_STATUSCODE); wcoInst.SetProperty(PVD_WBEM_PROVIDERNAME, PVD_WBEM_PROP_PROVIDERNAME); hr = (*ppHandler)->SetStatus( 0, hrStatus, 0, wcoInst.data( ) ); hr = hrStatus; } } } catch (CProvException& prove) { hr = prove.hrGetError(); } catch (_com_error& err) { hr = err.Error(); } return hr; } //*** CInstanceProv::SetExtendedStatus() ////////////////////////////////////////////////////////////////////////////// //++ // // HRESULT // CInstanceProv::S_HrCreateThis( // IUnknown * pUnknownOuterIn, // VOID ** ppvOut // ) // // Description: // Create an instance of the instance provider. // // Arguments: // pUnknownOuterIn -- Outer IUnknown pointer. // ppvOut -- Receives the created instance pointer. // // Return Values: // S_OK // //-- ////////////////////////////////////////////////////////////////////////////// HRESULT CInstanceProv::S_HrCreateThis( IN IUnknown* ,// pUnknownOuterIn, OUT VOID** ppv ) { _ASSERTE(ppv != NULL); *ppv = new CInstanceProv(); return S_OK; } //*** CInstanceProv::S_HrCreateThis() ////////////////////////////////////////////////////////////////////////////// //++ // // STDMETHODIMP // CInstanceProv::Initialize // // Description: // Initialize the instance provider. // // Arguments: // pszUserIn -- // lFlagsIn -- WMI flag // pszNamespaceIn -- // pszLocaleIn -- // pNamespaceIn -- // pCtxIn -- WMI context // pInitSinkIn -- WMI sink pointer // // Return Values: // WBEM_S_NO_ERROR // //-- ////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CInstanceProv::Initialize( IN LPWSTR pszUser, IN LONG lFlags, IN LPWSTR pszNamespace, IN LPWSTR pszLocale, IN IWbemServices* pNamespace, IN IWbemContext* pCtx, IN IWbemProviderInitSink* pInitSink ) { HRESULT hr = WBEM_S_NO_ERROR; try { if (!m_fInitialized) { g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_DISK, CClassCreator(CNasDisk::S_CreateThis, PVDR_CLASS_DISK))); g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_VOLUME, CClassCreator(CNasVolume::S_CreateThis, PVDR_CLASS_VOLUME))); g_ClassMap.insert(ClassMap::value_type(PVDR_CLASS_VOLUMEON, CClassCreator(CVolumeOn::S_CreateThis, PVDR_CLASS_VOLUMEON))); hr = CImpersonatedProvider::Initialize( pszUser, lFlags, pszNamespace, pszLocale, pNamespace, pCtx, pInitSink ); m_fInitialized = TRUE; } } catch(...) { hr = E_UNEXPECTED; } return hr; } //*** CInstanceProv::Initialize() // // Returns TRUE if error message was mapped // BOOL MapVdsErrorToMsgAndWMIStatus( IN HRESULT hr, OUT LONG* plMsgNum, OUT HRESULT* pHr ) { _ASSERTE(plMsgNum != NULL); _ASSERTE(pHr != NULL); LONG msg = 0; *plMsgNum = 0; *pHr = WBEM_E_PROVIDER_FAILURE; // Let Win32 errors through if (HRESULT_FACILITY(hr) == FACILITY_WIN32) { *pHr = hr; } // Let WMI errors through else if (HRESULT_FACILITY(hr) == FACILITY_ITF && HRESULT_CODE(hr) > 0x1000 && HRESULT_CODE(hr) < 0x108b) { *pHr = hr; } if ( msg == 0 ) return FALSE; *plMsgNum = msg; return TRUE; }