Source code of Windows XP (NT5)
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.

537 lines
12 KiB

  1. // METHPROV.CPP: implementation of the CBaseMethodProvider class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include <atlbase.h>
  5. #include "HMAgent.h"
  6. #include "methprov.h"
  7. //////////////////////////////////////////////////////////////////////
  8. // global data
  9. extern CSystem* g_pSystem;
  10. extern HANDLE g_hConfigLock;
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CBaseMethodProvider::CBaseMethodProvider()
  15. {
  16. OutputDebugString(L"CBaseMethodProvider::CBaseMethodProvider()\n");
  17. MY_ASSERT(g_pSystem);
  18. m_pSystem = g_pSystem;
  19. m_cRef = 0L;
  20. m_pIWbemServices = NULL;
  21. }
  22. CBaseMethodProvider::~CBaseMethodProvider()
  23. {
  24. OutputDebugString(L"CBaseMethodProvider::~CBaseMethodProvider()\n");
  25. if (m_pIWbemServices)
  26. {
  27. m_pIWbemServices->Release();
  28. }
  29. m_pIWbemServices = NULL;
  30. }
  31. //////////////////////////////////////////////////////////////////////
  32. // IUnknown Implementation
  33. //////////////////////////////////////////////////////////////////////
  34. STDMETHODIMP CBaseMethodProvider::QueryInterface(REFIID riid, LPVOID* ppv)
  35. {
  36. *ppv = NULL;
  37. if(riid== IID_IWbemServices)
  38. {
  39. *ppv=(IWbemServices*)this;
  40. }
  41. if(IID_IUnknown==riid || riid== IID_IWbemProviderInit)
  42. {
  43. *ppv=(IWbemProviderInit*)this;
  44. }
  45. if (NULL!=*ppv)
  46. {
  47. AddRef();
  48. return S_OK;
  49. }
  50. else
  51. {
  52. return E_NOINTERFACE;
  53. }
  54. }
  55. STDMETHODIMP_(ULONG) CBaseMethodProvider::AddRef(void)
  56. {
  57. return InterlockedIncrement((long*)&m_cRef);
  58. }
  59. STDMETHODIMP_(ULONG) CBaseMethodProvider::Release(void)
  60. {
  61. LONG lCount = InterlockedDecrement((long*)&m_cRef);
  62. if (0 != lCount)
  63. {
  64. return lCount;
  65. }
  66. delete this;
  67. return 0L;
  68. }
  69. //////////////////////////////////////////////////////////////////////
  70. // IWbemProviderInit Implementation
  71. //////////////////////////////////////////////////////////////////////
  72. HRESULT CBaseMethodProvider::Initialize(LPWSTR pszUser,
  73. LONG lFlags,
  74. LPWSTR pszNamespace,
  75. LPWSTR pszLocale,
  76. IWbemServices __RPC_FAR *pNamespace,
  77. IWbemContext __RPC_FAR *pCtx,
  78. IWbemProviderInitSink __RPC_FAR *pInitSink)
  79. {
  80. OutputDebugString(L"CBaseMethodProvider::Initialize()\n");
  81. if (NULL == pNamespace)
  82. {
  83. return WBEM_E_INVALID_PARAMETER;
  84. }
  85. m_pIWbemServices = pNamespace;
  86. m_pIWbemServices->AddRef();
  87. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  88. return WBEM_S_NO_ERROR;
  89. }
  90. //////////////////////////////////////////////////////////////////////
  91. // IWbemService Implementation
  92. //////////////////////////////////////////////////////////////////////
  93. HRESULT CBaseMethodProvider::ExecMethodAsync(const BSTR ObjectPath, const BSTR MethodName,
  94. long lFlags, IWbemContext* pCtx, IWbemClassObject* pInParams,
  95. IWbemObjectSink* pResultSink)
  96. {
  97. CComVariant var;
  98. CComVariant v;
  99. IWbemClassObject * pClass = NULL;
  100. IWbemClassObject * pOutClass = NULL;
  101. IWbemClassObject* pOutParams = NULL;
  102. SAFEARRAY* psa = NULL;
  103. LPTSTR szOriginalSystem = NULL;
  104. LPTSTR szOriginalParentGUID = NULL;
  105. LPTSTR szGUID = NULL;
  106. DWORD iRetValue;
  107. HRESULT hRetRes;
  108. BOOL bForceReplace;
  109. DWORD dwErr = 0;
  110. MY_OUTPUT(L"CBaseMethodProvider::ExecMethodAsync()", 1);
  111. //
  112. // Do some minimal error checking.
  113. //
  114. if(MethodName == NULL || pInParams == NULL || pResultSink == NULL)
  115. {
  116. return WBEM_E_INVALID_PARAMETER;
  117. }
  118. if (!g_pSystem)
  119. {
  120. hRetRes=WBEM_E_FAILED;
  121. goto error;
  122. }
  123. hRetRes = m_pIWbemServices->GetObject(ObjectPath, 0, pCtx, &pClass, NULL);
  124. if(hRetRes != S_OK)
  125. {
  126. MY_HRESASSERT(hRetRes);
  127. goto error;
  128. }
  129. // Call the appropriate method.
  130. // retval == 0 means success...
  131. // Get the input argument
  132. hRetRes = pInParams->Get(L"TargetGUID", 0, &var, NULL, NULL);
  133. MY_HRESASSERT(hRetRes);
  134. if (hRetRes != S_OK)
  135. {
  136. goto error;
  137. }
  138. if (V_VT(&var)==VT_NULL)
  139. {
  140. hRetRes = WBEM_E_INVALID_PARAMETER;
  141. goto error;
  142. }
  143. hRetRes = pClass->GetMethod(MethodName, 0, NULL, &pOutClass);
  144. MY_HRESASSERT(hRetRes);
  145. if (hRetRes != S_OK)
  146. {
  147. goto error;
  148. }
  149. hRetRes = pOutClass->SpawnInstance(0, &pOutParams);
  150. MY_HRESASSERT(hRetRes);
  151. if (hRetRes != S_OK)
  152. {
  153. goto error;
  154. }
  155. // now we need to acquire the Mutex, not before!
  156. MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync BLOCK - g_hConfigLock BLOCK WAIT", 4);
  157. dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
  158. if(dwErr != WAIT_OBJECT_0)
  159. {
  160. if(dwErr = WAIT_TIMEOUT)
  161. {
  162. TRACE_MUTEX(L"TIMEOUT MUTEX");
  163. return WBEM_S_TIMEDOUT;
  164. }
  165. else
  166. {
  167. MY_OUTPUT(L"WaitForSingleObject on Mutex failed",4);
  168. return WBEM_E_FAILED;
  169. }
  170. }
  171. MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync BLOCK - g_hConfigLock BLOCK GOT IT", 4);
  172. try
  173. {
  174. if (!wcscmp(MethodName, L"Delete"))
  175. {
  176. hRetRes = m_pSystem->FindAndDeleteByGUID(V_BSTR(&var));
  177. iRetValue = hRetRes;
  178. }
  179. else if (!wcscmp(MethodName, L"ResetAndCheckNow"))
  180. {
  181. hRetRes = m_pSystem->FindAndResetDEStateByGUID(V_BSTR(&var));
  182. iRetValue = hRetRes;
  183. }
  184. else if (!wcscmp(MethodName, L"ResetDataCollectorStatistics"))
  185. {
  186. hRetRes = m_pSystem->FindAndResetDEStatisticsByGUID(V_BSTR(&var));
  187. iRetValue = hRetRes;
  188. }
  189. else if (!wcscmp(MethodName, L"CopyWithActions"))
  190. {
  191. hRetRes = m_pSystem->FindAndCopyWithActionsByGUID(V_BSTR(&var), &psa, &szOriginalParentGUID);
  192. if (hRetRes==S_OK)
  193. {
  194. // This method returns values, and so create an instance of the
  195. // output argument class.
  196. DWORD dwNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  197. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  198. if (GetComputerName(szComputerName, &dwNameLen))
  199. {
  200. hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", szComputerName);
  201. }
  202. else
  203. {
  204. hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", L"LocalMachine");
  205. }
  206. if(FAILED(hRetRes))
  207. {
  208. goto error;
  209. }
  210. hRetRes = PutStrProperty(pOutParams, L"OriginalParentGUID", szOriginalParentGUID);
  211. if(FAILED(hRetRes))
  212. {
  213. goto error;
  214. }
  215. hRetRes = PutSAProperty(pOutParams, L"Instances", psa);
  216. if(FAILED(hRetRes))
  217. {
  218. goto error;
  219. }
  220. // Don't need to delete this below unless there was an error!
  221. // We do not free this if we sent it in a Put.
  222. // Because, we do a VariantClear(&v); inside of PutSAProperty.
  223. psa = NULL;
  224. iRetValue = 0;
  225. }
  226. else
  227. {
  228. iRetValue = hRetRes;
  229. MY_OUTPUT(L"failed to get instance!", 1);
  230. }
  231. }
  232. else if (!wcscmp(MethodName, L"PasteWithActions"))
  233. {
  234. hRetRes = pInParams->Get(L"Instances", 0L, &v, NULL, NULL);
  235. MY_ASSERT(hRetRes==S_OK);
  236. if (hRetRes != S_OK)
  237. {
  238. goto error;
  239. }
  240. if (V_VT(&v)==VT_NULL)
  241. {
  242. iRetValue = 1;
  243. }
  244. else
  245. {
  246. MY_ASSERT(V_VT(&v)==(VT_UNKNOWN|VT_ARRAY));
  247. hRetRes = GetStrProperty(pInParams, L"OriginalSystem", &szOriginalSystem);
  248. MY_ASSERT(hRetRes==S_OK);
  249. if (hRetRes != S_OK)
  250. {
  251. goto error;
  252. }
  253. hRetRes = GetStrProperty(pInParams, L"OriginalParentGUID", &szOriginalParentGUID);
  254. MY_ASSERT(hRetRes==S_OK);
  255. if (hRetRes != S_OK)
  256. {
  257. goto error;
  258. }
  259. hRetRes = GetBoolProperty(pInParams, L"ForceReplace", &bForceReplace);
  260. MY_ASSERT(hRetRes==S_OK);
  261. if(FAILED(hRetRes))
  262. {
  263. goto error;
  264. }
  265. hRetRes = m_pSystem->FindAndPasteWithActionsByGUID(V_BSTR(&var), v.parray, szOriginalSystem, szOriginalParentGUID, bForceReplace);
  266. if(FAILED(hRetRes))
  267. {
  268. goto error;
  269. }
  270. iRetValue = hRetRes;
  271. }
  272. //
  273. // Send the output object back to the client via the sink.
  274. }
  275. else if (!wcscmp(MethodName, L"Copy"))
  276. {
  277. hRetRes = m_pSystem->FindAndCopyByGUID(V_BSTR(&var), &psa, &szOriginalParentGUID);
  278. if (hRetRes==S_OK)
  279. {
  280. // This method returns values, and so create an instance of the
  281. // output argument class.
  282. DWORD dwNameLen = MAX_COMPUTERNAME_LENGTH + 1;
  283. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
  284. if (GetComputerName(szComputerName, &dwNameLen))
  285. {
  286. hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", szComputerName);
  287. }
  288. else
  289. {
  290. hRetRes = PutStrProperty(pOutParams, L"OriginalSystem", L"LocalMachine");
  291. }
  292. if(FAILED(hRetRes))
  293. {
  294. goto error;
  295. }
  296. hRetRes = PutStrProperty(pOutParams, L"OriginalParentGUID", szOriginalParentGUID);
  297. szOriginalParentGUID = NULL; // Don't need to delete this below, as we are pointing it to something
  298. if(FAILED(hRetRes))
  299. {
  300. goto error;
  301. }
  302. hRetRes = PutSAProperty(pOutParams, L"Instances", psa);
  303. if(FAILED(hRetRes))
  304. {
  305. goto error;
  306. }
  307. // Don't need to delete this below unless there was an error!
  308. // We do not free this if we sent it in a Put.
  309. // Because, we do a VariantClear(&v); inside of PutSAProperty.
  310. psa = NULL;
  311. iRetValue = 0;
  312. }
  313. else
  314. {
  315. iRetValue = hRetRes;
  316. szOriginalParentGUID = NULL; // Don't need to delete this below, as we are pointing it to something
  317. MY_OUTPUT(L"failed to get instance!", 1);
  318. }
  319. }
  320. else if (!wcscmp(MethodName, L"Paste"))
  321. {
  322. hRetRes = pInParams->Get(L"Instances", 0L, &v, NULL, NULL);
  323. MY_ASSERT(hRetRes==S_OK);
  324. if (hRetRes != S_OK)
  325. {
  326. goto error;
  327. }
  328. if (V_VT(&v)==VT_NULL)
  329. {
  330. iRetValue = 1;
  331. }
  332. else
  333. {
  334. MY_ASSERT(V_VT(&v)==(VT_UNKNOWN|VT_ARRAY));
  335. hRetRes = GetStrProperty(pInParams, L"OriginalSystem", &szOriginalSystem);
  336. MY_ASSERT(hRetRes==S_OK);
  337. if (hRetRes != S_OK)
  338. {
  339. goto error;
  340. }
  341. hRetRes = GetStrProperty(pInParams, L"OriginalParentGUID", &szOriginalParentGUID);
  342. MY_ASSERT(hRetRes==S_OK);
  343. if (hRetRes != S_OK)
  344. {
  345. goto error;
  346. }
  347. hRetRes = GetBoolProperty(pInParams, L"ForceReplace", &bForceReplace);
  348. MY_ASSERT(hRetRes==S_OK);
  349. if(FAILED(hRetRes))
  350. {
  351. goto error;
  352. }
  353. hRetRes = m_pSystem->FindAndPasteByGUID(V_BSTR(&var), v.parray, szOriginalSystem, szOriginalParentGUID, bForceReplace);
  354. if(FAILED(hRetRes))
  355. {
  356. goto error;
  357. }
  358. iRetValue = hRetRes;
  359. }
  360. //
  361. // Send the output object back to the client via the sink.
  362. }
  363. else if (!_wcsicmp(MethodName, L"Move"))
  364. {
  365. #ifdef SAVE
  366. hRetRes = GetStrProperty(pInParams, L"TargetParentGUID", &szGUID);
  367. MY_ASSERT(hRetRes==S_OK);
  368. if(FAILED(hRetRes))
  369. {
  370. goto error;
  371. }
  372. hRetRes = m_pSystem->Move(V_BSTR(&var), szGUID);
  373. iRetValue = hRetRes;
  374. if(FAILED(hRetRes))
  375. {
  376. goto error;
  377. }
  378. #endif
  379. hRetRes = S_OK;
  380. iRetValue = hRetRes;
  381. }
  382. else if (!wcscmp(MethodName, L"DeleteConfigurationActionAssociation"))
  383. {
  384. hRetRes = GetStrProperty(pInParams, L"ActionGUID", &szGUID);
  385. MY_ASSERT(hRetRes==S_OK);
  386. if(FAILED(hRetRes))
  387. {
  388. goto error;
  389. }
  390. hRetRes = m_pSystem->DeleteConfigActionAssoc(V_BSTR(&var), szGUID);
  391. iRetValue = hRetRes;
  392. if(FAILED(hRetRes))
  393. {
  394. goto error;
  395. }
  396. }
  397. else
  398. {
  399. hRetRes = WBEM_E_NOT_SUPPORTED;
  400. goto error;
  401. }
  402. }
  403. catch (...)
  404. {
  405. hRetRes = S_FALSE;
  406. iRetValue = S_FALSE;
  407. MY_ASSERT(FALSE);
  408. }
  409. //
  410. // Set the return value
  411. //
  412. VariantClear(&var);
  413. var.vt = VT_I4;
  414. var.lVal = iRetValue;
  415. hRetRes = pOutParams->Put(L"ReturnValue" , 0, &var, 0);
  416. if(FAILED(hRetRes))
  417. {
  418. goto error;
  419. }
  420. // Send the output object back to the client via the sink.
  421. hRetRes = pResultSink->Indicate(1, &pOutParams);
  422. if(FAILED(hRetRes))
  423. {
  424. goto error;
  425. }
  426. error:
  427. // all done now, set the status
  428. if(SUCCEEDED(hRetRes))
  429. {
  430. pResultSink->SetStatus(0,WBEM_S_NO_ERROR,NULL,NULL);
  431. }
  432. else
  433. {
  434. MY_ASSERT(FALSE);
  435. pResultSink->SetStatus(0,hRetRes,NULL,NULL);
  436. }
  437. if (pClass)
  438. pClass->Release();
  439. if (pOutClass)
  440. pOutClass->Release();
  441. if (pOutParams)
  442. pOutParams->Release();
  443. if (szOriginalSystem)
  444. delete [] szOriginalSystem;
  445. if (szOriginalParentGUID)
  446. delete [] szOriginalParentGUID;
  447. if (psa)
  448. {
  449. MY_ASSERT(FALSE);
  450. SafeArrayDestroy(psa);
  451. }
  452. if (szGUID)
  453. delete [] szGUID;
  454. MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync g_hConfigLock BLOCK - RELEASE IT", 4);
  455. ReleaseMutex(g_hConfigLock);
  456. MY_OUTPUT(L"BLOCK - BLOCK CBaseMethodProvider::ExecMethodAsync g_hConfigLock BLOCK - RELEASED", 4);
  457. return hRetRes;
  458. }