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.

1013 lines
30 KiB

  1. // AppParse.cpp : Implementation of CAppParse
  2. #include "stdafx.h"
  3. #include "AppParseWeb.h"
  4. #include "AppParseWrapper.h"
  5. #include "AppParse.h"
  6. #include <oledb.h>
  7. #include <shlobj.h>
  8. #include <comdef.h>
  9. #include <rpcdce.h>
  10. #include <msxml.h>
  11. #include <icrsint.h>
  12. #include <assert.h>
  13. #include "filebrowser.h"
  14. // Progress dialog functions
  15. void InitProgressDialog(char* szText, HANDLE hEvent);
  16. void KillProgressDialog();
  17. // Save time by creating only seven ADO objects, and sharing, when parsing information
  18. // into the database.
  19. struct SADOInfo
  20. {
  21. _ConnectionPtr pConn;
  22. IADORecordBinding* prbProjects;
  23. IADORecordBinding* prbModules;
  24. IADORecordBinding* prbFuncs;
  25. SProjectRecord pr;
  26. SModuleRecord mr;
  27. SFunctionRecord fr;
  28. };
  29. // Display an error message, then throw a COM error
  30. void APError(char* szMessage, HRESULT hr)
  31. {
  32. ::MessageBox(0, szMessage, "AppParse Error", MB_OK | MB_ICONERROR);
  33. _com_issue_error(hr);
  34. }
  35. // Get text subordinate to another node (e.g., <SIZE>0xabcdefg</SIZE>)
  36. bool GetChildText(IXMLDOMNode* pXMLNode, variant_t* pVtVal)
  37. {
  38. HRESULT hr;
  39. IXMLDOMNode* pXMLTextNode = 0;
  40. // Try to get first child node, return FALSE if not present
  41. hr = pXMLNode->get_firstChild(&pXMLTextNode);
  42. if(FAILED(hr))
  43. APError("Unable to parse XML output", hr);
  44. if(!pXMLTextNode)
  45. return false;
  46. // Check if it is a text node.
  47. DOMNodeType domNodeType;
  48. hr = pXMLTextNode->get_nodeType(&domNodeType);
  49. if(FAILED(hr))
  50. APError("Unable to parse XML output", hr);
  51. // If so, copy text into variant, otherwise return
  52. if(domNodeType == NODE_TEXT)
  53. {
  54. hr = pXMLTextNode->get_nodeValue(pVtVal);
  55. if(FAILED(hr))
  56. APError("Unable to parse XML output", hr);
  57. SafeRelease(pXMLTextNode);
  58. return true;
  59. }
  60. else
  61. {
  62. SafeRelease(pXMLTextNode);
  63. return false;
  64. }
  65. SafeRelease(pXMLTextNode);
  66. }
  67. // Convert a Month/Day/Year date into a DB-friendly date.
  68. // A DB Friendly date is a double, indicating number of days since
  69. // 1899 in the whole part, time in the fractional. We disregard time.
  70. double DateToDBDate(int month, int day, int year)
  71. {
  72. // Check that the date is even valid.
  73. assert (month > 0 && month < 13);
  74. assert(day > 0 && day < 32);
  75. assert(year > 1899);
  76. // Quick lookup for number of days in each month.
  77. int DaysInMonth[] = {-1, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  78. double dbDate = 0;
  79. // Get full years
  80. dbDate = (year - 1899 - 1) * 365;
  81. // Adjust for leap years
  82. dbDate += ((year-1899-1)/4);
  83. dbDate -= ((year-1899-1)/100);
  84. dbDate += ((year-1899-1)/400);
  85. // Add days for each month.
  86. for(int i = 1; i < month; i++)
  87. dbDate += DaysInMonth[i];
  88. // Add the day of month to total.
  89. dbDate += day;
  90. return dbDate;
  91. }
  92. // Get file information for the image from an <INFO> node.
  93. void GetImageInfo(IXMLDOMNode* pXMLInfoNode, SImageFileInfo* pInfo)
  94. {
  95. HRESULT hr;
  96. IXMLDOMNode* pXMLAttrChild = 0;
  97. IXMLDOMNodeList* pXMLChildList = 0;
  98. IXMLDOMNode* pXMLTextNode = 0;
  99. // Get list of child nodes and move to first.
  100. hr = pXMLInfoNode->get_childNodes(&pXMLChildList);
  101. if(FAILED(hr))
  102. APError("Unable to parse XML output", hr);
  103. hr = pXMLChildList->nextNode(&pXMLAttrChild);
  104. if(FAILED(hr))
  105. APError("Unable to parse XML output", hr);
  106. // As long as there is a child node
  107. while(pXMLAttrChild)
  108. {
  109. // Get thename of the node
  110. BSTR bstrName;
  111. hr = pXMLAttrChild->get_nodeName(&bstrName);
  112. if(FAILED(hr))
  113. APError("Unable to parse XML output", hr);
  114. bstr_t bsz(bstrName, false);
  115. // Extract info based on node type
  116. if(stricmp(bsz, "DATE")==0)
  117. {
  118. variant_t vtVal;
  119. if(GetChildText(pXMLAttrChild, &vtVal))
  120. {
  121. int month, day, year;
  122. sscanf(static_cast<bstr_t>(vtVal), "%d/%d/%d", &month,
  123. &day, &year);
  124. pInfo->Date = DateToDBDate(month, day, year);
  125. pInfo->DateStatus = adFldOK;
  126. }
  127. }
  128. else if(stricmp(bsz, "SIZE")==0)
  129. {
  130. variant_t vtVal;
  131. if(GetChildText(pXMLAttrChild, &vtVal))
  132. {
  133. sscanf(static_cast<bstr_t>(vtVal), "%x", &pInfo->Size);
  134. pInfo->SizeStatus = adFldOK;
  135. }
  136. }
  137. else if(stricmp(bsz, "BIN_FILE_VERSION")==0)
  138. {
  139. variant_t vtVal;
  140. if(GetChildText(pXMLAttrChild, &vtVal))
  141. {
  142. strncpy(pInfo->BinFileVersion, static_cast<bstr_t>(vtVal),50);
  143. pInfo->BinFileVersion[49] = '\0';
  144. pInfo->BinFileVersionStatus = adFldOK;
  145. }
  146. }
  147. else if(stricmp(bsz, "BIN_PRODUCT_VERSION")==0)
  148. {
  149. variant_t vtVal;
  150. if(GetChildText(pXMLAttrChild, &vtVal))
  151. {
  152. strncpy(pInfo->BinProductVersion, static_cast<bstr_t>(vtVal),50);
  153. pInfo->BinProductVersion[49] = '\0';
  154. pInfo->BinProductVersionStatus = adFldOK;
  155. }
  156. }
  157. else if(stricmp(bsz, "CHECKSUM")==0)
  158. {
  159. variant_t vtVal;
  160. if(GetChildText(pXMLAttrChild, &vtVal))
  161. {
  162. sscanf(static_cast<bstr_t>(vtVal), "%x", &pInfo->CheckSum);
  163. pInfo->CheckSumStatus = adFldOK;
  164. }
  165. }
  166. else if(stricmp(bsz, "COMPANY_NAME")==0)
  167. {
  168. variant_t vtVal;
  169. if(GetChildText(pXMLAttrChild, &vtVal))
  170. {
  171. strncpy(pInfo->CompanyName, static_cast<bstr_t>(vtVal),255);
  172. pInfo->CompanyName[254] = '\0';
  173. pInfo->CompanyNameStatus = adFldOK;
  174. }
  175. }
  176. else if(stricmp(bsz, "PRODUCT_VERSION")==0)
  177. {
  178. variant_t vtVal;
  179. if(GetChildText(pXMLAttrChild, &vtVal))
  180. {
  181. strncpy(pInfo->ProductVersion, static_cast<bstr_t>(vtVal),50);
  182. pInfo->ProductVersion[49];
  183. pInfo->ProductVersionStatus = adFldOK;
  184. }
  185. }
  186. else if(stricmp(bsz, "PRODUCT_NAME")==0)
  187. {
  188. variant_t vtVal;
  189. if(GetChildText(pXMLAttrChild, &vtVal))
  190. {
  191. strncpy(pInfo->ProductName, static_cast<bstr_t>(vtVal),255);
  192. pInfo->ProductName[254] = '\0';
  193. pInfo->ProductNameStatus = adFldOK;
  194. }
  195. }
  196. else if(stricmp(bsz, "FILE_DESCRIPTION")==0)
  197. {
  198. variant_t vtVal;
  199. if(GetChildText(pXMLAttrChild, &vtVal))
  200. {
  201. strncpy(pInfo->FileDesc, static_cast<bstr_t>(vtVal),255);
  202. pInfo->FileDesc[254] = '\0';
  203. pInfo->FileDescStatus = adFldOK;
  204. }
  205. }
  206. SafeRelease(pXMLAttrChild);
  207. // Move to next node
  208. hr = pXMLChildList->nextNode(&pXMLAttrChild);
  209. if(FAILED(hr))
  210. APError("Unable to parse XML output", hr);
  211. }
  212. SafeRelease(pXMLChildList);
  213. SafeRelease(pXMLAttrChild);
  214. SafeRelease(pXMLTextNode);
  215. }
  216. // Get all info related to a function from XML
  217. void GetFunctionInfo(IXMLDOMNode* pXMLFunctionNode, ULONG lModuleID, SADOInfo* pADOInfo)
  218. {
  219. HRESULT hr;
  220. IXMLDOMNamedNodeMap* pXMLAttrList= 0;
  221. IXMLDOMNode* pXMLAttrNode = 0;
  222. // Start with no members valid.
  223. pADOInfo->fr.AddressStatus = pADOInfo->fr.HintStatus =
  224. pADOInfo->fr.OrdinalStatus = pADOInfo->fr.ForwardNameStatus = adFldNull;
  225. // Get parent ID
  226. pADOInfo->fr.ModuleID = lModuleID;
  227. // Get all attribute nodes
  228. hr = pXMLFunctionNode->get_attributes(&pXMLAttrList);
  229. if(FAILED(hr) || !pXMLAttrList)
  230. APError("Unable to parse XML output", hr);
  231. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  232. if(FAILED(hr) || !pXMLAttrNode)
  233. APError("Unable to parse XML output", hr);
  234. // Loop through the list.
  235. while(pXMLAttrNode)
  236. {
  237. BSTR bszName;
  238. variant_t vtVal;
  239. // Get attribute name and value.
  240. hr = pXMLAttrNode->get_nodeName(&bszName);
  241. if(FAILED(hr))
  242. APError("Unable to parse XML output", hr);
  243. hr = pXMLAttrNode->get_nodeValue(&vtVal);
  244. if(FAILED(hr))
  245. APError("Unable to parse XML output", hr);
  246. bstr_t bsz(bszName, false);
  247. bstr_t bszVal = vtVal;
  248. // Copy info into struct
  249. if(stricmp(static_cast<PSTR>(bsz), "NAME")==0)
  250. {
  251. strncpy(pADOInfo->fr.Name, static_cast<PSTR>(bszVal), 255);
  252. }
  253. else if(stricmp(static_cast<PSTR>(bsz), "HINT")== 0)
  254. {
  255. pADOInfo->fr.HintStatus = adFldOK;
  256. pADOInfo->fr.Hint = atoi(bszVal);
  257. }
  258. else if (stricmp(static_cast<PSTR>(bsz), "ORDINAL") == 0)
  259. {
  260. pADOInfo->fr.OrdinalStatus = adFldOK;
  261. pADOInfo->fr.Ordinal = atoi(bszVal);
  262. }
  263. else if(stricmp(static_cast<PSTR>(bsz), "ADDRESS") == 0)
  264. {
  265. pADOInfo->fr.AddressStatus = adFldOK;
  266. pADOInfo->fr.Address = atoi(bszVal);
  267. }
  268. else if(stricmp(static_cast<PSTR>(bsz), "FORWARD_TO")==0)
  269. {
  270. pADOInfo->fr.ForwardNameStatus = adFldOK;
  271. strncpy(pADOInfo->fr.ForwardName, bszVal, 255);
  272. }
  273. else if(stricmp(static_cast<PSTR>(bsz), "DELAYED") == 0)
  274. {
  275. pADOInfo->fr.Delayed = (stricmp(bszVal, "true")==0);
  276. }
  277. SafeRelease(pXMLAttrNode);
  278. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  279. if(FAILED(hr))
  280. APError("Unable to parse XML output", hr);
  281. }
  282. // Add a new record to the database.
  283. hr = pADOInfo->prbFuncs->AddNew(&pADOInfo->fr);
  284. if(FAILED(hr))
  285. APError("Unable to add new function record to database", hr);
  286. SafeRelease(pXMLAttrList);
  287. SafeRelease(pXMLAttrNode);
  288. }
  289. // Get all info related to a module.
  290. void GetModuleInfo(IXMLDOMNode* pXMLModuleNode, ULONG lParentID, SADOInfo* pADOInfo,
  291. HANDLE hEvent, bool fTopLevel = false)
  292. {
  293. if(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
  294. return;
  295. HRESULT hr;
  296. IXMLDOMNode* pXMLChildNode = 0;
  297. IXMLDOMNodeList* pXMLNodeList = 0;
  298. IXMLDOMNamedNodeMap* pXMLAttrList= 0;
  299. IXMLDOMNode* pXMLAttrNode = 0;
  300. // All members are initially invalid.
  301. pADOInfo->mr.info.BinFileVersionStatus =
  302. pADOInfo->mr.info.BinProductVersionStatus =
  303. pADOInfo->mr.info.CheckSumStatus =
  304. pADOInfo->mr.info.CompanyNameStatus =
  305. pADOInfo->mr.info.DateStatus =
  306. pADOInfo->mr.info.FileDescStatus =
  307. pADOInfo->mr.info.ProductNameStatus =
  308. pADOInfo->mr.info.ProductVersionStatus =
  309. pADOInfo->mr.info.SizeStatus =
  310. pADOInfo->mr.ParentIDStatus =
  311. pADOInfo->mr.PtolemyIDStatus = adFldNull;
  312. // Copy parent ID
  313. pADOInfo->mr.ParentID = lParentID;
  314. // Check appropriate parent.
  315. if(fTopLevel)
  316. pADOInfo->mr.PtolemyIDStatus = adFldOK;
  317. else
  318. pADOInfo->mr.ParentIDStatus = adFldOK;
  319. // Get attributes
  320. hr = pXMLModuleNode->get_attributes(&pXMLAttrList);
  321. if(FAILED(hr) || !pXMLAttrList)
  322. APError("Unable to parse XML output", hr);
  323. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  324. if(FAILED(hr) || !pXMLAttrNode)
  325. APError("Unable to parse XML output", hr);
  326. // Loop through attribute list.
  327. while(pXMLAttrNode)
  328. {
  329. BSTR bszName;
  330. variant_t vtVal;
  331. // Get attribute name and value.
  332. hr = pXMLAttrNode->get_nodeName(&bszName);
  333. if(FAILED(hr))
  334. APError("Unable to parse XML output", hr);
  335. hr = pXMLAttrNode->get_nodeValue(&vtVal);
  336. if(FAILED(hr))
  337. APError("Unable to parse XML output", hr);
  338. bstr_t bsz(bszName, false);
  339. if(stricmp(static_cast<PSTR>(bsz), "NAME")==0)
  340. {
  341. bstr_t bszTemp = vtVal;
  342. strncpy(pADOInfo->mr.Name, static_cast<PSTR>(bszTemp), 100);
  343. }
  344. SafeRelease(pXMLAttrNode);
  345. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  346. if(FAILED(hr))
  347. APError("Unable to parse XML output", hr);
  348. }
  349. // Get info block, if present, for this module.
  350. hr = pXMLModuleNode->get_childNodes(&pXMLNodeList);
  351. if(FAILED(hr))
  352. APError("Unable to parse XML output", hr);
  353. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  354. if(FAILED(hr))
  355. APError("Unable to parse XML output", hr);
  356. while(pXMLChildNode)
  357. {
  358. DOMNodeType domNodeType;
  359. hr = pXMLChildNode->get_nodeType(&domNodeType);
  360. if(FAILED(hr))
  361. APError("Unable to parse XML output", hr);
  362. if(domNodeType == NODE_ELEMENT)
  363. {
  364. BSTR bstr;
  365. hr = pXMLChildNode->get_nodeName(&bstr);
  366. if(FAILED(hr))
  367. APError("Unable to parse XML output", hr);
  368. bstr_t bszName(bstr, false);
  369. // If info node, get info block.
  370. if(stricmp(bszName, "Info") == 0)
  371. GetImageInfo(pXMLChildNode, &pADOInfo->mr.info);
  372. // Otherwise, if a systemmodule node, get systemmodule state.
  373. else if(stricmp(bszName, "SYSTEMMODULE")==0)
  374. {
  375. hr = pXMLChildNode->get_attributes(&pXMLAttrList);
  376. if(FAILED(hr) || !pXMLAttrList)
  377. APError("Unable to parse XML output", hr);
  378. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  379. if(FAILED(hr) || !pXMLAttrNode)
  380. APError("Unable to parse XML output", hr);
  381. while(pXMLAttrNode)
  382. {
  383. BSTR bszAttrName;
  384. variant_t vtVal;
  385. hr = pXMLAttrNode->get_nodeName(&bszAttrName);
  386. if(FAILED(hr))
  387. APError("Unable to parse XML output", hr);
  388. hr = pXMLAttrNode->get_nodeValue(&vtVal);
  389. if(FAILED(hr))
  390. APError("Unable to parse XML output", hr);
  391. bstr_t bsz(bszAttrName, false);
  392. if(stricmp(static_cast<PSTR>(bsz), "VALUE")==0)
  393. {
  394. bstr_t bszTemp = vtVal;
  395. pADOInfo->mr.SysMod = atoi(bszTemp);
  396. }
  397. SafeRelease(pXMLAttrNode);
  398. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  399. if(FAILED(hr))
  400. APError("Unable to parse XML output", hr);
  401. }
  402. }
  403. }
  404. SafeRelease(pXMLChildNode);
  405. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  406. if(FAILED(hr))
  407. APError("Unable to parse XML output", hr);
  408. }
  409. // Add a new module record to the database
  410. hr = pADOInfo->prbModules->AddNew(&pADOInfo->mr);
  411. if(FAILED(hr))
  412. APError("Unable to new module record to database", hr);
  413. ULONG lThisModuleID = pADOInfo->mr.ModuleID;
  414. // Get all functions's imported by this module, and DLL's
  415. hr = pXMLModuleNode->get_childNodes(&pXMLNodeList);
  416. if(FAILED(hr))
  417. APError("Unable to parse XML output", hr);
  418. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  419. if(FAILED(hr))
  420. APError("Unable to parse XML output", hr);
  421. while(pXMLChildNode)
  422. {
  423. DOMNodeType domNodeType;
  424. hr = pXMLChildNode->get_nodeType(&domNodeType);
  425. if(FAILED(hr))
  426. APError("Unable to parse XML output", hr);
  427. if(domNodeType == NODE_ELEMENT)
  428. {
  429. BSTR bstr;
  430. hr = pXMLChildNode->get_nodeName(&bstr);
  431. if(FAILED(hr))
  432. APError("Unable to parse XML output", hr);
  433. bstr_t bszName(bstr, false);
  434. if(stricmp(bszName, "Function") == 0)
  435. GetFunctionInfo(pXMLChildNode, lThisModuleID, pADOInfo);
  436. else if(stricmp(bszName, "DLL") == 0)
  437. GetModuleInfo(pXMLChildNode, lThisModuleID, pADOInfo, hEvent);
  438. }
  439. SafeRelease(pXMLChildNode);
  440. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  441. if(FAILED(hr))
  442. APError("Unable to parse XML output", hr);
  443. }
  444. SafeRelease(pXMLChildNode);
  445. SafeRelease(pXMLNodeList);
  446. SafeRelease(pXMLAttrList);
  447. SafeRelease(pXMLAttrNode);
  448. }
  449. // Get project information from XML
  450. void GetProjectInfo(IXMLDOMNode* pXMLProjectNode, SADOInfo* pADOInfo, HANDLE hEvent)
  451. {
  452. if(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
  453. return;
  454. HRESULT hr;
  455. IXMLDOMNamedNodeMap* pXMLAttrList= 0;
  456. IXMLDOMNode* pXMLAttrNode = 0;
  457. IXMLDOMNode* pXMLChildNode = 0;
  458. IXMLDOMNodeList* pXMLNodeList = 0;
  459. pADOInfo->pr.PtolemyID = -1;
  460. pADOInfo->pr.Name[0] = '\0';
  461. // Get name and ptolemy id attributes
  462. hr = pXMLProjectNode->get_attributes(&pXMLAttrList);
  463. if(FAILED(hr) || !pXMLAttrList)
  464. APError("Unable to parse XML output", hr);
  465. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  466. if(FAILED(hr) || !pXMLAttrNode)
  467. APError("Unable to parse XML output", hr);
  468. while(pXMLAttrNode)
  469. {
  470. BSTR bszName;
  471. variant_t vtVal;
  472. hr = pXMLAttrNode->get_nodeName(&bszName);
  473. if(FAILED(hr))
  474. APError("Unable to parse XML output", hr);
  475. hr = pXMLAttrNode->get_nodeValue(&vtVal);
  476. if(FAILED(hr))
  477. APError("Unable to parse XML output", hr);
  478. bstr_t bsz(bszName, false);
  479. if(stricmp(static_cast<PSTR>(bsz), "NAME")==0)
  480. {
  481. bstr_t bszTemp = vtVal;
  482. strncpy(pADOInfo->pr.Name, static_cast<PSTR>(bszTemp), 100);
  483. }
  484. else if(stricmp(static_cast<PSTR>(bsz), "ID") == 0)
  485. {
  486. bstr_t bszTemp = vtVal;
  487. pADOInfo->pr.PtolemyID = atoi(static_cast<PSTR>(bszTemp));
  488. }
  489. SafeRelease(pXMLAttrNode);
  490. hr = pXMLAttrList->nextNode(&pXMLAttrNode);
  491. if(FAILED(hr))
  492. APError("Unable to parse XML output", hr);
  493. }
  494. hr = pADOInfo->prbProjects->AddNew(&pADOInfo->pr);
  495. if(FAILED(hr))
  496. APError("Unable to add new project record to database", hr);
  497. // Parse all Exe's included in this project
  498. hr = pXMLProjectNode->get_childNodes(&pXMLNodeList);
  499. if(FAILED(hr))
  500. APError("Unable to parse XML output", hr);
  501. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  502. if(FAILED(hr))
  503. APError("Unable to parse XML output", hr);
  504. while(pXMLChildNode)
  505. {
  506. DOMNodeType domNodeType;
  507. hr = pXMLChildNode->get_nodeType(&domNodeType);
  508. if(FAILED(hr))
  509. APError("Unable to parse XML output", hr);
  510. if(domNodeType == NODE_ELEMENT)
  511. {
  512. BSTR bstr;
  513. hr = pXMLChildNode->get_nodeName(&bstr);
  514. if(FAILED(hr))
  515. APError("Unable to parse XML output", hr);
  516. bstr_t bszName(bstr, false);
  517. if(stricmp(bszName, "EXE") == 0)
  518. GetModuleInfo(pXMLChildNode, pADOInfo->pr.PtolemyID, pADOInfo, hEvent, true);
  519. }
  520. SafeRelease(pXMLChildNode);
  521. hr = pXMLNodeList->nextNode(&pXMLChildNode);
  522. if(FAILED(hr))
  523. APError("Unable to parse XML output", hr);
  524. }
  525. SafeRelease(pXMLAttrList);
  526. SafeRelease(pXMLAttrNode);
  527. SafeRelease(pXMLNodeList);
  528. SafeRelease(pXMLChildNode);
  529. }
  530. // Functions for walking an XML DOM object and storing
  531. // information to the database
  532. void ParseXMLWriteDB(const char* szXML, const char* szConnect, HANDLE hEvent)
  533. {
  534. HRESULT hr;
  535. // Get DOM object associated with Projects node
  536. IXMLDOMDocument* pXMLDoc = 0;
  537. IXMLDOMNode* pXMLRootNode = 0;
  538. IXMLDOMNode* pXMLChildNode = 0;
  539. IXMLDOMNode* pXMLProjectNode = 0;
  540. IXMLDOMNodeList* pXMLChildNodeList = 0;
  541. // Create all ADO objects needed.
  542. SADOInfo adoInfo;
  543. _ConnectionPtr pConn = 0;
  544. _RecordsetPtr pRSProjects = 0;
  545. _RecordsetPtr pRSModules = 0;
  546. _RecordsetPtr pRSFuncs = 0;
  547. pConn.CreateInstance(__uuidof(Connection));
  548. pRSProjects.CreateInstance(__uuidof(Recordset));
  549. pRSModules.CreateInstance(__uuidof(Recordset));
  550. pRSFuncs.CreateInstance(__uuidof(Recordset));
  551. hr = pRSProjects->QueryInterface(__uuidof(IADORecordBinding),
  552. reinterpret_cast<void**>(&adoInfo.prbProjects));
  553. if(FAILED(hr))
  554. APError("Unable to retrieve ADO Recordset interface", hr);
  555. hr = pRSModules->QueryInterface(__uuidof(IADORecordBinding),
  556. reinterpret_cast<void**>(&adoInfo.prbModules));
  557. if(FAILED(hr))
  558. APError("Unable to retrieve ADO Recordset interface", hr);
  559. hr = pRSFuncs->QueryInterface(__uuidof(IADORecordBinding),
  560. reinterpret_cast<void**>(&adoInfo.prbFuncs));
  561. if(FAILED(hr))
  562. APError("Unable to retrieve ADO Recordset interface", hr);
  563. pConn->Open(szConnect, "", "", adConnectUnspecified);
  564. pConn->BeginTrans();
  565. pRSProjects->Open("Projects", variant_t((IDispatch*)pConn, true),
  566. adOpenKeyset, adLockOptimistic, adCmdTable);
  567. pRSModules->Open("Modules", variant_t((IDispatch*)pConn, true),
  568. adOpenKeyset, adLockOptimistic, adCmdTable);
  569. pRSFuncs->Open("Functions", variant_t((IDispatch*)pConn, true),
  570. adOpenKeyset, adLockOptimistic, adCmdTable);
  571. adoInfo.pConn = pConn;
  572. adoInfo.pr.Name[0] = '\0';
  573. adoInfo.pr.PtolemyID = -1;
  574. adoInfo.mr.info.BinFileVersionStatus =
  575. adoInfo.mr.info.BinProductVersionStatus =
  576. adoInfo.mr.info.CheckSumStatus =
  577. adoInfo.mr.info.CompanyNameStatus =
  578. adoInfo.mr.info.DateStatus =
  579. adoInfo.mr.info.FileDescStatus =
  580. adoInfo.mr.info.ProductNameStatus =
  581. adoInfo.mr.info.ProductVersionStatus =
  582. adoInfo.mr.info.SizeStatus =
  583. adoInfo.mr.ParentIDStatus =
  584. adoInfo.mr.PtolemyIDStatus =
  585. adoInfo.fr.AddressStatus =
  586. adoInfo.fr.HintStatus =
  587. adoInfo.fr.OrdinalStatus =
  588. adoInfo.fr.ForwardNameStatus = adFldNull;
  589. hr = adoInfo.prbProjects->BindToRecordset(&adoInfo.pr);
  590. if(FAILED(hr))
  591. APError("Unable to bind ADO recordset", hr);
  592. hr = adoInfo.prbModules->BindToRecordset(&adoInfo.mr);
  593. if(FAILED(hr))
  594. APError("Unable to bind ADO recordset", hr);
  595. hr = adoInfo.prbFuncs->BindToRecordset(&adoInfo.fr);
  596. if(FAILED(hr))
  597. APError("Unable to bind ADO recordset", hr);
  598. hr = CoCreateInstance(CLSID_DOMDocument, 0, CLSCTX_INPROC_SERVER,
  599. IID_IXMLDOMDocument, reinterpret_cast<void**>(&pXMLDoc));
  600. if(FAILED(hr))
  601. APError("Unable to create IE XML DOM object", hr);
  602. VARIANT_BOOL fSuccess;
  603. hr = pXMLDoc->load(variant_t(szXML), &fSuccess);
  604. if(FAILED(hr) || fSuccess == VARIANT_FALSE)
  605. APError("Unable to load XML output", hr);
  606. // Walk the tree until we find the top-level project node
  607. // which is the only top-level node we care about.
  608. hr = pXMLDoc->QueryInterface(IID_IXMLDOMNode,
  609. reinterpret_cast<void**>(&pXMLRootNode));
  610. if(FAILED(hr))
  611. APError("Unable to retrieve IE XML interface", hr);
  612. hr = pXMLRootNode->get_childNodes(&pXMLChildNodeList);
  613. if(FAILED(hr))
  614. APError("Unable to parse XML output", hr);
  615. hr = pXMLChildNodeList->nextNode(&pXMLChildNode);
  616. if(FAILED(hr))
  617. APError("Unable to parse XML output", hr);
  618. while(pXMLChildNode)
  619. {
  620. // Check if this is the projects node.
  621. DOMNodeType domNodeType;
  622. hr = pXMLChildNode->get_nodeType(&domNodeType);
  623. if(FAILED(hr))
  624. APError("Unable to parse XML output", hr);
  625. if(domNodeType == NODE_ELEMENT)
  626. {
  627. BSTR bszName;
  628. hr = pXMLChildNode->get_nodeName(&bszName);
  629. if(FAILED(hr))
  630. APError("Unable to parse XML output", hr);
  631. _bstr_t bsz(bszName, false);
  632. if(stricmp(static_cast<PSTR>(bsz), "AppParseResults")==0)
  633. {
  634. break;
  635. }
  636. }
  637. SafeRelease(pXMLChildNode);
  638. hr = pXMLChildNodeList->nextNode(&pXMLChildNode);
  639. if(FAILED(hr))
  640. APError("Unable to parse XML output", hr);
  641. }
  642. SafeRelease(pXMLChildNodeList);
  643. // No child node, record not found.
  644. if(!pXMLChildNode)
  645. APError("Unable to parse XML output", hr);
  646. // Locate project node in that.
  647. hr = pXMLChildNode->get_childNodes(&pXMLChildNodeList);
  648. if(FAILED(hr))
  649. APError("Unable to parse XML output", hr);
  650. hr = pXMLChildNodeList->nextNode(&pXMLProjectNode);
  651. if(FAILED(hr))
  652. APError("Unable to parse XML output", hr);
  653. while(pXMLProjectNode)
  654. {
  655. // Check if this is the projects node.
  656. DOMNodeType domNodeType;
  657. hr = pXMLProjectNode->get_nodeType(&domNodeType);
  658. if(FAILED(hr))
  659. APError("Unable to parse XML output", hr);
  660. if(domNodeType == NODE_ELEMENT)
  661. {
  662. BSTR bszName;
  663. hr = pXMLProjectNode->get_nodeName(&bszName);
  664. if(FAILED(hr))
  665. APError("Unable to parse XML output", hr);
  666. _bstr_t bsz(bszName, false);
  667. if(stricmp(static_cast<PSTR>(bsz), "Project")==0)
  668. {
  669. GetProjectInfo(pXMLProjectNode, &adoInfo, hEvent);
  670. }
  671. }
  672. SafeRelease(pXMLProjectNode);
  673. hr = pXMLChildNodeList->nextNode(&pXMLProjectNode);
  674. if(FAILED(hr))
  675. APError("Unable to parse XML output", hr);
  676. }
  677. pRSProjects->UpdateBatch(adAffectAll);
  678. pRSModules->UpdateBatch(adAffectAll);
  679. pRSFuncs->UpdateBatch(adAffectAll);
  680. // Important, skip commit if cancel was clicked by user.
  681. if(WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0)
  682. pConn->CommitTrans();
  683. pRSProjects->Close();
  684. pRSModules->Close();
  685. pRSFuncs->Close();
  686. pConn->Close();
  687. SafeRelease(adoInfo.prbProjects);
  688. SafeRelease(adoInfo.prbModules);
  689. SafeRelease(adoInfo.prbFuncs);
  690. SafeRelease(pXMLChildNodeList);
  691. SafeRelease(pXMLChildNode);
  692. SafeRelease(pXMLRootNode);
  693. SafeRelease(pXMLDoc);
  694. }
  695. /////////////////////////////////////////////////////////////////////////////
  696. // CAppParse
  697. STDMETHODIMP CAppParse::Parse()
  698. {
  699. if(!m_szPath)
  700. {
  701. ::MessageBox(0, TEXT("Please select a path to profile"), TEXT("AppParse"),
  702. MB_OK | MB_ICONERROR);
  703. return S_OK;
  704. }
  705. if(m_ID == -1)
  706. {
  707. ::MessageBox(0, TEXT("Please enter a Ptolemy ID"), TEXT("AppParse"),
  708. MB_OK | MB_ICONERROR);
  709. return S_OK;
  710. }
  711. // Show the progress dialog (reset the event to cancel)
  712. ResetEvent(m_hEvent);
  713. InitProgressDialog("Parsing, please do not close your browser window.", m_hEvent);
  714. // Generate a unique temp file name
  715. GUID guid;
  716. unsigned char* szUUID;
  717. char szFileName[MAX_PATH];
  718. HRESULT hr = CoCreateGuid(&guid);
  719. if(FAILED(hr))
  720. return hr;
  721. UuidToString(&guid, &szUUID);
  722. GetTempPath(MAX_PATH, szFileName);
  723. strcat(szFileName, reinterpret_cast<char*>(szUUID));
  724. strcat(szFileName, ".xml");
  725. FILE* pFile = fopen(szFileName, "wb");
  726. if(!pFile)
  727. APError("Unable to open output file", E_FAIL);
  728. // Parse the application
  729. AppParse(m_szPath, pFile, false, false, true, true,
  730. "*", m_ID);
  731. fclose(pFile);
  732. RpcStringFree(&szUUID);
  733. // If user didn't cancel . . .
  734. if(WaitForSingleObject(m_hEvent, 0) != WAIT_OBJECT_0)
  735. {
  736. // Write results to DB
  737. try
  738. {
  739. ParseXMLWriteDB(szFileName, m_szConnect, m_hEvent);
  740. }
  741. catch(_com_error& e)
  742. {
  743. ::MessageBox(0, (LPCSTR)e.ErrorMessage(), "COM Error", MB_OK);
  744. }
  745. }
  746. // Terminate temp file
  747. DeleteFile(szFileName);
  748. // Remove progress dialog box.
  749. KillProgressDialog();
  750. return S_OK;
  751. }
  752. STDMETHODIMP CAppParse::Browse()
  753. {
  754. PTSTR szPath = BrowseForFolder(0, 0);
  755. if(!szPath)
  756. return S_FALSE;
  757. if(m_szPath)
  758. delete m_szPath;
  759. m_szPath = new char[strlen(szPath)+1];
  760. strcpy(m_szPath,szPath);
  761. return S_OK;
  762. }
  763. STDMETHODIMP CAppParse::get_path(BSTR *pVal)
  764. {
  765. if(m_szPath)
  766. {
  767. OLECHAR* sz;
  768. sz = new OLECHAR[strlen(m_szPath)+1];
  769. MultiByteToWideChar(CP_ACP, 0, m_szPath, -1, sz, strlen(m_szPath)+1);
  770. *pVal = SysAllocString(sz);
  771. delete sz;
  772. }
  773. else
  774. *pVal = SysAllocString(L"");
  775. return S_OK;
  776. }
  777. STDMETHODIMP CAppParse::put_path(BSTR newVal)
  778. {
  779. if(m_szPath)
  780. {
  781. delete m_szPath;
  782. m_szPath = 0;
  783. }
  784. _bstr_t bstrGhostLoc(newVal);
  785. LPSTR szGhostLoc = (LPSTR)bstrGhostLoc;
  786. m_szPath = new char[strlen(szGhostLoc)+1];
  787. strcpy(m_szPath, szGhostLoc);
  788. return S_OK;
  789. }
  790. STDMETHODIMP CAppParse::get_PtolemyID(long *pVal)
  791. {
  792. *pVal = m_ID;
  793. return S_OK;
  794. }
  795. STDMETHODIMP CAppParse::put_PtolemyID(long newVal)
  796. {
  797. m_ID = newVal;
  798. return S_OK;
  799. }
  800. STDMETHODIMP CAppParse::get_ConnectionString(BSTR *pVal)
  801. {
  802. if(m_szConnect)
  803. {
  804. OLECHAR* sz;
  805. sz = new OLECHAR[strlen(m_szConnect)+1];
  806. MultiByteToWideChar(CP_ACP, 0, m_szConnect, -1, sz, strlen(m_szConnect)+1);
  807. *pVal = SysAllocString(sz);
  808. delete sz;
  809. }
  810. else
  811. *pVal = SysAllocString(L"");
  812. return S_OK;
  813. }
  814. STDMETHODIMP CAppParse::put_ConnectionString(BSTR newVal)
  815. {
  816. if(m_szConnect)
  817. {
  818. delete m_szConnect;
  819. m_szConnect = 0;
  820. }
  821. _bstr_t bstrGhostLoc(newVal);
  822. LPSTR szGhostLoc = (LPSTR)bstrGhostLoc;
  823. m_szConnect = new char[strlen(szGhostLoc)+1];
  824. strcpy(m_szConnect, szGhostLoc);
  825. return S_OK;
  826. }