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
16namespace 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