Home | History | Annotate | Download | only in include
      1 /**
      2  * This file has no copyright assigned and is placed in the Public Domain.
      3  * This file is part of the mingw-w64 runtime package.
      4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
      5  */
      6 #ifndef __ATLWMIPROV_H__
      7 #define __ATLWMIPROV_H__
      8 
      9 #ifndef __cplusplus
     10 #error Requires C++ compilation (use a .cpp suffix)
     11 #endif
     12 
     13 #include <wbemprov.h>
     14 #include <wmiutils.h>
     15 
     16 namespace ATL {
     17   class ATL_NO_VTABLE IWbemInstProviderImpl : public IWbemServices,public IWbemProviderInit {
     18   public:
     19     HRESULT WINAPI OpenNamespace(const BSTR Namespace,__LONG32 lFlags,IWbemContext *pCtx,IWbemServices **ppWorkingNamespace,IWbemCallResult **ppResult) {return WBEM_E_NOT_SUPPORTED;};
     20     HRESULT WINAPI CancelAsyncCall(IWbemObjectSink *pSink) {return WBEM_E_NOT_SUPPORTED;};
     21     HRESULT WINAPI QueryObjectSink(__LONG32 lFlags,IWbemObjectSink **ppResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     22     HRESULT WINAPI GetObject(const BSTR ObjectPath,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject **ppObject,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     23     HRESULT WINAPI PutClass(IWbemClassObject *pObject,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     24     HRESULT WINAPI PutClassAsync(IWbemClassObject *pObject,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     25     HRESULT WINAPI DeleteClass(const BSTR Class,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     26     HRESULT WINAPI DeleteClassAsync(const BSTR Class,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     27     HRESULT WINAPI CreateClassEnum(const BSTR Superclass,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
     28     HRESULT WINAPI CreateClassEnumAsync(const BSTR Superclass,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     29     HRESULT WINAPI PutInstance(IWbemClassObject *pInst,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     30     HRESULT WINAPI DeleteInstance(const BSTR ObjectPath,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     31     HRESULT WINAPI CreateInstanceEnum(const BSTR Class,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
     32     HRESULT WINAPI ExecQuery(const BSTR QueryLanguage,const BSTR Query,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
     33     HRESULT WINAPI ExecNotificationQuery(const BSTR QueryLanguage,const BSTR Query,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
     34     HRESULT WINAPI ExecNotificationQueryAsync(const BSTR QueryLanguage,const BSTR Query,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     35     HRESULT WINAPI ExecMethod(const BSTR strObjectPath,const BSTR strMethodName,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject *pInParams,IWbemClassObject **ppOutParams,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
     36     HRESULT WINAPI ExecMethodAsync(const BSTR strObjectPath,const BSTR strMethodName,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject *pInParams,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
     37   };
     38 
     39   class CProviderHelper {
     40   private:
     41     CComPtr<IWbemClassObject> m_pErrorObject;
     42     HRESULT m_hr;
     43   public:
     44     CProviderHelper(IWbemServices *pNamespace,IWbemContext *pCtx) {
     45       m_hr = WBEM_E_FAILED;
     46       m_pErrorObject = NULL;
     47       if(!pNamespace) {
     48 	m_hr = WBEM_E_INVALID_PARAMETER;
     49 	ATLASSERT (0);
     50 	return;
     51       }
     52       BSTR bstrString = SysAllocString(L"__ExtendedStatus");
     53       if(!bstrString) {
     54 	m_hr = WBEM_E_OUT_OF_MEMORY;
     55 	return;
     56       }
     57       m_hr = pNamespace->GetObject(bstrString,0,pCtx,&m_pErrorObject,NULL);
     58       SysFreeString(bstrString);
     59       return;
     60     }
     61     virtual ~CProviderHelper() { }
     62     HRESULT WINAPI ConstructErrorObject (const ULONG ulStatusCode,const BSTR bstrDescription,const BSTR bstrOperation,const BSTR bstrParameter,const BSTR bstrProviderName,IWbemClassObject **ppErrorObject) {
     63       static const LPWSTR lpwstrDescription = L"Description";
     64       static const LPWSTR lpwstrOperation = L"Operation";
     65       static const LPWSTR lpwstrStatusCode = L"StatusCode";
     66       static const LPWSTR lpwstrParameterInfo = L"ParameterInfo";
     67       static const LPWSTR lpwstrProviderName = L"ProviderName";
     68 
     69       if(FAILED (m_hr)) {
     70 	ATLASSERT (0);
     71 	return m_hr;
     72       }
     73       if(!ppErrorObject) {
     74 	ATLASSERT (0);
     75 	return WBEM_E_INVALID_PARAMETER;
     76       }
     77       HRESULT hr = m_pErrorObject->SpawnInstance(0,ppErrorObject);
     78       if(FAILED(hr)) return hr;
     79       VARIANT var;
     80       VariantInit(&var);
     81       var.vt = VT_I4;
     82       var.lVal = ulStatusCode;
     83       hr = (*ppErrorObject)->Put(lpwstrStatusCode,0,&var,0);
     84       if(FAILED(hr)) return hr;
     85       var.vt = VT_BSTR;
     86       if(bstrDescription!=NULL) {
     87 	var.bstrVal = bstrDescription;
     88 	hr = (*ppErrorObject)->Put(lpwstrDescription,0,&var,0);
     89 	if(FAILED(hr)) return hr;
     90       }
     91       if(bstrOperation!=NULL) {
     92 	var.bstrVal = bstrOperation;
     93 	hr = (*ppErrorObject)->Put(lpwstrOperation,0,&var,0);
     94 	if(FAILED(hr)) return hr;
     95       }
     96       if(bstrParameter!=NULL) {
     97 	var.bstrVal = bstrParameter;
     98 	hr = (*ppErrorObject)->Put(lpwstrParameterInfo,0,&var,0);
     99 	if(FAILED(hr)) return hr;
    100       }
    101       if(bstrProviderName!=NULL) {
    102 	var.bstrVal = bstrProviderName;
    103 	hr = (*ppErrorObject)->Put(lpwstrProviderName,0,&var,0);
    104 	if(FAILED(hr)) return hr;
    105       }
    106       return hr;
    107     }
    108   };
    109 
    110   class CIntrinsicEventProviderHelper : public CProviderHelper {
    111   private:
    112     CComPtr<IWbemClassObject> m_pCreationEventClass;
    113     CComPtr<IWbemClassObject> m_pDeletionEventClass;
    114     CComPtr<IWbemClassObject> m_pModificationEventClass;
    115     HRESULT m_hr;
    116   public:
    117     CIntrinsicEventProviderHelper(IWbemServices *pNamespace,IWbemContext *pCtx) : CProviderHelper (pNamespace,pCtx) {
    118       m_hr = WBEM_E_FAILED;
    119       if(!pNamespace || !pCtx) {
    120 	m_hr = WBEM_E_INVALID_PARAMETER;
    121 	ATLASSERT (0);
    122 	return;
    123       }
    124       m_pCreationEventClass = NULL;
    125       m_pModificationEventClass = NULL;
    126       m_pDeletionEventClass = NULL;
    127       BSTR bstrString = SysAllocString(L"__InstanceCreationEvent");
    128       if(!bstrString) {
    129 	m_hr = WBEM_E_OUT_OF_MEMORY;
    130 	return;
    131       }
    132       m_hr = pNamespace->GetObject(bstrString,0,pCtx,&m_pCreationEventClass,NULL);
    133       SysFreeString(bstrString);
    134       bstrString=NULL;
    135       if(FAILED(m_hr)) return;
    136       bstrString = SysAllocString(L"__InstanceModificationEvent");
    137       if(!bstrString) {
    138 	m_hr = WBEM_E_OUT_OF_MEMORY;
    139 	return;
    140       }
    141       m_hr = pNamespace->GetObject(bstrString,0,pCtx,&m_pModificationEventClass,NULL);
    142       SysFreeString(bstrString);
    143       bstrString=NULL;
    144       if(FAILED(m_hr)) return;
    145       bstrString = SysAllocString(L"__InstanceDeletionEvent");
    146       if(!bstrString) {
    147 	m_hr = WBEM_E_OUT_OF_MEMORY;
    148 	return;
    149       }
    150       m_hr = pNamespace->GetObject(bstrString,0,pCtx,&m_pDeletionEventClass,NULL);
    151       SysFreeString(bstrString);
    152       bstrString=NULL;
    153       if(FAILED(m_hr)) return;
    154       return;
    155     }
    156     virtual ~CIntrinsicEventProviderHelper() { }
    157     HRESULT WINAPI FireCreationEvent(IWbemClassObject *pNewInstance,IWbemObjectSink *pSink) {
    158       if(FAILED(m_hr)) {
    159 	ATLASSERT (0);
    160 	return m_hr;
    161       }
    162       if(!pNewInstance || !pSink) {
    163 	ATLASSERT (0);
    164 	return WBEM_E_INVALID_PARAMETER;
    165       }
    166       CComPtr<IWbemClassObject> pEvtInstance;
    167       HRESULT hr = m_pCreationEventClass->SpawnInstance(0,&pEvtInstance);
    168       if(FAILED(hr)) return hr;
    169       VARIANT var;
    170       VariantInit(&var);
    171       var.vt = VT_UNKNOWN;
    172       CComQIPtr<IUnknown,&IID_IUnknown>pTemp(pNewInstance);
    173       var.punkVal = pTemp;
    174       hr = pEvtInstance->Put(L"TargetInstance",0,&var,0);
    175       if(FAILED(hr)) return hr;
    176       IWbemClassObject *_pEvtInstance = (IWbemClassObject*)pEvtInstance;
    177       return pSink->Indicate(1,&_pEvtInstance);
    178     }
    179     HRESULT WINAPI FireDeletionEvent(IWbemClassObject *pInstanceToDelete,IWbemObjectSink *pSink) {
    180       if(FAILED (m_hr)) {
    181 	ATLASSERT (0);
    182 	return m_hr;
    183       }
    184       if(!pInstanceToDelete || !pSink) {
    185 	ATLASSERT (0);
    186 	return WBEM_E_INVALID_PARAMETER;
    187       }
    188       CComPtr<IWbemClassObject> pEvtInstance;
    189       HRESULT hr = m_pDeletionEventClass->SpawnInstance(0,&pEvtInstance);
    190       if(FAILED(hr)) return hr;
    191       VARIANT var;
    192       VariantInit(&var);
    193       var.vt = VT_UNKNOWN;
    194       CComQIPtr<IUnknown,&IID_IUnknown>pTemp(pInstanceToDelete);
    195       var.punkVal = pTemp;
    196       hr = pEvtInstance->Put(L"TargetInstance",0,&var,0);
    197       if(FAILED(hr)) return hr;
    198       IWbemClassObject *_pEvtInstance = (IWbemClassObject*)pEvtInstance;
    199       return pSink->Indicate(1,&_pEvtInstance);
    200     }
    201     HRESULT WINAPI FireModificationEvent(IWbemClassObject *pOldInstance,IWbemClassObject *pNewInstance,IWbemObjectSink *pSink) {
    202       if(FAILED (m_hr)) {
    203 	ATLASSERT (0);
    204 	return m_hr;
    205       }
    206       if(!pOldInstance || !pNewInstance || !pSink) {
    207 	ATLASSERT (0);
    208 	return WBEM_E_INVALID_PARAMETER;
    209       }
    210       CComPtr<IWbemClassObject> pEvtInstance;
    211       HRESULT hr = m_pModificationEventClass->SpawnInstance(0,&pEvtInstance);
    212       if(FAILED(hr)) return hr;
    213       VARIANT var;
    214       VariantInit(&var);
    215       var.vt = VT_UNKNOWN;
    216       CComQIPtr<IUnknown,&IID_IUnknown>pTempNew(pNewInstance);
    217       var.punkVal = pTempNew;
    218       hr = pEvtInstance->Put(L"TargetInstance",0,&var,0);
    219       if(FAILED(hr)) return hr;
    220       CComQIPtr<IUnknown,&IID_IUnknown>pTempOld(pOldInstance);
    221       var.punkVal = pTempOld;
    222       hr = pEvtInstance->Put(L"PreviousInstance",0,&var,0);
    223       if(FAILED(hr)) return hr;
    224       IWbemClassObject *_pEvtInstance = (IWbemClassObject*)pEvtInstance;
    225       return pSink->Indicate(1,&_pEvtInstance);
    226     }
    227   };
    228 
    229   class CInstanceProviderHelper : public CProviderHelper {
    230   public:
    231     CInstanceProviderHelper (IWbemServices *pNamespace,IWbemContext *pCtx) : CProviderHelper (pNamespace,pCtx) { }
    232     virtual ~CInstanceProviderHelper() { }
    233     HRESULT WINAPI CheckInstancePath(IClassFactory *pParserFactory,const BSTR ObjectPath,const BSTR ClassName,ULONGLONG ullTest) {
    234       if(!pParserFactory) {
    235 	ATLASSERT (0);
    236 	return WBEM_E_INVALID_PARAMETER;
    237       }
    238       CComPtr<IWbemPath>pPath;
    239       HRESULT hr = pParserFactory->CreateInstance(NULL,IID_IWbemPath,(void **) &pPath);
    240       if(FAILED(hr)) return WBEM_E_INVALID_PARAMETER;
    241       hr = pPath->SetText(WBEMPATH_CREATE_ACCEPT_ALL,ObjectPath);
    242       if(FAILED(hr)) return hr;
    243       unsigned int nPathLen = SysStringLen(ObjectPath);
    244       if(nPathLen >= (unsigned __LONG32)(-1)) return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
    245       unsigned __LONG32 ulBufLen = (unsigned __LONG32)(nPathLen + 1);
    246       WCHAR *wClass = new WCHAR[ulBufLen];
    247       if(!wClass) return WBEM_E_OUT_OF_MEMORY;
    248       hr = pPath->GetClassName(&ulBufLen,wClass);
    249       if(FAILED(hr)) {
    250 	delete[] wClass;
    251 	return hr;
    252       }
    253       DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),SORT_DEFAULT);
    254       if(CSTR_EQUAL!=CompareStringW(lcid,NORM_IGNORECASE,ClassName,-1,wClass,-1)) {
    255 	delete[] wClass;
    256 	return WBEM_E_NOT_FOUND;
    257       }
    258       delete[] wClass;
    259       __MINGW_EXTENSION unsigned __int64 ullPathInfo;
    260       hr = pPath->GetInfo((ULONG)0,&ullPathInfo);
    261       if(FAILED(hr)) return hr;
    262       if(!(ullPathInfo & ullTest)) return WBEM_E_INVALID_OBJECT_PATH;
    263       return WBEM_S_NO_ERROR;
    264     }
    265   };
    266 
    267   template <class T> class ATL_NO_VTABLE IWbemPullClassProviderImpl : public IWbemServices,public IWbemProviderInit {
    268   public:
    269     virtual HRESULT WINAPI OpenNamespace(const BSTR strNamespace,__LONG32 lFlags,IWbemContext *pCtx,IWbemServices **ppWorkingNamespace,IWbemCallResult **ppResult){return WBEM_E_NOT_SUPPORTED;};
    270     virtual HRESULT WINAPI CancelAsyncCall(IWbemObjectSink *pSink){return WBEM_E_NOT_SUPPORTED;};
    271     virtual HRESULT WINAPI QueryObjectSink(__LONG32 lFlags,IWbemObjectSink **ppResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
    272     virtual HRESULT WINAPI GetObject(const BSTR strObjectPath,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject **ppObject,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
    273     virtual HRESULT WINAPI PutClass(IWbemClassObject *pObject,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult){return WBEM_E_NOT_SUPPORTED;};
    274     virtual HRESULT WINAPI DeleteClass(const BSTR strClass,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult){return WBEM_E_NOT_SUPPORTED;};
    275     virtual HRESULT WINAPI CreateClassEnum(const BSTR strSuperclass,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
    276     virtual HRESULT WINAPI PutInstance(IWbemClassObject *pInst,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult){return WBEM_E_NOT_SUPPORTED;};
    277     virtual HRESULT WINAPI PutInstanceAsync(IWbemClassObject *pInst,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
    278     virtual HRESULT WINAPI DeleteInstance(const BSTR strObjectPath,__LONG32 lFlags,IWbemContext *pCtx,IWbemCallResult **ppCallResult){return WBEM_E_NOT_SUPPORTED;};
    279     virtual HRESULT WINAPI DeleteInstanceAsync(const BSTR strObjectPath,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler){return WBEM_E_NOT_SUPPORTED;};
    280     virtual HRESULT WINAPI CreateInstanceEnum(const BSTR strClass,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
    281     virtual HRESULT WINAPI CreateInstanceEnumAsync(const BSTR strClass,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
    282     virtual HRESULT WINAPI ExecQuery(const BSTR strQueryLanguage,const BSTR strQuery,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
    283     virtual HRESULT WINAPI ExecNotificationQuery(const BSTR strQueryLanguage,const BSTR strQuery,__LONG32 lFlags,IWbemContext *pCtx,IEnumWbemClassObject **ppEnum) {return WBEM_E_NOT_SUPPORTED;};
    284     virtual HRESULT WINAPI ExecNotificationQueryAsync(const BSTR strQueryLanguage,const BSTR strQuery,__LONG32 lFlags,IWbemContext *pCtx,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
    285     virtual HRESULT WINAPI ExecMethod(const BSTR strObjectPath,const BSTR strMethodName,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject *pInParams,IWbemClassObject **ppOutParams,IWbemCallResult **ppCallResult) {return WBEM_E_NOT_SUPPORTED;};
    286     virtual HRESULT WINAPI ExecMethodAsync(const BSTR strObjectPath,const BSTR strMethodName,__LONG32 lFlags,IWbemContext *pCtx,IWbemClassObject *pInParams,IWbemObjectSink *pResponseHandler) {return WBEM_E_NOT_SUPPORTED;};
    287   };
    288 
    289   class CImpersonateClientHelper {
    290   private:
    291     WINBOOL m_bImpersonate;
    292   public:
    293     CImpersonateClientHelper() { m_bImpersonate = FALSE; }
    294     ~CImpersonateClientHelper() {
    295       if(m_bImpersonate)
    296 	CoRevertToSelf();
    297     }
    298     HRESULT ImpersonateClient() {
    299       HRESULT hr = S_OK;
    300       if(SUCCEEDED(hr = CoImpersonateClient())) m_bImpersonate = TRUE;
    301       return hr;
    302     }
    303     HRESULT GetCurrentImpersonationLevel (DWORD & a_Level) {
    304       DWORD t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
    305       HANDLE t_ThreadToken = NULL;
    306       HRESULT t_Result = S_OK;
    307       if(SUCCEEDED(t_Result = CoImpersonateClient())) {
    308 	WINBOOL t_Status = OpenThreadToken (GetCurrentThread() ,TOKEN_QUERY,TRUE,&t_ThreadToken);
    309 	if(t_Status) {
    310 	  SECURITY_IMPERSONATION_LEVEL t_Level = SecurityAnonymous;
    311 	  DWORD t_Returned = 0;
    312 	  t_Status = GetTokenInformation (t_ThreadToken ,TokenImpersonationLevel ,&t_Level ,sizeof(SECURITY_IMPERSONATION_LEVEL),&t_Returned);
    313 	  CloseHandle (t_ThreadToken);
    314 	  if(t_Status==FALSE) {
    315 	    t_Result = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,GetLastError());
    316 	  } else {
    317 	    switch(t_Level) {
    318 	    case SecurityAnonymous:
    319 	      {
    320 		t_ImpersonationLevel = RPC_C_IMP_LEVEL_ANONYMOUS;
    321 	      }
    322 	      break;
    323 	    case SecurityIdentification:
    324 	      {
    325 		t_ImpersonationLevel = RPC_C_IMP_LEVEL_IDENTIFY;
    326 	      }
    327 	      break;
    328 	    case SecurityImpersonation:
    329 	      {
    330 		t_ImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
    331 	      }
    332 	      break;
    333 	    case SecurityDelegation:
    334 	      {
    335 		t_ImpersonationLevel = RPC_C_IMP_LEVEL_DELEGATE;
    336 	      }
    337 	      break;
    338 	    default:
    339 	      {
    340 		t_Result = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,E_UNEXPECTED);
    341 	      }
    342 	      break;
    343 	    }
    344 	  }
    345 	} else {
    346 	  t_Result = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,GetLastError());
    347 	}
    348 	CoRevertToSelf();
    349       }
    350       a_Level = t_ImpersonationLevel;
    351       return t_Result;
    352     }
    353   };
    354 }
    355 #endif
    356