Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1163 lines
27 KiB

/*
CWin32Clock.CPP
Module: WMI Current Time Instance Provider
Purpose: The methods of CWin32Clock class are defined here.
Copyright (c)1999 Microsoft Corporation, All Rights Reserved
*/
#include <wbemcli.h>
#include <wbemprov.h>
#include <wbemcomn.h>
#undef _ASSERT
#include <atlbase.h>
#include "genlex.h"
#include "objpath.h"
#include "dnf.h"
#include "datep.h"
#include "Win32Clock.h"
// **** long glNumInst = sizeof(MyDefs)/sizeof(InstDef);
/****************************************************************************/
CWin32Clock::CScheduledEvent::CScheduledEvent(void)
{
m_Type = TypeNONE;
m_cRef = 0;
m_dwId = -1;
m_stLastFiringTime = 0;
m_pWin32Clock = NULL;
m_WQLStmt = NULL;
}
CWin32Clock::CScheduledEvent::~CScheduledEvent(void)
{
if(0 != m_cRef)
{
// **** error
}
if(NULL != m_WQLStmt)
delete[] m_WQLStmt;
}
HRESULT CWin32Clock::CScheduledEvent::Init(CWin32Clock *pClock,
wchar_t *WQLStmt,
ULONG dwId)
{
HRESULT
hr = S_OK;
// **** check for valid arguments
if((NULL == pClock) || (NULL == WQLStmt) || (-1 == dwId))
return WBEM_E_FAILED;
// **** copy to local arguments
if((NULL != m_pWin32Clock) || (NULL != m_WQLStmt))
return WBEM_E_FAILED;
m_dwId = dwId;
m_pWin32Clock = pClock; // **** note: no AddRef() is done here because
// **** the lifetime of this CScheduledEvent obj is
// **** ALWAYS encapsulated within that of pClock
// **** now parse m_WQLStmt to determine values for timer start and interval
hr = ReInit(WQLStmt);
return hr;
}
HRESULT CWin32Clock::CScheduledEvent::ReInit(wchar_t *WQLStmt)
{
HRESULT
hr = WBEM_E_FAILED;
int
nRes;
if(NULL != m_WQLStmt)
delete[] m_WQLStmt;
// **** save WQL expression
m_WQLStmt = new wchar_t[wcslen(WQLStmt) + 1];
if(NULL == m_WQLStmt)
return WBEM_E_OUT_OF_MEMORY;
wcscpy(m_WQLStmt, WQLStmt);
// **** parse WQL expression
CTextLexSource src(m_WQLStmt);
QL1_Parser parser(&src);
QL_LEVEL_1_RPN_EXPRESSION *pExp = NULL;
QL_LEVEL_1_TOKEN *pToken = NULL;
#ifdef WQLDEBUG
wchar_t classbuf[128];
*classbuf = 0;
printf("[1] ----GetQueryClass----\n");
nRes = parser.GetQueryClass(classbuf, 128);
if (nRes)
{
printf("ERROR %d: line %d, token %S\n",
nRes,
parser.CurrentLine(),
parser.CurrentToken());
}
printf("Query class is %S\n", classbuf);
#endif
if(nRes = parser.Parse(&pExp))
{
#ifdef WQLDEBUG
if (nRes)
{
printf("ERROR %d: line %d, token %S\n",
nRes,
parser.CurrentLine(),
parser.CurrentToken());
}
else
{
printf("No errors.\n");
}
#endif
hr = WBEM_E_INVALID_QUERY;
goto cleanup;
}
// **** validate WQL statement
if((NULL == pExp) ||
(NULL == pExp->bsClassName) ||
(wbem_wcsicmp(L"__InstanceModificationEvent", pExp->bsClassName)) ||
(pExp->nNumTokens < 1))
{
#ifdef WQLDEBUG
printf("WQL statement failed validation\n");
#endif
hr = WBEM_E_INVALID_QUERY;
goto cleanup;
}
// **** determine type
for(int i = 0; i < pExp->nNumTokens && (m_Type == TypeNONE); i++)
{
pToken = pExp->pArrayOfTokens + i;
if(NULL == pToken) continue;
if ( (pToken->nTokenType == QL_LEVEL_1_TOKEN::OP_EXPRESSION) &&
(pToken->vConstValue.vt == VT_BSTR))
{
long nElts = pToken->PropertyName.GetNumElements();
LPCWSTR pAttrName = pToken->PropertyName.GetStringAt(nElts -1);
if ( pAttrName != NULL &&
0 == wbem_wcsicmp(L"targetinstance", pAttrName))
{
if(0 == wbem_wcsicmp(WIN32LOCALTIMECLASS, pToken->vConstValue.bstrVal)) m_Type = TypeLocal;
else if(0 == wbem_wcsicmp(WIN32UTCTIMECLASS, pToken->vConstValue.bstrVal)) m_Type = TypeUTC;
}
}
}
if(TypeNONE == m_Type)
{
hr = WBEM_E_INVALID_QUERY;
goto cleanup;
}
// **** interpret WQL Expression
#ifdef WQLDEBUG
printf("\n[2] ----ShowParseTree----\n");
pExp->Dump("CON");
printf("\n[3] ----ShowRebuiltQuery----\n");
LPWSTR wszText = pExp->GetText();
printf("--WQL passed to provider--\n");
printf("%S\n", wszText);
printf("\n[4] ----ShowInterpretation----\n");
#endif
try
{
hr = m_WQLTime.Init(pExp);
}
catch(...)
{
hr = WBEM_E_FAILED;
goto cleanup;
}
#ifdef WQLDEBUG
printf("\n\n[5] ----End of WQL Compilation----\n");
delete [] wszText;
#endif
cleanup:
delete pExp;
return hr;
}
void CWin32Clock::CScheduledEvent::AddRef()
{
InterlockedIncrement((long *)&m_cRef);
}
void CWin32Clock::CScheduledEvent::Release()
{
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
if(0L == nNewCount)
delete this;
}
int CWin32Clock::CScheduledEvent::GetInstructionType()
{
return INSTTYPE_WBEM;
}
CWbemTime CWin32Clock::CScheduledEvent::GetNextFiringTime(CWbemTime LastFiringTime,
long *plFiringCount) const
{
FILETIME
FileTime,
FileTime2;
ULONGLONG
NextFiringTime,
CurrentTime;
CWbemTime
ResultTime;
int
nMisses = 0;
// **** save the firing time for event just fired from LastFiringTime
((CWin32Clock::CScheduledEvent*)this)->m_stLastFiringTime = LastFiringTime.Get100nss();
// **** calculate the next firing time after LastFiringTime and after the current time
GetFileTime(&FileTime);
CurrentTime = FileTime.dwHighDateTime;
CurrentTime = (CurrentTime << 32) + FileTime.dwLowDateTime;
while((NextFiringTime = ((WQLDateTime*)&m_WQLTime)->GetNextTime()) <= CurrentTime)
nMisses += 1;
if(-1 == NextFiringTime)
{
// **** no future event to be scheduled so, so indicate
return CWbemTime::GetInfinity();
}
if(NULL != plFiringCount)
*plFiringCount = nMisses;
// **** if local time, convert to UTC time for the scheduling logic
if(TypeLocal == m_Type)
{
FileTime.dwLowDateTime = ((NextFiringTime << 32) >> 32);
FileTime.dwHighDateTime = (NextFiringTime >> 32);
LocalFileTimeToFileTime(&FileTime, &FileTime2);
NextFiringTime = FileTime2.dwHighDateTime;
NextFiringTime = (NextFiringTime << 32) + FileTime2.dwLowDateTime;
}
ResultTime.Set100nss(NextFiringTime);
return ResultTime;
}
CWbemTime CWin32Clock::CScheduledEvent::GetFirstFiringTime() const
{
SYSTEMTIME
CurrentTime;
CWbemTime
ResultTime;
ULONGLONG
ullStartTime;
GetTime(&CurrentTime);
/*
Since the finest granularity used by the time provider is seconds, set milliseconds
to zero so that we can compare two FILETIME values in the Fire method and have
the numbers agree.
*/
CurrentTime.wMilliseconds = 0;
ullStartTime = ((WQLDateTime*)&m_WQLTime)->SetStartTime(&CurrentTime);
if(TypeLocal == m_Type)
{
FILETIME
FileTime,
FileTime2;
FileTime.dwLowDateTime = ((ullStartTime << 32) >> 32);
FileTime.dwHighDateTime = (ullStartTime >> 32);
LocalFileTimeToFileTime(&FileTime, &FileTime2);
ullStartTime = FileTime2.dwHighDateTime;
ullStartTime = (ullStartTime << 32) + FileTime2.dwLowDateTime;
}
ResultTime.Set100nss(ullStartTime);
return ResultTime;
}
HRESULT CWin32Clock::CScheduledEvent::Fire(long lNumTimes,
CWbemTime NextFiringTime)
{
HRESULT
hr = WBEM_E_FAILED;
FILETIME
ft,
ft2;
SYSTEMTIME
SystemTime;
CComPtr<IWbemClassObject>
pSystemTime;
// **** Do a check of arguments and make sure we have pointer to sink obj
if((NULL == m_pWin32Clock) || (NULL == m_pWin32Clock->m_ClockResetThread))
{
hr = WBEM_E_INVALID_PARAMETER;
}
// **** create an instance of Win32_CurrentTime for each timezone
else
{
CInCritSec
ics(&(m_pWin32Clock->m_csWin32Clock));
// **** reconstitute a SYSTEMTIME from the current firing time
ft.dwLowDateTime = ((m_stLastFiringTime << 32) >> 32);
ft.dwHighDateTime = (m_stLastFiringTime >> 32);
if(((TypeLocal == m_Type) && (m_pWin32Clock->m_MostRecentLocalFiringTime != m_stLastFiringTime)) ||
((TypeUTC == m_Type) && (m_pWin32Clock->m_MostRecentUTCFiringTime != m_stLastFiringTime)))
{
if(TypeLocal == m_Type)
{
m_pWin32Clock->m_MostRecentLocalFiringTime = m_stLastFiringTime;
FileTimeToLocalFileTime(&ft, &ft2);
ft = ft2;
}
else if(TypeUTC == m_Type)
m_pWin32Clock->m_MostRecentUTCFiringTime = m_stLastFiringTime;
if(FileTimeToSystemTime(&ft, &SystemTime))
{
#ifdef WQLDEBUG
printf("[%d] Fire: Misses(%d) %d/%d/%d %d:%d:%d",
m_dwId,
lNumTimes,
SystemTime.wMonth,
SystemTime.wDay,
SystemTime.wYear,
SystemTime.wHour,
SystemTime.wMinute,
SystemTime.wSecond);
#else
// **** Send the object to the caller
if(TypeUTC == m_Type)
hr = CWin32Clock::SystemTimeToWin32_CurrentTime(m_pWin32Clock->m_pUTCTimeClassDef, &pSystemTime, &SystemTime);
else if(TypeLocal == m_Type)
hr = CWin32Clock::SystemTimeToWin32_CurrentTime(m_pWin32Clock->m_pLocalTimeClassDef, &pSystemTime, &SystemTime);
hr = m_pWin32Clock->SendEvent(pSystemTime);
#endif
}
else
hr = WBEM_E_FAILED;
}
}
return hr;
}
/******************************************************************/
LRESULT CALLBACK Win32ClockProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
DWORD CWin32Clock::AsyncEventThread(LPVOID pArg)
{
if(NULL == pArg)
return -1;
CWin32Clock
*pCWin32Clock = (CWin32Clock*)pArg;
WNDCLASS wndclass;
MSG msg;
BOOL bRet;
// **** create top level window to receive system messages
wndclass.style = 0;
wndclass.lpfnWndProc = Win32ClockProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(DWORD);
wndclass.hInstance = GetModuleHandle(NULL);
wndclass.hIcon = NULL;
wndclass.hCursor = NULL;
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = TEXT("Win32Clock");
if(!RegisterClass(&wndclass))
{
if(GetLastError() != ERROR_CLASS_ALREADY_EXISTS)
{
return NULL;
}
}
HMODULE
hModule = GetModuleHandle(NULL);
if(NULL == hModule)
return -1;
try
{
pCWin32Clock->m_hEventWindowHandle = CreateWindow(TEXT("Win32Clock"),
TEXT("Win32ClockMsgs"),
WS_OVERLAPPED,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
HWND_MESSAGE,
NULL,
hModule,
NULL);
}
catch(...)
{
return -1;
}
if(NULL == pCWin32Clock->m_hEventWindowHandle)
{
return NULL;
}
ShowWindow(pCWin32Clock->m_hEventWindowHandle, SW_HIDE);
// **** start the message loop
while(GetMessage(&msg, pCWin32Clock->m_hEventWindowHandle, 0, 0))
{
switch (msg.message)
{
case WM_TIMECHANGE:
pCWin32Clock->ReAlignToCurrentTime();
break;
default:
DefWindowProc(pCWin32Clock->m_hEventWindowHandle, msg.message, msg.wParam, msg.lParam);
}
}
// **** cleanup
bRet = DestroyWindow(pCWin32Clock->m_hEventWindowHandle);
bRet = UnregisterClass(TEXT("Win32Clock"), 0);
return 0;
}
void CWin32Clock::CScheduledEvent::GetTime(SYSTEMTIME *TheTime) const
{
if(NULL != TheTime)
{
memset(TheTime, 0, sizeof(SYSTEMTIME));
if(TypeLocal == m_Type)
GetLocalTime(TheTime);
else if(TypeUTC == m_Type)
GetSystemTime(TheTime);
}
}
void CWin32Clock::CScheduledEvent::GetFileTime(FILETIME *TheTime) const
{
SYSTEMTIME
SysTime;
if(NULL != TheTime)
{
memset(TheTime, 0, sizeof(FILETIME));
if(TypeLocal == m_Type)
{
GetLocalTime(&SysTime);
SystemTimeToFileTime(&SysTime, TheTime);
}
else if(TypeUTC == m_Type)
{
GetSystemTime(&SysTime);
SystemTimeToFileTime(&SysTime, TheTime);
}
}
}
HRESULT CWin32Clock::SendEvent(IWbemClassObject *pSystemTime)
{
HRESULT
hr = WBEM_E_FAILED;
CComPtr<IWbemClassObject>
pInstanceModEvnt;
CComVariant
v;
// **** if m_pSink has not been provided by winmgmt just drop
// **** generated events on the floor
if((NULL != m_pSink) && (NULL != pSystemTime))
{
// **** create and init instance of __InstanceModificationEvent
hr = m_pInstModClassDef->SpawnInstance(0, &pInstanceModEvnt);
if(FAILED(hr)) return hr;
// **** put Win32_CurrentTime into __InstanceModificationEvent
v.vt = VT_UNKNOWN;
v.punkVal = NULL;
hr = pSystemTime->QueryInterface(IID_IUnknown, (void**)&(v.punkVal));
if(FAILED(hr)) return hr;
hr = pInstanceModEvnt->Put(L"TargetInstance", 0, &v, 0);
if(FAILED(hr)) return hr;
// **** deliver new event to WMI
hr = m_pSink->Indicate(1, &pInstanceModEvnt);
}
return hr;
}
HRESULT CWin32Clock::ReAlignToCurrentTime()
{
CInCritSec
ics(&m_csWin32Clock);
HRESULT
hr = S_OK;
ULONG
i,
nElts;
CScheduledEvent
*pcEvent;
#ifdef WQLDEBUG
printf("System Clock Resync\n");
#endif
m_EventArray.Lock();
nElts = *(ULONG *)(&(this->m_EventArray)); // voodoo
m_MostRecentLocalFiringTime = 0;
m_MostRecentUTCFiringTime = 0;
for(i = 0; i < nElts; i++)
{
// **** pull event from the event queue
pcEvent = m_EventArray[i];
if(NULL != pcEvent)
{
// **** change time for event obj and re-queue
m_Timer.Remove(&CIdentityTest(pcEvent));
m_Timer.Set(pcEvent);
}
}
m_EventArray.UnLock();
return hr;
}
CWin32Clock::CWin32Clock(CLifeControl* pControl)
: m_Timer(), m_EventArray(), m_pControl(pControl)
{
pControl->ObjectCreated((IWbemServices*)this);
m_cRef = 0;
m_MostRecentLocalFiringTime = 0;
m_MostRecentUTCFiringTime = 0;
m_pNs = NULL;
m_pSink = NULL;
m_pInstModClassDef = NULL;
m_pLocalTimeClassDef = NULL;
m_pUTCTimeClassDef = NULL;
m_ClockResetThread = NULL;
m_hEventWindowHandle = NULL;
}
CWin32Clock::~CWin32Clock(void)
{
// **** Kill Async thread if it has been started
if(NULL != m_ClockResetThread)
{
BOOL
bRes;
do
{
bRes = PostMessage(m_hEventWindowHandle, WM_QUIT, 0, 0);
}
while(WAIT_TIMEOUT == WaitForSingleObject(m_ClockResetThread, 6000));
}
// **** shutdown event thread
m_Timer.Shutdown();
// **** release all held COM objects
if(NULL != m_pNs) m_pNs->Release();
if(NULL != m_pSink) m_pSink->Release();
if(NULL != m_pInstModClassDef) m_pInstModClassDef->Release();
if(NULL != m_pLocalTimeClassDef) m_pLocalTimeClassDef->Release();
if(NULL != m_pUTCTimeClassDef) m_pUTCTimeClassDef->Release();
m_pControl->ObjectDestroyed((IWbemServices*)this);
}
// **** ***************************************************************************
// ****
// **** CWin32Clock::QueryInterface
// **** CWin32Clock::AddRef
// **** CWin32Clock::Release
// ****
// **** Purpose: IUnknown members for CWin32Clock object.
// **** ***************************************************************************
STDMETHODIMP CWin32Clock::QueryInterface(REFIID riid, PVOID *ppv)
{
*ppv=NULL;
// **** cast to the type of the base class specified by riid
if(IID_IWbemEventProvider == riid)
{
*ppv = (IWbemEventProvider *)this;
}
else if(IID_IWbemEventProviderQuerySink == riid)
{
*ppv = (IWbemEventProviderQuerySink *)this;
}
else if(IID_IWbemServices == riid)
{
*ppv=(IWbemServices*)this;
}
else if(IID_IUnknown == riid || IID_IWbemProviderInit == riid)
{
*ppv=(IWbemProviderInit*)this;
}
if(NULL!=*ppv)
{
AddRef();
return S_OK;
}
else
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CWin32Clock::AddRef(void)
{
return InterlockedIncrement((long *)&m_cRef);
}
STDMETHODIMP_(ULONG) CWin32Clock::Release(void)
{
ULONG nNewCount = InterlockedDecrement((long *)&m_cRef);
if(0L == nNewCount)
delete this;
return nNewCount;
}
/*
IWbemProviderInit::Initialize
Purpose: This is the implementation of IWbemProviderInit. The method
is need to initialize with CIMOM.
The members set up include:
m_pNs
m_pLocalTimeClassDef
m_pUTCTimeClassDef
m_pInstModClassDef
*/
HRESULT CWin32Clock::Initialize(LPWSTR pszUser,
LONG lFlags,
LPWSTR pszNamespace,
LPWSTR pszLocale,
IWbemServices *pNamespace,
IWbemContext *pCtx,
IWbemProviderInitSink *pInitSink)
{
HRESULT
hr = WBEM_E_FAILED;
if((NULL != pNamespace) && (NULL != pInitSink))
{
m_pNs = pNamespace;
m_pNs->AddRef();
// **** get needed class definitions
hr = m_pNs->GetObject(WIN32LOCALTIMECLASS,
0, pCtx, &m_pLocalTimeClassDef, 0);
if(SUCCEEDED(hr))
hr = m_pNs->GetObject(WIN32UTCTIMECLASS,
0, pCtx, &m_pUTCTimeClassDef, 0);
if(SUCCEEDED(hr))
hr = m_pNs->GetObject(INSTMODEVCLASS,
0, pCtx, &m_pInstModClassDef, 0);
if(WBEM_S_NO_ERROR == hr)
{
pInitSink->SetStatus(WBEM_S_INITIALIZED,0);
hr = WBEM_NO_ERROR;
}
}
// **** if there was a problem, release the resources we have aquired
if(FAILED(hr))
{
if(NULL != m_pLocalTimeClassDef) { m_pLocalTimeClassDef->Release(); m_pLocalTimeClassDef = NULL; }
if(NULL != m_pUTCTimeClassDef) { m_pUTCTimeClassDef->Release(); m_pUTCTimeClassDef = NULL; }
if(NULL != m_pInstModClassDef) { m_pInstModClassDef->Release(); m_pInstModClassDef = NULL; }
}
return hr;
}
/*
IWbemEventProvider::ProvideEvents
Purpose: register to provide events to the WMI service
*/
HRESULT CWin32Clock::ProvideEvents(IWbemObjectSink *pSink,
long lFlags)
{
HRESULT
hr = WBEM_S_NO_ERROR;
// **** copy object sink for future event registrations
m_pSink = pSink;
if(NULL != m_pSink)
m_pSink->AddRef();
else
hr = WBEM_E_FAILED;
// **** start system clock change adj. thread
DWORD dwThreadId;
if(NULL == m_ClockResetThread)
{
m_ClockResetThread = CreateThread(
NULL, // pointer to thread security attributes
0, // initial thread stack size, in bytes
(LPTHREAD_START_ROUTINE)AsyncEventThread, // pointer to thread function
(LPVOID)this, // argument for new thread
0, // creation flags
&dwThreadId); // pointer to returned thread identifier
if(NULL == m_ClockResetThread)
hr = WBEM_E_FAILED;
}
else
hr = WBEM_E_FAILED;
return hr;
}
/*
IWbemEventProviderQuerySink::NewQuery
Purpose: add a new query for event generation
*/
HRESULT CWin32Clock::NewQuery(ULONG dwId,
wchar_t *wszQueryLanguage,
wchar_t *wszQuery)
{
HRESULT
hr = WBEM_E_FAILED;
CScheduledEvent
*pNewEvent = NULL;
if(wbem_wcsicmp(L"WQL", wszQueryLanguage) || (NULL == wszQuery))
return WBEM_E_FAILED;
// **** see if event obj with dwId is already in queue
pNewEvent = m_EventArray(dwId, TRUE); // find registered event query
if(NULL != pNewEvent)
{
#ifdef WQLDEBUG
printf("[%d] Redefinition: %s\n", dwId, wszQuery);
#endif
if(wbem_wcsicmp(wszQuery, pNewEvent->m_WQLStmt))
{
hr = m_Timer.Remove(&CIdentityTest(pNewEvent)); // may or may not be in queue
hr = pNewEvent->ReInit(wszQuery); // on failure, NewEvent is preserved
m_Timer.Set(pNewEvent);
}
m_EventArray.UnLock();
}
// **** this is a new event, create it and place it in the event queue
else
{
#ifdef WQLDEBUG
printf("[%d] Definition: %s\n", dwId, wszQuery);
#endif
// **** create new event and initialize
pNewEvent = new CScheduledEvent();
if(NULL == pNewEvent)
hr = WBEM_E_OUT_OF_MEMORY;
else
{
pNewEvent->AddRef();
hr = pNewEvent->Init(this, wszQuery, dwId);
// **** add event to queue
if(SUCCEEDED(hr))
{
m_EventArray.Insert(pNewEvent, dwId);
hr = m_Timer.Set(pNewEvent);
}
else
{
pNewEvent->Release();
pNewEvent = NULL;
}
}
}
return hr;
}
/*
IWbemEventProviderQuerySink::CancelQuery
Purpose: remove an event generator from the queue
*/
HRESULT CWin32Clock::CancelQuery(ULONG dwId)
{
CInCritSec
ics(&m_csWin32Clock);
CScheduledEvent
*pDeadEvent = NULL;
HRESULT hr = WBEM_S_NO_ERROR;
// **** first find element in list and remove it
pDeadEvent = m_EventArray(dwId, TRUE);
if(NULL != pDeadEvent)
{
m_EventArray.Remove(pDeadEvent);
m_EventArray.UnLock();
hr = m_Timer.Remove(&CIdentityTest(pDeadEvent));
// **** now kill it dead
pDeadEvent->Release();
pDeadEvent = NULL;
}
return hr;
}
/*
IWbemServices::CreateInstanceEnumAsync
Purpose: Asynchronously enumerates the instances.
*/
HRESULT CWin32Clock::CreateInstanceEnumAsync(const BSTR RefStr,
long lFlags,
IWbemContext *pCtx,
IWbemObjectSink FAR* pHandler)
{
HRESULT
sc = WBEM_E_FAILED;
IWbemClassObject
FAR* pNewInst = NULL;
SYSTEMTIME
TheTime;
// **** Do a check of arguments and make sure we have pointer to Namespace
if(NULL == pHandler)
{
return WBEM_E_INVALID_PARAMETER;
}
// **** Create Win32_CurrentTime instance
else if(0 == wbem_wcsicmp(RefStr, WIN32LOCALTIMECLASS))
{
GetLocalTime(&TheTime);
sc = SystemTimeToWin32_CurrentTime(m_pLocalTimeClassDef, &pNewInst, &TheTime);
// **** Send the object to the caller
pHandler->Indicate(1,&pNewInst);
pNewInst->Release();
}
// **** Create Win32_CurrentTime instance
else if(0 == wbem_wcsicmp(RefStr, WIN32UTCTIMECLASS))
{
GetSystemTime(&TheTime);
sc = SystemTimeToWin32_CurrentTime(m_pUTCTimeClassDef, &pNewInst, &TheTime);
// **** Send the object to the caller
pHandler->Indicate(1,&pNewInst);
pNewInst->Release();
}
else if(0 == wbem_wcsicmp(RefStr, L"Win32_CurrentTime"))
{}
else
{
sc = WBEM_E_INVALID_CLASS;
}
// **** Set status
pHandler->SetStatus(0, sc, NULL, NULL);
return sc;
}
/*
IWbemServices::GetObjectByPathAsync
Purpose: Creates an instance given a particular path value.
*/
HRESULT CWin32Clock::GetObjectAsync(const BSTR ObjectPath,
long lFlags,
IWbemContext *pCtx,
IWbemObjectSink FAR* pHandler)
{
HRESULT
sc = WBEM_E_FAILED;
IWbemClassObject
FAR* pObj = NULL;
WCHAR
*pwcTest = NULL,
*pwcVALUE = NULL;
CObjectPathParser
ObjPath(e_ParserAcceptRelativeNamespace);
ParsedObjectPath
*pParsedObjectPath = NULL;
SYSTEMTIME
SystemTime;
// **** Parse ObjectPath into a key member name and value
// **** <CLASS>.<MEMBER>="<VALUE>"
if(NULL == ObjectPath)
return WBEM_E_INVALID_OBJECT_PATH;
// **** parse object path
if((ObjPath.NoError != ObjPath.Parse(ObjectPath, &pParsedObjectPath)) || (NULL == pParsedObjectPath))
{
ERRORTRACE((LOG_ESS, "Win32_LocalTime: Parse error for object: %S\n", ObjectPath));
sc = WBEM_E_INVALID_QUERY;
}
// **** do the get, pass the object on to the notify
if(0 == wbem_wcsicmp(WIN32LOCALTIMECLASS, pParsedObjectPath->m_pClass))
{
GetLocalTime(&SystemTime);
sc = SystemTimeToWin32_CurrentTime(m_pLocalTimeClassDef, &pObj, &SystemTime);
if(WBEM_S_NO_ERROR == sc)
{
pHandler->Indicate(1,&pObj);
pObj->Release();
}
}
else if(0 == wbem_wcsicmp(WIN32UTCTIMECLASS, pParsedObjectPath->m_pClass))
{
GetSystemTime(&SystemTime);
sc = SystemTimeToWin32_CurrentTime(m_pUTCTimeClassDef, &pObj, &SystemTime);
if(WBEM_S_NO_ERROR == sc)
{
pHandler->Indicate(1,&pObj);
pObj->Release();
}
}
else
{
ERRORTRACE((LOG_ESS, "Win32_LocalTime: Parse error for object: %S\n", ObjectPath));
sc = WBEM_E_INVALID_QUERY;
}
// **** Set Status
pHandler->SetStatus(0,sc, NULL, NULL);
return sc;
}
/*
CWin32Clock::CreateInstCurrentTime
Purpose: creates an instance of the object Win32_CurrentTime representing
the current time with the given offset UTCOffset
*/
HRESULT CWin32Clock::SystemTimeToWin32_CurrentTime(IWbemClassObject *pClassDef, IWbemClassObject ** pNewInst, SYSTEMTIME *TheTime)
{
HRESULT
sc = WBEM_E_FAILED;
VARIANT
v;
// **** create blank instance of class InstTime
sc = pClassDef->SpawnInstance(0, pNewInst);
if(FAILED(sc))
return sc;
// **** Create Win32_CurrentTime instance
v.vt = VT_I4;
v.lVal = TheTime->wYear;
sc = (*pNewInst)->Put(L"Year", 0, &v, 0);
v.lVal = TheTime->wMonth;
sc = (*pNewInst)->Put(L"Month", 0, &v, 0);
v.lVal = TheTime->wDay;
sc = (*pNewInst)->Put(L"Day", 0, &v, 0);
v.lVal = TheTime->wDayOfWeek;
sc = (*pNewInst)->Put(L"DayOfWeek", 0, &v, 0);
v.lVal = (((8 - (TheTime->wDay - TheTime->wDayOfWeek + 7) % 7) % 7) + TheTime->wDay -1) / 7 + 1;
sc = (*pNewInst)->Put(L"WeekInMonth", 0, &v, 0);
v.lVal = (TheTime->wMonth - 1) / 3 + 1;
sc = (*pNewInst)->Put(L"Quarter", 0, &v, 0);
v.lVal = TheTime->wHour;
sc = (*pNewInst)->Put(L"Hour", 0, &v, 0);
v.lVal = TheTime->wMinute;
sc = (*pNewInst)->Put(L"Minute", 0, &v, 0);
v.lVal = TheTime->wSecond;
sc = (*pNewInst)->Put(L"Second", 0, &v, 0);
VariantClear(&v);
return sc;
}