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.

1061 lines
33 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 "ErrorInfo.h"
  23. #include "WMICliXMLLog.h"
  24. #include "CmdTokenizer.h"
  25. #include "CmdAlias.h"
  26. #include "ParserEngine.h"
  27. #include "ExecEngine.h"
  28. #include "FormatEngine.h"
  29. #include "WmiCmdLn.h"
  30. /*------------------------------------------------------------------------
  31. Name :CWMICliXMLLog
  32. Synopsis :Constructor
  33. Type :Constructor
  34. Input parameter :None
  35. Output parameters :None
  36. Return Type :None
  37. Global Variables :None
  38. Calling Syntax :None
  39. Notes :None
  40. ------------------------------------------------------------------------*/
  41. CWMICliXMLLog::CWMICliXMLLog()
  42. {
  43. m_pIXMLDoc = NULL;
  44. m_pszLogFile = NULL;
  45. m_bCreate = FALSE;
  46. m_nItrNum = 0;
  47. m_bTrace = FALSE;
  48. m_eloErrLogOpt = NO_LOGGING;
  49. }
  50. /*------------------------------------------------------------------------
  51. Name :~CWMICliXMLLog
  52. Synopsis :Destructor
  53. Type :Destructor
  54. Input parameter :None
  55. Output parameters :None
  56. Return Type :None
  57. Global Variables :None
  58. Calling Syntax :None
  59. Notes :None
  60. ------------------------------------------------------------------------*/
  61. CWMICliXMLLog::~CWMICliXMLLog()
  62. {
  63. SAFEDELETE(m_pszLogFile);
  64. SAFEIRELEASE(m_pIXMLDoc);
  65. }
  66. /*----------------------------------------------------------------------------
  67. Name :Uninitialize
  68. Synopsis :This function uninitializes the member variables when
  69. the execution of a command string issued on the command
  70. line is completed.
  71. Type :Member Function
  72. Input Parameter(s):
  73. bFinal - boolean value which when set indicates that the program
  74. Output parameters :None
  75. Return Type :None
  76. Global Variables :None
  77. Calling Syntax :Uninitialize(bFinal)
  78. Notes :None
  79. ----------------------------------------------------------------------------*/
  80. void CWMICliXMLLog::Uninitialize(BOOL bFinal)
  81. {
  82. if (bFinal)
  83. {
  84. SAFEDELETE(m_pszLogFile);
  85. SAFEIRELEASE(m_pIXMLDoc);
  86. }
  87. m_bTrace = FALSE;
  88. m_eloErrLogOpt = NO_LOGGING;
  89. }
  90. /*------------------------------------------------------------------------
  91. Name :WriteToXMLLog
  92. Synopsis :Logs the input & output to the xml log file
  93. Type :Member Function
  94. Input parameter :
  95. rParsedInfo - reference to CParsedInfo object
  96. bstrOutput - output that goes into CDATA section.
  97. Output parameters :None
  98. Return Type :HRESULT
  99. Global Variables :None
  100. Calling Syntax :WriteToXMLLog(rParsedInfo, bstrOutput)
  101. Notes :None
  102. ------------------------------------------------------------------------*/
  103. HRESULT CWMICliXMLLog::WriteToXMLLog(CParsedInfo& rParsedInfo, BSTR bstrOutput)
  104. {
  105. HRESULT hr = S_OK;
  106. _variant_t varValue;
  107. DWORD dwThreadId = GetCurrentThreadId();
  108. BSTR bstrUser = NULL,
  109. bstrStart = NULL,
  110. bstrInput = NULL,
  111. bstrTarget = NULL,
  112. bstrNode = NULL;
  113. WMICLIINT nSeqNum = 0;
  114. BOOL bNewCmd = FALSE;
  115. BOOL bNewCycle = FALSE;
  116. // Initialize the TRACE and ERRORLOG variables.
  117. m_bTrace = rParsedInfo.GetGlblSwitchesObject().GetTraceStatus();
  118. m_eloErrLogOpt = rParsedInfo.GetErrorLogObject().GetErrLogOption();
  119. bNewCmd = rParsedInfo.GetNewCommandStatus();
  120. bNewCycle = rParsedInfo.GetNewCycleStatus();
  121. CHString chsMsg;
  122. try
  123. {
  124. bstrUser = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  125. GetLoggedonUser());
  126. if (bstrUser == NULL)
  127. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  128. bstrStart = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  129. GetStartTime());
  130. if (bstrStart == NULL)
  131. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  132. _TCHAR *pszCommandInput = rParsedInfo.GetCmdSwitchesObject().
  133. GetCommandInput();
  134. STRING strCommand(pszCommandInput);
  135. // Delete /RECORD entries
  136. FindAndDeleteRecord(strCommand);
  137. bstrInput = ::SysAllocString((LPTSTR)strCommand.data());
  138. if (bstrInput == NULL)
  139. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  140. if (!rParsedInfo.GetGlblSwitchesObject().GetAggregateFlag())
  141. {
  142. bstrTarget = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  143. GetNode());
  144. if (bstrTarget == NULL)
  145. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  146. }
  147. else
  148. {
  149. _bstr_t bstrTemp;
  150. _TCHAR* pszVerb = rParsedInfo.GetCmdSwitchesObject().GetVerbName();
  151. if (pszVerb)
  152. {
  153. if ( CompareTokens(pszVerb, CLI_TOKEN_LIST) ||
  154. CompareTokens(pszVerb, CLI_TOKEN_ASSOC) ||
  155. CompareTokens(pszVerb, CLI_TOKEN_GET))
  156. {
  157. rParsedInfo.GetGlblSwitchesObject().GetNodeString(bstrTemp);
  158. bstrTarget = ::SysAllocString((LPWSTR)bstrTemp);
  159. if (bstrTarget == NULL)
  160. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  161. }
  162. // CALL, SET, CREATE, DELETE and, user defined verbs
  163. else
  164. {
  165. bstrTarget= ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  166. GetNode());
  167. if (bstrTarget == NULL)
  168. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  169. }
  170. }
  171. else
  172. {
  173. rParsedInfo.GetGlblSwitchesObject().GetNodeString(bstrTemp);
  174. bstrTarget = ::SysAllocString((LPWSTR)bstrTemp);
  175. if (bstrTarget == NULL)
  176. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  177. }
  178. }
  179. bstrNode = ::SysAllocString(rParsedInfo.GetGlblSwitchesObject().
  180. GetMgmtStationName());
  181. if (bstrNode == NULL)
  182. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  183. nSeqNum = rParsedInfo.GetGlblSwitchesObject().GetSequenceNumber();
  184. // If first time.
  185. if(!m_bCreate)
  186. {
  187. // Create the XML root node
  188. hr = CreateXMLLogRoot(rParsedInfo, bstrUser);
  189. ONFAILTHROWERROR(hr);
  190. }
  191. if (bNewCmd == TRUE)
  192. {
  193. m_nItrNum = 1;
  194. // Create the node fragment and append it
  195. hr = CreateNodeFragment(nSeqNum, bstrNode, bstrStart,
  196. bstrInput, bstrOutput, bstrTarget,
  197. rParsedInfo);
  198. ONFAILTHROWERROR(hr);
  199. }
  200. else
  201. {
  202. if (bNewCycle)
  203. m_nItrNum++;
  204. hr = AppendOutputNode(bstrOutput, bstrTarget, rParsedInfo);
  205. ONFAILTHROWERROR(hr);
  206. }
  207. // Save the result to the XML file specified.
  208. varValue = (WCHAR*) m_pszLogFile;
  209. hr = m_pIXMLDoc->save(varValue);
  210. if (m_bTrace || m_eloErrLogOpt)
  211. {
  212. chsMsg.Format(L"IXMLDOMDocument2::save(L\"%s\")",
  213. (LPWSTR) varValue.bstrVal);
  214. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  215. dwThreadId, rParsedInfo, m_bTrace);
  216. }
  217. ONFAILTHROWERROR(hr);
  218. ::SysFreeString(bstrUser);
  219. ::SysFreeString(bstrStart);
  220. ::SysFreeString(bstrInput);
  221. ::SysFreeString(bstrTarget);
  222. ::SysFreeString(bstrNode);
  223. }
  224. catch(_com_error& e)
  225. {
  226. ::SysFreeString(bstrUser);
  227. ::SysFreeString(bstrStart);
  228. ::SysFreeString(bstrInput);
  229. ::SysFreeString(bstrTarget);
  230. ::SysFreeString(bstrNode);
  231. hr = e.Error();
  232. }
  233. catch(CHeap_Exception)
  234. {
  235. ::SysFreeString(bstrUser);
  236. ::SysFreeString(bstrStart);
  237. ::SysFreeString(bstrInput);
  238. ::SysFreeString(bstrTarget);
  239. ::SysFreeString(bstrNode);
  240. hr = WBEM_E_OUT_OF_MEMORY;
  241. }
  242. return hr;
  243. }
  244. /*------------------------------------------------------------------------
  245. Name :SetLogFilePath
  246. Synopsis :This function sets the m_pszLogFile name with the
  247. input
  248. Type :Member Function
  249. Input parameter :
  250. pszLogFile - String type,Contains the log file name
  251. Return Type :void
  252. Global Variables :None
  253. Calling Syntax :SetLogFilePath(pszLogFile)
  254. Notes :None
  255. ------------------------------------------------------------------------*/
  256. void CWMICliXMLLog::SetLogFilePath(_TCHAR* pszLogFile) throw (WMICLIINT)
  257. {
  258. SAFEDELETE(m_pszLogFile);
  259. m_pszLogFile = new _TCHAR [lstrlen(pszLogFile) + 1];
  260. if (m_pszLogFile)
  261. {
  262. //Copy the input argument into the log file name
  263. lstrcpy(m_pszLogFile, pszLogFile);
  264. }
  265. else
  266. throw(OUT_OF_MEMORY);
  267. }
  268. /*------------------------------------------------------------------------
  269. Name :CreateXMLLogRoot
  270. Synopsis :Creates the root node of the xml log file
  271. Type :Member Function
  272. Input parameter :
  273. rParsedInfo - reference to CParsedInfo object
  274. bstrUser - current user name
  275. Output parameters :None
  276. Return Type :HRESULT
  277. Global Variables :None
  278. Calling Syntax :CreateXMLLogRoot(rParsedInfo, bstrUser)
  279. Notes :None
  280. ------------------------------------------------------------------------*/
  281. HRESULT CWMICliXMLLog::CreateXMLLogRoot(CParsedInfo& rParsedInfo, BSTR bstrUser)
  282. {
  283. HRESULT hr = S_OK;
  284. IXMLDOMNode *pINode = NULL;
  285. DWORD dwThreadId = GetCurrentThreadId();
  286. CHString chsMsg;
  287. try
  288. {
  289. // Create single instance of the IXMLDOMDocument2 interface
  290. hr = CoCreateInstance(CLSID_FreeThreadedDOMDocument, NULL,
  291. CLSCTX_INPROC_SERVER,
  292. IID_IXMLDOMDocument2,
  293. (LPVOID*)&m_pIXMLDoc);
  294. if (m_bTrace || m_eloErrLogOpt)
  295. {
  296. chsMsg.Format(L"CoCreateInstance(CLSID_FreeThreadedDOMDocument, NULL,"
  297. L"CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument2, -)");
  298. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  299. dwThreadId, rParsedInfo, m_bTrace);
  300. }
  301. ONFAILTHROWERROR(hr);
  302. // Create the XML root node <WMICRECORD USER=XXX>
  303. _variant_t varType((short)NODE_ELEMENT);
  304. _bstr_t bstrName(L"WMIRECORD");
  305. _variant_t varValue;
  306. // Create a new node
  307. hr = CreateNodeAndSetContent(&pINode, varType, bstrName, NULL,
  308. rParsedInfo);
  309. ONFAILTHROWERROR(hr);
  310. // Append the attribute "USER"
  311. bstrName = L"USER";
  312. varValue = (WCHAR*)bstrUser;
  313. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  314. ONFAILTHROWERROR(hr);
  315. hr = m_pIXMLDoc->appendChild(pINode, NULL);
  316. if (m_bTrace || m_eloErrLogOpt)
  317. {
  318. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  319. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  320. dwThreadId, rParsedInfo, m_bTrace);
  321. }
  322. ONFAILTHROWERROR(hr);
  323. SAFEIRELEASE(pINode);
  324. // set the m_bCreate flag to TRUE
  325. m_bCreate=TRUE;
  326. }
  327. catch(_com_error& e)
  328. {
  329. SAFEIRELEASE(pINode);
  330. hr = e.Error();
  331. }
  332. catch(CHeap_Exception)
  333. {
  334. SAFEIRELEASE(pINode);
  335. hr = WBEM_E_OUT_OF_MEMORY;
  336. }
  337. return hr;
  338. }
  339. /*------------------------------------------------------------------------
  340. Name :StopLogging
  341. Synopsis :Stops logging and closes the xml DOM document object
  342. Type :Member Function
  343. Input parameter :None
  344. Output parameters :None
  345. Return Type :void
  346. Global Variables :None
  347. Calling Syntax :StopLogging()
  348. Notes :None
  349. ------------------------------------------------------------------------*/
  350. void CWMICliXMLLog::StopLogging()
  351. {
  352. SAFEDELETE(m_pszLogFile);
  353. SAFEIRELEASE(m_pIXMLDoc);
  354. m_bCreate = FALSE;
  355. }
  356. /*------------------------------------------------------------------------
  357. Name :CreateNodeAndSetContent
  358. Synopsis :Creates the new node and sets the content
  359. Type :Member Function
  360. Input parameter :
  361. pINode - pointer to node object
  362. varType - node type
  363. bstrName - Node name
  364. bstrValue - node content
  365. rParsedInfo - reference to CParsedInfo object
  366. Output parameters :None
  367. Return Type :HRESULT
  368. Global Variables :None
  369. Calling Syntax :CreateNodeAndSetContent(&pINode, varType,
  370. bstrName, bstrValue, rParsedInfo)
  371. Notes :None
  372. ------------------------------------------------------------------------*/
  373. HRESULT CWMICliXMLLog::CreateNodeAndSetContent(IXMLDOMNode** pINode,
  374. VARIANT varType,
  375. BSTR bstrName, BSTR bstrValue,
  376. CParsedInfo& rParsedInfo)
  377. {
  378. HRESULT hr = S_OK;
  379. DWORD dwThreadId = GetCurrentThreadId();
  380. CHString chsMsg;
  381. try
  382. {
  383. hr = m_pIXMLDoc->createNode(varType, bstrName, L"", pINode);
  384. if (m_bTrace || m_eloErrLogOpt)
  385. {
  386. chsMsg.Format(L"IXMLDOMDocument2::createNode(%d, \"%s\", L\"\","
  387. L" -)", varType.lVal, (LPWSTR) bstrName);
  388. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  389. dwThreadId, rParsedInfo, m_bTrace);
  390. }
  391. ONFAILTHROWERROR(hr);
  392. if (bstrValue)
  393. {
  394. hr = (*pINode)->put_text(bstrValue);
  395. if (m_bTrace || m_eloErrLogOpt)
  396. {
  397. chsMsg.Format(L"IXMLDOMNode::put_text(L\"%s\")", (LPWSTR) bstrValue);
  398. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  399. dwThreadId, rParsedInfo, m_bTrace);
  400. }
  401. ONFAILTHROWERROR(hr);
  402. }
  403. }
  404. catch(_com_error& e)
  405. {
  406. hr = e.Error();
  407. }
  408. catch(CHeap_Exception)
  409. {
  410. hr = WBEM_E_OUT_OF_MEMORY;
  411. }
  412. return hr;
  413. }
  414. /*------------------------------------------------------------------------
  415. Name :AppendAttribute
  416. Synopsis :Append attribute with the given value to the node
  417. specified.
  418. Type :Member Function
  419. Input parameter :
  420. pINode - node object
  421. bstrAttribName - Attribute name
  422. varValue - attribute value
  423. rParsedInfo - reference to CParsedInfo object
  424. Output parameters :None
  425. Return Type :HRESULT
  426. Global Variables :None
  427. Calling Syntax :AppendAttribute(pINode, bstrAttribName, varValue,
  428. rParsedInfo)
  429. Notes :None
  430. ------------------------------------------------------------------------*/
  431. HRESULT CWMICliXMLLog::AppendAttribute(IXMLDOMNode* pINode, BSTR bstrAttribName,
  432. VARIANT varValue, CParsedInfo& rParsedInfo)
  433. {
  434. HRESULT hr = S_OK;
  435. IXMLDOMNamedNodeMap *pINodeMap = NULL;
  436. IXMLDOMAttribute *pIAttrib = NULL;
  437. DWORD dwThreadId = GetCurrentThreadId();
  438. CHString chsMsg;
  439. try
  440. {
  441. // Get the attributes map
  442. hr = pINode->get_attributes(&pINodeMap);
  443. if (m_bTrace || m_eloErrLogOpt)
  444. {
  445. chsMsg.Format(L"IXMLDOMNode::get_attributes(-)");
  446. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  447. dwThreadId, rParsedInfo, m_bTrace);
  448. }
  449. ONFAILTHROWERROR(hr);
  450. if (pINodeMap)
  451. {
  452. // Create the attribute with the given name.
  453. hr = m_pIXMLDoc->createAttribute(bstrAttribName, &pIAttrib);
  454. if (m_bTrace || m_eloErrLogOpt)
  455. {
  456. chsMsg.Format(L"IXMLDOMDocument2::createAttribute(L\"%s\", -)",
  457. (LPWSTR) bstrAttribName);
  458. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  459. dwThreadId, rParsedInfo, m_bTrace);
  460. }
  461. ONFAILTHROWERROR(hr);
  462. // Set the attribute value
  463. if (pIAttrib)
  464. {
  465. hr = pIAttrib->put_nodeValue(varValue);
  466. if (m_bTrace || m_eloErrLogOpt)
  467. {
  468. chsMsg.Format(L"IXMLDOMAttribute::put_nodeValue(L\"%s\")",
  469. (LPWSTR) _bstr_t(varValue));
  470. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  471. dwThreadId, rParsedInfo, m_bTrace);
  472. }
  473. ONFAILTHROWERROR(hr);
  474. hr = pINodeMap->setNamedItem(pIAttrib, NULL);
  475. if (m_bTrace || m_eloErrLogOpt)
  476. {
  477. chsMsg.Format(L"IXMLDOMNamedNodeMap::setNamedItem(-, NULL)");
  478. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  479. dwThreadId, rParsedInfo, m_bTrace);
  480. }
  481. ONFAILTHROWERROR(hr);
  482. SAFEIRELEASE(pIAttrib);
  483. }
  484. SAFEIRELEASE(pINodeMap);
  485. }
  486. }
  487. catch(_com_error& e)
  488. {
  489. SAFEIRELEASE(pIAttrib);
  490. SAFEIRELEASE(pINodeMap);
  491. hr = e.Error();
  492. }
  493. catch(CHeap_Exception)
  494. {
  495. SAFEIRELEASE(pIAttrib);
  496. SAFEIRELEASE(pINodeMap);
  497. hr = WBEM_E_OUT_OF_MEMORY;
  498. }
  499. return hr;
  500. }
  501. /*------------------------------------------------------------------------
  502. Name :CreateNodeFragment
  503. Synopsis :Creates a new node fragment with the predefined format
  504. and appends it to the document object
  505. Type :Member Function
  506. Input parameter :
  507. nSeqNum - sequence # of the command.
  508. bstrNode - management workstation name
  509. bstrStart - command issued time
  510. bstrInput - commandline input
  511. bstrOutput - commandline output
  512. bstrTarget - target node
  513. rParsedInfo - reference to CParsedInfo object
  514. Output parameters :None
  515. Return Type :HRESULT
  516. Global Variables :None
  517. Calling Syntax :CreateNodeFragment(nSeqNum, bstrNode, bstrStart,
  518. bstrInput, bstrOutput, bstrTarget, rParsedInfo)
  519. Notes :None
  520. ------------------------------------------------------------------------*/
  521. HRESULT CWMICliXMLLog::CreateNodeFragment(WMICLIINT nSeqNum, BSTR bstrNode,
  522. BSTR bstrStart, BSTR bstrInput,
  523. BSTR bstrOutput, BSTR bstrTarget,
  524. CParsedInfo& rParsedInfo)
  525. {
  526. HRESULT hr = S_OK;
  527. IXMLDOMNode *pINode = NULL,
  528. *pISNode = NULL,
  529. *pITNode = NULL;
  530. IXMLDOMDocumentFragment *pIFrag = NULL;
  531. IXMLDOMElement *pIElement = NULL;
  532. _variant_t varType;
  533. _bstr_t bstrName;
  534. _variant_t varValue;
  535. DWORD dwThreadId = GetCurrentThreadId();
  536. CHString chsMsg;
  537. try
  538. {
  539. // The nodetype is NODE_ELEMENT
  540. varType = ((short)NODE_ELEMENT);
  541. bstrName = _T("RECORD");
  542. // Create a new node
  543. hr = CreateNodeAndSetContent(&pINode, varType,
  544. bstrName, NULL, rParsedInfo);
  545. ONFAILTHROWERROR(hr);
  546. // Append the attribute "SEQUENCENUM"
  547. bstrName = L"SEQUENCENUM";
  548. varValue = (long) nSeqNum;
  549. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  550. ONFAILTHROWERROR(hr);
  551. // Append the attribute "ISSUEDFROM"
  552. bstrName = L"ISSUEDFROM";
  553. varValue = (WCHAR*)bstrNode;
  554. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  555. ONFAILTHROWERROR(hr);
  556. // Append the attribute "STARTTIME"
  557. bstrName = L"STARTTIME";
  558. varValue = (WCHAR*) bstrStart;
  559. hr = AppendAttribute(pINode, bstrName, varValue, rParsedInfo);
  560. ONFAILTHROWERROR(hr);
  561. // Create a document fragment and associate the new node with it.
  562. hr = m_pIXMLDoc->createDocumentFragment(&pIFrag);
  563. if (m_bTrace || m_eloErrLogOpt)
  564. {
  565. chsMsg.Format(L"IXMLDOMDocument2::createDocumentFragment(-)");
  566. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  567. dwThreadId, rParsedInfo, m_bTrace);
  568. }
  569. ONFAILTHROWERROR(hr);
  570. hr = pIFrag->appendChild(pINode, NULL);
  571. if (m_bTrace || m_eloErrLogOpt)
  572. {
  573. chsMsg.Format(L"IXMLDOMDocumentFragment::appendChild(-, NULL)");
  574. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  575. dwThreadId, rParsedInfo, m_bTrace);
  576. }
  577. ONFAILTHROWERROR(hr);
  578. // Append the REQUEST node together with the input command.
  579. bstrName = _T("REQUEST");
  580. hr = CreateNodeAndSetContent(&pISNode, varType,
  581. bstrName, NULL, rParsedInfo);
  582. ONFAILTHROWERROR(hr);
  583. hr = pINode->appendChild(pISNode, &pITNode);
  584. if (m_bTrace || m_eloErrLogOpt)
  585. {
  586. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  587. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  588. dwThreadId, rParsedInfo, m_bTrace);
  589. }
  590. ONFAILTHROWERROR(hr);
  591. SAFEIRELEASE(pISNode);
  592. bstrName = _T("COMMANDLINE");
  593. hr = CreateNodeAndSetContent(&pISNode, varType,
  594. bstrName, bstrInput, rParsedInfo);
  595. ONFAILTHROWERROR(hr);
  596. hr = pITNode->appendChild(pISNode, NULL);
  597. if (m_bTrace || m_eloErrLogOpt)
  598. {
  599. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  600. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  601. dwThreadId, rParsedInfo, m_bTrace);
  602. }
  603. ONFAILTHROWERROR(hr);
  604. SAFEIRELEASE(pISNode);
  605. SAFEIRELEASE(pITNode);
  606. hr = FrameOutputNode(&pINode, bstrOutput, bstrTarget, rParsedInfo);
  607. // Get the document element of the XML log file
  608. hr = m_pIXMLDoc->get_documentElement(&pIElement);
  609. if (m_bTrace || m_eloErrLogOpt)
  610. {
  611. chsMsg.Format(L"IXMLDOMDocument2::get_documentElement(-, NULL)");
  612. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  613. dwThreadId, rParsedInfo, m_bTrace);
  614. }
  615. ONFAILTHROWERROR(hr);
  616. // Append the newly create fragment to the document element
  617. hr = pIElement->appendChild(pIFrag, NULL);
  618. if (m_bTrace || m_eloErrLogOpt)
  619. {
  620. chsMsg.Format(L"IXMLDOMElement::appendChild(-, NULL)");
  621. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  622. dwThreadId, rParsedInfo, m_bTrace);
  623. }
  624. ONFAILTHROWERROR(hr);
  625. SAFEIRELEASE(pINode);
  626. SAFEIRELEASE(pIFrag);
  627. SAFEIRELEASE(pIElement);
  628. }
  629. catch(_com_error& e)
  630. {
  631. SAFEIRELEASE(pISNode);
  632. SAFEIRELEASE(pITNode);
  633. SAFEIRELEASE(pINode);
  634. SAFEIRELEASE(pIFrag);
  635. SAFEIRELEASE(pIElement);
  636. hr = e.Error();
  637. }
  638. catch(CHeap_Exception)
  639. {
  640. SAFEIRELEASE(pISNode);
  641. SAFEIRELEASE(pITNode);
  642. SAFEIRELEASE(pINode);
  643. SAFEIRELEASE(pIFrag);
  644. SAFEIRELEASE(pIElement);
  645. hr = WBEM_E_OUT_OF_MEMORY;
  646. }
  647. return hr;
  648. }
  649. /*------------------------------------------------------------------------
  650. Name :FrameOutputNode
  651. Synopsis :Frames a new output node
  652. Type :Member Function
  653. Input parameter :
  654. pINode - pointer to pointer to IXMLDOMNode object
  655. bstrOutput - commandline output
  656. bstrTarget - target node
  657. rParsedInfo - reference to CParsedInfo object
  658. Output parameters :
  659. pINode - pointer to pointer to IXMLDOMNode object
  660. Return Type :HRESULT
  661. Global Variables :None
  662. Calling Syntax :FrameOutputNode(&pINode, bstrOutput, bstrTarget,
  663. rParsedInfo)
  664. Notes :None
  665. ------------------------------------------------------------------------*/
  666. HRESULT CWMICliXMLLog::FrameOutputNode(IXMLDOMNode **pINode, BSTR bstrOutput,
  667. BSTR bstrTarget,
  668. CParsedInfo& rParsedInfo)
  669. {
  670. HRESULT hr = S_OK;
  671. IXMLDOMNode *pISNode = NULL;
  672. IXMLDOMCDATASection *pICDATASec = NULL;
  673. _bstr_t bstrName;
  674. _variant_t varType,
  675. varValue;
  676. DWORD dwThreadId = GetCurrentThreadId();
  677. CHString chsMsg;
  678. try
  679. {
  680. // The nodetype is NODE_ELEMENT
  681. varType = ((short)NODE_ELEMENT);
  682. // Append the OUTPUT node together with the output generated.
  683. bstrName = _T("OUTPUT");
  684. hr = CreateNodeAndSetContent(&pISNode, varType,
  685. bstrName, NULL, rParsedInfo);
  686. ONFAILTHROWERROR(hr);
  687. // Append the attribute "TARGETNODE"
  688. bstrName = L"TARGETNODE";
  689. varValue = (WCHAR*) bstrTarget;
  690. hr = AppendAttribute(pISNode, bstrName, varValue, rParsedInfo);
  691. ONFAILTHROWERROR(hr);
  692. // Append the attribute "ITERATION"
  693. bstrName = L"ITERATION";
  694. varValue = (long)m_nItrNum;
  695. hr = AppendAttribute(pISNode, bstrName, varValue, rParsedInfo);
  696. ONFAILTHROWERROR(hr);
  697. // Create the CDATASection
  698. hr = m_pIXMLDoc->createCDATASection(bstrOutput, &pICDATASec);
  699. if (m_bTrace || m_eloErrLogOpt)
  700. {
  701. chsMsg.Format(L"IXMLDOMDocument2::createCDATASection(-, -)");
  702. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  703. dwThreadId, rParsedInfo, m_bTrace);
  704. }
  705. ONFAILTHROWERROR(hr);
  706. // Append the CDATASection node to the OUTPUT node.
  707. hr = pISNode->appendChild(pICDATASec, NULL);
  708. if (m_bTrace || m_eloErrLogOpt)
  709. {
  710. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  711. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  712. dwThreadId, rParsedInfo, m_bTrace);
  713. }
  714. ONFAILTHROWERROR(hr);
  715. SAFEIRELEASE(pICDATASec);
  716. hr = (*pINode)->appendChild(pISNode, NULL);
  717. if (m_bTrace || m_eloErrLogOpt)
  718. {
  719. chsMsg.Format(L"IXMLDOMNode::appendChild(-, NULL)");
  720. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  721. dwThreadId, rParsedInfo, m_bTrace);
  722. }
  723. ONFAILTHROWERROR(hr);
  724. SAFEIRELEASE(pISNode);
  725. }
  726. catch(_com_error& e)
  727. {
  728. SAFEIRELEASE(pICDATASec);
  729. SAFEIRELEASE(pISNode);
  730. hr = e.Error();
  731. }
  732. catch(CHeap_Exception)
  733. {
  734. SAFEIRELEASE(pICDATASec);
  735. SAFEIRELEASE(pISNode);
  736. hr = WBEM_E_OUT_OF_MEMORY;
  737. }
  738. return hr;
  739. }
  740. /*------------------------------------------------------------------------
  741. Name :AppendOutputNode
  742. Synopsis :appends the newoutput node element to the exisitng
  743. and that too last RECORD node
  744. Type :Member Function
  745. Input parameter :
  746. bstrOutput - commandline output
  747. bstrTarget - target node
  748. rParsedInfo - reference to CParsedInfo object
  749. Output parameters : None
  750. Return Type :HRESULT
  751. Global Variables :None
  752. Calling Syntax :AppendOutputNode(bstrOutput, bstrTarget,
  753. rParsedInfo)
  754. Notes :None
  755. ------------------------------------------------------------------------*/
  756. HRESULT CWMICliXMLLog::AppendOutputNode(BSTR bstrOutput, BSTR bstrTarget,
  757. CParsedInfo& rParsedInfo)
  758. {
  759. IXMLDOMNodeList *pINodeList = NULL;
  760. HRESULT hr = S_OK;
  761. LONG lValue = 0;
  762. IXMLDOMNode *pINode = NULL;
  763. IXMLDOMNode *pIParent = NULL,
  764. *pIClone = NULL;
  765. DWORD dwThreadId = GetCurrentThreadId();
  766. CHString chsMsg;
  767. try
  768. {
  769. hr = m_pIXMLDoc->getElementsByTagName(_T("RECORD"), &pINodeList);
  770. if (m_bTrace || m_eloErrLogOpt)
  771. {
  772. chsMsg.Format(L"IXMLDOMDocument2::getElementsByTagName(L\"RECORD\", -)");
  773. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  774. dwThreadId, rParsedInfo, m_bTrace);
  775. }
  776. ONFAILTHROWERROR(hr);
  777. hr = pINodeList->get_length(&lValue);
  778. ONFAILTHROWERROR(hr);
  779. hr = pINodeList->get_item(lValue-1, &pINode);
  780. if (m_bTrace || m_eloErrLogOpt)
  781. {
  782. chsMsg.Format(L"IXMLDOMNodeList::get_item(%d, -)", lValue-1);
  783. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  784. dwThreadId, rParsedInfo, m_bTrace);
  785. }
  786. ONFAILTHROWERROR(hr);
  787. if (pINode)
  788. {
  789. hr = pINode->cloneNode(VARIANT_TRUE, &pIClone);
  790. if (m_bTrace || m_eloErrLogOpt)
  791. {
  792. chsMsg.Format(L"IXMLDOMNode::cloneNode(VARIANT_TRUE, -)");
  793. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  794. dwThreadId, rParsedInfo, m_bTrace);
  795. }
  796. ONFAILTHROWERROR(hr);
  797. hr = pINode->get_parentNode(&pIParent);
  798. if (m_bTrace || m_eloErrLogOpt)
  799. {
  800. chsMsg.Format(L"IXMLDOMNode::get_ParentNode(-)");
  801. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  802. dwThreadId, rParsedInfo, m_bTrace);
  803. }
  804. ONFAILTHROWERROR(hr);
  805. hr = FrameOutputNode(&pIClone, bstrOutput, bstrTarget, rParsedInfo);
  806. ONFAILTHROWERROR(hr);
  807. hr = pIParent->replaceChild(pIClone, pINode, NULL);
  808. if (m_bTrace || m_eloErrLogOpt)
  809. {
  810. chsMsg.Format(L"IXMLDOMNode::replaceChild(-, -, NULL)");
  811. WMITRACEORERRORLOG(hr, __LINE__, __FILE__, (LPCWSTR)chsMsg,
  812. dwThreadId, rParsedInfo, m_bTrace);
  813. }
  814. ONFAILTHROWERROR(hr);
  815. }
  816. SAFEIRELEASE(pINodeList);
  817. SAFEIRELEASE(pIClone);
  818. SAFEIRELEASE(pIParent);
  819. SAFEIRELEASE(pINode);
  820. }
  821. catch(_com_error& e)
  822. {
  823. SAFEIRELEASE(pINodeList);
  824. SAFEIRELEASE(pIClone);
  825. SAFEIRELEASE(pIParent);
  826. SAFEIRELEASE(pINode);
  827. hr = e.Error();
  828. }
  829. catch(CHeap_Exception)
  830. {
  831. SAFEIRELEASE(pINodeList);
  832. SAFEIRELEASE(pIClone);
  833. SAFEIRELEASE(pIParent);
  834. SAFEIRELEASE(pINode);
  835. hr = WBEM_E_OUT_OF_MEMORY;
  836. }
  837. return hr;
  838. }
  839. /*----------------------------------------------------------------------------
  840. Name :FindAndDeleteRecord
  841. Synopsis :Search and deletes all the occurences of /RECORD entries
  842. in the given string strString
  843. Type :Member Function
  844. Input parameter :
  845. strString - string buffer
  846. Output parameters :None
  847. Return Type :void
  848. Global Variables :g_wmiCmd
  849. Calling Syntax :FindAndDeleteRecord(strString)
  850. Notes :None
  851. ----------------------------------------------------------------------------*/
  852. void CWMICliXMLLog::FindAndDeleteRecord(STRING& strString)
  853. {
  854. CHARVECTOR cvTokens = g_wmiCmd.GetTokenVector();
  855. //the iterator to span throuh the vector variable
  856. CHARVECTOR::iterator theIterator;
  857. // Check for the presence of tokens. Absence of tokens indicates
  858. // no command string is fed as input.
  859. if (cvTokens.size())
  860. {
  861. // Obtain the pointer to the beginning of the token vector.
  862. theIterator = cvTokens.begin();
  863. // If first token is forward slash then check for /RECORD entry
  864. if (CompareTokens(*theIterator, CLI_TOKEN_FSLASH))
  865. {
  866. DeleteRecord(strString, cvTokens, theIterator);
  867. }
  868. while (GetNextToken(cvTokens, theIterator))
  869. {
  870. // If token is forward slash then check for /RECORD entry
  871. // and delete it
  872. if (CompareTokens(*theIterator, CLI_TOKEN_FSLASH))
  873. {
  874. DeleteRecord(strString, cvTokens, theIterator);
  875. }
  876. }
  877. }
  878. }
  879. /*----------------------------------------------------------------------------
  880. Name :DeleteRecord
  881. Synopsis :Search and deletes the /RECORD entry at current position
  882. in the given string strString
  883. Type :Member Function
  884. Input parameter :
  885. strString - string buffer
  886. cvTokens - the tokens vector
  887. theIterator - the Iterator to the cvTokens vector.
  888. Output parameters :None
  889. Return Type :void
  890. Global Variables :None
  891. Calling Syntax :DeleteRecord(strString)
  892. Notes :None
  893. ----------------------------------------------------------------------------*/
  894. void CWMICliXMLLog::DeleteRecord(STRING& strString, CHARVECTOR& cvTokens,
  895. CHARVECTOR::iterator& theIterator)
  896. {
  897. if (GetNextToken(cvTokens, theIterator))
  898. {
  899. // if current token is RECORD the delete the complete entry
  900. if (CompareTokens(*theIterator, CLI_TOKEN_RECORD))
  901. {
  902. _TCHAR* pszFromStr = *theIterator;
  903. _TCHAR* pszToStr = _T("");
  904. STRING::size_type stFromStrLen = lstrlen(pszFromStr);
  905. STRING::size_type stToStrLen = lstrlen(pszToStr);
  906. STRING::size_type stStartPos = 0;
  907. STRING::size_type stPos = 0;
  908. stPos = strString.find(pszFromStr, stStartPos, stFromStrLen);
  909. strString.replace(stPos, stFromStrLen, pszToStr);
  910. stStartPos = stPos;
  911. // Search and delete forward slash just before RECORD
  912. pszFromStr = CLI_TOKEN_FSLASH;
  913. stFromStrLen = lstrlen(pszFromStr);
  914. stPos = strString.rfind(pszFromStr, stStartPos, stFromStrLen);
  915. strString.replace(stPos, stFromStrLen, pszToStr);
  916. stStartPos = stPos;
  917. WMICLIINT nCount = 0;
  918. // Delete the /RECORD value that is /RECORD:<record file name>
  919. while (GetNextToken(cvTokens, theIterator))
  920. {
  921. if (nCount == 0 &&
  922. !CompareTokens(*theIterator, CLI_TOKEN_COLON))
  923. {
  924. // if after /RECORD, next token is not ":" then break
  925. break;
  926. }
  927. // Delete the record file name from command line string
  928. // which will be recorded in the recorded file
  929. nCount++;
  930. pszFromStr = *theIterator;
  931. stFromStrLen = lstrlen(pszFromStr);
  932. stPos = strString.find(pszFromStr, stStartPos, stFromStrLen);
  933. strString.replace(stPos, stFromStrLen, pszToStr);
  934. stStartPos = stPos;
  935. // Delete only 2 tokens that is ":" and record file name
  936. if(nCount == 2)
  937. {
  938. // Search and delete double quotes that may be
  939. // used with record file name
  940. pszFromStr = _T("\"\"");
  941. stFromStrLen = lstrlen(pszFromStr);
  942. stStartPos--;
  943. stPos = strString.find(pszFromStr, stStartPos, stFromStrLen);
  944. if(stPos != strString.npos)
  945. strString.replace(stPos, stFromStrLen, pszToStr);
  946. break;
  947. }
  948. }
  949. }
  950. }
  951. return;
  952. }
  953. /*----------------------------------------------------------------------------
  954. Name :GetNextToken
  955. Synopsis :This function retrieves the next token from the token
  956. vector list, returns FALSE if no more tokens are present
  957. Type :Member Function
  958. Input Parameter(s):
  959. cvTokens - the tokens vector
  960. theIterator - the Iterator to the cvTokens vector.
  961. Output Parameter(s):None
  962. Return Type :BOOL
  963. Global Variables :None
  964. Calling Syntax :GetNextToken(cvTokens,theIterator)
  965. Notes :None
  966. ----------------------------------------------------------------------------*/
  967. BOOL CWMICliXMLLog::GetNextToken(CHARVECTOR& cvTokens,
  968. CHARVECTOR::iterator& theIterator)
  969. {
  970. theIterator++;
  971. return (theIterator >= cvTokens.end()) ? FALSE : TRUE;
  972. }