/****************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Microsoft_SA_Chime_Sample.CPP -- WMI provider class implementation Generated by Microsoft WMI Code Generation Engine - When linking, make sure you link to framedyd.lib & msvcrtd.lib (debug) or framedyn.lib & msvcrt.lib (retail). Description: Provider for the Server Appliance Kit Sample ******************************************************************/ #include // This must be the first include. #include "stdafx.h" #include "ChimeProv.h" const WCHAR PROVIDER_NAME_MICROSOFT_SA_CHIME_SAMPLE[]=L"Microsoft_SA_Chime_Sample"; CMicrosoft_SA_Chime_Sample MyMicrosoft_SA_Chime_SampleSet (PROVIDER_NAME_MICROSOFT_SA_CHIME_SAMPLE, L"root\\cimv2") ; // Property names //=============== const static WCHAR* PINTERVAL = L"Interval" ; const static WCHAR* PTIMETOCHIME = L"TimeToChime" ; const static WCHAR* PTYPE = L"Type" ; // // Registry location // const WCHAR REGKEY_SA_CHIMESETTINGS[]=L"Software\\Microsoft\\ServerAppliance\\Chime"; const WCHAR REGSTR_VAL_CHIME_TYPE[]=L"ChimeType"; const WCHAR REGSTR_VAL_CHIME_INTERVAL[]=L"ChimeInterval"; /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::CMicrosoft_SA_Chime_Sample * * DESCRIPTION : Constructor * * INPUTS : none * * RETURNS : nothing * * COMMENTS : Calls the Provider constructor. * *****************************************************************************/ CMicrosoft_SA_Chime_Sample::CMicrosoft_SA_Chime_Sample (LPCWSTR lpwszName, LPCWSTR lpwszNameSpace ) : Provider(lpwszName, lpwszNameSpace) { } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::~CMicrosoft_SA_Chime_Sample * * DESCRIPTION : Destructor * * INPUTS : none * * RETURNS : nothing * * COMMENTS : * *****************************************************************************/ CMicrosoft_SA_Chime_Sample::~CMicrosoft_SA_Chime_Sample () { } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::EnumerateInstances * * DESCRIPTION : Returns all the instances of this class. * * INPUTS : A pointer to the MethodContext for communication with WinMgmt. * A long that contains the flags described in * IWbemServices::CreateInstanceEnumAsync. Note that the following * flags are handled by (and filtered out by) WinMgmt: * WBEM_FLAG_DEEP * WBEM_FLAG_SHALLOW * WBEM_FLAG_RETURN_IMMEDIATELY * WBEM_FLAG_FORWARD_ONLY * WBEM_FLAG_BIDIRECTIONAL * * RETURNS : WBEM_S_NO_ERROR if successful * * COMMENTS : TO DO: All instances on the machine should be returned here and * all properties that this class knows how to populate must * be filled in. If there are no instances, return * WBEM_S_NO_ERROR. It is not an error to have no instances. * If you are implementing a 'method only' provider, you * should remove this method. * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::EnumerateInstances ( MethodContext* pMethodContext, long lFlags ) { HRESULT hrRet = WBEM_S_NO_ERROR; CInstance *pInstance=NULL; // // Create a new instance based on the passed-in MethodContext. // Note that CreateNewInstance may throw, but will never return NULL. // try{ do { //following call will not return NULL but throw an exception pInstance = CreateNewInstance(pMethodContext); if (FALSE == FillInstance(pInstance)) { TRACE("CMicrosoft_SA_Chime_Sample::EnumInstances FillInstance call failed"); hrRet= WBEM_E_CRITICAL_ERROR; break; } hrRet = pInstance->Commit(); if (FAILED(hrRet)) { TRACE("CMicrosoft_SA_Chime_Sample::EnumInstances Commit call failed"); break; } } while(false); } catch(...) { TRACE("CMicrosoft_SA_Chime_Sample::EnumInstances: Exception caught, exiting"); hrRet = WBEM_E_CRITICAL_ERROR; } if(pInstance) { pInstance->Release(); } return hrRet ; } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::GetObject * * DESCRIPTION : Find a single instance based on the key properties for the * class. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::GetObjectAsync. * * RETURNS : WBEM_S_NO_ERROR if the instance can be found * WBEM_E_NOT_FOUND if the instance described by the key properties * could not be found * WBEM_E_FAILED if the instance could be found but another error * occurred. * * COMMENTS : If you are implementing a 'method only' provider, you should * remove this method. * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::GetObject ( CInstance* pInstance, long lFlags ) { HRESULT hrRet = WBEM_S_NO_ERROR; if(FALSE == FillInstance(pInstance)) { TRACE("CMicrosoft_SA_Chime_Sample::GetObject failed in FillInstance"); hrRet=WBEM_E_CRITICAL_ERROR; } return hrRet ; } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::ExecQuery * * DESCRIPTION : You are passed a method context to use in the creation of * instances that satisfy the query, and a CFrameworkQuery * which describes the query. Create and populate all * instances which satisfy the query. You may return more * instances or more properties than are requested and WinMgmt * will post filter out any that do not apply. * * INPUTS : A pointer to the MethodContext for communication with WinMgmt. * A query object describing the query to satisfy. * A long that contains the flags described in * IWbemServices::CreateInstanceEnumAsync. Note that the following * flags are handled by (and filtered out by) WinMgmt: * WBEM_FLAG_FORWARD_ONLY * WBEM_FLAG_BIDIRECTIONAL * WBEM_FLAG_ENSURE_LOCATABLE * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if queries not supported for * this class or if the query is too complex for this class * to interpret. The framework will call the EnumerateInstances * function instead and let Winmgmt post filter. * WBEM_E_FAILED if the query failed * WBEM_S_NO_ERROR if query was successful * * COMMENTS : TO DO: Most providers will not need to implement this method. If you don't, WinMgmt * will call your enumerate function to get all the instances and perform the * filtering for you. Unless you expect SIGNIFICANT savings from implementing * queries, you should remove this method. You should also remove this method * if you are implementing a 'method only' provider. * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::ExecQuery (MethodContext *pMethodContext, CFrameworkQuery& Query, long lFlags) { return (WBEM_E_PROVIDER_NOT_CAPABLE); } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::PutInstance * * DESCRIPTION : PutInstance should be used in provider classes that can * write instance information back to the hardware or * software. For example: Win32_Environment will allow a * PutInstance to create or update an environment variable. * However, a class like MotherboardDevice will not allow * editing of the number of slots, since it is difficult for * a provider to affect that number. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::PutInstanceAsync. * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if PutInstance is not available * WBEM_E_FAILED if there is an error delivering the instance * WBEM_E_INVALID_PARAMETER if any of the instance properties * are incorrect. * WBEM_S_NO_ERROR if instance is properly delivered * * COMMENTS : TO DO: If you don't intend to support writing to your provider, * or are creating a 'method only' provider, remove this * method. * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::PutInstance ( const CInstance &Instance, long lFlags) { // Use the CInstance Get functions (for example, call // GetCHString(L"Name", sTemp)) against Instance to see the key values // the client requested. return (WBEM_E_PROVIDER_NOT_CAPABLE); } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::DeleteInstance * * DESCRIPTION : DeleteInstance, like PutInstance, actually writes information * to the software or hardware. For most hardware devices, * DeleteInstance should not be implemented, but for software * configuration, DeleteInstance implementation is plausible. * * INPUTS : A pointer to a CInstance object containing the key properties. * A long that contains the flags described in * IWbemServices::DeleteInstanceAsync. * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if DeleteInstance is not available. * WBEM_E_FAILED if there is an error deleting the instance. * WBEM_E_INVALID_PARAMETER if any of the instance properties * are incorrect. * WBEM_S_NO_ERROR if instance is properly deleted. * * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::DeleteInstance ( const CInstance &Instance, long lFlags ) { return (WBEM_E_PROVIDER_NOT_CAPABLE); } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::ExecMethod * * DESCRIPTION : Override this function to provide support for methods. * A method is an entry point for the user of your provider * to request your class perform some function above and * beyond a change of state. (A change of state should be * handled by PutInstance() ) * * INPUTS : A pointer to a CInstance containing the instance the method was executed against. * A string containing the method name * A pointer to the CInstance which contains the IN parameters. * A pointer to the CInstance to contain the OUT parameters. * A set of specialized method flags * * RETURNS : WBEM_E_PROVIDER_NOT_CAPABLE if not implemented for this class * WBEM_S_NO_ERROR if method executes successfully * WBEM_E_FAILED if error occurs executing method * * *****************************************************************************/ HRESULT CMicrosoft_SA_Chime_Sample::ExecMethod ( const CInstance& Instance, const BSTR bstrMethodName, CInstance *pInParams, CInstance *pOutParams, long lFlags) { // For non-static methods, use the CInstance Get functions (for example, // call GetCHString(L"Name", sTemp)) against Instance to see the key // values the client requested. return (WBEM_E_PROVIDER_NOT_CAPABLE); } /***************************************************************************** * * FUNCTION : CMicrosoft_SA_Chime_Sample::FillInstance * * DESCRIPTION : Fills in the parameters for the instance * INPUTS : A pointer to a CInstance object containing the key properties. * RETURNS : BOOL - TRUE if succeeds, FAIL if fails. * *****************************************************************************/ BOOL CMicrosoft_SA_Chime_Sample::FillInstance(CInstance *pInstance) { DWORD dwChimeType = 0; DWORD dwChimeInterval = 0x7FFFFFFF; DWORD dwSecondsToChime = 0; DWORD dwSecondsSinceLastHour = 0; CRegKey crChimeRegKey; LONG lRes; if (NULL == pInstance) { return FALSE; } // // Get ChimeType and ChimeInterval from Registry // lRes = crChimeRegKey.Open(HKEY_LOCAL_MACHINE, REGKEY_SA_CHIMESETTINGS, KEY_READ); if (ERROR_SUCCESS != lRes) { TRACE1("CMicrosoft_SA_Chime_Sample::FillInstance RegOpenKey failed, getlasterror= %x",GetLastError()); return FALSE; } crChimeRegKey.QueryValue(dwChimeType, REGSTR_VAL_CHIME_TYPE); crChimeRegKey.QueryValue(dwChimeInterval, REGSTR_VAL_CHIME_INTERVAL); // // Calculate the TimeToChime (in seconds) by: // 1. Getting the localtime, // 2. Calculating the seconds since last hour (assumes the ChimeInterval // is <= 60 minutes). // 3. Mod that value by dwChimeInterval // 4. Subtract the mod from dwChimeInterval // SYSTEMTIME LocalTime; GetLocalTime(&LocalTime); dwSecondsSinceLastHour = (60*LocalTime.wMinute + LocalTime.wSecond); dwSecondsToChime = dwChimeInterval - (dwSecondsSinceLastHour % dwChimeInterval); // // Set the values // pInstance->SetDWORD(PINTERVAL, dwChimeInterval); pInstance->SetDWORD(PTIMETOCHIME, dwSecondsToChime); pInstance->SetDWORD(PTYPE, dwChimeType); return TRUE; }