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.

1040 lines
23 KiB

  1. // unparse singleton
  2. // check parser return codes
  3. /*++
  4. Copyright (c) 1999-2001 Microsoft Corporation, All Rights Reserved
  5. Module Name:
  6. OBJPATH.CPP
  7. Abstract:
  8. Object path parser.
  9. --*/
  10. #include <windows.h>
  11. #include <stdio.h>
  12. #include <wmiutils.h>
  13. #include <wbemcli.h>
  14. #include "npath.h"
  15. DWORD CalcCimType(VARTYPE vt)
  16. {
  17. DWORD dwRet = CIM_EMPTY;
  18. switch (vt)
  19. {
  20. case VT_BSTR:
  21. {
  22. dwRet = CIM_STRING;
  23. break;
  24. }
  25. case VT_UI1:
  26. {
  27. dwRet = CIM_UINT8;
  28. break;
  29. }
  30. case VT_I2:
  31. {
  32. dwRet = CIM_CHAR16;
  33. break;
  34. }
  35. case VT_I4:
  36. {
  37. dwRet = CIM_UINT32;
  38. break;
  39. }
  40. case VT_BOOL:
  41. {
  42. dwRet = CIM_BOOLEAN;
  43. break;
  44. }
  45. }
  46. return dwRet;
  47. }
  48. ParsedObjectPath::ParsedObjectPath() :
  49. m_pServer(NULL),
  50. m_dwNumNamespaces(0),
  51. m_dwAllocNamespaces(0),
  52. m_paNamespaces(NULL),
  53. m_pClass(NULL),
  54. m_dwNumKeys(0),
  55. m_dwAllocKeys(0),
  56. m_paKeys(NULL)
  57. {
  58. m_paNamespaces = new LPWSTR[2];
  59. // Note: We don't HAVE to throw here. We're trying to
  60. // pre-allocate space. However, m_dwAllocNamespaces
  61. // will correctly show how many pre-alloocated spaces we have
  62. // available. During the add, we will new again
  63. if(m_paNamespaces)
  64. {
  65. m_dwAllocNamespaces = 2;
  66. for (unsigned i = 0; i < m_dwAllocNamespaces; i++)
  67. {
  68. m_paNamespaces[i] = NULL;
  69. }
  70. }
  71. m_bSingletonObj = FALSE;
  72. m_paKeys = new KeyRef *[2];
  73. // Note: We don't HAVE to throw here. We're trying to
  74. // pre-allocate space. However, m_dwAllocNamespaces
  75. // will correctly show how many pre-alloocated spaces we have
  76. // available. During the add, we will new again
  77. if (m_paKeys)
  78. {
  79. m_dwAllocKeys = 2;
  80. for (unsigned i = 0; i < m_dwAllocKeys; i++)
  81. {
  82. m_paKeys[i] = NULL;
  83. }
  84. }
  85. }
  86. ParsedObjectPath::~ParsedObjectPath()
  87. {
  88. if (m_pServer)
  89. {
  90. delete [] m_pServer;
  91. }
  92. if (m_paNamespaces)
  93. {
  94. for (DWORD dwIx = 0; dwIx < m_dwNumNamespaces; dwIx++)
  95. {
  96. delete m_paNamespaces[dwIx];
  97. }
  98. delete [] m_paNamespaces;
  99. }
  100. if (m_pClass)
  101. {
  102. delete [] m_pClass;
  103. }
  104. if (m_paKeys)
  105. {
  106. for (DWORD dwIx = 0; dwIx < m_dwNumKeys; dwIx++)
  107. {
  108. delete m_paKeys[dwIx];
  109. }
  110. delete [] m_paKeys;
  111. }
  112. }
  113. void* __cdecl ParsedObjectPath::operator new( size_t n)
  114. {
  115. void *ptr = ::new BYTE[n];
  116. return ptr;
  117. }
  118. void __cdecl ParsedObjectPath::operator delete( void *ptr )
  119. {
  120. ::delete ptr;
  121. }
  122. void* __cdecl ParsedObjectPath::operator new[]( size_t n)
  123. {
  124. void *ptr = ::new BYTE[n];
  125. return ptr;
  126. }
  127. void __cdecl ParsedObjectPath::operator delete[]( void *ptr )
  128. {
  129. ::delete [] ptr;
  130. }
  131. BOOL ParsedObjectPath::SetClassName(LPCWSTR wszClassName)
  132. {
  133. BOOL bRet = TRUE;
  134. if (m_pClass)
  135. {
  136. delete [] m_pClass;
  137. }
  138. if(wszClassName == NULL)
  139. {
  140. m_pClass = NULL;
  141. }
  142. else
  143. {
  144. DWORD dwLen = wcslen(wszClassName) + 1;
  145. m_pClass = new WCHAR[dwLen];
  146. if (m_pClass)
  147. {
  148. memcpy(m_pClass, wszClassName, dwLen * sizeof(WCHAR));
  149. }
  150. else
  151. {
  152. bRet = FALSE;
  153. }
  154. }
  155. return bRet;
  156. }
  157. BOOL ParsedObjectPath::SetServerName(LPCWSTR wszServerName)
  158. {
  159. BOOL bRet = TRUE;
  160. if (wszServerName)
  161. {
  162. delete [] m_pServer;
  163. }
  164. if(wszServerName == NULL)
  165. {
  166. m_pServer = NULL;
  167. }
  168. else
  169. {
  170. DWORD dwLen = wcslen(wszServerName) + 1;
  171. m_pServer = new WCHAR[dwLen];
  172. if (m_pServer)
  173. {
  174. memcpy(m_pServer, wszServerName, dwLen * sizeof(WCHAR));
  175. }
  176. else
  177. {
  178. bRet = FALSE;
  179. }
  180. }
  181. return bRet;
  182. }
  183. BOOL ParsedObjectPath::IsClass()
  184. {
  185. BOOL bRet = FALSE;
  186. if(IsObject())
  187. {
  188. bRet = TRUE;
  189. }
  190. else
  191. {
  192. bRet = (m_dwNumKeys == 0 && !m_bSingletonObj);
  193. }
  194. return bRet;
  195. }
  196. BOOL ParsedObjectPath::IsInstance()
  197. {
  198. return IsObject() && !IsClass();
  199. }
  200. BOOL ParsedObjectPath::IsObject()
  201. {
  202. BOOL bRet = FALSE;
  203. // It's not a valid object unless we have a class name
  204. if(m_pClass != NULL)
  205. {
  206. // If we have a server name, we must have namespaces. If no
  207. // server name, then we must have zero namespaces.
  208. if(m_pServer)
  209. {
  210. bRet = (m_dwNumNamespaces > 0);
  211. }
  212. else
  213. {
  214. bRet = (m_dwNumNamespaces == 0);
  215. }
  216. }
  217. return bRet;
  218. }
  219. BOOL ParsedObjectPath::AddNamespace(LPCWSTR wszNamespace)
  220. {
  221. BOOL bRet = TRUE;
  222. // See if we have filled all our existing ns slots
  223. if(m_dwNumNamespaces == m_dwAllocNamespaces)
  224. {
  225. DWORD dwNewAllocNamespaces = m_dwAllocNamespaces * 2;
  226. LPWSTR* paNewNamespaces = new LPWSTR[dwNewAllocNamespaces];
  227. if(paNewNamespaces != NULL)
  228. {
  229. memcpy(paNewNamespaces, m_paNamespaces, sizeof(LPWSTR) * m_dwAllocNamespaces);
  230. delete [] m_paNamespaces;
  231. m_paNamespaces = paNewNamespaces;
  232. m_dwAllocNamespaces = dwNewAllocNamespaces;
  233. }
  234. else
  235. {
  236. bRet = FALSE;
  237. }
  238. }
  239. if (bRet)
  240. {
  241. DWORD dwLen = wcslen(wszNamespace) + 1;
  242. m_paNamespaces[m_dwNumNamespaces] = new WCHAR[dwLen];
  243. if (m_paNamespaces[m_dwNumNamespaces])
  244. {
  245. memcpy(m_paNamespaces[m_dwNumNamespaces++], wszNamespace, dwLen * sizeof(WCHAR));
  246. }
  247. else
  248. {
  249. bRet = FALSE;
  250. }
  251. }
  252. return bRet;
  253. }
  254. BOOL ParsedObjectPath::AddKeyRefEx(LPCWSTR wszKeyName, VARIANT* pvValue )
  255. {
  256. BOOL bStatus = TRUE ;
  257. BOOL bFound = FALSE ;
  258. BOOL bUnNamed = FALSE ;
  259. for ( ULONG dwIndex = 0 ; dwIndex < m_dwNumKeys ; dwIndex ++ )
  260. {
  261. if ( ( m_paKeys [ dwIndex ]->m_pName ) && wszKeyName )
  262. {
  263. if ( _wcsicmp ( m_paKeys [ dwIndex ]->m_pName , wszKeyName )
  264. == 0 )
  265. {
  266. bFound = TRUE ;
  267. break ;
  268. }
  269. }
  270. else
  271. {
  272. if ( ( ( m_paKeys [ dwIndex ]->m_pName ) == 0 ) )
  273. {
  274. bUnNamed = TRUE ;
  275. if ( ( wszKeyName == 0 ) )
  276. {
  277. bFound = TRUE ;
  278. break ;
  279. }
  280. }
  281. }
  282. }
  283. if ( ! wszKeyName )
  284. {
  285. /* Remove all existing keys */
  286. for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
  287. dwDeleteIndex ++ )
  288. {
  289. delete [] ( m_paKeys [ dwDeleteIndex ]->m_pName ) ;
  290. m_paKeys [ dwDeleteIndex ]->m_pName = NULL ;
  291. VariantClear ( & ( m_paKeys [ dwDeleteIndex ]->m_vValue ) ) ;
  292. }
  293. bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ 0 ]->m_vValue, pvValue));
  294. m_dwNumKeys = 1 ;
  295. }
  296. else
  297. {
  298. if ( bFound )
  299. {
  300. /*
  301. * If key already exists then just replace the value
  302. */
  303. if ( wszKeyName )
  304. {
  305. m_paKeys [ dwIndex ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
  306. if (m_paKeys [ dwIndex ]->m_pName)
  307. {
  308. wcscpy ( m_paKeys [ dwIndex ]->m_pName , wszKeyName ) ;
  309. }
  310. else
  311. {
  312. bStatus = FALSE;
  313. }
  314. }
  315. if (bStatus)
  316. {
  317. bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ dwIndex ]->m_vValue, pvValue));
  318. if (!bStatus)
  319. {
  320. delete [] m_paKeys [ dwIndex ]->m_pName;
  321. m_paKeys [ dwIndex ]->m_pName = NULL;
  322. VariantClear(&m_paKeys [ dwIndex ]->m_vValue);
  323. }
  324. }
  325. }
  326. else
  327. {
  328. if ( bUnNamed )
  329. {
  330. /* Add an un named key */
  331. for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
  332. dwDeleteIndex ++ )
  333. {
  334. delete [] ( m_paKeys [ dwDeleteIndex ]->m_pName ) ;
  335. m_paKeys [ dwDeleteIndex ]->m_pName = NULL ;
  336. VariantClear (& ( m_paKeys [ dwDeleteIndex ]->m_vValue ) );
  337. }
  338. m_paKeys [ 0 ]->m_pName = new WCHAR [ wcslen ( wszKeyName ) + 1 ] ;
  339. if (m_paKeys [ 0 ]->m_pName)
  340. {
  341. wcscpy ( m_paKeys [ 0 ]->m_pName , wszKeyName ) ;
  342. }
  343. else
  344. {
  345. bStatus = FALSE;
  346. }
  347. if (bStatus)
  348. {
  349. bStatus = SUCCEEDED(VariantCopy(&m_paKeys [ 0 ]->m_vValue, pvValue));
  350. m_dwNumKeys = 1 ;
  351. }
  352. if (!bStatus)
  353. {
  354. delete [] m_paKeys [ 0 ]->m_pName;
  355. m_paKeys [ 0 ]->m_pName = NULL;
  356. VariantClear(&m_paKeys [ 0 ]->m_vValue);
  357. m_dwNumKeys = 0;
  358. }
  359. }
  360. else
  361. {
  362. /* Add a Named Key */
  363. AddKeyRef(wszKeyName, pvValue);
  364. }
  365. }
  366. }
  367. return bStatus;
  368. }
  369. void ParsedObjectPath::ClearKeys ()
  370. {
  371. for ( ULONG dwDeleteIndex = 0 ; dwDeleteIndex < m_dwNumKeys ;
  372. dwDeleteIndex ++ )
  373. {
  374. delete m_paKeys [ dwDeleteIndex ] ;
  375. m_paKeys [ dwDeleteIndex ] = NULL ;
  376. }
  377. delete [] m_paKeys ;
  378. m_dwNumKeys = 0;
  379. m_paKeys = new KeyRef *[2];
  380. // Note: We don't HAVE to throw here. We're trying to
  381. // pre-allocate space. However, m_dwAllocNamespaces
  382. // will correctly show how many pre-alloocated spaces we have
  383. // available. During the add, we will new again
  384. if (m_paKeys)
  385. {
  386. m_dwAllocKeys = 2;
  387. }
  388. }
  389. BOOL ParsedObjectPath::AddKeyRef(LPCWSTR wszKeyName, VARIANT* pvValue)
  390. {
  391. BOOL bRet = TRUE;
  392. if(m_dwNumKeys == m_dwAllocKeys)
  393. {
  394. DWORD dwNewAllocKeys = m_dwAllocKeys * 2;
  395. KeyRef** paNewKeys = new KeyRef*[dwNewAllocKeys];
  396. if (paNewKeys)
  397. {
  398. memcpy(paNewKeys, m_paKeys, sizeof(KeyRef*) * m_dwAllocKeys);
  399. delete [] m_paKeys;
  400. m_paKeys = paNewKeys;
  401. m_dwAllocKeys = dwNewAllocKeys;
  402. }
  403. else
  404. {
  405. bRet = FALSE;
  406. }
  407. }
  408. if (bRet)
  409. {
  410. m_paKeys[m_dwNumKeys] = new KeyRef;
  411. if (m_paKeys[m_dwNumKeys])
  412. {
  413. DWORD dwLen = wcslen(wszKeyName) + 1;
  414. m_paKeys[m_dwNumKeys]->m_pName = new WCHAR[dwLen];
  415. if (m_paKeys[m_dwNumKeys]->m_pName)
  416. {
  417. memcpy(m_paKeys[m_dwNumKeys]->m_pName, wszKeyName, dwLen * sizeof(WCHAR));
  418. bRet = SUCCEEDED(VariantCopy(&m_paKeys[m_dwNumKeys]->m_vValue, pvValue));
  419. if (bRet)
  420. {
  421. m_dwNumKeys++;
  422. }
  423. else
  424. {
  425. delete [] m_paKeys[m_dwNumKeys]->m_pName;
  426. m_paKeys[m_dwNumKeys]->m_pName = NULL;
  427. }
  428. }
  429. else
  430. {
  431. bRet = FALSE;
  432. }
  433. }
  434. else
  435. {
  436. bRet = FALSE;
  437. }
  438. }
  439. return bRet;
  440. }
  441. BOOL ParsedObjectPath::AddKeyRef(KeyRef* pAcquireRef)
  442. {
  443. BOOL bRet = TRUE;
  444. if(m_dwNumKeys == m_dwAllocKeys)
  445. {
  446. DWORD dwNewAllocKeys = m_dwAllocKeys * 2;
  447. KeyRef** paNewKeys = new KeyRef*[dwNewAllocKeys];
  448. if(paNewKeys != NULL)
  449. {
  450. memcpy(paNewKeys, m_paKeys, sizeof(KeyRef*) * m_dwAllocKeys);
  451. delete [] m_paKeys;
  452. m_paKeys = paNewKeys;
  453. m_dwAllocKeys = dwNewAllocKeys;
  454. }
  455. else
  456. {
  457. bRet = FALSE;
  458. }
  459. }
  460. if (bRet)
  461. {
  462. m_paKeys[m_dwNumKeys] = pAcquireRef;
  463. m_dwNumKeys++;
  464. }
  465. return bRet;
  466. }
  467. LPWSTR ParsedObjectPath::GetNamespacePart()
  468. {
  469. if (m_dwNumNamespaces == 0)
  470. return NULL;
  471. // Compute necessary space
  472. // =======================
  473. int nSpace = 0;
  474. for(DWORD i = 0; i < m_dwNumNamespaces; i++)
  475. {
  476. nSpace += 1 + wcslen(m_paNamespaces[i]);
  477. }
  478. nSpace--;
  479. // Allocate buffer
  480. // ===============
  481. LPWSTR wszOut = new WCHAR[nSpace + 1];
  482. if (wszOut)
  483. {
  484. *wszOut = L'\0';
  485. // Output
  486. // ======
  487. for(i = 0; i < m_dwNumNamespaces; i++)
  488. {
  489. if(i != 0)
  490. {
  491. wcscat(wszOut, L"\\");
  492. }
  493. wcscat(wszOut, m_paNamespaces[i]);
  494. }
  495. }
  496. return wszOut;
  497. }
  498. LPWSTR ParsedObjectPath::GetParentNamespacePart()
  499. {
  500. if(m_dwNumNamespaces < 2)
  501. {
  502. return NULL;
  503. }
  504. // Compute necessary space
  505. // =======================
  506. int nSpace = 0;
  507. for(DWORD i = 0; i < m_dwNumNamespaces - 1; i++)
  508. {
  509. nSpace += 1 + wcslen(m_paNamespaces[i]);
  510. }
  511. nSpace--;
  512. // Allocate buffer
  513. // ===============
  514. LPWSTR wszOut = new wchar_t[nSpace + 1];
  515. if(wszOut != NULL)
  516. {
  517. *wszOut = 0;
  518. // Output
  519. // ======
  520. for(i = 0; i < m_dwNumNamespaces - 1; i++)
  521. {
  522. if(i != 0)
  523. {
  524. wcscat(wszOut, L"\\");
  525. }
  526. wcscat(wszOut, m_paNamespaces[i]);
  527. }
  528. }
  529. return wszOut;
  530. }
  531. BOOL ParsedObjectPath::IsRelative(LPCWSTR wszMachine, LPCWSTR wszNamespace)
  532. {
  533. // I have no idea what this routine is for. If we are checking
  534. // whether the parsed object is relative, why do we need params? If
  535. // we are checking the params, why do we need the data members?
  536. //
  537. // On the plus side, it does the same thing as the old object parser did.
  538. if(!IsLocal(wszMachine))
  539. return FALSE;
  540. if(m_dwNumNamespaces == 0)
  541. return TRUE;
  542. LPWSTR wszCopy = new wchar_t[wcslen(wszNamespace) + 1];
  543. if(wszCopy == NULL)
  544. {
  545. return FALSE;
  546. }
  547. wcscpy(wszCopy, wszNamespace);
  548. LPWSTR wszLeft = wszCopy;
  549. BOOL bFailed = FALSE;
  550. for(DWORD i = 0; i < m_dwNumNamespaces; i++)
  551. {
  552. unsigned int nLen = wcslen(m_paNamespaces[i]);
  553. if(nLen > wcslen(wszLeft))
  554. {
  555. bFailed = TRUE;
  556. break;
  557. }
  558. if(i == m_dwNumNamespaces - 1 && wszLeft[nLen] != 0)
  559. {
  560. bFailed = TRUE;
  561. break;
  562. }
  563. if(i != m_dwNumNamespaces - 1 && wszLeft[nLen] != L'\\')
  564. {
  565. bFailed = TRUE;
  566. break;
  567. }
  568. wszLeft[nLen] = 0;
  569. if(_wcsicmp(wszLeft, m_paNamespaces[i]))
  570. {
  571. bFailed = TRUE;
  572. break;
  573. }
  574. wszLeft += nLen+1;
  575. }
  576. delete [] wszCopy;
  577. return !bFailed;
  578. }
  579. BOOL ParsedObjectPath::IsLocal(LPCWSTR wszMachine)
  580. {
  581. return (m_pServer == NULL || !wcscmp(m_pServer, L".") ||
  582. !_wcsicmp(m_pServer, wszMachine));
  583. }
  584. //=================================================================================================
  585. KeyRef::KeyRef()
  586. {
  587. m_pName = NULL;
  588. VariantInit(&m_vValue);
  589. }
  590. KeyRef::~KeyRef()
  591. {
  592. delete [] m_pName;
  593. VariantClear(&m_vValue);
  594. }
  595. void* __cdecl KeyRef::operator new( size_t n)
  596. {
  597. void *ptr = ::new BYTE[n];
  598. return ptr;
  599. }
  600. void __cdecl KeyRef::operator delete( void *ptr )
  601. {
  602. ::delete ptr;
  603. }
  604. void* __cdecl KeyRef::operator new[]( size_t n)
  605. {
  606. void *ptr = ::new BYTE[n];
  607. return ptr;
  608. }
  609. void __cdecl KeyRef::operator delete[]( void *ptr )
  610. {
  611. ::delete [] ptr;
  612. }
  613. //=================================================================================================
  614. CObjectPathParser::CObjectPathParser(ObjectParserFlags eFlags)
  615. : m_eFlags(eFlags)
  616. {
  617. }
  618. CObjectPathParser::~CObjectPathParser()
  619. {
  620. }
  621. void* __cdecl CObjectPathParser::operator new( size_t n)
  622. {
  623. void *ptr = ::new BYTE[n];
  624. return ptr;
  625. }
  626. void __cdecl CObjectPathParser::operator delete( void *ptr )
  627. {
  628. ::delete ptr;
  629. }
  630. void* __cdecl CObjectPathParser::operator new[]( size_t n)
  631. {
  632. void *ptr = ::new BYTE[n];
  633. return ptr;
  634. }
  635. void __cdecl CObjectPathParser::operator delete[]( void *ptr )
  636. {
  637. ::delete [] ptr;
  638. }
  639. int WINAPI CObjectPathParser::Unparse(
  640. ParsedObjectPath* pInput,
  641. DELETE_ME LPWSTR* pwszPath)
  642. {
  643. if ( (pInput == NULL) || (pInput->m_pClass == NULL) )
  644. {
  645. return CObjectPathParser::InvalidParameter;
  646. }
  647. int iRet = CObjectPathParser::NoError;
  648. SCODE sc = S_OK;
  649. IWbemPath *pTempParser = NULL;
  650. sc = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
  651. IID_IWbemPath, (LPVOID *) &pTempParser);
  652. if (SUCCEEDED(sc))
  653. {
  654. sc = pTempParser->SetClassName(pInput->m_pClass);
  655. if (SUCCEEDED(sc))
  656. {
  657. sc = pTempParser->SetServer(pInput->m_pServer);
  658. for (DWORD x=0; (x < pInput->m_dwNumNamespaces) && SUCCEEDED(sc); x++)
  659. {
  660. sc = pTempParser->SetNamespaceAt(x, pInput->m_paNamespaces[x]);
  661. }
  662. if (SUCCEEDED(sc))
  663. {
  664. IWbemPathKeyList *pKeyList = NULL;
  665. sc = pTempParser->GetKeyList(&pKeyList);
  666. if (SUCCEEDED(sc))
  667. {
  668. for (x=0; x < (pInput->m_dwNumKeys) && SUCCEEDED(sc); x++)
  669. {
  670. sc = pKeyList->SetKey2(pInput->m_paKeys[x]->m_pName,
  671. 0,
  672. CalcCimType(pInput->m_paKeys[x]->m_vValue.vt),
  673. &pInput->m_paKeys[x]->m_vValue);
  674. }
  675. pKeyList->Release();
  676. }
  677. if (SUCCEEDED(sc))
  678. {
  679. DWORD dwLen = 0;
  680. sc = pTempParser->GetText(WBEMPATH_GET_SERVER_TOO, &dwLen, NULL);
  681. if (SUCCEEDED(sc))
  682. {
  683. *pwszPath = new WCHAR[dwLen];
  684. if (*pwszPath)
  685. {
  686. sc = pTempParser->GetText(WBEMPATH_GET_SERVER_TOO, &dwLen, *pwszPath);
  687. }
  688. else
  689. {
  690. iRet = CObjectPathParser::OutOfMemory;
  691. }
  692. }
  693. }
  694. }
  695. }
  696. pTempParser->Release();
  697. }
  698. if (FAILED(sc))
  699. {
  700. if (sc == WBEM_E_OUT_OF_MEMORY)
  701. {
  702. iRet = CObjectPathParser::OutOfMemory;
  703. }
  704. else
  705. {
  706. iRet = CObjectPathParser::InvalidParameter;
  707. }
  708. }
  709. return iRet;
  710. }
  711. LPWSTR WINAPI CObjectPathParser::GetRelativePath(LPWSTR wszFullPath)
  712. {
  713. LPWSTR wsz = wcschr(wszFullPath, L':');
  714. if(wsz)
  715. return wsz + 1;
  716. else
  717. return NULL;
  718. }
  719. int CObjectPathParser::Parse(
  720. LPCWSTR pRawPath,
  721. ParsedObjectPath **pOutput
  722. )
  723. {
  724. if (pOutput == 0 || pRawPath == 0 || pRawPath[0] == L'\0')
  725. {
  726. return CObjectPathParser::InvalidParameter;
  727. }
  728. // Check for leading / trailing ws.
  729. // ================================
  730. if (iswspace(pRawPath[wcslen(pRawPath)-1]) || iswspace(pRawPath[0]))
  731. {
  732. return InvalidParameter;
  733. }
  734. ParsedObjectPath *pTempPath = new ParsedObjectPath;
  735. if (!pTempPath)
  736. return OutOfMemory;
  737. int iRet = CObjectPathParser::NoError;
  738. SCODE sc = S_OK;
  739. BOOL bRet = TRUE;
  740. IWbemPath *pTempParser = NULL;
  741. sc = CoCreateInstance(CLSID_WbemDefPath, 0, CLSCTX_INPROC_SERVER,
  742. IID_IWbemPath, (LPVOID *) &pTempParser);
  743. if (SUCCEEDED(sc))
  744. {
  745. sc = pTempParser->SetText(WBEMPATH_CREATE_ACCEPT_ALL, pRawPath);
  746. if (SUCCEEDED(sc))
  747. {
  748. WCHAR wTemp[256];
  749. DWORD dwSize;
  750. //
  751. dwSize = 256;
  752. sc = pTempParser->GetClassName(&dwSize, wTemp);
  753. if (SUCCEEDED(sc))
  754. {
  755. bRet = pTempPath->SetClassName(wTemp);
  756. if (bRet)
  757. {
  758. //
  759. dwSize = 256;
  760. sc = pTempParser->GetServer(&dwSize, wTemp);
  761. if (SUCCEEDED(sc))
  762. {
  763. bRet = pTempPath->SetServerName(wTemp);
  764. if (bRet)
  765. {
  766. //
  767. ULONG lCnt;
  768. sc = pTempParser->GetNamespaceCount(&lCnt);
  769. for(DWORD dwCnt = 0; (dwCnt < lCnt) && SUCCEEDED(sc) && bRet; dwCnt++)
  770. {
  771. dwSize = 256;
  772. sc = pTempParser->GetNamespaceAt(dwCnt, &dwSize, wTemp);
  773. bRet = pTempPath->AddNamespace(wTemp);
  774. }
  775. if (SUCCEEDED(sc) && bRet)
  776. {
  777. //
  778. unsigned __int64 ull;
  779. sc = pTempParser->GetInfo(0, &ull);
  780. if (SUCCEEDED(sc))
  781. {
  782. pTempPath->m_bSingletonObj = (ull & WBEMPATH_INFO_CONTAINS_SINGLETON) > 0;
  783. //
  784. IWbemPathKeyList *pKeyList = NULL;
  785. sc = pTempParser->GetKeyList(&pKeyList);
  786. if (SUCCEEDED(sc))
  787. {
  788. unsigned long uNumKey;
  789. sc = pKeyList->GetCount(&uNumKey);
  790. ULONG ulType;
  791. VARIANT var;
  792. for(DWORD uKeyIx = 0;
  793. (uKeyIx < uNumKey) && SUCCEEDED(sc) && bRet;
  794. uKeyIx++)
  795. {
  796. dwSize = 256;
  797. sc = pKeyList->GetKey2(uKeyIx, 0, &dwSize, wTemp, &var, &ulType);
  798. if(SUCCEEDED(sc))
  799. {
  800. bRet = pTempPath->AddKeyRefEx(wTemp, &var);
  801. VariantClear(&var);
  802. }
  803. }
  804. pKeyList->Release();
  805. }
  806. }
  807. }
  808. }
  809. }
  810. }
  811. }
  812. }
  813. pTempParser->Release();
  814. }
  815. if (!bRet)
  816. {
  817. iRet = CObjectPathParser::OutOfMemory;
  818. }
  819. else if (FAILED(sc))
  820. {
  821. if (sc == WBEM_E_OUT_OF_MEMORY)
  822. {
  823. iRet = CObjectPathParser::OutOfMemory;
  824. }
  825. else
  826. {
  827. iRet = CObjectPathParser::InvalidParameter;
  828. }
  829. }
  830. // Add in key refs.
  831. // ================
  832. *pOutput = pTempPath;
  833. return iRet;
  834. }
  835. void CObjectPathParser::Free(ParsedObjectPath *pOutput)
  836. {
  837. delete pOutput;
  838. }
  839. void CObjectPathParser::Free( LPWSTR wszUnparsedPath )
  840. {
  841. delete wszUnparsedPath;
  842. }