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.

874 lines
26 KiB

  1. ///////////////////////////////////////////////////////////////////////
  2. /****************************************************************************
  3. Copyright information : Copyright (c) 1998-1999 Microsoft Corporation
  4. File Name : WMICliLog.cpp
  5. Project Name : WMI Command Line
  6. Author Name : Biplab Mistry
  7. Date of Creation (dd/mm/yy) : 02-March-2001
  8. Version Number : 1.0
  9. Brief Description : This class encapsulates the functionality needed
  10. for logging the input and output.
  11. Revision History :
  12. Last Modified By : Ch. Sriramachandramurthy
  13. Last Modified Date : 27-March-2001
  14. *****************************************************************************/
  15. // WMICliXMLLog.cpp : implementation file
  16. #include "Precomp.h"
  17. #include "helpinfo.h"
  18. #include "ErrorLog.h"
  19. #include "GlobalSwitches.h"
  20. #include "CommandSwitches.h"
  21. #include "ParsedInfo.h"
  22. #include "WMICliXMLLog.h"
  23. /*------------------------------------------------------------------------
  24. Name :CWMICliXMLLog
  25. Synopsis :Constructor
  26. Type :Constructor
  27. Input parameter :None
  28. Output parameters :None
  29. Return Type :None
  30. Global Variables :None
  31. Calling Syntax :None
  32. Notes :None
  33. ------------------------------------------------------------------------*/
  34. CWMICliXMLLog::CWMICliXMLLog()
  35. {
  36. m_pIXMLDoc = NULL;
  37. m_pszLogFile = NULL;
  38. m_bCreate = FALSE;
  39. m_nItrNum = 0;
  40. m_bTrace = FALSE;
  41. m_eloErrLogOpt = NO_LOGGING;
  42. }
  43. /*------------------------------------------------------------------------
  44. Name :~CWMICliXMLLog
  45. Synopsis :Destructor
  46. Type :Destructor
  47. Input parameter :None
  48. Output parameters :None
  49. Return Type :None
  50. Global Variables :None
  51. Calling Syntax :None
  52. Notes :None
  53. ------------------------------------------------------------------------*/
  54. CWMICliXMLLog::~CWMICliXMLLog()
  55. {
  56. SAFEDELETE(m_pszLogFile);
  57. SAFEIRELEASE(m_pIXMLDoc);
  58. }
  59. /*----------------------------------------------------------------------------
  60. Name :Uninitialize
  61. Synopsis :This function uninitializes the member variables when
  62. the execution of a command string issued on the command
  63. line is completed.
  64. Type :Member Function
  65. Input Parameter(s):
  66. bFinal - boolean value which when set indicates that the program
  67. Output parameters :None
  68. Return Type :None
  69. Global Variables :None
  70. Calling Syntax :Uninitialize(bFinal)
  71. Notes :None
  72. ----------------------------------------------------------------------------*/
  73. void CWMICliXMLLog::Uninitialize(BOOL bFinal)
  74. {
  75. if (bFinal)
  76. {
  77. SAFEDELETE(m_pszLogFile);
  78. SAFEIRELEASE(m_pIXMLDoc);
  79. }
  80. m_bTrace = FALSE;
  81. m_eloErrLogOpt = NO_LOGGING;
  82. }
  83. /*------------------------------------------------------------------------
  84. Name :WriteToXMLLog
  85. Synopsis :Logs the input & output to the xml log file
  86. Type :Member Function
  87. Input parameter :
  88. rParsedInfo - reference to CParsedInfo object
  89. bstrOutput - output that goes into CDATA section.
  90. Output parameters :None
  91. Return Type :HRESULT
  92. Global Variables :None
  93. Calling Syntax :WriteToXMLLog(rParsedInfo, bstrOutput)
  94. Notes :None
  95. ------------------------------------------------------------------------*/
  96. HRESULT CWMICliXMLLog::WriteToXMLLog(CParsedInfo& rParsedInfo, BSTR bstrOutput)
  97. {
  98. HRESULT hr = S_OK;
  99. _variant_t varValue;
  100. DWORD dwThreadId = GetCurrentThreadId();
  101. BSTR bstrUser = NULL,
  102. bstrStart = NULL,
  103. bstrInput = NULL,
  104. bstrTarget = NULL,
  105. bstrNode = NULL;
  106. WMICLIINT nSeqNum = 0;
  107. BOOL bNewCmd = FALSE;
  108. BOOL bNewCycle = FALSE;
  109. // Initialize the TRACE and ERRORLOG variables.
  110. m_bTrace = rParsedInfo.GetGlblSwitchesObject().GetTraceStatus();
  111. m_eloErrLogOpt = rParsedInfo.GetErrorLogObject().GetErrLogOption();
  112. bNewCmd = rParsedInfo.GetNewCommandStatus();
  113. bNewCycle = rParsedInfo.GetNewCycleStatus();
  114. CHString chsMsg;
  115. try
  116. {
  117. bstrUser = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  118. GetLoggedonUser());
  119. bstrStart = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  120. GetStartTime());
  121. bstrInput = ::SysAllocString(rParsedInfo.GetCmdSwitchesObject().
  122. GetCommandInput());
  123. if (!rParsedInfo.GetGlblSwitchesObject().GetAggregateFlag())
  124. {
  125. bstrTarget= ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  126. GetNode());
  127. }
  128. else
  129. {
  130. _bstr_t bstrTemp;
  131. _TCHAR* pszVerb = rParsedInfo.GetCmdSwitchesObject().GetVerbName();
  132. if (pszVerb)
  133. {
  134. if ( CompareTokens(pszVerb, CLI_TOKEN_LIST) ||
  135. CompareTokens(pszVerb, CLI_TOKEN_ASSOC) ||
  136. CompareTokens(pszVerb, CLI_TOKEN_GET))
  137. {
  138. rParsedInfo.GetGlblSwitchesObject().GetNodeString(bstrTemp);
  139. bstrTarget = ::SysAllocString((LPWSTR)bstrTemp);
  140. }
  141. // CALL, SET, CREATE, DELETE and, user defined verbs
  142. else
  143. {
  144. bstrTarget= ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  145. GetNode());
  146. }
  147. }
  148. else
  149. {
  150. rParsedInfo.GetGlblSwitchesObject().GetNodeString(bstrTemp);
  151. bstrTarget = ::SysAllocString((LPWSTR)bstrTemp);
  152. }
  153. }
  154. bstrNode = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  155. GetMgmtStationName());
  156. nSeqNum = rParsedInfo.GetGlblSwitchesObject().GetSequenceNumber();
  157. // If first time.
  158. if(!m_bCreate)
  159. {
  160. // Create the XML root node
  161. hr = CreateXMLLogRoot(rParsedInfo, bstrUser);
  162. ONFAILTHROWERROR(hr);
  163. }
  164. if (bNewCmd == TRUE)
  165. {
  166. m_nItrNum = 1;
  167. // Create the node fragment and append it
  168. hr = CreateNodeFragment(nSeqNum, bstrNode, bstrStart,
  169. bstrInput, bstrOutput, bstrTarget,
  170. rParsedInfo);
  171. ONFAILTHROWERROR(hr);
  172. }
  173. else
  174. {
  175. if (bNewCycle)
  176. m_nItrNum++;
  177. hr = AppendOutputNode(bstrOutput, bstrTarget, rParsedInfo);
  178. ONFAILTHROWERROR(hr);
  179. }
  180. // Save the result to the XML file specified.
  181. varValue = (WCHAR*) m_pszLogFile;
  182. hr = m_pIXMLDoc->save(varValue);
  183. if (m_bTrace || m_eloErrLogOpt)
  184. {
  185. chsMsg.Format(L"IXMLDOMDocument2::save(L\"%s\")",
  186. (LPWSTR) varValue.bstrVal);
  187. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  188. dwThreadId, rParsedInfo, m_bTrace);
  189. }
  190. ONFAILTHROWERROR(hr);
  191. ::SysFreeString(bstrUser);
  192. ::SysFreeString(bstrStart);
  193. ::SysFreeString(bstrInput);
  194. ::SysFreeString(bstrTarget);
  195. ::SysFreeString(bstrNode);
  196. }
  197. catch(_com_error& e)
  198. {
  199. ::SysFreeString(bstrUser);
  200. ::SysFreeString(bstrStart);
  201. ::SysFreeString(bstrInput);
  202. ::SysFreeString(bstrTarget);
  203. ::SysFreeString(bstrNode);
  204. hr = e.Error();
  205. }
  206. catch(CHeap_Exception)
  207. {
  208. ::SysFreeString(bstrUser);
  209. ::SysFreeString(bstrStart);
  210. ::SysFreeString(bstrInput);
  211. ::SysFreeString(bstrTarget);
  212. ::SysFreeString(bstrNode);
  213. hr = WBEM_E_OUT_OF_MEMORY;
  214. }
  215. return hr;
  216. }
  217. /*------------------------------------------------------------------------
  218. Name :SetLogFilePath
  219. Synopsis :This function sets the m_pszLogFile name with the
  220. input
  221. Type :Member Function
  222. Input parameter :
  223. pszLogFile - String type,Contains the log file name
  224. Return Type :void
  225. Global Variables :None
  226. Calling Syntax :SetLogFilePath(pszLogFile)
  227. Notes :None
  228. ------------------------------------------------------------------------*/
  229. void CWMICliXMLLog::SetLogFilePath(_TCHAR* pszLogFile) throw (WMICLIINT)
  230. {
  231. SAFEDELETE(m_pszLogFile);
  232. m_pszLogFile = new _TCHAR [lstrlen(pszLogFile) + 1];
  233. if (m_pszLogFile)
  234. {
  235. //Copy the input argument into the log file name
  236. lstrcpy(m_pszLogFile, pszLogFile);
  237. }
  238. else
  239. throw(OUT_OF_MEMORY);
  240. }
  241. /*------------------------------------------------------------------------
  242. Name :CreateXMLLogRoot
  243. Synopsis :Creates the root node of the xml log file
  244. Type :Member Function
  245. Input parameter :
  246. rParsedInfo - reference to CParsedInfo object
  247. bstrUser - current user name
  248. Output parameters :None
  249. Return Type :HRESULT
  250. Global Variables :None
  251. Calling Syntax :CreateXMLLogRoot(rParsedInfo, bstrUser)
  252. Notes :None
  253. ------------------------------------------------------------------------*/
  254. HRESULT CWMICliXMLLog::CreateXMLLogRoot(CParsedInfo& rParsedInfo, BSTR bstrUser)
  255. {
  256. HRESULT hr = S_OK;
  257. IXMLDOMNode *pINode = NULL;
  258. DWORD dwThreadId = GetCurrentThreadId();
  259. CHString chsMsg;
  260. try
  261. {
  262. // Create single instance of the IXMLDOMDocument2 interface
  263. hr = CoCreateInstance(CLSID_DOMDocument, NULL,
  264. CLSCTX_INPROC_SERVER,
  265. IID_IXMLDOMDocument2,
  266. (LPVOID*)&m_pIXMLDoc);
  267. if (m_bTrace || m_eloErrLogOpt)
  268. {
  269. chsMsg.Format(L"CoCreateInstance(CLSID_DOMDocument, NULL,"
  270. L"CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, -)");
  271. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  272. dwThreadId, rParsedInfo, m_bTrace);
  273. }
  274. ONFAILTHROWERROR(hr);
  275. // Create the XML root node <WMICRECORD USER=XXX>
  276. _variant_t varType((short)NODE_ELEMENT);
  277. _bstr_t bstrName(L"WMIRECORD");
  278. _variant_t varValue;
  279. // Create a new node
  280. hr = CreateNodeAndSetContent(&pINode, varType, bstrName, NULL,
  281. rParsedInfo);
  282. ONFAILTHROWERROR(hr);
  283. // Append the attribute "USER"
  284. bstrName = L"USER";
  285. varValue = (WCHAR*)bstrUser;
  286. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  287. ONFAILTHROWERROR(hr);
  288. hr = m_pIXMLDoc->appendChild(pINode, NULL);
  289. if (m_bTrace || m_eloErrLogOpt)
  290. {
  291. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  292. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  293. dwThreadId, rParsedInfo, m_bTrace);
  294. }
  295. ONFAILTHROWERROR(hr);
  296. SAFEIRELEASE(pINode);
  297. // set the m_bCreate flag to TRUE
  298. m_bCreate=TRUE;
  299. }
  300. catch(_com_error& e)
  301. {
  302. SAFEIRELEASE(pINode);
  303. hr = e.Error();
  304. }
  305. catch(CHeap_Exception)
  306. {
  307. SAFEIRELEASE(pINode);
  308. hr = WBEM_E_OUT_OF_MEMORY;
  309. }
  310. return hr;
  311. }
  312. /*------------------------------------------------------------------------
  313. Name :StopLogging
  314. Synopsis :Stops logging and closes the xml DOM document object
  315. Type :Member Function
  316. Input parameter :None
  317. Output parameters :None
  318. Return Type :void
  319. Global Variables :None
  320. Calling Syntax :StopLogging()
  321. Notes :None
  322. ------------------------------------------------------------------------*/
  323. void CWMICliXMLLog::StopLogging()
  324. {
  325. SAFEDELETE(m_pszLogFile);
  326. SAFEIRELEASE(m_pIXMLDoc);
  327. m_bCreate = FALSE;
  328. }
  329. /*------------------------------------------------------------------------
  330. Name :CreateNodeAndSetContent
  331. Synopsis :Creates the new node and sets the content
  332. Type :Member Function
  333. Input parameter :
  334. pINode - pointer to node object
  335. varType - node type
  336. bstrName - Node name
  337. bstrValue - node content
  338. rParsedInfo - reference to CParsedInfo object
  339. Output parameters :None
  340. Return Type :HRESULT
  341. Global Variables :None
  342. Calling Syntax :CreateNodeAndSetContent(&pINode, varType,
  343. bstrName, bstrValue, rParsedInfo)
  344. Notes :None
  345. ------------------------------------------------------------------------*/
  346. HRESULT CWMICliXMLLog::CreateNodeAndSetContent(IXMLDOMNode** pINode,
  347. VARIANT varType,
  348. BSTR bstrName, BSTR bstrValue,
  349. CParsedInfo& rParsedInfo)
  350. {
  351. HRESULT hr = S_OK;
  352. DWORD dwThreadId = GetCurrentThreadId();
  353. CHString chsMsg;
  354. try
  355. {
  356. hr = m_pIXMLDoc->createNode(varType, bstrName, L"", pINode);
  357. if (m_bTrace || m_eloErrLogOpt)
  358. {
  359. chsMsg.Format(L"IXMLDOMDocument2::createNode(%d, \"%s\", L\"\","
  360. L" -)", varType.lVal, (LPWSTR) bstrName);
  361. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  362. dwThreadId, rParsedInfo, m_bTrace);
  363. }
  364. ONFAILTHROWERROR(hr);
  365. if (bstrValue)
  366. {
  367. hr = (*pINode)->put_text(bstrValue);
  368. if (m_bTrace || m_eloErrLogOpt)
  369. {
  370. chsMsg.Format(L"IXMLDOMNode::put_text(L\"%s\")", (LPWSTR) bstrValue);
  371. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  372. dwThreadId, rParsedInfo, m_bTrace);
  373. }
  374. ONFAILTHROWERROR(hr);
  375. }
  376. }
  377. catch(_com_error& e)
  378. {
  379. hr = e.Error();
  380. }
  381. catch(CHeap_Exception)
  382. {
  383. hr = WBEM_E_OUT_OF_MEMORY;
  384. }
  385. return hr;
  386. }
  387. /*------------------------------------------------------------------------
  388. Name :AppendAttribute
  389. Synopsis :Append attribute with the given value to the node
  390. specified.
  391. Type :Member Function
  392. Input parameter :
  393. pINode - node object
  394. bstrAttribName - Attribute name
  395. varValue - attribute value
  396. rParsedInfo - reference to CParsedInfo object
  397. Output parameters :None
  398. Return Type :HRESULT
  399. Global Variables :None
  400. Calling Syntax :AppendAttribute(pINode, bstrAttribName, varValue,
  401. rParsedInfo)
  402. Notes :None
  403. ------------------------------------------------------------------------*/
  404. HRESULT CWMICliXMLLog::AppendAttribute(IXMLDOMNode* pINode, BSTR bstrAttribName,
  405. VARIANT varValue, CParsedInfo& rParsedInfo)
  406. {
  407. HRESULT hr = S_OK;
  408. IXMLDOMNamedNodeMap *pINodeMap = NULL;
  409. IXMLDOMAttribute *pIAttrib = NULL;
  410. DWORD dwThreadId = GetCurrentThreadId();
  411. CHString chsMsg;
  412. try
  413. {
  414. // Get the attributes map
  415. hr = pINode->get_attributes(&pINodeMap);
  416. if (m_bTrace || m_eloErrLogOpt)
  417. {
  418. chsMsg.Format(L"IXMLDOMNode::get_attributes(-)");
  419. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  420. dwThreadId, rParsedInfo, m_bTrace);
  421. }
  422. ONFAILTHROWERROR(hr);
  423. if (pINodeMap)
  424. {
  425. // Create the attribute with the given name.
  426. hr = m_pIXMLDoc->createAttribute(bstrAttribName, &pIAttrib);
  427. if (m_bTrace || m_eloErrLogOpt)
  428. {
  429. chsMsg.Format(L"IXMLDOMDocument2::createAttribute(L\"%s\", -)",
  430. (LPWSTR) bstrAttribName);
  431. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  432. dwThreadId, rParsedInfo, m_bTrace);
  433. }
  434. ONFAILTHROWERROR(hr);
  435. // Set the attribute value
  436. if (pIAttrib)
  437. {
  438. hr = pIAttrib->put_nodeValue(varValue);
  439. if (m_bTrace || m_eloErrLogOpt)
  440. {
  441. chsMsg.Format(L"IXMLDOMAttribute::put_nodeValue(L\"%s\")",
  442. (LPWSTR) _bstr_t(varValue));
  443. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  444. dwThreadId, rParsedInfo, m_bTrace);
  445. }
  446. ONFAILTHROWERROR(hr);
  447. hr = pINodeMap->setNamedItem(pIAttrib, NULL);
  448. if (m_bTrace || m_eloErrLogOpt)
  449. {
  450. chsMsg.Format(L"IXMLDOMNamedNodeMap::setNamedItem(-, NULL)");
  451. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  452. dwThreadId, rParsedInfo, m_bTrace);
  453. }
  454. ONFAILTHROWERROR(hr);
  455. SAFEIRELEASE(pIAttrib);
  456. }
  457. SAFEIRELEASE(pINodeMap);
  458. }
  459. }
  460. catch(_com_error& e)
  461. {
  462. SAFEIRELEASE(pIAttrib);
  463. SAFEIRELEASE(pINodeMap);
  464. hr = e.Error();
  465. }
  466. catch(CHeap_Exception)
  467. {
  468. SAFEIRELEASE(pIAttrib);
  469. SAFEIRELEASE(pINodeMap);
  470. hr = WBEM_E_OUT_OF_MEMORY;
  471. }
  472. return hr;
  473. }
  474. /*------------------------------------------------------------------------
  475. Name :CreateNodeFragment
  476. Synopsis :Creates a new node fragment with the predefined format
  477. and appends it to the document object
  478. Type :Member Function
  479. Input parameter :
  480. nSeqNum - sequence # of the command.
  481. bstrNode - management workstation name
  482. bstrStart - command issued time
  483. bstrInput - commandline input
  484. bstrOutput - commandline output
  485. bstrTarget - target node
  486. rParsedInfo - reference to CParsedInfo object
  487. Output parameters :None
  488. Return Type :HRESULT
  489. Global Variables :None
  490. Calling Syntax :CreateNodeFragment(nSeqNum, bstrNode, bstrStart,
  491. bstrInput, bstrOutput, bstrTarget, rParsedInfo)
  492. Notes :None
  493. ------------------------------------------------------------------------*/
  494. HRESULT CWMICliXMLLog::CreateNodeFragment(WMICLIINT nSeqNum, BSTR bstrNode,
  495. BSTR bstrStart, BSTR bstrInput,
  496. BSTR bstrOutput, BSTR bstrTarget,
  497. CParsedInfo& rParsedInfo)
  498. {
  499. HRESULT hr = S_OK;
  500. IXMLDOMNode *pINode = NULL,
  501. *pISNode = NULL,
  502. *pITNode = NULL;
  503. IXMLDOMDocumentFragment *pIFrag = NULL;
  504. IXMLDOMElement *pIElement = NULL;
  505. _variant_t varType;
  506. _bstr_t bstrName;
  507. _variant_t varValue;
  508. DWORD dwThreadId = GetCurrentThreadId();
  509. CHString chsMsg;
  510. try
  511. {
  512. // The nodetype is NODE_ELEMENT
  513. varType = ((short)NODE_ELEMENT);
  514. bstrName = _T("RECORD");
  515. // Create a new node
  516. hr = CreateNodeAndSetContent(&pINode, varType,
  517. bstrName, NULL, rParsedInfo);
  518. ONFAILTHROWERROR(hr);
  519. // Append the attribute "SEQUENCENUM"
  520. bstrName = L"SEQUENCENUM";
  521. varValue = (long) nSeqNum;
  522. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  523. ONFAILTHROWERROR(hr);
  524. // Append the attribute "ISSUEDFROM"
  525. bstrName = L"ISSUEDFROM";
  526. varValue = (WCHAR*)bstrNode;
  527. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  528. ONFAILTHROWERROR(hr);
  529. // Append the attribute "STARTTIME"
  530. bstrName = L"STARTTIME";
  531. varValue = (WCHAR*) bstrStart;
  532. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  533. ONFAILTHROWERROR(hr);
  534. // Create a document fragment and associate the new node with it.
  535. hr = m_pIXMLDoc->createDocumentFragment(&pIFrag);
  536. if (m_bTrace || m_eloErrLogOpt)
  537. {
  538. chsMsg.Format(L"IXMLDOMDocument2::createDocumentFragment(-)");
  539. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  540. dwThreadId, rParsedInfo, m_bTrace);
  541. }
  542. ONFAILTHROWERROR(hr);
  543. hr = pIFrag->appendChild(pINode, NULL);
  544. if (m_bTrace || m_eloErrLogOpt)
  545. {
  546. chsMsg.Format(L"IXMLDOMDocumentFragment::appendChild(-, NULL)");
  547. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  548. dwThreadId, rParsedInfo, m_bTrace);
  549. }
  550. ONFAILTHROWERROR(hr);
  551. // Append the REQUEST node together with the input command.
  552. bstrName = _T("REQUEST");
  553. hr = CreateNodeAndSetContent(&pISNode, varType,
  554. bstrName, NULL, rParsedInfo);
  555. ONFAILTHROWERROR(hr);
  556. hr = pINode->appendChild(pISNode, &pITNode);
  557. if (m_bTrace || m_eloErrLogOpt)
  558. {
  559. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  560. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  561. dwThreadId, rParsedInfo, m_bTrace);
  562. }
  563. ONFAILTHROWERROR(hr);
  564. SAFEIRELEASE(pISNode);
  565. bstrName = _T("COMMANDLINE");
  566. hr = CreateNodeAndSetContent(&pISNode, varType,
  567. bstrName, bstrInput, rParsedInfo);
  568. ONFAILTHROWERROR(hr);
  569. hr = pITNode->appendChild(pISNode, NULL);
  570. if (m_bTrace || m_eloErrLogOpt)
  571. {
  572. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  573. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  574. dwThreadId, rParsedInfo, m_bTrace);
  575. }
  576. ONFAILTHROWERROR(hr);
  577. SAFEIRELEASE(pISNode);
  578. SAFEIRELEASE(pITNode);
  579. hr = FrameOutputNode(&pINode, bstrOutput, bstrTarget, rParsedInfo);
  580. // Get the document element of the XML log file
  581. hr = m_pIXMLDoc->get_documentElement(&pIElement);
  582. if (m_bTrace || m_eloErrLogOpt)
  583. {
  584. chsMsg.Format(L"IXMLDOMDocument2::get_documentElement(-, NULL)");
  585. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  586. dwThreadId, rParsedInfo, m_bTrace);
  587. }
  588. ONFAILTHROWERROR(hr);
  589. // Append the newly create fragment to the document element
  590. hr = pIElement->appendChild(pIFrag, NULL);
  591. if (m_bTrace || m_eloErrLogOpt)
  592. {
  593. chsMsg.Format(L"IXMLDOMElement::appendChild(-, NULL)");
  594. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  595. dwThreadId, rParsedInfo, m_bTrace);
  596. }
  597. ONFAILTHROWERROR(hr);
  598. SAFEIRELEASE(pINode);
  599. SAFEIRELEASE(pIFrag);
  600. SAFEIRELEASE(pIElement);
  601. }
  602. catch(_com_error& e)
  603. {
  604. SAFEIRELEASE(pISNode);
  605. SAFEIRELEASE(pITNode);
  606. SAFEIRELEASE(pINode);
  607. SAFEIRELEASE(pIFrag);
  608. SAFEIRELEASE(pIElement);
  609. hr = e.Error();
  610. }
  611. catch(CHeap_Exception)
  612. {
  613. SAFEIRELEASE(pISNode);
  614. SAFEIRELEASE(pITNode);
  615. SAFEIRELEASE(pINode);
  616. SAFEIRELEASE(pIFrag);
  617. SAFEIRELEASE(pIElement);
  618. hr = WBEM_E_OUT_OF_MEMORY;
  619. }
  620. return hr;
  621. }
  622. /*------------------------------------------------------------------------
  623. Name :FrameOutputNode
  624. Synopsis :Frames a new output node
  625. Type :Member Function
  626. Input parameter :
  627. pINode - pointer to pointer to IXMLDOMNode object
  628. bstrOutput - commandline output
  629. bstrTarget - target node
  630. rParsedInfo - reference to CParsedInfo object
  631. Output parameters :
  632. pINode - pointer to pointer to IXMLDOMNode object
  633. Return Type :HRESULT
  634. Global Variables :None
  635. Calling Syntax :FrameOutputNode(&pINode, bstrOutput, bstrTarget,
  636. rParsedInfo)
  637. Notes :None
  638. ------------------------------------------------------------------------*/
  639. HRESULT CWMICliXMLLog::FrameOutputNode(IXMLDOMNode **pINode, BSTR bstrOutput,
  640. BSTR bstrTarget,
  641. CParsedInfo& rParsedInfo)
  642. {
  643. HRESULT hr = S_OK;
  644. IXMLDOMNode *pISNode = NULL;
  645. IXMLDOMCDATASection *pICDATASec = NULL;
  646. _bstr_t bstrName;
  647. _variant_t varType,
  648. varValue;
  649. DWORD dwThreadId = GetCurrentThreadId();
  650. CHString chsMsg;
  651. try
  652. {
  653. // The nodetype is NODE_ELEMENT
  654. varType = ((short)NODE_ELEMENT);
  655. // Append the OUTPUT node together with the output generated.
  656. bstrName = _T("OUTPUT");
  657. hr = CreateNodeAndSetContent(&pISNode, varType,
  658. bstrName, NULL, rParsedInfo);
  659. ONFAILTHROWERROR(hr);
  660. // Append the attribute "TARGETNODE"
  661. bstrName = L"TARGETNODE";
  662. varValue = (WCHAR*) bstrTarget;
  663. hr = AppendAttribute(pISNode, bstrName, varValue, rParsedInfo);
  664. ONFAILTHROWERROR(hr);
  665. // Append the attribute "ITERATION"
  666. bstrName = L"ITERATION";
  667. varValue = (long)m_nItrNum;
  668. hr = AppendAttribute(pISNode, bstrName, varValue, rParsedInfo);
  669. ONFAILTHROWERROR(hr);
  670. // Create the CDATASection
  671. hr = m_pIXMLDoc->createCDATASection(bstrOutput, &pICDATASec);
  672. if (m_bTrace || m_eloErrLogOpt)
  673. {
  674. chsMsg.Format(L"IXMLDOMDocument2::createCDATASection(-, -)");
  675. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  676. dwThreadId, rParsedInfo, m_bTrace);
  677. }
  678. ONFAILTHROWERROR(hr);
  679. // Append the CDATASection node to the OUTPUT node.
  680. hr = pISNode->appendChild(pICDATASec, NULL);
  681. if (m_bTrace || m_eloErrLogOpt)
  682. {
  683. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  684. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  685. dwThreadId, rParsedInfo, m_bTrace);
  686. }
  687. ONFAILTHROWERROR(hr);
  688. SAFEIRELEASE(pICDATASec);
  689. hr = (*pINode)->appendChild(pISNode, NULL);
  690. if (m_bTrace || m_eloErrLogOpt)
  691. {
  692. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  693. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  694. dwThreadId, rParsedInfo, m_bTrace);
  695. }
  696. ONFAILTHROWERROR(hr);
  697. SAFEIRELEASE(pISNode);
  698. }
  699. catch(_com_error& e)
  700. {
  701. SAFEIRELEASE(pICDATASec);
  702. SAFEIRELEASE(pISNode);
  703. hr = e.Error();
  704. }
  705. catch(CHeap_Exception)
  706. {
  707. SAFEIRELEASE(pICDATASec);
  708. SAFEIRELEASE(pISNode);
  709. hr = WBEM_E_OUT_OF_MEMORY;
  710. }
  711. return hr;
  712. }
  713. /*------------------------------------------------------------------------
  714. Name :AppendOutputNode
  715. Synopsis :appends the newoutput node element to the exisitng
  716. and that too last RECORD node
  717. Type :Member Function
  718. Input parameter :
  719. bstrOutput - commandline output
  720. bstrTarget - target node
  721. rParsedInfo - reference to CParsedInfo object
  722. Output parameters : None
  723. Return Type :HRESULT
  724. Global Variables :None
  725. Calling Syntax :AppendOutputNode(bstrOutput, bstrTarget,
  726. rParsedInfo)
  727. Notes :None
  728. ------------------------------------------------------------------------*/
  729. HRESULT CWMICliXMLLog::AppendOutputNode(BSTR bstrOutput, BSTR bstrTarget,
  730. CParsedInfo& rParsedInfo)
  731. {
  732. IXMLDOMNodeList *pINodeList = NULL;
  733. HRESULT hr = S_OK;
  734. LONG lValue = 0;
  735. IXMLDOMNode *pINode = NULL;
  736. IXMLDOMNode *pIParent = NULL,
  737. *pIClone = NULL;
  738. DWORD dwThreadId = GetCurrentThreadId();
  739. CHString chsMsg;
  740. try
  741. {
  742. hr = m_pIXMLDoc->getElementsByTagName(_T("RECORD"), &pINodeList);
  743. if (m_bTrace || m_eloErrLogOpt)
  744. {
  745. chsMsg.Format(L"IXMLDOMDocument2::getElementsByTagName(L\"RECORD\", -)");
  746. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  747. dwThreadId, rParsedInfo, m_bTrace);
  748. }
  749. ONFAILTHROWERROR(hr);
  750. hr = pINodeList->get_length(&lValue);
  751. ONFAILTHROWERROR(hr);
  752. hr = pINodeList->get_item(lValue-1, &pINode);
  753. if (m_bTrace || m_eloErrLogOpt)
  754. {
  755. chsMsg.Format(L"IXMLDOMNodeList::get_item(%d, -)", lValue-1);
  756. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  757. dwThreadId, rParsedInfo, m_bTrace);
  758. }
  759. ONFAILTHROWERROR(hr);
  760. if (pINode)
  761. {
  762. hr = pINode->cloneNode(VARIANT_TRUE, &pIClone);
  763. if (m_bTrace || m_eloErrLogOpt)
  764. {
  765. chsMsg.Format(L"IXMLDOMNode::cloneNode(VARIANT_TRUE, -)");
  766. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  767. dwThreadId, rParsedInfo, m_bTrace);
  768. }
  769. ONFAILTHROWERROR(hr);
  770. hr = pINode->get_parentNode(&pIParent);
  771. if (m_bTrace || m_eloErrLogOpt)
  772. {
  773. chsMsg.Format(L"IXMLDOMNode::get_ParentNode(-)");
  774. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  775. dwThreadId, rParsedInfo, m_bTrace);
  776. }
  777. ONFAILTHROWERROR(hr);
  778. hr = FrameOutputNode(&pIClone, bstrOutput, bstrTarget, rParsedInfo);
  779. ONFAILTHROWERROR(hr);
  780. hr = pIParent->replaceChild(pIClone, pINode, NULL);
  781. if (m_bTrace || m_eloErrLogOpt)
  782. {
  783. chsMsg.Format(L"IXMLDOMNode::replaceChild(-, -, NULL)");
  784. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  785. dwThreadId, rParsedInfo, m_bTrace);
  786. }
  787. ONFAILTHROWERROR(hr);
  788. }
  789. SAFEIRELEASE(pINodeList);
  790. SAFEIRELEASE(pIClone);
  791. SAFEIRELEASE(pIParent);
  792. SAFEIRELEASE(pINode);
  793. }
  794. catch(_com_error& e)
  795. {
  796. SAFEIRELEASE(pINodeList);
  797. SAFEIRELEASE(pIClone);
  798. SAFEIRELEASE(pIParent);
  799. SAFEIRELEASE(pINode);
  800. hr = e.Error();
  801. }
  802. catch(CHeap_Exception)
  803. {
  804. SAFEIRELEASE(pINodeList);
  805. SAFEIRELEASE(pIClone);
  806. SAFEIRELEASE(pIParent);
  807. SAFEIRELEASE(pINode);
  808. hr = WBEM_E_OUT_OF_MEMORY;
  809. }
  810. return hr;
  811. }