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.

696 lines
17 KiB

  1. //***************************************************************************
  2. //
  3. // VPGET.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the GetObject implementation
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <provcoll.h>
  15. #include <provtempl.h>
  16. #include <provmt.h>
  17. #include <typeinfo.h>
  18. #include <process.h>
  19. #include <objbase.h>
  20. #include <stdio.h>
  21. #include <wbemidl.h>
  22. #include <provcont.h>
  23. #include <provevt.h>
  24. #include <provthrd.h>
  25. #include <provlog.h>
  26. #include <cominit.h>
  27. #include <dsgetdc.h>
  28. #include <lmcons.h>
  29. #include <instpath.h>
  30. #include <genlex.h>
  31. #include <sql_1.h>
  32. #include <objpath.h>
  33. #include <vpdefs.h>
  34. #include <vpquals.h>
  35. #include <vpserv.h>
  36. #include <vptasks.h>
  37. GetObjectTaskObject::GetObjectTaskObject(CViewProvServ *a_Provider,
  38. wchar_t *a_ObjectPath, ULONG a_Flag, IWbemObjectSink *a_NotificationHandler ,
  39. IWbemContext *pCtx, IWbemServices* a_Serv, CWbemServerWrap *a_ServerWrap)
  40. : WbemTaskObject (a_Provider, a_NotificationHandler, a_Flag, pCtx, a_Serv, a_ServerWrap),
  41. m_ObjectPath(NULL),
  42. m_ParsedObjectPath(NULL)
  43. {
  44. m_ObjectPath = UnicodeStringDuplicate(a_ObjectPath);
  45. }
  46. GetObjectTaskObject::~GetObjectTaskObject ()
  47. {
  48. BOOL t_Status = TRUE;
  49. if (m_bIndicate)
  50. {
  51. IWbemClassObject *t_NotifyStatus = NULL ;
  52. if (WBEM_NO_ERROR != m_ErrorObject.GetWbemStatus ())
  53. {
  54. t_Status = GetExtendedNotifyStatusObject ( &t_NotifyStatus ) ;
  55. }
  56. if ( t_Status )
  57. {
  58. m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , t_NotifyStatus ) ;
  59. if (t_NotifyStatus)
  60. {
  61. t_NotifyStatus->Release () ;
  62. }
  63. }
  64. else
  65. {
  66. m_NotificationHandler->SetStatus ( 0 , m_ErrorObject.GetWbemStatus () , 0 , NULL ) ;
  67. }
  68. }
  69. if (m_ObjectPath != NULL)
  70. {
  71. delete [] m_ObjectPath;
  72. }
  73. if (NULL != m_ParsedObjectPath)
  74. {
  75. delete m_ParsedObjectPath;
  76. }
  77. if (m_StatusHandle != NULL)
  78. {
  79. CloseHandle(m_StatusHandle);
  80. }
  81. }
  82. BOOL GetObjectTaskObject::PerformGet(WbemProvErrorObject &a_ErrorObject, IWbemClassObject** pInst, const wchar_t* src, BOOL bAllprops)
  83. {
  84. m_StatusHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
  85. if (m_StatusHandle == NULL)
  86. {
  87. a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ;
  88. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  89. a_ErrorObject.SetMessage ( L"Failed to create an Synchronization object" ) ;
  90. return FALSE;
  91. }
  92. BOOL retVal = PerformQueries(a_ErrorObject, bAllprops);
  93. BOOL bWait = TRUE;
  94. while (retVal && bWait)
  95. {
  96. DWORD dwWait = WbemWaitForSingleObject(m_StatusHandle, VP_QUERY_TIMEOUT);
  97. switch(dwWait)
  98. {
  99. case WAIT_OBJECT_0:
  100. {
  101. retVal = ProcessResults(a_ErrorObject, pInst, src);
  102. bWait = FALSE;
  103. }
  104. break;
  105. case WAIT_TIMEOUT:
  106. {
  107. BOOL bCleanup = TRUE;
  108. if (m_ArrayLock.Lock())
  109. {
  110. if (m_ResultReceived)
  111. {
  112. m_ResultReceived = FALSE;
  113. bCleanup = FALSE;
  114. }
  115. m_ArrayLock.Unlock();
  116. }
  117. if (bCleanup)
  118. {
  119. CleanUpObjSinks(TRUE);
  120. a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ;
  121. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  122. a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed, or query timed out" ) ;
  123. retVal = FALSE;
  124. bWait = FALSE;
  125. }
  126. }
  127. break;
  128. default:
  129. {
  130. //Cancel outstanding requests and delete object sinks...
  131. //======================================================
  132. CleanUpObjSinks(TRUE);
  133. a_ErrorObject.SetStatus ( WBEM_PROV_E_FAILED ) ;
  134. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  135. a_ErrorObject.SetMessage ( L"Wait on a sychronization object failed" ) ;
  136. retVal = FALSE;
  137. bWait = FALSE;
  138. }
  139. }
  140. }
  141. return retVal;
  142. }
  143. BOOL GetObjectTaskObject::PerformQueries(WbemProvErrorObject &a_ErrorObject, BOOL bAllprops)
  144. {
  145. //need enough tokens to handle association work-around serverpath or dotpath or relpath
  146. SQL_LEVEL_1_TOKEN* tokArray = new SQL_LEVEL_1_TOKEN[(m_ParsedObjectPath->m_dwNumKeys) * 6];
  147. m_iQueriesAsked++;
  148. m_ObjSinkArray.SetSize(0, m_NSpaceArray.GetSize());
  149. //m_NSpaceArray size is 1 for associations
  150. for (int x = 0; x < m_NSpaceArray.GetSize(); x++)
  151. {
  152. BOOL bContinue = TRUE;
  153. DWORD dwToks = 0;
  154. BOOL bFirst = TRUE;
  155. for (int i = 0; i < m_ParsedObjectPath->m_dwNumKeys; i++)
  156. {
  157. CPropertyQualifierItem* propItem;
  158. BOOL bFoundKey = FALSE;
  159. if (m_ParsedObjectPath->m_paKeys[i]->m_pName != NULL)
  160. {
  161. bFoundKey = m_PropertyMap.Lookup(m_ParsedObjectPath->m_paKeys[i]->m_pName, propItem);
  162. }
  163. else if (m_ParsedObjectPath->m_dwNumKeys == 1)
  164. {
  165. POSITION pos = m_PropertyMap.GetStartPosition();
  166. while (pos)
  167. {
  168. CStringW itmName;
  169. m_PropertyMap.GetNextAssoc(pos, itmName, propItem);
  170. if (propItem->IsKey())
  171. {
  172. bFoundKey = TRUE;
  173. break;
  174. }
  175. }
  176. }
  177. if (bFoundKey)
  178. {
  179. if (!propItem->m_SrcPropertyNames[x].IsEmpty())
  180. {
  181. tokArray[dwToks].nTokenType = SQL_LEVEL_1_TOKEN::OP_EXPRESSION;
  182. tokArray[dwToks].nOperator = SQL_LEVEL_1_TOKEN::OP_EQUAL;
  183. tokArray[dwToks].pPropertyName = propItem->m_SrcPropertyNames[x].AllocSysString();
  184. if (m_bAssoc && (propItem->GetCimType() == CIM_REFERENCE))
  185. {
  186. bContinue = TransposeReference(propItem, m_ParsedObjectPath->m_paKeys[i]->m_vValue,
  187. &(tokArray[dwToks].vConstValue), FALSE, NULL);
  188. if (!bContinue)
  189. {
  190. break;
  191. }
  192. else
  193. {
  194. //add the extra tokens if neccessary
  195. //for the association work-around
  196. wchar_t *t_pChar = tokArray[dwToks].vConstValue.bstrVal;
  197. //must be \\server\namespace and not \\.\namespace or relpath
  198. if ( (*t_pChar == L'\\') && (*(t_pChar+1) == L'\\') && (*(t_pChar+2) != L'.') )
  199. {
  200. //add the dotted version
  201. tokArray[dwToks + 1] = tokArray[dwToks];
  202. dwToks++;
  203. t_pChar = tokArray[dwToks].vConstValue.bstrVal + 2;
  204. while (*t_pChar != L'\\')
  205. {
  206. t_pChar++;
  207. }
  208. --t_pChar;
  209. *t_pChar = L'.';
  210. --t_pChar;
  211. *t_pChar = L'\\';
  212. --t_pChar;
  213. *t_pChar = L'\\';
  214. BSTR t_strtmp = SysAllocString(t_pChar);
  215. VariantClear(&(tokArray[dwToks].vConstValue));
  216. VariantInit(&(tokArray[dwToks].vConstValue));
  217. tokArray[dwToks].vConstValue.vt = VT_BSTR;
  218. tokArray[dwToks].vConstValue.bstrVal = t_strtmp;
  219. dwToks++;
  220. tokArray[dwToks].nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_OR;
  221. //add the relpath version
  222. tokArray[dwToks + 1] = tokArray[dwToks - 1];
  223. dwToks++;
  224. t_pChar = tokArray[dwToks].vConstValue.bstrVal + 4;
  225. while (*t_pChar != L':')
  226. {
  227. t_pChar++;
  228. }
  229. //exclude the ':'
  230. t_pChar++;
  231. t_strtmp = SysAllocString(t_pChar);
  232. VariantClear(&(tokArray[dwToks].vConstValue));
  233. VariantInit(&(tokArray[dwToks].vConstValue));
  234. tokArray[dwToks].vConstValue.vt = VT_BSTR;
  235. tokArray[dwToks].vConstValue.bstrVal = t_strtmp;
  236. dwToks++;
  237. tokArray[dwToks].nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_OR;
  238. }
  239. }
  240. }
  241. else
  242. {
  243. VariantInit(&(tokArray[dwToks].vConstValue));
  244. if (FAILED(VariantCopy(&(tokArray[dwToks].vConstValue),
  245. &(m_ParsedObjectPath->m_paKeys[i]->m_vValue))))
  246. {
  247. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  248. }
  249. }
  250. //after every key add an AND
  251. //except if this is the first key && there is no where clause
  252. dwToks++;
  253. if ((!bFirst) || (m_SourceArray[x]->GetRPNExpression()->nNumTokens != 0))
  254. {
  255. tokArray[dwToks++].nTokenType = SQL_LEVEL_1_TOKEN::TOKEN_AND;
  256. }
  257. bFirst = FALSE;
  258. }
  259. }
  260. }
  261. if (bContinue)
  262. {
  263. CStringW queryStr = GetStringFromRPN(m_SourceArray[x]->GetRPNExpression(), dwToks, tokArray, bAllprops);
  264. CObjectSinkResults * objSnk = new CObjectSinkResults(this, x);
  265. objSnk->AddRef();
  266. m_ObjSinkArray.SetAtGrow(x, objSnk);
  267. CWbemServerWrap** nsPtrs = m_NSpaceArray[x]->GetServerPtrs();
  268. for (int m = 0; m < m_NSpaceArray[x]->GetCount(); m++)
  269. {
  270. if (nsPtrs[m] != NULL)
  271. {
  272. CViewProvObjectSink* pSnk = new CViewProvObjectSink(objSnk, nsPtrs[m], m);
  273. pSnk->AddRef();
  274. BSTR queryBStr = queryStr.AllocSysString();
  275. BSTR queryLBStr = SysAllocString(WBEM_QUERY_LANGUAGE_SQL1);
  276. IWbemObjectSink* pQuerySink = pSnk;
  277. IWbemContext * t_pCtx = m_Ctx;
  278. if (nsPtrs[m]->IsRemote())
  279. {
  280. pQuerySink = pSnk->Associate();
  281. t_pCtx = NULL; //don't use context for remote calls
  282. }
  283. IWbemServices *ptmpServ = nsPtrs[m]->GetServerOrProxy();
  284. if (ptmpServ)
  285. {
  286. if ( pQuerySink )
  287. {
  288. HRESULT t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink);
  289. if ( FAILED(t_hr) && (HRESULT_FACILITY(t_hr) != FACILITY_ITF) && nsPtrs[m]->IsRemote())
  290. {
  291. if ( SUCCEEDED(UpdateConnection(&(nsPtrs[m]), &ptmpServ)) )
  292. {
  293. if (ptmpServ)
  294. {
  295. t_hr = ptmpServ->ExecQueryAsync(queryLBStr, queryBStr, 0, t_pCtx, pQuerySink);
  296. }
  297. }
  298. }
  299. if (SUCCEEDED(t_hr))
  300. {
  301. if (m_ArrayLock.Lock())
  302. {
  303. m_iQueriesAsked++;
  304. m_ArrayLock.Unlock();
  305. }
  306. else
  307. {
  308. pSnk->DisAssociate();
  309. }
  310. }
  311. else
  312. {
  313. pSnk->DisAssociate();
  314. }
  315. }
  316. else
  317. {
  318. pSnk->DisAssociate();
  319. }
  320. if (ptmpServ)
  321. {
  322. nsPtrs[m]->ReturnServerOrProxy(ptmpServ);
  323. }
  324. }
  325. else
  326. {
  327. pSnk->DisAssociate();
  328. }
  329. pSnk->Release();
  330. SysFreeString(queryBStr);
  331. SysFreeString(queryLBStr);
  332. }
  333. }
  334. }
  335. //clean up token array for next pass...
  336. for (int n = 0; n < dwToks; n++)
  337. {
  338. if (tokArray[n].nTokenType == SQL_LEVEL_1_TOKEN::OP_EXPRESSION)
  339. {
  340. VariantClear(&(tokArray[n].vConstValue));
  341. SysFreeString(tokArray[n].pPropertyName);
  342. tokArray[n].pPropertyName = NULL;
  343. }
  344. }
  345. }
  346. delete [] tokArray;
  347. if (m_ArrayLock.Lock())
  348. {
  349. m_iQueriesAsked--;
  350. if (m_iQueriesAsked != m_iQueriesAnswered)
  351. {
  352. //just in case this was triggerred while we had yet to ask some queries
  353. ResetEvent(m_StatusHandle);
  354. }
  355. else
  356. {
  357. //just in case this wasn't triggerred while we were asking queries
  358. SetEvent(m_StatusHandle);
  359. }
  360. m_ArrayLock.Unlock();
  361. }
  362. if (m_iQueriesAsked == 0)
  363. {
  364. for (int x = 0; x < m_ObjSinkArray.GetSize(); x++)
  365. {
  366. if (m_ObjSinkArray[x] != NULL)
  367. {
  368. m_ObjSinkArray[x]->Release();
  369. }
  370. }
  371. m_ObjSinkArray.RemoveAll();
  372. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  373. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  374. a_ErrorObject.SetMessage ( L"Failed to send any queries, invalid namespaces" ) ;
  375. return FALSE;
  376. }
  377. return TRUE;
  378. }
  379. BOOL GetObjectTaskObject::ProcessResults(WbemProvErrorObject &a_ErrorObject, IWbemClassObject** pInst, const wchar_t* src)
  380. {
  381. BOOL retVal = TRUE;
  382. int arrayIndex;
  383. int indexCnt = 0;
  384. for (int x = 0; retVal && (x < m_ObjSinkArray.GetSize()); x++)
  385. {
  386. if ((m_ObjSinkArray[x] != NULL) && m_ObjSinkArray[x]->IsSet())
  387. {
  388. if (SUCCEEDED(m_ObjSinkArray[x]->GetResult()))
  389. {
  390. DWORD dwCount = m_ObjSinkArray[x]->m_ObjArray.GetSize();
  391. if (0 < dwCount)
  392. {
  393. arrayIndex = x;
  394. indexCnt++;
  395. }
  396. }
  397. else
  398. {
  399. retVal = FALSE;
  400. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  401. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  402. a_ErrorObject.SetMessage ( L"Object path and Class qualifiers resulted in a failed query." ) ;
  403. }
  404. }
  405. else
  406. {
  407. retVal = FALSE;
  408. a_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  409. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  410. a_ErrorObject.SetMessage ( L"Invalid source namespace path OR object path and Class qualifiers resulted in a failed query." ) ;
  411. }
  412. }
  413. if (retVal)
  414. {
  415. if (0 == indexCnt)
  416. {
  417. retVal = FALSE;
  418. a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ;
  419. a_ErrorObject.SetWbemStatus ( WBEM_E_NOT_FOUND ) ;
  420. a_ErrorObject.SetMessage ( L"No source objects found to support view object path." ) ;
  421. CleanUpObjSinks();
  422. }
  423. else
  424. {
  425. if ((src != NULL) && (pInst != NULL))
  426. {
  427. DWORD *pdwIndices = NULL;
  428. DWORD dwIndxCount = GetIndexList(src, &pdwIndices);
  429. for (DWORD i = 0; i < dwIndxCount; i++)
  430. {
  431. if ((m_ObjSinkArray[pdwIndices[i]] != NULL) && SUCCEEDED(m_ObjSinkArray[pdwIndices[i]]->GetResult())
  432. && m_ObjSinkArray[pdwIndices[i]]->m_ObjArray.GetSize() == 1)
  433. {
  434. if (*pInst == NULL)
  435. {
  436. m_ObjSinkArray[pdwIndices[i]]->m_ObjArray[0]->GetWrappedObject()->AddRef();
  437. *pInst = m_ObjSinkArray[pdwIndices[i]]->m_ObjArray[0]->GetWrappedObject();
  438. }
  439. else
  440. {
  441. (*pInst)->Release();
  442. *pInst = NULL;
  443. }
  444. }
  445. }
  446. if (dwIndxCount)
  447. {
  448. delete [] pdwIndices;
  449. }
  450. }
  451. if (m_JoinOnArray.IsValid())
  452. {
  453. #ifdef VP_PERFORMANT_JOINS
  454. retVal = CreateAndIndicateJoinsPerf(a_ErrorObject, TRUE);
  455. #else
  456. retVal = CreateAndIndicateJoins(a_ErrorObject, TRUE);
  457. #endif
  458. if (!retVal && (a_ErrorObject.GetWbemStatus() == WBEM_NO_ERROR))
  459. {
  460. a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ;
  461. a_ErrorObject.SetWbemStatus ( WBEM_E_NOT_FOUND ) ;
  462. a_ErrorObject.SetMessage ( L"Failed to map source instance(s) to view instance." ) ;
  463. }
  464. }
  465. else //union
  466. {
  467. if ( (1 < indexCnt) || (m_ObjSinkArray[arrayIndex]->m_ObjArray.GetSize() > 1) )
  468. {
  469. retVal = FALSE;
  470. a_ErrorObject.SetStatus ( WBEM_PROV_E_TOOMANYRESULTSRETURNED ) ;
  471. a_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  472. a_ErrorObject.SetMessage ( L"Ambiguous object path. Too many source instances returned." ) ;
  473. CleanUpObjSinks();
  474. }
  475. else
  476. {
  477. if ((src == NULL) && (pInst != NULL))
  478. {
  479. if ((m_ObjSinkArray[arrayIndex] != NULL) && SUCCEEDED(m_ObjSinkArray[arrayIndex]->GetResult())
  480. && m_ObjSinkArray[arrayIndex]->m_ObjArray.GetSize())
  481. {
  482. m_ObjSinkArray[arrayIndex]->m_ObjArray[0]->GetWrappedObject()->AddRef();
  483. *pInst = m_ObjSinkArray[arrayIndex]->m_ObjArray[0]->GetWrappedObject();
  484. }
  485. }
  486. retVal = CreateAndIndicateUnions(a_ErrorObject, arrayIndex);
  487. if (!retVal && (a_ErrorObject.GetWbemStatus() == WBEM_NO_ERROR))
  488. {
  489. a_ErrorObject.SetStatus ( WBEM_PROV_E_NOT_FOUND ) ;
  490. a_ErrorObject.SetWbemStatus ( WBEM_E_NOT_FOUND ) ;
  491. a_ErrorObject.SetMessage ( L"Failed to map source instance(s) to view instance." ) ;
  492. }
  493. }
  494. }
  495. if (!retVal && (pInst != NULL) && (*pInst != NULL))
  496. {
  497. (*pInst)->Release();
  498. *pInst = NULL;
  499. }
  500. }
  501. }
  502. else
  503. {
  504. CleanUpObjSinks();
  505. }
  506. return retVal;
  507. }
  508. BOOL GetObjectTaskObject::GetSourceObject(const wchar_t* src, IWbemClassObject** pInst, BOOL bAllprops)
  509. {
  510. //Have to test that object path is real and return
  511. //the IWbemClassObject for the source requested....
  512. //==================================================
  513. m_bIndicate = FALSE;
  514. CObjectPathParser objectPathParser;
  515. BOOL t_Status = ! objectPathParser.Parse ( m_ObjectPath , &m_ParsedObjectPath ) ;
  516. if ( t_Status )
  517. {
  518. t_Status = SetClass(m_ParsedObjectPath->m_pClass) ;
  519. if ( t_Status )
  520. {
  521. t_Status = ParseAndProcessClassQualifiers(m_ErrorObject, m_ParsedObjectPath);
  522. if (t_Status)
  523. {
  524. if (m_bAssoc)
  525. {
  526. t_Status = FALSE;
  527. }
  528. else
  529. {
  530. t_Status = PerformGet(m_ErrorObject, pInst, src, bAllprops);
  531. }
  532. }
  533. }
  534. }
  535. else
  536. {
  537. t_Status = FALSE ;
  538. }
  539. return t_Status ;
  540. }
  541. BOOL GetObjectTaskObject :: GetObject ()
  542. {
  543. DebugOut2(
  544. CViewProvServ::sm_debugLog->WriteFileAndLine (
  545. _T(__FILE__),__LINE__,
  546. _T("GetObjectTaskObject :: GetObject\r\n")
  547. ) ;
  548. )
  549. CObjectPathParser objectPathParser;
  550. BOOL t_Status = ! objectPathParser.Parse ( m_ObjectPath , &m_ParsedObjectPath ) ;
  551. if ( t_Status )
  552. {
  553. t_Status = SetClass(m_ParsedObjectPath->m_pClass) ;
  554. if ( t_Status )
  555. {
  556. t_Status = ParseAndProcessClassQualifiers(m_ErrorObject, m_ParsedObjectPath);
  557. if (t_Status)
  558. {
  559. t_Status = PerformGet(m_ErrorObject);
  560. }
  561. }
  562. else
  563. {
  564. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_CLASS ) ;
  565. m_ErrorObject.SetWbemStatus ( WBEM_E_FAILED ) ;
  566. m_ErrorObject.SetMessage ( L"Class definition not found" ) ;
  567. DebugOut2(
  568. CViewProvServ::sm_debugLog->WriteFileAndLine (
  569. _T(__FILE__),__LINE__,
  570. _T("GetObjectTaskObject :: GetObject:Class definition not found\r\n")
  571. ) ;
  572. )
  573. }
  574. }
  575. else
  576. {
  577. t_Status = FALSE ;
  578. m_ErrorObject.SetStatus ( WBEM_PROV_E_INVALID_PARAMETER ) ;
  579. m_ErrorObject.SetWbemStatus ( WBEM_E_INVALID_PARAMETER ) ;
  580. m_ErrorObject.SetMessage ( L"Unable to parse object path" ) ;
  581. DebugOut2(
  582. CViewProvServ::sm_debugLog->WriteW (
  583. L"GetObjectTaskObject :: GetObject:Unable to parse object path %s\r\n",
  584. m_ObjectPath
  585. ) ;
  586. )
  587. }
  588. DebugOut2(
  589. CViewProvServ::sm_debugLog->WriteFileAndLine (
  590. _T(__FILE__),__LINE__,
  591. _T("leaving GetObjectTaskObject :: GetObject with %lx\r\n"),
  592. t_Status
  593. ) ;
  594. )
  595. return t_Status ;
  596. }