Leaked source code of windows server 2003
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.

2038 lines
54 KiB

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. XmlUtil.cpp
  5. Abstract:
  6. This file contains the implementation of the XmlUtil class,
  7. the support class for handling XML data.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 04/17/99
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. /////////////////////////////////////////////////////////////////////////////
  14. class ATL_NO_VTABLE AsyncXMLParser : public CComObjectRootEx<CComMultiThreadModel>, public IDispatch
  15. {
  16. CComPtr<IXMLDOMDocument> m_xddDoc;
  17. HANDLE m_hEvent;
  18. HRESULT m_hr;
  19. void SetHandler( IDispatch* obj )
  20. {
  21. if(m_xddDoc)
  22. {
  23. VARIANT v;
  24. v.vt = VT_DISPATCH;
  25. v.pdispVal = obj;
  26. m_xddDoc->put_onreadystatechange( v );
  27. if(obj)
  28. {
  29. m_xddDoc->put_async( VARIANT_TRUE );
  30. }
  31. }
  32. }
  33. void Init( IXMLDOMDocument* xddDoc ,
  34. HANDLE hEvent )
  35. {
  36. MPC::SmartLock<_ThreadModel> lock( this );
  37. Clean();
  38. m_xddDoc = xddDoc;
  39. m_hEvent = hEvent; if(hEvent) ::ResetEvent( hEvent );
  40. m_hr = E_ABORT;
  41. SetHandler( this );
  42. }
  43. void Clean()
  44. {
  45. MPC::SmartLock<_ThreadModel> lock( this );
  46. //
  47. // Before releasing the object, unregister from event notification.
  48. //
  49. SetHandler( NULL );
  50. m_xddDoc.Release();
  51. m_hEvent = NULL;
  52. }
  53. public:
  54. BEGIN_COM_MAP(AsyncXMLParser)
  55. COM_INTERFACE_ENTRY(IDispatch)
  56. END_COM_MAP()
  57. AsyncXMLParser()
  58. {
  59. // CComPtr<IXMLDOMDocument> m_xddDoc;
  60. m_hEvent = NULL; // HANDLE m_hEvent;
  61. m_hr = E_ABORT; // HRESULT m_hr;
  62. }
  63. ~AsyncXMLParser()
  64. {
  65. Clean();
  66. }
  67. HRESULT Load( /*[in]*/ IXMLDOMDocument* xddDoc ,
  68. /*[in]*/ HANDLE hEvent ,
  69. /*[in]*/ DWORD dwTimeout ,
  70. /*[in]*/ CComVariant& v )
  71. {
  72. __MPC_FUNC_ENTRY( COMMONID, "AsyncXMLParser::Load" );
  73. HRESULT hr;
  74. MPC::SmartLock<_ThreadModel> lock( this );
  75. VARIANT_BOOL fSuccess;
  76. DWORD dwRes;
  77. Init( xddDoc, hEvent );
  78. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->load( v, &fSuccess ));
  79. lock = NULL;
  80. dwRes = MPC::WaitForSingleObject( hEvent, dwTimeout );
  81. lock = this;
  82. hr = m_hr;
  83. __MPC_FUNC_CLEANUP;
  84. Clean();
  85. if(xddDoc && hr == E_ABORT) xddDoc->abort();
  86. __MPC_FUNC_EXIT(hr);
  87. }
  88. public:
  89. //
  90. // IDispatch
  91. //
  92. STDMETHOD(GetTypeInfoCount)( UINT* pctinfo )
  93. {
  94. return E_NOTIMPL;
  95. }
  96. STDMETHOD(GetTypeInfo)( UINT itinfo ,
  97. LCID lcid ,
  98. ITypeInfo* *pptinfo )
  99. {
  100. return E_NOTIMPL;
  101. }
  102. STDMETHOD(GetIDsOfNames)( REFIID riid ,
  103. LPOLESTR* rgszNames ,
  104. UINT cNames ,
  105. LCID lcid ,
  106. DISPID* rgdispid )
  107. {
  108. return E_NOTIMPL;
  109. }
  110. STDMETHOD(Invoke)( DISPID dispidMember ,
  111. REFIID riid ,
  112. LCID lcid ,
  113. WORD wFlags ,
  114. DISPPARAMS* pdispparams ,
  115. VARIANT* pvarResult ,
  116. EXCEPINFO* pexcepinfo ,
  117. UINT* puArgErr )
  118. {
  119. MPC::SmartLock<_ThreadModel> lock( this );
  120. if(m_hEvent && m_xddDoc)
  121. {
  122. long state;
  123. if(SUCCEEDED(m_xddDoc->get_readyState( &state )) && state == 4) // COMPLETED
  124. {
  125. CComPtr<IXMLDOMParseError> pError;
  126. if(FAILED(m_xddDoc->get_parseError( &pError )) || !pError || FAILED(pError->get_errorCode( &m_hr ))) m_hr = E_ABORT;
  127. ::SetEvent( m_hEvent );
  128. }
  129. }
  130. return S_OK;
  131. }
  132. };
  133. ////////////////////////////////////////////////////////////////////////////////
  134. static HRESULT getStartNode( /*[in ]*/ LPCWSTR szTag ,
  135. /*[in ]*/ IXMLDOMNode* pxdnNode ,
  136. /*[out]*/ CComPtr<IXMLDOMNode>& xdnNodeStart ,
  137. /*[out]*/ bool& fFound )
  138. {
  139. __MPC_FUNC_ENTRY( COMMONID, "getStartNode" );
  140. HRESULT hr;
  141. //
  142. // Initialize OUT parameters for 'Not Found' case.
  143. //
  144. xdnNodeStart = NULL;
  145. fFound = false;
  146. __MPC_PARAMCHECK_BEGIN(hr)
  147. __MPC_PARAMCHECK_NOTNULL(pxdnNode); // No root...
  148. __MPC_PARAMCHECK_END();
  149. if(szTag)
  150. {
  151. CComBSTR tagName = szTag;
  152. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdnNode->selectSingleNode( tagName, &xdnNodeStart ));
  153. }
  154. else
  155. {
  156. xdnNodeStart = pxdnNode;
  157. }
  158. if(xdnNodeStart)
  159. {
  160. fFound = true;
  161. }
  162. hr = S_OK;
  163. __MPC_FUNC_CLEANUP;
  164. __MPC_FUNC_EXIT(hr);
  165. }
  166. static HRESULT getValueNode( /*[in ]*/ IXMLDOMNode* pxdnNode ,
  167. /*[out]*/ CComPtr<IXMLDOMNode>& xdnValue ,
  168. /*[out]*/ bool& fFound )
  169. {
  170. __MPC_FUNC_ENTRY( COMMONID, "getValueNode" );
  171. _ASSERT(pxdnNode != NULL);
  172. HRESULT hr;
  173. CComPtr<IXMLDOMNodeList> xdnlList;
  174. CComPtr<IXMLDOMNode> xdnChild;
  175. //
  176. // Initialize OUT parameters for 'Not Found' case.
  177. //
  178. xdnValue = NULL;
  179. fFound = false;
  180. //
  181. // Get all the childs of given element.
  182. //
  183. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdnNode->get_childNodes( &xdnlList ));
  184. //
  185. // Walk through all the child, searching for a TEXT or CDATA_SECTION.
  186. //
  187. for(;SUCCEEDED(hr = xdnlList->nextNode( &xdnChild )) && xdnChild != NULL; xdnChild = NULL)
  188. {
  189. DOMNodeType nodeType;
  190. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nodeType( &nodeType ));
  191. if(nodeType == NODE_TEXT ||
  192. nodeType == NODE_CDATA_SECTION )
  193. {
  194. //
  195. // Found...
  196. //
  197. xdnValue = xdnChild;
  198. fFound = true;
  199. break;
  200. }
  201. }
  202. hr = S_OK;
  203. __MPC_FUNC_CLEANUP;
  204. __MPC_FUNC_EXIT(hr);
  205. }
  206. /////////////////////////////////////////////////////////////////////////////
  207. /////////////////////////////////////////////////////////////////////////////
  208. /////////////////////////////////////////////////////////////////////////////
  209. MPC::XmlUtil::XmlUtil( /*[in]*/ const XmlUtil& xml )
  210. {
  211. m_xddDoc = xml.m_xddDoc;
  212. m_xdnRoot = xml.m_xdnRoot;
  213. Init();
  214. }
  215. MPC::XmlUtil::XmlUtil( /*[in]*/ IXMLDOMDocument* xddDoc ,
  216. /*[in]*/ LPCWSTR szRootTag )
  217. {
  218. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::XmlUtil" );
  219. CComPtr<IXMLDOMElement> xdeElem;
  220. CComPtr<IXMLDOMNode> xdnRoot;
  221. Init();
  222. if(SUCCEEDED(xddDoc->get_documentElement( &xdeElem )))
  223. {
  224. if(SUCCEEDED(xdeElem->QueryInterface( IID_IXMLDOMNode, (void **)&xdnRoot )))
  225. {
  226. *this = xdnRoot;
  227. }
  228. }
  229. if(szRootTag)
  230. {
  231. bool fLoaded;
  232. bool fFound;
  233. (void)LoadPost( szRootTag, fLoaded, &fFound );
  234. }
  235. }
  236. MPC::XmlUtil::XmlUtil( /*[in]*/ IXMLDOMNode* xdnRoot ,
  237. /*[in]*/ LPCWSTR szRootTag )
  238. {
  239. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::XmlUtil" );
  240. Init(); *this = xdnRoot;
  241. if(szRootTag)
  242. {
  243. bool fLoaded;
  244. bool fFound;
  245. (void)LoadPost( szRootTag, fLoaded, &fFound );
  246. }
  247. }
  248. MPC::XmlUtil::~XmlUtil()
  249. {
  250. Clean();
  251. }
  252. MPC::XmlUtil& MPC::XmlUtil::operator=( /*[in]*/ const XmlUtil& xml )
  253. {
  254. m_xddDoc = xml.m_xddDoc;
  255. m_xdnRoot = xml.m_xdnRoot;
  256. return *this;
  257. }
  258. MPC::XmlUtil& MPC::XmlUtil::operator=( /*[in]*/ IXMLDOMNode* xdnRoot )
  259. {
  260. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::operator=" );
  261. m_xddDoc = NULL;
  262. m_xdnRoot = NULL;
  263. if(xdnRoot)
  264. {
  265. if(SUCCEEDED(xdnRoot->get_ownerDocument( &m_xddDoc )))
  266. {
  267. m_xdnRoot = xdnRoot;
  268. }
  269. }
  270. return *this;
  271. }
  272. /////////////////////////////////////////////////////////////////////////////
  273. /////////////////////////////////////////////////////////////////////////////
  274. /////////////////////////////////////////////////////////////////////////////
  275. void MPC::XmlUtil::Init()
  276. {
  277. m_hEvent = ::CreateEvent( NULL, FALSE, TRUE, NULL ); // HANDLE m_hEvent;
  278. m_dwTimeout = INFINITE; // DWORD m_dwTimeout;
  279. }
  280. void MPC::XmlUtil::Clean()
  281. {
  282. if(m_hEvent)
  283. {
  284. ::CloseHandle( m_hEvent );
  285. m_hEvent = NULL;
  286. }
  287. }
  288. HRESULT MPC::XmlUtil::CreateParser()
  289. {
  290. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::CreateParser" );
  291. HRESULT hr;
  292. m_xddDoc .Release();
  293. m_xdnRoot.Release();
  294. //
  295. // Create the DOM object.
  296. //
  297. __MPC_EXIT_IF_METHOD_FAILS(hr, ::CoCreateInstance( CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&m_xddDoc ));
  298. //
  299. // Set synchronous operation.
  300. //
  301. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->put_async( VARIANT_FALSE ));
  302. hr = S_OK;
  303. __MPC_FUNC_CLEANUP;
  304. __MPC_FUNC_EXIT(hr);
  305. }
  306. HRESULT MPC::XmlUtil::New( /*[in]*/ IXMLDOMNode* xdnRoot,
  307. /*[in]*/ BOOL fDeep )
  308. {
  309. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::New" );
  310. HRESULT hr;
  311. CComPtr<IXMLDOMDocument> xddDoc;
  312. CComPtr<IXMLDOMNode> xdnNode;
  313. CComPtr<IXMLDOMNodeList> xdnlList;
  314. CComPtr<IXMLDOMNode> xdnChild;
  315. __MPC_PARAMCHECK_BEGIN(hr)
  316. __MPC_PARAMCHECK_NOTNULL(xdnRoot);
  317. __MPC_PARAMCHECK_END();
  318. //
  319. // Create the parser.
  320. //
  321. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateParser());
  322. //
  323. // Search the processing elements in the document to clone.
  324. //
  325. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRoot->get_ownerDocument( &xddDoc ));
  326. __MPC_EXIT_IF_METHOD_FAILS(hr, xddDoc ->QueryInterface ( IID_IXMLDOMNode, (void **)&xdnNode ));
  327. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNode->get_childNodes ( &xdnlList )); xdnNode = NULL;
  328. for(;SUCCEEDED(hr = xdnlList->nextNode( &xdnChild )) && xdnChild != NULL; xdnChild = NULL)
  329. {
  330. DOMNodeType nodeType;
  331. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nodeType( &nodeType ));
  332. //
  333. // It's a processing element, so clone it.
  334. //
  335. if(nodeType == NODE_PROCESSING_INSTRUCTION)
  336. {
  337. CComPtr<IXMLDOMNode> xdnChildCloned;
  338. CComPtr<IXMLDOMNode> xdnChildNew;
  339. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->cloneNode ( VARIANT_TRUE , &xdnChildCloned ));
  340. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->appendChild( xdnChildCloned, &xdnChildNew ));
  341. }
  342. }
  343. //
  344. // Clone the node.
  345. //
  346. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnRoot->cloneNode( fDeep ? VARIANT_TRUE : VARIANT_FALSE, &xdnNode ));
  347. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->appendChild( xdnNode, &m_xdnRoot ));
  348. hr = S_OK;
  349. __MPC_FUNC_CLEANUP;
  350. __MPC_FUNC_EXIT(hr);
  351. }
  352. HRESULT MPC::XmlUtil::New( /*[in]*/ LPCWSTR szRootTag ,
  353. /*[in]*/ LPCWSTR szEncoding )
  354. {
  355. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::New" );
  356. HRESULT hr;
  357. __MPC_PARAMCHECK_BEGIN(hr)
  358. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szRootTag);
  359. __MPC_PARAMCHECK_END();
  360. //
  361. // Create the parser.
  362. //
  363. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateParser());
  364. //
  365. // XML header.
  366. //
  367. {
  368. CComPtr<IXMLDOMProcessingInstruction> xdpiElem;
  369. CComPtr<IXMLDOMNode> xdnNode;
  370. CComPtr<IXMLDOMNode> xdnNodeNew;
  371. CComBSTR bstrData( L"version=\"1.0\" encoding=\"" );
  372. CComBSTR bstrPI ( L"xml" );
  373. bstrData.Append( szEncoding );
  374. bstrData.Append( "\"" );
  375. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createProcessingInstruction( bstrPI, bstrData, &xdpiElem ));
  376. __MPC_EXIT_IF_METHOD_FAILS(hr, xdpiElem->QueryInterface( IID_IXMLDOMNode, (void **)&xdnNode ));
  377. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->appendChild( xdnNode, &xdnNodeNew ));
  378. }
  379. //
  380. // Create the root node.
  381. //
  382. {
  383. CComPtr<IXMLDOMNode> xdnNode;
  384. CComPtr<IXMLDOMElement> xdeElem;
  385. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createElement( CComBSTR( szRootTag ), &xdeElem ));
  386. __MPC_EXIT_IF_METHOD_FAILS(hr, xdeElem->QueryInterface( IID_IXMLDOMNode, (void **)&xdnNode ));
  387. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->appendChild( xdnNode, &m_xdnRoot ));
  388. }
  389. hr = S_OK;
  390. __MPC_FUNC_CLEANUP;
  391. __MPC_FUNC_EXIT(hr);
  392. }
  393. HRESULT MPC::XmlUtil::LoadPost( /*[in ]*/ LPCWSTR szRootTag ,
  394. /*[out]*/ bool& fLoaded ,
  395. /*[out]*/ bool* fFound )
  396. {
  397. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::LoadPost" );
  398. HRESULT hr;
  399. if(szRootTag)
  400. {
  401. CComBSTR bstrTag( szRootTag );
  402. CComPtr<IXMLDOMNode> xdnNode;
  403. if(m_xdnRoot)
  404. {
  405. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xdnRoot->selectSingleNode( bstrTag, &xdnNode ));
  406. }
  407. else
  408. {
  409. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->selectSingleNode( bstrTag, &xdnNode ));
  410. }
  411. m_xdnRoot = xdnNode;
  412. }
  413. else
  414. {
  415. CComPtr<IXMLDOMElement> xdeElem;
  416. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->get_documentElement( &xdeElem ));
  417. m_xdnRoot.Release();
  418. if(xdeElem)
  419. {
  420. __MPC_EXIT_IF_METHOD_FAILS(hr, xdeElem->QueryInterface( IID_IXMLDOMNode, (void **)&m_xdnRoot ));
  421. }
  422. }
  423. if(m_xdnRoot)
  424. {
  425. if(fFound) *fFound = true;
  426. }
  427. fLoaded = true;
  428. hr = S_OK;
  429. __MPC_FUNC_CLEANUP;
  430. __MPC_FUNC_EXIT(hr);
  431. }
  432. HRESULT MPC::XmlUtil::Load( /*[in ]*/ LPCWSTR szFile ,
  433. /*[in ]*/ LPCWSTR szRootTag ,
  434. /*[out]*/ bool& fLoaded ,
  435. /*[out]*/ bool* fFound )
  436. {
  437. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::Load" );
  438. HRESULT hr;
  439. CComVariant v( szFile );
  440. CComPtr<AsyncXMLParser> pAsync;
  441. fLoaded = false;
  442. if(fFound) *fFound = false;
  443. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateParser());
  444. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstanceNoLock( &pAsync ));
  445. if(FAILED(pAsync->Load( m_xddDoc, m_hEvent, m_dwTimeout, v )))
  446. {
  447. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  448. }
  449. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( szRootTag, fLoaded, fFound ));
  450. hr = S_OK;
  451. __MPC_FUNC_CLEANUP;
  452. __MPC_FUNC_EXIT(hr);
  453. }
  454. HRESULT MPC::XmlUtil::LoadAsStream( /*[in ]*/ IUnknown* pStream ,
  455. /*[in ]*/ LPCWSTR szRootTag ,
  456. /*[out]*/ bool& fLoaded ,
  457. /*[out]*/ bool* fFound )
  458. {
  459. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::LoadAsStream" );
  460. HRESULT hr;
  461. CComVariant v( pStream );
  462. CComPtr<AsyncXMLParser> pAsync;
  463. fLoaded = false;
  464. if(fFound) *fFound = false;
  465. //
  466. // Create the parser.
  467. //
  468. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateParser());
  469. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstanceNoLock( &pAsync ));
  470. if(FAILED(pAsync->Load( m_xddDoc, m_hEvent, m_dwTimeout, v )))
  471. {
  472. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  473. }
  474. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( szRootTag, fLoaded, fFound ));
  475. hr = S_OK;
  476. __MPC_FUNC_CLEANUP;
  477. __MPC_FUNC_EXIT(hr);
  478. }
  479. HRESULT MPC::XmlUtil::LoadAsString( /*[in ]*/ BSTR bstrData ,
  480. /*[in ]*/ LPCWSTR szRootTag ,
  481. /*[out]*/ bool& fLoaded ,
  482. /*[out]*/ bool* fFound )
  483. {
  484. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::LoadAsString" );
  485. HRESULT hr;
  486. VARIANT_BOOL fSuccess;
  487. fLoaded = false;
  488. if(fFound) *fFound = false;
  489. //
  490. // Create the parser.
  491. //
  492. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateParser());
  493. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->loadXML( bstrData, &fSuccess ));
  494. if(fSuccess == VARIANT_FALSE)
  495. {
  496. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  497. }
  498. __MPC_EXIT_IF_METHOD_FAILS(hr, LoadPost( szRootTag, fLoaded, fFound ));
  499. hr = S_OK;
  500. __MPC_FUNC_CLEANUP;
  501. __MPC_FUNC_EXIT(hr);
  502. }
  503. ////////////////////////////////////////////////////////////////////////////////
  504. HRESULT MPC::XmlUtil::Save( /*[in]*/ LPCWSTR szFile )
  505. {
  506. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::Save" );
  507. HRESULT hr;
  508. __MPC_PARAMCHECK_BEGIN(hr)
  509. __MPC_PARAMCHECK_NOTNULL(m_xddDoc); // No document...
  510. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szFile);
  511. __MPC_PARAMCHECK_END();
  512. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->save( CComVariant( szFile ) ));
  513. hr = S_OK;
  514. __MPC_FUNC_CLEANUP;
  515. __MPC_FUNC_EXIT(hr);
  516. }
  517. HRESULT MPC::XmlUtil::SaveAsStream( /*[out]*/ IUnknown* *ppStream )
  518. {
  519. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::SaveAsStream" );
  520. HRESULT hr;
  521. __MPC_PARAMCHECK_BEGIN(hr)
  522. __MPC_PARAMCHECK_NOTNULL(m_xddDoc); // No document...
  523. __MPC_PARAMCHECK_POINTER_AND_SET(ppStream,NULL);
  524. __MPC_PARAMCHECK_END();
  525. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->QueryInterface( IID_IStream, (void **)ppStream ));
  526. hr = S_OK;
  527. __MPC_FUNC_CLEANUP;
  528. __MPC_FUNC_EXIT(hr);
  529. }
  530. HRESULT MPC::XmlUtil::SaveAsString( /*[out]*/ BSTR *pbstrData )
  531. {
  532. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::SaveAsString" );
  533. HRESULT hr;
  534. __MPC_PARAMCHECK_BEGIN(hr)
  535. __MPC_PARAMCHECK_NOTNULL(m_xddDoc); // No document...
  536. __MPC_PARAMCHECK_POINTER_AND_SET(pbstrData,NULL);
  537. __MPC_PARAMCHECK_END();
  538. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->get_xml( pbstrData ));
  539. hr = S_OK;
  540. __MPC_FUNC_CLEANUP;
  541. __MPC_FUNC_EXIT(hr);
  542. }
  543. /////////////////////////////////////////////////////////////////////////////
  544. /////////////////////////////////////////////////////////////////////////////
  545. /////////////////////////////////////////////////////////////////////////////
  546. HRESULT MPC::XmlUtil::DumpError()
  547. {
  548. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::DumpError" );
  549. HRESULT hr;
  550. CComPtr<IXMLDOMParseError> pxdpeError;
  551. long lErrorCode;
  552. CComBSTR bstrUrlString;
  553. CComBSTR bstrReasonString;
  554. CComBSTR bstrSourceString;
  555. long lLineNumber;
  556. long lLinePosition;
  557. long lFilePosition;
  558. __MPC_PARAMCHECK_BEGIN(hr)
  559. __MPC_PARAMCHECK_NOTNULL(m_xddDoc); // No document...
  560. __MPC_PARAMCHECK_END();
  561. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->get_parseError( &pxdpeError ));
  562. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_errorCode( &lErrorCode ));
  563. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_url ( &bstrUrlString ));
  564. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_reason ( &bstrReasonString ));
  565. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_srcText ( &bstrSourceString ));
  566. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_line ( &lLineNumber ));
  567. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_linepos ( &lLinePosition ));
  568. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdpeError->get_filepos ( &lFilePosition ));
  569. // CODEWORK: dump error information.
  570. __MPC_FUNC_CLEANUP;
  571. __MPC_FUNC_EXIT(hr);
  572. }
  573. /////////////////////////////////////////////////////////////////////////////
  574. /////////////////////////////////////////////////////////////////////////////
  575. /////////////////////////////////////////////////////////////////////////////
  576. HRESULT MPC::XmlUtil::SetTimeout( /*[in]*/ DWORD dwTimeout ) { m_dwTimeout = dwTimeout; return S_OK; }
  577. HRESULT MPC::XmlUtil::Abort ( ) { if(m_hEvent) { ::SetEvent( m_hEvent ); } return S_OK; }
  578. HRESULT MPC::XmlUtil::SetVersionAndEncoding( /*[in]*/ LPCWSTR szVersion ,
  579. /*[in]*/ LPCWSTR szEncoding )
  580. {
  581. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::SetVersionAndEncoding" );
  582. HRESULT hr;
  583. CComPtr<IXMLDOMProcessingInstruction> xdpiElem;
  584. CComPtr<IXMLDOMNode> xdnOldPI;
  585. CComPtr<IXMLDOMNode> xdnNewPI;
  586. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->get_firstChild( &xdnOldPI ));
  587. if(xdnOldPI)
  588. {
  589. CComBSTR bstrTarget = L"xml";
  590. CComBSTR bstrData = L"version=\"";
  591. bstrData.Append( szVersion );
  592. bstrData.Append( L"\" encoding=\"" );
  593. bstrData.Append( szEncoding );
  594. bstrData.Append( "\"" );
  595. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createProcessingInstruction( bstrTarget, bstrData, &xdpiElem ));
  596. __MPC_EXIT_IF_METHOD_FAILS(hr, xdpiElem->QueryInterface( IID_IXMLDOMNode, (void **)&xdnNewPI ));
  597. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->replaceChild( xdnNewPI, xdnOldPI, NULL ));
  598. }
  599. hr = S_OK;
  600. __MPC_FUNC_CLEANUP;
  601. __MPC_FUNC_EXIT(hr);
  602. }
  603. HRESULT MPC::XmlUtil::GetDocument( /*[out]*/ IXMLDOMDocument* *pVal ) const
  604. {
  605. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetDocument" );
  606. HRESULT hr;
  607. __MPC_PARAMCHECK_BEGIN(hr)
  608. __MPC_PARAMCHECK_NOTNULL(m_xddDoc); // No document...
  609. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  610. __MPC_PARAMCHECK_END();
  611. hr = m_xddDoc->QueryInterface( IID_IXMLDOMDocument, (void **)pVal );
  612. __MPC_FUNC_CLEANUP;
  613. __MPC_FUNC_EXIT(hr);
  614. }
  615. HRESULT MPC::XmlUtil::GetRoot( /*[out]*/ IXMLDOMNode* *pVal ) const
  616. {
  617. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetRoot" );
  618. HRESULT hr;
  619. __MPC_PARAMCHECK_BEGIN(hr)
  620. __MPC_PARAMCHECK_NOTNULL(m_xdnRoot); // No document...
  621. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  622. __MPC_PARAMCHECK_END();
  623. hr = m_xdnRoot->QueryInterface( IID_IXMLDOMNode, (void **)pVal );
  624. __MPC_FUNC_CLEANUP;
  625. __MPC_FUNC_EXIT(hr);
  626. }
  627. HRESULT MPC::XmlUtil::GetNodes( /*[in ]*/ LPCWSTR szTag ,
  628. /*[out]*/ IXMLDOMNodeList* *pVal ) const
  629. {
  630. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetNodes" );
  631. HRESULT hr;
  632. CComBSTR bstrTagName = szTag;
  633. __MPC_PARAMCHECK_BEGIN(hr)
  634. __MPC_PARAMCHECK_NOTNULL(m_xdnRoot); // No root...
  635. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szTag);
  636. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  637. __MPC_PARAMCHECK_END();
  638. hr = m_xdnRoot->selectNodes( bstrTagName, pVal );
  639. __MPC_FUNC_CLEANUP;
  640. __MPC_FUNC_EXIT(hr);
  641. }
  642. HRESULT MPC::XmlUtil::GetNode( /*[in ]*/ LPCWSTR szTag ,
  643. /*[out]*/ IXMLDOMNode* *pVal ) const
  644. {
  645. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetNode" );
  646. HRESULT hr;
  647. __MPC_PARAMCHECK_BEGIN(hr)
  648. __MPC_PARAMCHECK_NOTNULL(m_xdnRoot); // No root...
  649. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szTag);
  650. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  651. __MPC_PARAMCHECK_END();
  652. hr = m_xdnRoot->selectSingleNode( CComBSTR( szTag ), pVal );
  653. __MPC_FUNC_CLEANUP;
  654. __MPC_FUNC_EXIT(hr);
  655. }
  656. HRESULT MPC::XmlUtil::CreateNode( /*[in ]*/ LPCWSTR szTag ,
  657. /*[out]*/ IXMLDOMNode* *pVal ,
  658. /*[in ]*/ IXMLDOMNode* pxdnNode )
  659. {
  660. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::CreateNode" );
  661. HRESULT hr;
  662. CComPtr<IXMLDOMElement> xdeElem;
  663. CComPtr<IXMLDOMNode> xdnChild;
  664. __MPC_PARAMCHECK_BEGIN(hr)
  665. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szTag);
  666. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  667. __MPC_PARAMCHECK_END();
  668. if(m_xdnRoot)
  669. {
  670. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  671. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createElement( CComBSTR( szTag ), &xdeElem ));
  672. __MPC_EXIT_IF_METHOD_FAILS(hr, xdeElem->QueryInterface( IID_IXMLDOMNode, (void **)&xdnChild ));
  673. __MPC_EXIT_IF_METHOD_FAILS(hr, pxdnNode->appendChild( xdnChild, pVal ));
  674. }
  675. else
  676. {
  677. //
  678. // No document, so create a new one or attach to the supplied node's document.
  679. //
  680. if(pxdnNode)
  681. {
  682. __MPC_EXIT_IF_METHOD_FAILS(hr, New( pxdnNode ));
  683. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateNode( szTag, pVal ));
  684. }
  685. else
  686. {
  687. __MPC_EXIT_IF_METHOD_FAILS(hr, New( szTag ));
  688. __MPC_EXIT_IF_METHOD_FAILS(hr, GetRoot( pVal ));
  689. }
  690. }
  691. hr = S_OK;
  692. __MPC_FUNC_CLEANUP;
  693. __MPC_FUNC_EXIT(hr);
  694. }
  695. /////////////////////////////////////////////////////////////////////////////
  696. /////////////////////////////////////////////////////////////////////////////
  697. /////////////////////////////////////////////////////////////////////////////
  698. HRESULT MPC::XmlUtil::GetAttribute( /*[in ]*/ LPCWSTR szTag ,
  699. /*[in ]*/ LPCWSTR szAttr ,
  700. /*[out]*/ IXMLDOMAttribute* *pVal ,
  701. /*[out]*/ bool& fFound ,
  702. /*[in ]*/ IXMLDOMNode* pxdnNode )
  703. {
  704. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetAttribute" );
  705. HRESULT hr;
  706. CComPtr<IXMLDOMNode> xdnNodeStart;
  707. CComPtr<IXMLDOMNode> xdnAttr;
  708. //
  709. // Initialize OUT parameters for 'Not Found' case.
  710. //
  711. fFound = false;
  712. __MPC_PARAMCHECK_BEGIN(hr)
  713. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  714. __MPC_PARAMCHECK_END();
  715. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  716. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  717. if(fFound == false)
  718. {
  719. // Node not found...
  720. fFound = false;
  721. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  722. }
  723. if(szAttr)
  724. {
  725. CComBSTR bstrAttrName = szAttr;
  726. CComPtr<IXMLDOMNamedNodeMap> xdnnmAttrs;
  727. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeStart->get_attributes( &xdnnmAttrs ));
  728. if(xdnnmAttrs == NULL)
  729. {
  730. // No attributes...
  731. fFound = false;
  732. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  733. }
  734. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnnmAttrs->getNamedItem( bstrAttrName, &xdnAttr ));
  735. if(hr == S_FALSE)
  736. {
  737. // Unknown attribute...
  738. fFound = false;
  739. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  740. }
  741. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnAttr->QueryInterface( IID_IXMLDOMAttribute, (void**)pVal ));
  742. }
  743. else
  744. {
  745. CComQIPtr<IXMLDOMAttribute> xdaAttr;
  746. xdaAttr = xdnNodeStart;
  747. if(xdaAttr == NULL)
  748. {
  749. // Unknown attribute...
  750. fFound = false;
  751. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  752. }
  753. *pVal = xdaAttr.Detach();
  754. }
  755. fFound = true;
  756. hr = S_OK;
  757. __MPC_FUNC_CLEANUP;
  758. __MPC_FUNC_EXIT(hr);
  759. }
  760. HRESULT MPC::XmlUtil::GetAttribute( /*[in ]*/ LPCWSTR szTag ,
  761. /*[in ]*/ LPCWSTR szAttr ,
  762. /*[out]*/ CComBSTR& bstrVal ,
  763. /*[out]*/ bool& fFound ,
  764. /*[in ]*/ IXMLDOMNode* pxdnNode )
  765. {
  766. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetAttribute" );
  767. HRESULT hr;
  768. CComPtr<IXMLDOMAttribute> xdaAttr;
  769. CComVariant vValue;
  770. bstrVal.Empty();
  771. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  772. if(fFound == false)
  773. {
  774. // Unknown attribute...
  775. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  776. }
  777. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->get_value( &vValue ));
  778. __MPC_EXIT_IF_METHOD_FAILS(hr, vValue.ChangeType( VT_BSTR ));
  779. bstrVal = vValue.bstrVal;
  780. fFound = true;
  781. hr = S_OK;
  782. __MPC_FUNC_CLEANUP;
  783. __MPC_FUNC_EXIT(hr);
  784. }
  785. HRESULT MPC::XmlUtil::GetAttribute( /*[in ]*/ LPCWSTR szTag ,
  786. /*[in ]*/ LPCWSTR szAttr ,
  787. /*[out]*/ MPC::wstring& szVal ,
  788. /*[out]*/ bool& fFound ,
  789. /*[in ]*/ IXMLDOMNode* pxdnNode )
  790. {
  791. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetAttribute" );
  792. HRESULT hr;
  793. CComBSTR bstrVal;
  794. szVal = L"";
  795. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, bstrVal, fFound, pxdnNode ));
  796. if(fFound)
  797. {
  798. szVal = SAFEBSTR( bstrVal );
  799. }
  800. hr = S_OK;
  801. __MPC_FUNC_CLEANUP;
  802. __MPC_FUNC_EXIT(hr);
  803. }
  804. HRESULT MPC::XmlUtil::GetAttribute( /*[in ]*/ LPCWSTR szTag ,
  805. /*[in ]*/ LPCWSTR szAttr ,
  806. /*[out]*/ LONG& lVal ,
  807. /*[out]*/ bool& fFound ,
  808. /*[in ]*/ IXMLDOMNode* pxdnNode )
  809. {
  810. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetAttribute" );
  811. HRESULT hr;
  812. CComPtr<IXMLDOMAttribute> xdaAttr;
  813. CComVariant vValue;
  814. lVal = 0;
  815. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  816. if(fFound == false)
  817. {
  818. // Unknown attribute...
  819. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  820. }
  821. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->get_value( &vValue ));
  822. __MPC_EXIT_IF_METHOD_FAILS(hr, vValue.ChangeType( VT_I4 ));
  823. lVal = vValue.lVal;
  824. fFound = true;
  825. hr = S_OK;
  826. __MPC_FUNC_CLEANUP;
  827. __MPC_FUNC_EXIT(hr);
  828. }
  829. /////////////////////////////////////////////////////////////////////////////
  830. HRESULT MPC::XmlUtil::GetValue( /*[in ]*/ LPCWSTR szTag ,
  831. /*[out]*/ CComVariant& vValue ,
  832. /*[out]*/ bool& fFound ,
  833. /*[in ]*/ IXMLDOMNode* pxdnNode )
  834. {
  835. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::GetValue" );
  836. HRESULT hr;
  837. CComPtr<IXMLDOMNode> xdnNodeStart;
  838. CComPtr<IXMLDOMNode> xdnChild;
  839. vValue.Clear();
  840. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  841. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  842. if(fFound == false)
  843. {
  844. // Node not found...
  845. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  846. }
  847. //
  848. // Find the node holding the value.
  849. //
  850. __MPC_EXIT_IF_METHOD_FAILS(hr, getValueNode( xdnNodeStart, xdnChild, fFound ));
  851. if(fFound == false)
  852. {
  853. //
  854. // Not found...
  855. //
  856. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  857. }
  858. //
  859. // Read the value.
  860. //
  861. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nodeValue( &vValue ));
  862. fFound = true;
  863. hr = S_OK;
  864. __MPC_FUNC_CLEANUP;
  865. __MPC_FUNC_EXIT(hr);
  866. }
  867. HRESULT MPC::XmlUtil::GetValue( /*[in ]*/ LPCWSTR szTag ,
  868. /*[out]*/ CComBSTR& bstrValue ,
  869. /*[out]*/ bool& fFound ,
  870. /*[in ]*/ IXMLDOMNode* pxdnNode )
  871. {
  872. HRESULT hr;
  873. CComVariant vValue;
  874. if(SUCCEEDED(hr = GetValue( szTag, vValue, fFound, pxdnNode )))
  875. {
  876. if(fFound && SUCCEEDED(vValue.ChangeType( VT_BSTR )))
  877. {
  878. bstrValue = vValue.bstrVal;
  879. }
  880. }
  881. return hr;
  882. }
  883. HRESULT MPC::XmlUtil::GetValue( /*[in ]*/ LPCWSTR szTag ,
  884. /*[out]*/ MPC::wstring& szValue ,
  885. /*[out]*/ bool& fFound ,
  886. /*[in ]*/ IXMLDOMNode* pxdnNode )
  887. {
  888. HRESULT hr;
  889. CComVariant vValue;
  890. if(SUCCEEDED(hr = GetValue( szTag, vValue, fFound, pxdnNode )))
  891. {
  892. if(fFound && SUCCEEDED(vValue.ChangeType( VT_BSTR )))
  893. {
  894. szValue = SAFEBSTR( vValue.bstrVal );
  895. }
  896. }
  897. return hr;
  898. }
  899. /////////////////////////////////////////////////////////////////////////////
  900. /////////////////////////////////////////////////////////////////////////////
  901. /////////////////////////////////////////////////////////////////////////////
  902. HRESULT MPC::XmlUtil::ModifyAttribute( /*[in ]*/ LPCWSTR szTag ,
  903. /*[in ]*/ LPCWSTR szAttr ,
  904. /*[in ]*/ const CComBSTR& bstrVal ,
  905. /*[out]*/ bool& fFound ,
  906. /*[in ]*/ IXMLDOMNode* pxdnNode )
  907. {
  908. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::ModifyAttribute" );
  909. HRESULT hr;
  910. CComPtr<IXMLDOMAttribute> xdaAttr;
  911. CComVariant vValue( bstrVal );
  912. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  913. if(fFound == false)
  914. {
  915. // Unknown attribute...
  916. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  917. }
  918. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  919. fFound = true;
  920. hr = S_OK;
  921. __MPC_FUNC_CLEANUP;
  922. __MPC_FUNC_EXIT(hr);
  923. }
  924. HRESULT MPC::XmlUtil::ModifyAttribute( /*[in ]*/ LPCWSTR szTag ,
  925. /*[in ]*/ LPCWSTR szAttr ,
  926. /*[in ]*/ const MPC::wstring& szVal ,
  927. /*[out]*/ bool& fFound ,
  928. /*[in ]*/ IXMLDOMNode* pxdnNode )
  929. {
  930. return ModifyAttribute( szTag, szAttr, SAFEWSTR( szVal.c_str() ), fFound, pxdnNode );
  931. }
  932. HRESULT MPC::XmlUtil::ModifyAttribute( /*[in ]*/ LPCWSTR szTag ,
  933. /*[in ]*/ LPCWSTR szAttr ,
  934. /*[in ]*/ LPCWSTR szVal ,
  935. /*[out]*/ bool& fFound ,
  936. /*[in ]*/ IXMLDOMNode* pxdnNode )
  937. {
  938. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::ModifyAttribute" );
  939. HRESULT hr;
  940. CComPtr<IXMLDOMAttribute> xdaAttr;
  941. CComVariant vValue( szVal );
  942. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  943. if(fFound == false)
  944. {
  945. // Unknown attribute...
  946. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  947. }
  948. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  949. fFound = true;
  950. hr = S_OK;
  951. __MPC_FUNC_CLEANUP;
  952. __MPC_FUNC_EXIT(hr);
  953. }
  954. HRESULT MPC::XmlUtil::ModifyAttribute( /*[in ]*/ LPCWSTR szTag ,
  955. /*[in ]*/ LPCWSTR szAttr ,
  956. /*[in ]*/ LONG lVal ,
  957. /*[out]*/ bool& fFound ,
  958. /*[in ]*/ IXMLDOMNode* pxdnNode )
  959. {
  960. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::ModifyAttribute" );
  961. HRESULT hr;
  962. CComPtr<IXMLDOMAttribute> xdaAttr;
  963. CComVariant vValue( lVal );
  964. __MPC_EXIT_IF_METHOD_FAILS(hr, GetAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  965. if(fFound == false)
  966. {
  967. // Unknown attribute...
  968. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  969. }
  970. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  971. fFound = true;
  972. hr = S_OK;
  973. __MPC_FUNC_CLEANUP;
  974. __MPC_FUNC_EXIT(hr);
  975. }
  976. /////////////////////////////////////////////////////////////////////////////
  977. HRESULT MPC::XmlUtil::ModifyValue( /*[in ]*/ LPCWSTR szTag ,
  978. /*[in ]*/ const CComVariant& vValue ,
  979. /*[out]*/ bool& fFound ,
  980. /*[in ]*/ IXMLDOMNode* pxdnNode )
  981. {
  982. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::ModifyValue" );
  983. HRESULT hr;
  984. CComPtr<IXMLDOMNode> xdnNodeStart;
  985. CComPtr<IXMLDOMNode> xdnChild;
  986. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  987. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  988. if(fFound == false)
  989. {
  990. // Node not found...
  991. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  992. }
  993. //
  994. // Find the node holding the value.
  995. //
  996. __MPC_EXIT_IF_METHOD_FAILS(hr, getValueNode( xdnNodeStart, xdnChild, fFound ));
  997. if(fFound == false)
  998. {
  999. //
  1000. // Not found...
  1001. //
  1002. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  1003. }
  1004. //
  1005. // Modify the value.
  1006. //
  1007. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->put_nodeValue( vValue ));
  1008. fFound = true;
  1009. hr = S_OK;
  1010. __MPC_FUNC_CLEANUP;
  1011. __MPC_FUNC_EXIT(hr);
  1012. }
  1013. HRESULT MPC::XmlUtil::ModifyValue( /*[in ]*/ LPCWSTR szTag ,
  1014. /*[in ]*/ const CComBSTR& bstrValue ,
  1015. /*[out]*/ bool& fFound ,
  1016. /*[out]*/ IXMLDOMNode* pxdnNode )
  1017. {
  1018. CComVariant vValue = bstrValue;
  1019. return ModifyValue( szTag, vValue, fFound, pxdnNode );
  1020. }
  1021. HRESULT MPC::XmlUtil::ModifyValue( /*[in ]*/ LPCWSTR szTag ,
  1022. /*[in ]*/ const MPC::wstring& szValue ,
  1023. /*[out]*/ bool& fFound ,
  1024. /*[out]*/ IXMLDOMNode* pxdnNode )
  1025. {
  1026. CComVariant vValue = szValue.c_str();
  1027. return ModifyValue( szTag, vValue, fFound, pxdnNode );
  1028. }
  1029. /////////////////////////////////////////////////////////////////////////////
  1030. /////////////////////////////////////////////////////////////////////////////
  1031. /////////////////////////////////////////////////////////////////////////////
  1032. HRESULT MPC::XmlUtil::PutAttribute( /*[in ]*/ LPCWSTR szTag ,
  1033. /*[in ]*/ LPCWSTR szAttr ,
  1034. /*[out]*/ IXMLDOMAttribute* *pVal ,
  1035. /*[out]*/ bool& fFound ,
  1036. /*[in ]*/ IXMLDOMNode* pxdnNode )
  1037. {
  1038. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::PutAttribute" );
  1039. HRESULT hr;
  1040. CComBSTR bstrAttrName = szAttr;
  1041. CComPtr<IXMLDOMNode> xdnNodeStart;
  1042. CComPtr<IXMLDOMNamedNodeMap> xdnnmAttrs;
  1043. CComPtr<IXMLDOMNode> xdnAttr;
  1044. __MPC_PARAMCHECK_BEGIN(hr)
  1045. __MPC_PARAMCHECK_STRING_NOT_EMPTY(szAttr);
  1046. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,NULL);
  1047. __MPC_PARAMCHECK_END();
  1048. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  1049. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  1050. if(fFound == false)
  1051. {
  1052. // Node not found...
  1053. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  1054. }
  1055. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeStart->get_attributes( &xdnnmAttrs ));
  1056. if(xdnnmAttrs == NULL)
  1057. {
  1058. // No attributes...
  1059. fFound = false;
  1060. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  1061. }
  1062. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnnmAttrs->getNamedItem( bstrAttrName, &xdnAttr ));
  1063. if(hr == S_FALSE)
  1064. {
  1065. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createAttribute( bstrAttrName, pVal ));
  1066. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnnmAttrs->setNamedItem( *pVal, NULL ));
  1067. }
  1068. else
  1069. {
  1070. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnAttr->QueryInterface( IID_IXMLDOMAttribute, (void**)pVal ));
  1071. }
  1072. fFound = true;
  1073. hr = S_OK;
  1074. __MPC_FUNC_CLEANUP;
  1075. __MPC_FUNC_EXIT(hr);
  1076. }
  1077. HRESULT MPC::XmlUtil::PutAttribute( /*[in ]*/ LPCWSTR szTag ,
  1078. /*[in ]*/ LPCWSTR szAttr ,
  1079. /*[in ]*/ const CComBSTR& bstrVal ,
  1080. /*[out]*/ bool& fFound ,
  1081. /*[in ]*/ IXMLDOMNode* pxdnNode )
  1082. {
  1083. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::PutAttribute" );
  1084. HRESULT hr;
  1085. CComPtr<IXMLDOMAttribute> xdaAttr;
  1086. CComVariant vValue( bstrVal );
  1087. __MPC_EXIT_IF_METHOD_FAILS(hr, PutAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  1088. if(fFound == true)
  1089. {
  1090. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  1091. }
  1092. fFound = true;
  1093. hr = S_OK;
  1094. __MPC_FUNC_CLEANUP;
  1095. __MPC_FUNC_EXIT(hr);
  1096. }
  1097. HRESULT MPC::XmlUtil::PutAttribute( /*[in ]*/ LPCWSTR szTag ,
  1098. /*[in ]*/ LPCWSTR szAttr ,
  1099. /*[in ]*/ const MPC::wstring& szVal ,
  1100. /*[out]*/ bool& fFound ,
  1101. /*[in ]*/ IXMLDOMNode* pxdnNode )
  1102. {
  1103. return PutAttribute( szTag, szAttr, SAFEWSTR( szVal.c_str() ), fFound, pxdnNode );
  1104. }
  1105. HRESULT MPC::XmlUtil::PutAttribute( /*[in ]*/ LPCWSTR szTag ,
  1106. /*[in ]*/ LPCWSTR szAttr ,
  1107. /*[in ]*/ LPCWSTR szVal ,
  1108. /*[out]*/ bool& fFound ,
  1109. /*[in ]*/ IXMLDOMNode* pxdnNode )
  1110. {
  1111. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::PutAttribute" );
  1112. HRESULT hr;
  1113. CComPtr<IXMLDOMAttribute> xdaAttr;
  1114. CComVariant vValue( szVal );
  1115. __MPC_EXIT_IF_METHOD_FAILS(hr, PutAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  1116. if(fFound == true)
  1117. {
  1118. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  1119. }
  1120. fFound = true;
  1121. hr = S_OK;
  1122. __MPC_FUNC_CLEANUP;
  1123. __MPC_FUNC_EXIT(hr);
  1124. }
  1125. HRESULT MPC::XmlUtil::PutAttribute( /*[in ]*/ LPCWSTR szTag ,
  1126. /*[in ]*/ LPCWSTR szAttr ,
  1127. /*[in ]*/ LONG lVal ,
  1128. /*[out]*/ bool& fFound ,
  1129. /*[in ]*/ IXMLDOMNode* pxdnNode )
  1130. {
  1131. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::PutAttribute" );
  1132. HRESULT hr;
  1133. CComPtr<IXMLDOMAttribute> xdaAttr;
  1134. CComVariant vValue( lVal );
  1135. __MPC_EXIT_IF_METHOD_FAILS(hr, PutAttribute( szTag, szAttr, &xdaAttr, fFound, pxdnNode ));
  1136. if(fFound == true)
  1137. {
  1138. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->put_value( vValue ));
  1139. }
  1140. fFound = true;
  1141. hr = S_OK;
  1142. __MPC_FUNC_CLEANUP;
  1143. __MPC_FUNC_EXIT(hr);
  1144. }
  1145. /////////////////////////////////////////////////////////////////////////////
  1146. HRESULT MPC::XmlUtil::PutValue( /*[in ]*/ LPCWSTR szTag ,
  1147. /*[in ]*/ const CComVariant& vValue ,
  1148. /*[out]*/ bool& fFound ,
  1149. /*[out]*/ IXMLDOMNode* pxdnNode )
  1150. {
  1151. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::PutValue" );
  1152. HRESULT hr;
  1153. CComPtr<IXMLDOMNode> xdnNodeStart;
  1154. CComPtr<IXMLDOMNode> xdnChild;
  1155. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  1156. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  1157. if(fFound == false)
  1158. {
  1159. if(szTag == NULL)
  1160. {
  1161. // Node not found...
  1162. __MPC_SET_ERROR_AND_EXIT(hr, S_OK);
  1163. }
  1164. //
  1165. // Tag supplied, let's try to create a new node.
  1166. //
  1167. __MPC_EXIT_IF_METHOD_FAILS(hr, CreateNode( szTag, &xdnNodeStart, pxdnNode ));
  1168. }
  1169. //
  1170. // Find the node holding the value.
  1171. //
  1172. __MPC_EXIT_IF_METHOD_FAILS(hr, getValueNode( xdnNodeStart, xdnChild, fFound ));
  1173. if(fFound == false)
  1174. {
  1175. if(vValue.vt == VT_ARRAY)
  1176. {
  1177. CComPtr<IXMLDOMCDATASection> xdcData;
  1178. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createCDATASection( NULL, &xdcData ));
  1179. __MPC_EXIT_IF_METHOD_FAILS(hr, xdcData->QueryInterface( IID_IXMLDOMNode, (void **)&xdnChild ));
  1180. }
  1181. else
  1182. {
  1183. CComPtr<IXMLDOMText> xdtData;
  1184. __MPC_EXIT_IF_METHOD_FAILS(hr, m_xddDoc->createTextNode( NULL, &xdtData ));
  1185. __MPC_EXIT_IF_METHOD_FAILS(hr, xdtData->QueryInterface( IID_IXMLDOMNode, (void **)&xdnChild ));
  1186. }
  1187. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeStart->appendChild( xdnChild, NULL ));
  1188. }
  1189. //
  1190. // Modify the value.
  1191. //
  1192. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->put_nodeValue( vValue ));
  1193. fFound = true;
  1194. hr = S_OK;
  1195. __MPC_FUNC_CLEANUP;
  1196. __MPC_FUNC_EXIT(hr);
  1197. }
  1198. HRESULT MPC::XmlUtil::PutValue( /*[in ]*/ LPCWSTR szTag ,
  1199. /*[in ]*/ const CComBSTR& bstrValue ,
  1200. /*[out]*/ bool& fFound ,
  1201. /*[out]*/ IXMLDOMNode* pxdnNode )
  1202. {
  1203. CComVariant vValue = bstrValue;
  1204. return PutValue( szTag, vValue, fFound, pxdnNode );
  1205. }
  1206. HRESULT MPC::XmlUtil::PutValue( /*[in ]*/ LPCWSTR szTag ,
  1207. /*[in ]*/ const MPC::wstring& szValue ,
  1208. /*[out]*/ bool& fFound ,
  1209. /*[out]*/ IXMLDOMNode* pxdnNode )
  1210. {
  1211. CComVariant vValue = szValue.c_str();
  1212. return PutValue( szTag, vValue, fFound, pxdnNode );
  1213. }
  1214. ////////////////////////////////////////
  1215. HRESULT MPC::XmlUtil::RemoveAttribute( /*[in]*/ LPCWSTR szTag ,
  1216. /*[in]*/ LPCWSTR szAttr ,
  1217. /*[in]*/ IXMLDOMNode* pxdnNode )
  1218. {
  1219. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::RemoveAttribute" );
  1220. HRESULT hr;
  1221. CComPtr<IXMLDOMNode> xdnNodeStart;
  1222. bool fFound;
  1223. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  1224. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  1225. if(fFound)
  1226. {
  1227. CComPtr<IXMLDOMNamedNodeMap> xdnnmAttrs;
  1228. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeStart->get_attributes( &xdnnmAttrs ));
  1229. if(xdnnmAttrs)
  1230. {
  1231. CComPtr<IXMLDOMNode> xdnAttr;
  1232. (void)xdnnmAttrs->removeNamedItem( CComBSTR( szAttr ), &xdnAttr );
  1233. }
  1234. }
  1235. hr = S_OK;
  1236. __MPC_FUNC_CLEANUP;
  1237. __MPC_FUNC_EXIT(hr);
  1238. }
  1239. HRESULT MPC::XmlUtil::RemoveValue( /*[in]*/ LPCWSTR szTag ,
  1240. /*[in]*/ IXMLDOMNode* pxdnNode )
  1241. {
  1242. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::RemoveValue" );
  1243. HRESULT hr;
  1244. CComPtr<IXMLDOMNode> xdnNodeStart;
  1245. bool fFound;
  1246. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  1247. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  1248. if(fFound)
  1249. {
  1250. ; // TODO
  1251. }
  1252. hr = S_OK;
  1253. __MPC_FUNC_CLEANUP;
  1254. __MPC_FUNC_EXIT(hr);
  1255. }
  1256. HRESULT MPC::XmlUtil::RemoveNode( /*[in]*/ LPCWSTR szTag ,
  1257. /*[in]*/ IXMLDOMNode* pxdnNode )
  1258. {
  1259. __MPC_FUNC_ENTRY( COMMONID, "MPC::XmlUtil::RemoveNode" );
  1260. HRESULT hr;
  1261. CComPtr<IXMLDOMNode> xdnNodeStart;
  1262. bool fFound;
  1263. if(pxdnNode == NULL) { pxdnNode = m_xdnRoot; } // Use root as base of search, if no base node is supplied.
  1264. __MPC_EXIT_IF_METHOD_FAILS(hr, getStartNode( szTag, pxdnNode, xdnNodeStart, fFound ));
  1265. if(fFound)
  1266. {
  1267. CComPtr<IXMLDOMNode> xdnNodeParent;
  1268. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeStart->get_parentNode( &xdnNodeParent ));
  1269. if(xdnNodeParent)
  1270. {
  1271. CComPtr<IXMLDOMNode> xdnNodeChild;
  1272. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnNodeParent->removeChild( xdnNodeStart, &xdnNodeChild ));
  1273. }
  1274. }
  1275. hr = S_OK;
  1276. __MPC_FUNC_CLEANUP;
  1277. __MPC_FUNC_EXIT(hr);
  1278. }
  1279. ////////////////////////////////////////////////////////////////////////////////
  1280. ////////////////////////////////////////////////////////////////////////////////
  1281. ////////////////////////////////////////////////////////////////////////////////
  1282. static HRESULT local_Reg_to_XML( /*[in]*/ const MPC::RegKey& rkKey ,
  1283. /*[in]*/ LPCWSTR szName ,
  1284. /*[in]*/ IXMLDOMNode* node )
  1285. {
  1286. __MPC_FUNC_ENTRY( COMMONID, "local_Reg_to_XML" );
  1287. HRESULT hr;
  1288. MPC::WStringList lst;
  1289. MPC::WStringIter it;
  1290. MPC::XmlUtil xml( node );
  1291. MPC::RegKey rkSubKey;
  1292. CComVariant v;
  1293. bool fFound;
  1294. //
  1295. // Get the subkey.
  1296. //
  1297. __MPC_EXIT_IF_METHOD_FAILS(hr, rkKey.SubKey( szName, rkSubKey ));
  1298. //
  1299. // Copy all the values.
  1300. //
  1301. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.EnumerateValues( lst ));
  1302. for(it=lst.begin(); it != lst.end(); it++)
  1303. {
  1304. LPCWSTR szNameValue = it->c_str();
  1305. if(szNameValue[0] == 0) szNameValue = NULL; // Special case for the default key.
  1306. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.get_Value( v, fFound, szNameValue ));
  1307. if(fFound)
  1308. {
  1309. if(szNameValue)
  1310. {
  1311. __MPC_EXIT_IF_METHOD_FAILS(hr, v.ChangeType( VT_BSTR ));
  1312. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutAttribute( NULL, szNameValue, v.bstrVal, fFound ));
  1313. }
  1314. else
  1315. {
  1316. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutValue( NULL, v, fFound ));
  1317. }
  1318. }
  1319. }
  1320. //
  1321. // Copy all the subkeys.
  1322. //
  1323. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.EnumerateSubKeys( lst ));
  1324. for(it=lst.begin(); it != lst.end(); it++)
  1325. {
  1326. CComPtr<IXMLDOMNode> xdnChild;
  1327. LPCWSTR szNameKey = it->c_str();
  1328. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( szNameKey, &xdnChild ));
  1329. __MPC_EXIT_IF_METHOD_FAILS(hr, local_Reg_to_XML( rkSubKey, szNameKey, xdnChild ));
  1330. }
  1331. hr = S_OK;
  1332. __MPC_FUNC_CLEANUP;
  1333. __MPC_FUNC_EXIT(hr);
  1334. }
  1335. HRESULT MPC::ConvertFromRegistryToXML( /*[in] */ const MPC::RegKey& rkKey ,
  1336. /*[out]*/ MPC::XmlUtil& xml )
  1337. {
  1338. __MPC_FUNC_ENTRY( COMMONID, "MPC::ConvertFromRegistryToXML" );
  1339. HRESULT hr;
  1340. MPC::WStringList lst;
  1341. //
  1342. // Get the first subkey.
  1343. //
  1344. __MPC_EXIT_IF_METHOD_FAILS(hr, rkKey.EnumerateSubKeys( lst ));
  1345. if(lst.size() > 0)
  1346. {
  1347. CComPtr<IXMLDOMNode> xdnRoot;
  1348. LPCWSTR szName = lst.begin()->c_str();
  1349. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.New ( szName ));
  1350. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnRoot ));
  1351. __MPC_EXIT_IF_METHOD_FAILS(hr, local_Reg_to_XML( rkKey, szName, xdnRoot ));
  1352. }
  1353. hr = S_OK;
  1354. __MPC_FUNC_CLEANUP;
  1355. __MPC_FUNC_EXIT(hr);
  1356. }
  1357. ////////////////////////////////////////
  1358. static HRESULT local_XML_to_Reg( /*[in]*/ IXMLDOMNode* node ,
  1359. /*[in]*/ MPC::RegKey& rkKey )
  1360. {
  1361. __MPC_FUNC_ENTRY( COMMONID, "local_XML_to_Reg" );
  1362. HRESULT hr;
  1363. MPC::XmlUtil xml( node );
  1364. MPC::RegKey rkSubKey;
  1365. CComVariant v;
  1366. CComBSTR bstr;
  1367. bool fFound;
  1368. //
  1369. // Create a subkey using the TAG name.
  1370. //
  1371. __MPC_EXIT_IF_METHOD_FAILS(hr, node->get_nodeName( &bstr ));
  1372. if(!bstr) __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
  1373. __MPC_EXIT_IF_METHOD_FAILS(hr, rkKey.SubKey( bstr, rkSubKey )); bstr.Empty();
  1374. //
  1375. // Clean up the key.
  1376. //
  1377. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.Create ());
  1378. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.DeleteSubKeys());
  1379. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.DeleteValues ());
  1380. //
  1381. // Transfer the default value.
  1382. //
  1383. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, v, fFound ));
  1384. if(fFound)
  1385. {
  1386. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.put_Value( v ));
  1387. }
  1388. //
  1389. // Copy all the values.
  1390. //
  1391. {
  1392. CComPtr<IXMLDOMNamedNodeMap> xdnnmAttrs;
  1393. __MPC_EXIT_IF_METHOD_FAILS(hr, node->get_attributes( &xdnnmAttrs ));
  1394. if(xdnnmAttrs)
  1395. {
  1396. while(1)
  1397. {
  1398. CComPtr<IXMLDOMNode> xdnAttr;
  1399. CComPtr<IXMLDOMAttribute> xdaAttr;
  1400. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnnmAttrs->nextNode( &xdnAttr ));
  1401. if(xdnAttr == NULL) break;
  1402. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnAttr->QueryInterface( &xdaAttr ));
  1403. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->get_name ( &bstr ));
  1404. __MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttr->get_value ( &v ));
  1405. if(bstr)
  1406. {
  1407. __MPC_EXIT_IF_METHOD_FAILS(hr, rkSubKey.put_Value( v, bstr ));
  1408. bstr.Empty();
  1409. }
  1410. }
  1411. }
  1412. }
  1413. //
  1414. // Copy all the subnodes.
  1415. //
  1416. {
  1417. CComPtr<IXMLDOMNodeList> xdnlNodes;
  1418. __MPC_EXIT_IF_METHOD_FAILS(hr, node->get_childNodes( &xdnlNodes ));
  1419. if(xdnlNodes)
  1420. {
  1421. while(1)
  1422. {
  1423. CComPtr<IXMLDOMNode> xdnChild;
  1424. DOMNodeType type;
  1425. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnlNodes->nextNode( &xdnChild ));
  1426. if(xdnChild == NULL) break;
  1427. __MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nodeType( &type ));
  1428. if(type == NODE_ELEMENT)
  1429. {
  1430. __MPC_EXIT_IF_METHOD_FAILS(hr, local_XML_to_Reg( xdnChild, rkSubKey ));
  1431. }
  1432. }
  1433. }
  1434. }
  1435. hr = S_OK;
  1436. __MPC_FUNC_CLEANUP;
  1437. __MPC_FUNC_EXIT(hr);
  1438. }
  1439. HRESULT MPC::ConvertFromXMLToRegistry( /*[in] */ const MPC::XmlUtil& xml ,
  1440. /*[out]*/ MPC::RegKey& rkKey )
  1441. {
  1442. __MPC_FUNC_ENTRY( COMMONID, "MPC::ConvertFromXMLToRegistry" );
  1443. HRESULT hr;
  1444. MPC::wstring szName;
  1445. CComPtr<IXMLDOMNode> xdnRoot;
  1446. __MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnRoot ));
  1447. __MPC_EXIT_IF_METHOD_FAILS(hr, local_XML_to_Reg( xdnRoot, rkKey ));
  1448. hr = S_OK;
  1449. __MPC_FUNC_CLEANUP;
  1450. __MPC_FUNC_EXIT(hr);
  1451. }