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.

1203 lines
24 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 2000-2002 Microsoft Corporation
  3. Module Name:
  4. parser.cpp
  5. Abstract:
  6. Source file module for parsing XML file
  7. Author:
  8. Xiaohai Zhang (xzhang) 22-March-2000
  9. Revision History:
  10. --*/
  11. #include "windows.h"
  12. #include "objbase.h"
  13. #include "msxml.h"
  14. #include "error.h"
  15. #include "parser.h"
  16. #include "resource.h"
  17. #include "tchar.h"
  18. #include "util.h"
  19. const TCHAR CIds::m_szEmptyString[2] = _T("");
  20. void WINAPI FormatString (
  21. LPTSTR szFmt,
  22. LPTSTR szOutput,
  23. DWORD cchOutput,
  24. ...
  25. )
  26. {
  27. va_list ap;
  28. va_start (ap, cchOutput);
  29. FormatMessage (
  30. FORMAT_MESSAGE_FROM_STRING,
  31. szFmt,
  32. 0,
  33. 0,
  34. szOutput,
  35. cchOutput,
  36. &ap
  37. );
  38. va_end (ap);
  39. }
  40. ///////////////////////////////////////////////////////////
  41. //
  42. // CXMLParser implementation
  43. //
  44. ///////////////////////////////////////////////////////////
  45. //
  46. // With the XML file provided by the user, we create a temporary file
  47. // with the format of
  48. // <TsecRoot xmlns="x-schema:file://c:\temp\Sche1111.tmp">
  49. // Original XML file goes here
  50. // </TsecRoot>
  51. // for validating with the schema
  52. //
  53. char gszXMLHeader1[] = "<TsecRoot xmlns=\"x-schema:file://";
  54. char gszXMLHeader2[] = "\">\r\n";
  55. char gszXMLTail[] = "\r\n</TsecRoot>";
  56. //
  57. // Constructor / Destructor
  58. //
  59. CXMLParser::CXMLParser (void)
  60. {
  61. m_bInited = FALSE;
  62. m_szXMLFile[0] = 0;
  63. m_szTempSchema[0] = 0;
  64. m_szTempXML[0] = 0;
  65. m_pDocInput = NULL;
  66. }
  67. CXMLParser::~CXMLParser ()
  68. {
  69. if (m_pDocInput)
  70. m_pDocInput->Release();
  71. }
  72. //
  73. // Public functions
  74. //
  75. HRESULT CXMLParser::SetXMLFile (LPCTSTR szFile)
  76. {
  77. HRESULT hr = S_OK;
  78. OFSTRUCT ofs;
  79. HANDLE hFile;
  80. if (szFile == NULL ||
  81. _tcslen(szFile) > sizeof(m_szXMLFile)/sizeof(TCHAR) - 1)
  82. {
  83. hr = TSECERR_BADFILENAME;
  84. goto ExitHere;
  85. }
  86. if ((hFile = CreateFile (
  87. szFile,
  88. 0,
  89. 0,
  90. NULL,
  91. OPEN_EXISTING,
  92. FILE_ATTRIBUTE_NORMAL,
  93. NULL
  94. )) == INVALID_HANDLE_VALUE)
  95. {
  96. hr = TSECERR_FILENOTEXIST;
  97. goto ExitHere;
  98. }
  99. else
  100. {
  101. CloseHandle (hFile);
  102. }
  103. _tcscpy (m_szXMLFile, szFile);
  104. ExitHere:
  105. return hr;
  106. }
  107. HRESULT CXMLParser::GetXMLFile (LPTSTR szFile, DWORD cch)
  108. {
  109. return E_NOTIMPL;
  110. }
  111. HRESULT CXMLParser::CreateTempFiles ()
  112. {
  113. HRESULT hr = S_OK;
  114. TCHAR szTempPath[MAX_PATH];
  115. char szAnsiFile[MAX_PATH * sizeof(TCHAR)];
  116. HINSTANCE hModule;
  117. HRSRC hRes;
  118. HGLOBAL hSchema;
  119. LPVOID lpSchema;
  120. DWORD dwSchemaSize;
  121. HANDLE hFileSchema = NULL;
  122. DWORD dwBytesWritten;
  123. HANDLE hFileXML = NULL;
  124. HANDLE hFileUserXML = NULL;
  125. DWORD dwBytesRead;
  126. TCHAR szBuf[256];
  127. //
  128. // Prepare temporary file path
  129. //
  130. if (GetTempPath (sizeof(szTempPath)/sizeof(TCHAR), szTempPath) == 0 ||
  131. GetTempFileName (
  132. szTempPath,
  133. TEXT("Schema"),
  134. 0,
  135. m_szTempSchema
  136. ) == 0 ||
  137. GetTempFileName (
  138. szTempPath,
  139. TEXT("XML"),
  140. 0,
  141. m_szTempXML
  142. ) == 0
  143. )
  144. {
  145. hr = HRESULT_FROM_WIN32 (GetLastError ());
  146. goto ExitHere;
  147. }
  148. //
  149. // Prepare the temporary file containing the schema
  150. //
  151. // Load the schema.xml resource
  152. hModule = GetModuleHandle (NULL);
  153. if (hModule == NULL)
  154. {
  155. hr = HRESULT_FROM_WIN32 (GetLastError ());
  156. goto ExitHere;
  157. }
  158. hRes = FindResource (
  159. hModule,
  160. MAKEINTRESOURCE(IDR_SCHEMA),
  161. MAKEINTRESOURCE(SCHEMARES)
  162. );
  163. if (hRes == NULL)
  164. {
  165. hr = HRESULT_FROM_WIN32 (GetLastError ());
  166. goto ExitHere;
  167. }
  168. hSchema = LoadResource (
  169. hModule,
  170. hRes);
  171. if (hSchema == NULL)
  172. {
  173. hr = HRESULT_FROM_WIN32 (GetLastError ());
  174. goto ExitHere;
  175. }
  176. lpSchema = LockResource (hSchema);
  177. if (lpSchema == NULL)
  178. {
  179. hr = HRESULT_FROM_WIN32 (GetLastError ());
  180. goto ExitHere;
  181. }
  182. dwSchemaSize = SizeofResource (hModule, hRes);
  183. if (dwSchemaSize == 0)
  184. {
  185. hr = HRESULT_FROM_WIN32 (GetLastError ());
  186. goto ExitHere;
  187. }
  188. // Copy schema.xml into the temporary file
  189. hFileSchema = CreateFile (
  190. m_szTempSchema,
  191. GENERIC_WRITE,
  192. 0,
  193. NULL,
  194. OPEN_ALWAYS | TRUNCATE_EXISTING,
  195. FILE_ATTRIBUTE_NORMAL,
  196. NULL
  197. );
  198. if (hFileSchema == INVALID_HANDLE_VALUE)
  199. {
  200. hr = HRESULT_FROM_WIN32 (GetLastError ());
  201. goto ExitHere;
  202. }
  203. if (!WriteFile (
  204. hFileSchema,
  205. lpSchema,
  206. dwSchemaSize,
  207. &dwBytesWritten,
  208. NULL
  209. ))
  210. {
  211. hr = HRESULT_FROM_WIN32 (GetLastError ());
  212. goto ExitHere;
  213. }
  214. CloseHandle (hFileSchema);
  215. hFileSchema = INVALID_HANDLE_VALUE;
  216. //
  217. // Now create the temp file for the XML file to be parsed
  218. //
  219. hFileXML = CreateFile (
  220. m_szTempXML,
  221. GENERIC_WRITE,
  222. 0,
  223. NULL,
  224. OPEN_ALWAYS | TRUNCATE_EXISTING,
  225. FILE_ATTRIBUTE_NORMAL,
  226. NULL
  227. );
  228. if (hFileXML == INVALID_HANDLE_VALUE)
  229. {
  230. hr = HRESULT_FROM_WIN32 (GetLastError ());
  231. goto ExitHere;
  232. }
  233. // Write the XML header
  234. if (!WriteFile (
  235. hFileXML,
  236. gszXMLHeader1,
  237. lstrlenA(gszXMLHeader1),
  238. &dwBytesWritten,
  239. NULL
  240. ))
  241. {
  242. hr = HRESULT_FROM_WIN32 (GetLastError ());
  243. goto ExitHere;
  244. }
  245. #ifdef UNICODE
  246. if (WideCharToMultiByte (
  247. CP_ACP,
  248. 0,
  249. m_szTempSchema,
  250. -1,
  251. szAnsiFile,
  252. sizeof(szAnsiFile),
  253. NULL,
  254. NULL
  255. ) == 0)
  256. {
  257. hr = HRESULT_FROM_WIN32 (GetLastError ());
  258. goto ExitHere;
  259. }
  260. #else
  261. lstrcpy (szAnsiFile, m_szTempSchema);
  262. #endif
  263. if (!WriteFile (
  264. hFileXML,
  265. szAnsiFile,
  266. lstrlenA (szAnsiFile),
  267. &dwBytesWritten,
  268. NULL
  269. ))
  270. {
  271. hr = HRESULT_FROM_WIN32 (GetLastError ());
  272. goto ExitHere;
  273. }
  274. if (!WriteFile (
  275. hFileXML,
  276. gszXMLHeader2,
  277. lstrlenA(gszXMLHeader2),
  278. &dwBytesWritten,
  279. NULL
  280. ))
  281. {
  282. hr = HRESULT_FROM_WIN32 (GetLastError ());
  283. goto ExitHere;
  284. }
  285. // Copy over the input XML file
  286. hFileUserXML = CreateFile (
  287. m_szXMLFile,
  288. GENERIC_READ,
  289. FILE_SHARE_READ,
  290. NULL,
  291. OPEN_EXISTING,
  292. FILE_ATTRIBUTE_NORMAL,
  293. NULL
  294. );
  295. if (hFileUserXML == INVALID_HANDLE_VALUE)
  296. {
  297. hr = HRESULT_FROM_WIN32 (GetLastError ());
  298. goto ExitHere;
  299. }
  300. while (ReadFile (
  301. hFileUserXML,
  302. szBuf,
  303. sizeof(szBuf),
  304. &dwBytesRead,
  305. NULL) &&
  306. dwBytesRead > 0)
  307. {
  308. if (!WriteFile (
  309. hFileXML,
  310. szBuf,
  311. dwBytesRead,
  312. &dwBytesWritten,
  313. NULL
  314. ))
  315. {
  316. hr = HRESULT_FROM_WIN32 (GetLastError ());
  317. goto ExitHere;
  318. }
  319. }
  320. CloseHandle (hFileUserXML);
  321. hFileUserXML = INVALID_HANDLE_VALUE;
  322. // Write the XML tail
  323. if (!WriteFile (
  324. hFileXML,
  325. gszXMLTail,
  326. lstrlenA(gszXMLTail),
  327. &dwBytesWritten,
  328. NULL
  329. ))
  330. {
  331. hr = HRESULT_FROM_WIN32 (GetLastError ());
  332. goto ExitHere;
  333. }
  334. CloseHandle (hFileXML);
  335. hFileXML = INVALID_HANDLE_VALUE;
  336. ExitHere:
  337. if (FAILED (hr))
  338. {
  339. m_szTempSchema[0] = 0;
  340. m_szTempXML[0] = 0;
  341. }
  342. if (hFileSchema != INVALID_HANDLE_VALUE)
  343. {
  344. CloseHandle (hFileSchema);
  345. }
  346. if (hFileXML != INVALID_HANDLE_VALUE)
  347. {
  348. CloseHandle (hFileXML);
  349. }
  350. if (hFileUserXML != INVALID_HANDLE_VALUE)
  351. {
  352. CloseHandle (hFileUserXML);
  353. }
  354. return hr;
  355. }
  356. HRESULT CXMLParser::ReportParsingError ()
  357. {
  358. HRESULT hr = S_OK;
  359. IXMLDOMParseError * pError = NULL;
  360. long lErrCode;
  361. long lLineNum;
  362. long lLinePos;
  363. BSTR szReason = NULL;
  364. BSTR szSrc =NULL;
  365. LPTSTR szError = NULL;
  366. TCHAR szBuf[256];
  367. TCHAR szBuf2[256];
  368. HINSTANCE hModule;
  369. CIds IdsError (IDS_ERROR);
  370. // Check to make sure we have a document to work on
  371. if (m_pDocInput == NULL)
  372. {
  373. goto ExitHere;
  374. }
  375. // Make sure we do have an error to report
  376. hr = m_pDocInput->get_parseError (&pError);
  377. if (FAILED (hr))
  378. {
  379. goto ExitHere;
  380. }
  381. hr = pError->get_errorCode (&lErrCode);
  382. if (FAILED (hr) || lErrCode == 0)
  383. {
  384. goto ExitHere;
  385. }
  386. // Collect error information
  387. if (
  388. (hr = pError->get_line (&lLineNum)) != 0 ||
  389. (hr = pError->get_linepos (&lLinePos)) != 0 ||
  390. (hr = pError->get_reason (&szReason)) != 0 ||
  391. (hr = pError->get_srcText (&szSrc)) != 0)
  392. {
  393. goto ExitHere;
  394. }
  395. // adjust line number because we added one line
  396. --lLineNum;
  397. //
  398. // Format error report
  399. //
  400. // The format is similar to the following
  401. //
  402. // Invalid XML file format
  403. //
  404. // Failure reason goes here
  405. //
  406. // Line 2, Pos 12
  407. //
  408. // Failure source goes here
  409. // -----^
  410. //
  411. hModule = GetModuleHandle (NULL);
  412. if (hModule == NULL)
  413. {
  414. hr = HRESULT_FROM_WIN32 (GetLastError ());
  415. goto ExitHere;
  416. }
  417. // Get the text of "Invalid XML file format"
  418. if (FormatMessage (
  419. FORMAT_MESSAGE_FROM_HMODULE,
  420. hModule,
  421. TSEC_INVALFILEFORMAT,
  422. 0,
  423. szBuf,
  424. sizeof(szBuf)/sizeof(TCHAR),
  425. NULL
  426. ) == 0)
  427. {
  428. hr = HRESULT_FROM_WIN32 (GetLastError ());
  429. goto ExitHere;
  430. }
  431. szError = AppendStringAndFree (szError, szBuf);
  432. // Put in the failure reason
  433. if (szError == NULL ||
  434. ((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL) ||
  435. ((szError = AppendStringAndFree (szError, szReason)) == NULL) ||
  436. ((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL)
  437. )
  438. {
  439. hr = TSECERR_NOMEM;
  440. goto ExitHere;
  441. }
  442. // Get the error position string
  443. if (LoadString (
  444. hModule,
  445. IDS_ERRORPOS,
  446. szBuf,
  447. sizeof(szBuf)/sizeof(TCHAR)
  448. ) == 0
  449. )
  450. {
  451. hr = HRESULT_FROM_WIN32 (GetLastError ());
  452. goto ExitHere;
  453. }
  454. FormatString (
  455. szBuf,
  456. szBuf2,
  457. sizeof(szBuf2)/sizeof(TCHAR),
  458. lLineNum,
  459. lLinePos
  460. );
  461. // Put error position text & error source text
  462. if (
  463. ((szError = AppendStringAndFree (szError, szBuf2)) == NULL) ||
  464. ((szError = AppendStringAndFree (szError, TEXT("\r\n\r\n"))) == NULL) ||
  465. ((szError = AppendStringAndFree (szError, szSrc)) == NULL)
  466. )
  467. {
  468. hr = TSECERR_NOMEM;
  469. goto ExitHere;
  470. }
  471. // If the error position is not too large, put ----^ to intuitively point
  472. // to the place error occurred
  473. if (lLinePos < sizeof(szBuf)/sizeof(TCHAR) - 1 && lLinePos > 0)
  474. {
  475. szBuf[lLinePos] = 0;
  476. szBuf[--lLinePos] = TEXT('^');
  477. while (lLinePos > 0)
  478. {
  479. szBuf[--lLinePos] = TEXT('-');
  480. }
  481. if (
  482. ((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL) ||
  483. ((szError = AppendStringAndFree (szError, szBuf)) == NULL)
  484. )
  485. {
  486. hr = TSECERR_NOMEM;
  487. goto ExitHere;
  488. }
  489. }
  490. //
  491. // Now report the error
  492. //
  493. MessagePrint (szError, IdsError.GetString ());
  494. ExitHere:
  495. if (pError)
  496. {
  497. pError->Release ();
  498. }
  499. SysFreeString (szReason);
  500. SysFreeString (szSrc);
  501. if (szError)
  502. {
  503. delete [] szError;
  504. }
  505. return hr;
  506. }
  507. HRESULT CXMLParser::Parse (void)
  508. {
  509. HRESULT hr = S_OK;
  510. IXMLDOMDocument * pDocInput = NULL;
  511. VARIANT_BOOL bSuccess;
  512. VARIANT varXMLFile;
  513. // Ensure we have an xml file to process
  514. if (*m_szXMLFile == 0)
  515. {
  516. hr = TSECERR_BADFILENAME;
  517. goto ExitHere;
  518. }
  519. hr = CreateTempFiles ();
  520. if (FAILED (hr))
  521. {
  522. goto ExitHere;
  523. }
  524. // Create XMLDOMDocument object
  525. hr = CoCreateInstance (
  526. CLSID_DOMFreeThreadedDocument,
  527. NULL,
  528. CLSCTX_INPROC_SERVER,
  529. IID_IXMLDOMDocument,
  530. (void **)&pDocInput
  531. );
  532. if (FAILED (hr) || pDocInput == NULL)
  533. {
  534. goto ExitHere;
  535. }
  536. // Set the validateOnParse property
  537. hr = pDocInput->put_validateOnParse(VARIANT_TRUE);
  538. if (FAILED (hr))
  539. {
  540. goto ExitHere;
  541. }
  542. // We do a synchronous load for now
  543. hr = pDocInput->put_async (VARIANT_TRUE);
  544. if (FAILED (hr))
  545. {
  546. goto ExitHere;
  547. }
  548. // Parse the document
  549. VariantInit (&varXMLFile);
  550. V_VT(&varXMLFile) = VT_BSTR;
  551. V_BSTR(&varXMLFile) = SysAllocString (m_szTempXML);
  552. hr = pDocInput->load (
  553. varXMLFile,
  554. &bSuccess
  555. );
  556. SysFreeString (V_BSTR(&varXMLFile));
  557. if (FAILED (hr))
  558. {
  559. goto ExitHere;
  560. }
  561. if (bSuccess != VARIANT_TRUE)
  562. {
  563. hr = TSECERR_INVALFILEFORMAT;
  564. }
  565. m_pDocInput = pDocInput;
  566. pDocInput = NULL;
  567. ExitHere:
  568. if (pDocInput != NULL)
  569. {
  570. pDocInput->Release();
  571. }
  572. if (m_szTempSchema[0] != 0)
  573. {
  574. DeleteFile (m_szTempSchema);
  575. }
  576. if (m_szTempXML[0] != 0)
  577. {
  578. DeleteFile (m_szTempXML);
  579. }
  580. return hr;
  581. }
  582. HRESULT CXMLParser::GetFirstUser (CXMLUser ** ppUser)
  583. {
  584. HRESULT hr = S_OK;
  585. IXMLDOMElement * pEleRoot = NULL;
  586. IXMLDOMNode * pFirstNode = NULL;
  587. BSTR bstr = NULL;
  588. *ppUser = NULL;
  589. if (m_pDocInput == NULL)
  590. {
  591. hr = S_FALSE;
  592. goto ExitHere;
  593. }
  594. if (FAILED(hr = m_pDocInput->get_documentElement(&pEleRoot)) ||
  595. pEleRoot == NULL)
  596. {
  597. goto ExitHere;
  598. }
  599. if ((bstr = SysAllocString (L"UserList/User")) == NULL)
  600. {
  601. hr = TSECERR_NOMEM;
  602. goto ExitHere;
  603. }
  604. if (FAILED(hr = pEleRoot->selectSingleNode (bstr, &pFirstNode)) ||
  605. pFirstNode == NULL)
  606. {
  607. goto ExitHere;
  608. }
  609. *ppUser = new CXMLUser (pFirstNode);
  610. if (*ppUser == NULL)
  611. {
  612. hr = TSECERR_NOMEM;
  613. goto ExitHere;
  614. }
  615. else
  616. {
  617. pFirstNode->AddRef();
  618. }
  619. ExitHere:
  620. if (pEleRoot)
  621. {
  622. pEleRoot->Release();
  623. }
  624. if (bstr)
  625. {
  626. SysFreeString (bstr);
  627. }
  628. if (pFirstNode)
  629. {
  630. pFirstNode->Release();
  631. }
  632. return hr;
  633. }
  634. ///////////////////////////////////////////////////////////
  635. //
  636. // CXMLUser implementation
  637. //
  638. ///////////////////////////////////////////////////////////
  639. HRESULT CXMLUser::GetNextUser (CXMLUser **ppNextUser)
  640. {
  641. HRESULT hr = S_OK;
  642. IXMLDOMNode * pNodeNext = NULL;
  643. *ppNextUser = NULL;
  644. if (m_pUserNode == NULL)
  645. {
  646. hr = S_FALSE;
  647. goto ExitHere;
  648. }
  649. if (FAILED(hr = m_pUserNode->get_nextSibling (&pNodeNext)) ||
  650. pNodeNext == NULL)
  651. {
  652. goto ExitHere;
  653. }
  654. *ppNextUser = new CXMLUser (pNodeNext);
  655. if (*ppNextUser == NULL)
  656. {
  657. hr = TSECERR_NOMEM;
  658. // goto ExitHere;
  659. }
  660. else
  661. {
  662. pNodeNext->AddRef();
  663. }
  664. ExitHere:
  665. if (pNodeNext)
  666. {
  667. pNodeNext->Release();
  668. }
  669. return hr;
  670. }
  671. HRESULT CXMLUser::GetDomainUser (LPTSTR szBuf, DWORD cch)
  672. {
  673. HRESULT hr = S_OK;
  674. IXMLDOMNode * pNodeDU = NULL;
  675. BSTR bstrDU = NULL;
  676. BSTR bstrText = NULL;
  677. szBuf[0] = 0;
  678. if (m_pUserNode == NULL)
  679. {
  680. hr = S_FALSE;
  681. goto ExitHere;
  682. }
  683. bstrDU = SysAllocString (L"DomainUser");
  684. if (bstrDU == NULL)
  685. {
  686. hr = TSECERR_NOMEM;
  687. goto ExitHere;
  688. }
  689. hr = m_pUserNode->selectSingleNode (bstrDU, &pNodeDU);
  690. if (FAILED (hr) || pNodeDU == NULL)
  691. {
  692. goto ExitHere;
  693. }
  694. hr = pNodeDU->get_text (&bstrText);
  695. if (FAILED (hr) || bstrText == NULL)
  696. {
  697. goto ExitHere;
  698. }
  699. _tcsncpy (szBuf, bstrText, cch);
  700. szBuf[cch - 1] = 0;
  701. ExitHere:
  702. if (pNodeDU)
  703. {
  704. pNodeDU->Release();
  705. }
  706. if (bstrDU)
  707. {
  708. SysFreeString (bstrDU);
  709. }
  710. if (bstrText)
  711. {
  712. SysFreeString (bstrText);
  713. }
  714. if (szBuf[0] == 0)
  715. {
  716. hr = S_FALSE;
  717. }
  718. return hr;
  719. }
  720. HRESULT CXMLUser::GetFriendlyName (LPTSTR szBuf, DWORD cch)
  721. {
  722. HRESULT hr = S_OK;
  723. IXMLDOMNode * pNodeFN = NULL;
  724. BSTR bstrFN = NULL;
  725. BSTR bstrText = NULL;
  726. szBuf[0] = 0;
  727. if (m_pUserNode == NULL)
  728. {
  729. hr = S_FALSE;
  730. goto ExitHere;
  731. }
  732. bstrFN = SysAllocString (L"FriendlyName");
  733. if (bstrFN == NULL)
  734. {
  735. hr = TSECERR_NOMEM;
  736. goto ExitHere;
  737. }
  738. hr = m_pUserNode->selectSingleNode (bstrFN, &pNodeFN);
  739. if (FAILED (hr) || pNodeFN == NULL)
  740. {
  741. goto ExitHere;
  742. }
  743. hr = pNodeFN->get_text (&bstrText);
  744. if (FAILED (hr) || bstrText == NULL)
  745. {
  746. goto ExitHere;
  747. }
  748. _tcsncpy (szBuf, bstrText, cch);
  749. szBuf[cch - 1] = 0;
  750. ExitHere:
  751. if (pNodeFN)
  752. {
  753. pNodeFN->Release();
  754. }
  755. if (bstrFN)
  756. {
  757. SysFreeString (bstrFN);
  758. }
  759. if (bstrText)
  760. {
  761. SysFreeString (bstrText);
  762. }
  763. return hr;
  764. }
  765. HRESULT CXMLUser::IsNoMerge (BOOL *pb)
  766. {
  767. HRESULT hr = S_OK;
  768. IXMLDOMNamedNodeMap * pAttribs = NULL;
  769. IXMLDOMNode * pAttrib = NULL;
  770. BSTR bstrNM = NULL;
  771. VARIANT varNM;
  772. if (m_pUserNode == NULL)
  773. {
  774. hr = S_FALSE;
  775. goto ExitHere;
  776. }
  777. hr = m_pUserNode->get_attributes(&pAttribs);
  778. if (FAILED (hr) || pAttribs == NULL)
  779. {
  780. goto ExitHere;
  781. }
  782. bstrNM = SysAllocString (L"NoMerge");
  783. if (bstrNM == NULL)
  784. {
  785. hr = TSECERR_NOMEM;
  786. goto ExitHere;
  787. }
  788. hr = pAttribs->getNamedItem(bstrNM, &pAttrib);
  789. if (FAILED (hr) || pAttrib == NULL)
  790. {
  791. goto ExitHere;
  792. }
  793. VariantInit (&varNM);
  794. hr = pAttrib->get_nodeTypedValue (&varNM);
  795. if (FAILED(hr))
  796. {
  797. VariantClear (&varNM);
  798. goto ExitHere;
  799. }
  800. if (V_VT(&varNM) == VT_BOOL)
  801. {
  802. *pb = (V_BOOL(&varNM) == VARIANT_TRUE) ? TRUE : FALSE;
  803. }
  804. else if (V_VT(&varNM) == VT_BSTR)
  805. {
  806. *pb = (V_BSTR(&varNM)[0] == L'1') ? TRUE : FALSE;
  807. }
  808. else
  809. {
  810. *pb = FALSE;
  811. }
  812. VariantClear (&varNM);
  813. ExitHere:
  814. if (bstrNM)
  815. {
  816. SysFreeString (bstrNM);
  817. }
  818. if (pAttrib)
  819. {
  820. pAttrib->Release();
  821. }
  822. if (pAttribs)
  823. {
  824. pAttribs->Release();
  825. }
  826. return hr;
  827. }
  828. HRESULT CXMLUser::GetFirstLine (CXMLLine ** ppLine)
  829. {
  830. HRESULT hr = S_OK;
  831. BSTR bstrLine = NULL;
  832. IXMLDOMNode * pNodeLine = NULL;
  833. *ppLine = NULL;
  834. if (m_pUserNode == NULL)
  835. {
  836. hr = S_FALSE;
  837. goto ExitHere;
  838. }
  839. bstrLine = SysAllocString (L"LineList/Line");
  840. if (bstrLine == NULL)
  841. {
  842. hr = TSECERR_NOMEM;
  843. goto ExitHere;
  844. }
  845. hr = m_pUserNode->selectSingleNode (bstrLine, &pNodeLine);
  846. if (FAILED(hr) || pNodeLine == NULL)
  847. {
  848. goto ExitHere;
  849. }
  850. *ppLine = new CXMLLine (pNodeLine);
  851. if (*ppLine == NULL)
  852. {
  853. hr = TSECERR_NOMEM;
  854. goto ExitHere;
  855. }
  856. else
  857. {
  858. pNodeLine->AddRef();
  859. }
  860. ExitHere:
  861. if (pNodeLine)
  862. {
  863. pNodeLine->Release();
  864. }
  865. if (bstrLine)
  866. {
  867. SysFreeString (bstrLine);
  868. }
  869. return hr;
  870. }
  871. ///////////////////////////////////////////////////////////
  872. //
  873. // CXMLLine implementation
  874. //
  875. ///////////////////////////////////////////////////////////
  876. HRESULT CXMLLine::GetNextLine (CXMLLine ** ppLine)
  877. {
  878. HRESULT hr = S_OK;
  879. IXMLDOMNode * pNodeNext = NULL;
  880. *ppLine = NULL;
  881. if (m_pLineNode == NULL)
  882. {
  883. hr = S_FALSE;
  884. goto ExitHere;
  885. }
  886. hr = m_pLineNode->get_nextSibling (&pNodeNext);
  887. if (FAILED(hr) || pNodeNext == NULL)
  888. {
  889. goto ExitHere;
  890. }
  891. *ppLine = new CXMLLine (pNodeNext);
  892. if (*ppLine == NULL)
  893. {
  894. hr = TSECERR_NOMEM;
  895. }
  896. else
  897. {
  898. pNodeNext->AddRef();
  899. }
  900. ExitHere:
  901. if (pNodeNext)
  902. {
  903. pNodeNext->Release();
  904. }
  905. return hr;
  906. }
  907. HRESULT CXMLLine::GetAddress (LPTSTR szBuf, DWORD cch)
  908. {
  909. HRESULT hr = S_OK;
  910. BSTR bstrAddr = NULL;
  911. BSTR bstrText = NULL;
  912. IXMLDOMNode * pNodeAddr = NULL;
  913. if (m_pLineNode == NULL)
  914. {
  915. hr = S_FALSE;
  916. goto ExitHere;
  917. }
  918. bstrAddr = SysAllocString (L"Address");
  919. if (bstrAddr == NULL)
  920. {
  921. hr = TSECERR_NOMEM;
  922. goto ExitHere;
  923. }
  924. hr = m_pLineNode->selectSingleNode (bstrAddr, &pNodeAddr);
  925. if (FAILED(hr) || pNodeAddr == NULL)
  926. {
  927. goto ExitHere;
  928. }
  929. hr = pNodeAddr->get_text(&bstrText);
  930. if (FAILED(hr) || bstrText == NULL)
  931. {
  932. goto ExitHere;
  933. }
  934. _tcsncpy (szBuf, bstrText, cch);
  935. szBuf[cch - 1] = 0;
  936. ExitHere:
  937. if (bstrAddr)
  938. {
  939. SysFreeString (bstrAddr);
  940. }
  941. if (bstrText)
  942. {
  943. SysFreeString (bstrText);
  944. }
  945. if (pNodeAddr)
  946. {
  947. pNodeAddr->Release();
  948. }
  949. return hr;
  950. }
  951. HRESULT CXMLLine::GetPermanentID (ULONG * pID)
  952. {
  953. HRESULT hr = S_OK;
  954. BSTR bstrPID = NULL;
  955. IXMLDOMNode * pNodePID = NULL;
  956. VARIANT varPID;
  957. if (m_pLineNode == NULL)
  958. {
  959. hr = S_FALSE;
  960. goto ExitHere;
  961. }
  962. bstrPID = SysAllocString (L"PermanentID");
  963. if (bstrPID == NULL)
  964. {
  965. hr = TSECERR_NOMEM;
  966. goto ExitHere;
  967. }
  968. hr = m_pLineNode->selectSingleNode (bstrPID, &pNodePID);
  969. if (FAILED(hr) || pNodePID == NULL)
  970. {
  971. goto ExitHere;
  972. }
  973. VariantInit (&varPID);
  974. hr = pNodePID->get_nodeTypedValue(&varPID);
  975. if (FAILED(hr))
  976. {
  977. VariantClear (&varPID);
  978. goto ExitHere;
  979. }
  980. if (V_VT(&varPID) == VT_UI4)
  981. {
  982. *pID = (ULONG) V_UI4(&varPID);
  983. }
  984. else
  985. {
  986. hr = S_FALSE;
  987. *pID = 0;
  988. }
  989. VariantClear (&varPID);
  990. ExitHere:
  991. if (bstrPID)
  992. {
  993. SysFreeString (bstrPID);
  994. }
  995. if (pNodePID)
  996. {
  997. pNodePID->Release();
  998. }
  999. return hr;
  1000. }
  1001. HRESULT CXMLLine::IsPermanentID (BOOL *pb)
  1002. {
  1003. HRESULT hr = S_OK;
  1004. BSTR bstrPID = NULL;
  1005. IXMLDOMNode * pNodePID = NULL;
  1006. VARIANT varPID;
  1007. if (m_pLineNode == NULL)
  1008. {
  1009. hr = S_FALSE;
  1010. goto ExitHere;
  1011. }
  1012. bstrPID = SysAllocString (L"PermanentID");
  1013. if (bstrPID == NULL)
  1014. {
  1015. hr = TSECERR_NOMEM;
  1016. goto ExitHere;
  1017. }
  1018. hr = m_pLineNode->selectSingleNode (bstrPID, &pNodePID);
  1019. if (FAILED(hr) || pNodePID == NULL)
  1020. {
  1021. *pb = FALSE;
  1022. hr = S_OK;
  1023. }
  1024. else
  1025. {
  1026. *pb = TRUE;
  1027. }
  1028. ExitHere:
  1029. if (pNodePID)
  1030. {
  1031. pNodePID->Release();
  1032. }
  1033. if (bstrPID)
  1034. {
  1035. SysFreeString (bstrPID);
  1036. }
  1037. return hr;
  1038. }
  1039. HRESULT CXMLLine::IsRemove (BOOL *pb)
  1040. {
  1041. HRESULT hr = S_OK;
  1042. IXMLDOMNamedNodeMap * pAttribs = NULL;
  1043. IXMLDOMNode * pAttrib = NULL;
  1044. BSTR bstrRM = NULL;
  1045. VARIANT varRM;
  1046. if (m_pLineNode == NULL)
  1047. {
  1048. hr = S_FALSE;
  1049. goto ExitHere;
  1050. }
  1051. hr = m_pLineNode->get_attributes(&pAttribs);
  1052. if (FAILED (hr) || pAttribs == NULL)
  1053. {
  1054. goto ExitHere;
  1055. }
  1056. bstrRM = SysAllocString (L"Remove");
  1057. if (bstrRM == NULL)
  1058. {
  1059. hr = TSECERR_NOMEM;
  1060. goto ExitHere;
  1061. }
  1062. hr = pAttribs->getNamedItem(bstrRM, &pAttrib);
  1063. if (FAILED (hr) || pAttrib == NULL)
  1064. {
  1065. goto ExitHere;
  1066. }
  1067. VariantInit (&varRM);
  1068. hr = pAttrib->get_nodeTypedValue (&varRM);
  1069. if (FAILED(hr))
  1070. {
  1071. VariantClear (&varRM);
  1072. goto ExitHere;
  1073. }
  1074. if (V_VT(&varRM) == VT_BOOL)
  1075. {
  1076. *pb = (V_BOOL(&varRM) == VARIANT_TRUE) ? TRUE : FALSE;
  1077. }
  1078. else if(V_VT(&varRM) == VT_BSTR)
  1079. {
  1080. *pb = (V_BSTR(&varRM)[0] == L'1') ? TRUE : FALSE;
  1081. }
  1082. else
  1083. {
  1084. *pb = FALSE;
  1085. }
  1086. VariantClear (&varRM);
  1087. ExitHere:
  1088. if (bstrRM)
  1089. {
  1090. SysFreeString (bstrRM);
  1091. }
  1092. if (pAttrib)
  1093. {
  1094. pAttrib->Release();
  1095. }
  1096. if (pAttribs)
  1097. {
  1098. pAttribs->Release();
  1099. }
  1100. return hr;
  1101. }