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.

4135 lines
105 KiB

  1. /*
  2. File: diagrprt.c
  3. 'ras diag' sub context
  4. 09/13/01
  5. */
  6. #include "precomp.h"
  7. static CONST WCHAR g_wchUnicodeMarker = 0xFEFF;
  8. static CONST WCHAR g_pwszNewLine[] = L"\r\n";
  9. static CONST WCHAR g_pwszHeaderSep[] =
  10. L"-------------------------------------------------------------------------------\r\n";
  11. static CONST WCHAR g_pwszCmMappings[] =
  12. L"Software\\Microsoft\\Connection Manager\\Mappings";
  13. CONST WCHAR g_pwszLBracket = L'[';
  14. CONST WCHAR g_pwszRBracket = L']';
  15. CONST WCHAR g_pwszSpace[] = L" ";
  16. CONST WCHAR g_pwszBackSlash = L'\\';
  17. CONST WCHAR g_pwszNull = L'\0';
  18. CONST WCHAR g_pwszLogSrchStr[] = L"*.LOG";
  19. CONST WCHAR g_pwszLogging[] = L"Logging";
  20. CONST WCHAR g_pwszDispNewLine[] = L"\n";
  21. CONST WCHAR g_pwszEmpty[] = L"";
  22. CONST WCHAR g_pwszNewLineHtml[] = L"<p/>";
  23. CONST WCHAR g_pwszPreStart[] = L"<pre>";
  24. CONST WCHAR g_pwszPreEnd[] = L"</pre>";
  25. CONST WCHAR g_pwszAnNameStart[] = L"<A NAME=\"";
  26. CONST WCHAR g_pwszAnNameMiddle[] = L"\"><h4> ";
  27. CONST WCHAR g_pwszAnNameEnd[] = L" </h4></A>";
  28. CONST WCHAR g_pwszAnStart[] = L" <A HREF=\"#";
  29. CONST WCHAR g_pwszAnMiddle[] = L"\">";
  30. CONST WCHAR g_pwszAnEnd[] = L"</A> ";
  31. CONST WCHAR g_pwszLiStart[] = L"<li>";
  32. CONST WCHAR g_pwszLiEnd[] = L"</li>";
  33. static CONST WCHAR g_wszQuoteHtm[] = L"&#34;";
  34. static CONST WCHAR g_wszAmpHtm[] = L"&#38;";
  35. static CONST WCHAR g_wszLeftHtm[] = L"&#60;";
  36. static CONST WCHAR g_wszRightHtm[] = L"&#62;";
  37. static CONST WCHAR g_pwszPER[] = L"PER";
  38. static CONST WCHAR g_pwszPRO[] = L"PRO";
  39. static CONST WCHAR g_pwszDTC[] = L"DTC";
  40. static CONST WCHAR g_pwszADS[] = L"ADS";
  41. static CONST WCHAR g_pwszSRV[] = L"SRV";
  42. static CONST WCHAR g_pwszx86[] = L"x86";
  43. static CONST WCHAR g_pwszIA64[] = L"IA64";
  44. static CONST WCHAR g_pwszIA32[] = L"IA32";
  45. static CONST WCHAR g_pwszAMD64[] = L"AMD64";
  46. static CONST WCHAR g_pwszRasUser[] = L"\\Microsoft\\Network\\Connections\\Pbk\\";
  47. static CONST WCHAR g_pwszCmUser[] = L"\\Microsoft\\Network\\Connections\\Cm\\";
  48. static CONST WCHAR g_pwszMsinfo[] = L"\\Common Files\\Microsoft Shared\\MSInfo\\";
  49. CONST WCHAR g_pwszTableOfContents[] = L"TableOfContents";
  50. CONST WCHAR g_pwszTraceCollectTracingLogs[] = L"TraceCollectTracingLogs";
  51. CONST WCHAR g_pwszTraceCollectCmLogs[] = L"TraceCollectCmLogs";
  52. CONST WCHAR g_pwszTraceCollectModemLogs[] = L"g_pwszTraceCollectModemLogs";
  53. CONST WCHAR g_pwszTraceCollectIpsecLogs[] = L"g_pwszTraceCollectIpsecLogs";
  54. CONST WCHAR g_pwszPrintRasEventLogs[] = L"PrintRasEventLogs";
  55. CONST WCHAR g_pwszPrintSecurityEventLogs[] = L"PrintSecurityEventLogs";
  56. CONST WCHAR g_pwszPrintRasInfData[] = L"PrintRasInfData";
  57. CONST WCHAR g_pwszHrValidateRas[] = L"HrValidateRas";
  58. CONST WCHAR g_pwszHrShowNetComponentsAll[] = L"HrShowNetComponentsAll";
  59. CONST WCHAR g_pwszCheckRasRegistryKeys[] = L"CheckRasRegistryKeys";
  60. CONST WCHAR g_pwszPrintRasEnumDevices[] = L"PrintRasEnumDevices";
  61. CONST WCHAR g_pwszPrintProcessInfo[] = L"PrintProcessInfo";
  62. CONST WCHAR g_pwszPrintConsoleUtils[] = L"PrintConsoleUtils";
  63. CONST WCHAR g_pwszPrintWinMsdReport[] = L"PrintWinMsdReport";
  64. CONST WCHAR g_pwszPrintAllRasPbks[] = L"PrintAllRasPbks";
  65. static CONST CMD_LINE_UTILS g_CmdLineUtils[] =
  66. {
  67. {L"arp.exe -a", L"arp.exe"},
  68. {L"ipconfig.exe /all", L"ipconfig.exe1"},
  69. {L"ipconfig.exe /displaydns", L"ipconfig.exe2"},
  70. {L"route.exe print", L"route.exe"},
  71. {L"net.exe start", L"net.exe"},
  72. {L"netstat.exe -e", L"netstat.exe1"},
  73. {L"netstat.exe -o", L"netstat.exe2"},
  74. {L"netstat.exe -s", L"netstat.exe3"},
  75. {L"netstat.exe -n", L"netstat.exe4"},
  76. {L"nbtstat.exe -c", L"nbtstat.exe1"},
  77. {L"nbtstat.exe -n", L"nbtstat.exe2"},
  78. {L"nbtstat.exe -r", L"nbtstat.exe3"},
  79. {L"nbtstat.exe -S", L"nbtstat.exe4"},
  80. {L"netsh.exe dump", L"netsh.exe"},
  81. };
  82. static CONST UINT g_ulNumCmdLines = sizeof(g_CmdLineUtils) / sizeof(CMD_LINE_UTILS);
  83. //
  84. // Declarations from rasnetcfg
  85. //
  86. VOID
  87. HrValidateRas(
  88. IN BUFFER_WRITE_FILE* pBuff);
  89. VOID
  90. HrShowNetComponentsAll(
  91. IN BUFFER_WRITE_FILE* pBuff);
  92. //
  93. // Local declarations
  94. //
  95. DWORD
  96. WriteUnicodeMarker(
  97. IN BUFFER_WRITE_FILE* pBuff);
  98. DWORD
  99. AllocBufferWriteFile(
  100. IN BUFFER_WRITE_FILE* pBuff);
  101. VOID
  102. FreeBufferWriteFile(
  103. IN BUFFER_WRITE_FILE* pBuff);
  104. DWORD
  105. BufferWriteFile(
  106. IN BUFFER_WRITE_FILE* pBuff,
  107. IN CONST LPBYTE lpBuff,
  108. IN DWORD dwSize);
  109. DWORD
  110. BufferWriteToHtml(
  111. IN BUFFER_WRITE_FILE* pBuff,
  112. IN CONST LPBYTE lpBuff,
  113. IN DWORD dwSize);
  114. DWORD
  115. BufferWriteToHtmlA(
  116. IN BUFFER_WRITE_FILE* pBuff,
  117. IN CONST LPBYTE lpBuff,
  118. IN DWORD dwSize);
  119. DWORD
  120. BufferWriteMessageVA(
  121. IN BUFFER_WRITE_FILE* pBuff,
  122. IN LPCWSTR pwszFormat,
  123. IN va_list* parglist);
  124. PWCHAR
  125. FindLastCmLogHeader(
  126. IN LPCWSTR pStart,
  127. IN LPCWSTR pEnd,
  128. IN LPCWSTR pCurrent);
  129. PWCHAR
  130. GetCMLoggingPath(
  131. IN LPCWSTR pwcszCMPFile);
  132. PWCHAR
  133. GetSystemInfoString();
  134. PWCHAR
  135. GetVersionExString(
  136. OUT PDWORD pdwBuild);
  137. VOID
  138. PrintConsoleUtilsToc(
  139. IN BUFFER_WRITE_FILE* pBuff);
  140. BOOL
  141. GetCommonFolderPath(
  142. IN DWORD dwMode,
  143. OUT TCHAR* pszPathBuf);
  144. LONG
  145. ProcessTimeString(
  146. IN PCHAR pszTime,
  147. IN DWORD dwHours);
  148. BOOL
  149. CALLBACK
  150. EnumWindowsProc(
  151. HWND hwnd,
  152. LPARAM lParam);
  153. BOOL
  154. EnumMessageWindows(
  155. WNDENUMPROC lpEnumFunc,
  156. LPARAM lParam);
  157. BOOL
  158. CALLBACK
  159. EnumDesktopProc(
  160. LPTSTR lpszDesktop,
  161. LPARAM lParam);
  162. BOOL
  163. CALLBACK
  164. EnumWindowStationProc(
  165. LPTSTR lpszWindowStation,
  166. LPARAM lParam);
  167. VOID
  168. GetWindowTitles(
  169. PTASK_LIST_ENUM te);
  170. VOID
  171. PrintRasInfData(
  172. IN BUFFER_WRITE_FILE* pBuff);
  173. VOID
  174. PrintRasEnumDevices(
  175. IN BUFFER_WRITE_FILE* pBuff);
  176. VOID
  177. PrintProcessInfo(
  178. IN BUFFER_WRITE_FILE* pBuff);
  179. VOID
  180. PrintConsoleUtils(
  181. IN REPORT_INFO* pInfo);
  182. VOID
  183. PrintWinMsdReport(
  184. IN REPORT_INFO* pInfo);
  185. BOOL
  186. PrintRasPbk(
  187. IN REPORT_INFO* pInfo,
  188. IN DWORD dwType);
  189. VOID
  190. PrintAllRasPbks(
  191. IN REPORT_INFO* pInfo);
  192. PUCHAR
  193. GetSystemProcessInfo();
  194. VOID
  195. FreeSystemProcessInfo(
  196. IN PUCHAR pProcessInfo);
  197. DWORD
  198. DiagGetReport(
  199. IN DWORD dwFlags,
  200. IN OUT LPCWSTR pwszString,
  201. IN OPTIONAL DiagGetReportCb pCallback,
  202. IN OPTIONAL PVOID pContext)
  203. {
  204. DWORD dwErr = NO_ERROR;
  205. PWCHAR pwszTempFile = NULL;
  206. REPORT_INFO ReportInfo;
  207. BUFFER_WRITE_FILE Buff;
  208. GET_REPORT_STRING_CB CbInfo;
  209. do
  210. {
  211. ZeroMemory(&ReportInfo, sizeof(REPORT_INFO));
  212. ZeroMemory(&Buff, sizeof(BUFFER_WRITE_FILE));
  213. ZeroMemory(&CbInfo, sizeof(GET_REPORT_STRING_CB));
  214. if (!pwszString)
  215. {
  216. dwErr = ERROR_INVALID_PARAMETER;
  217. break;
  218. }
  219. if ((dwFlags & RAS_DIAG_EXPORT_TO_EMAIL) ||
  220. (dwFlags & RAS_DIAG_DISPLAY_FILE)
  221. )
  222. {
  223. WCHAR wszTempFileName[MAX_PATH + 1];
  224. dwErr = CopyTempFileName(wszTempFileName);
  225. BREAK_ON_DWERR(dwErr);
  226. pwszTempFile = CreateHtmFileName(wszTempFileName);
  227. if (!pwszTempFile)
  228. {
  229. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  230. break;
  231. }
  232. }
  233. else if (dwFlags & RAS_DIAG_EXPORT_TO_FILE)
  234. {
  235. pwszTempFile = CreateHtmFileName(pwszString);
  236. if (!pwszTempFile)
  237. {
  238. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  239. break;
  240. }
  241. }
  242. else
  243. {
  244. dwErr = ERROR_INVALID_PARAMETER;
  245. break;
  246. }
  247. //
  248. // Init the Report Information structure
  249. //
  250. ReportInfo.fVerbose = !!(dwFlags & RAS_DIAG_VERBOSE_REPORT);
  251. ReportInfo.pBuff = &Buff;
  252. //
  253. // Create the report file
  254. //
  255. dwErr = CreateReportFile(ReportInfo.pBuff, pwszTempFile);
  256. BREAK_ON_DWERR(dwErr);
  257. //
  258. // Print header and table of contents to report
  259. //
  260. PrintHtmlHeader(ReportInfo.pBuff);
  261. PrintTableOfContents(&ReportInfo, SHOW_ALL);
  262. //
  263. // Init callback data
  264. //
  265. if (pCallback)
  266. {
  267. CbInfo.pContext = pContext;
  268. CbInfo.pwszState = RutlAlloc(
  269. (MAX_MSG_LENGTH + 1) * sizeof(WCHAR),
  270. FALSE);
  271. ReportInfo.pCbInfo = &CbInfo;
  272. ReportInfo.pCallback = pCallback;
  273. }
  274. dwErr = RasDiagShowAll(&ReportInfo);
  275. PrintHtmlFooter(ReportInfo.pBuff);
  276. CloseReportFile(ReportInfo.pBuff);
  277. //
  278. // If report gathering was cancelled via the UI, dwErr will =
  279. // ERROR_CANCELLED. We do not want to continue in this case.
  280. //
  281. if (dwErr)
  282. {
  283. DeleteFile(pwszTempFile);
  284. break;
  285. }
  286. if (dwFlags & RAS_DIAG_EXPORT_TO_EMAIL)
  287. {
  288. PWCHAR pwszCabFile = NULL;
  289. pwszCabFile = CabCompressFile(pwszTempFile);
  290. if (!pwszCabFile)
  291. {
  292. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  293. break;
  294. }
  295. dwErr = MapiSendMail(pwszString, pwszCabFile);
  296. DeleteFile(pwszCabFile);
  297. DeleteFile(pwszTempFile);
  298. RutlFree(pwszCabFile);
  299. }
  300. else
  301. {
  302. lstrcpyn((PWCHAR)pwszString, pwszTempFile, MAX_PATH);
  303. }
  304. } while (FALSE);
  305. //
  306. // Clean up
  307. //
  308. RutlFree(CbInfo.pwszState);
  309. RutlFree(pwszTempFile);
  310. return dwErr;
  311. }
  312. VOID
  313. WriteLinkBackToToc(
  314. IN BUFFER_WRITE_FILE* pBuff)
  315. {
  316. BufferWriteFileStrW(pBuff, g_pwszSpace);
  317. BufferWriteFileCharW(pBuff, g_pwszLBracket);
  318. BufferWriteFileStrW(pBuff, g_pwszAnStart);
  319. BufferWriteFileStrW(pBuff, g_pwszTableOfContents);
  320. BufferWriteFileStrW(pBuff, g_pwszAnMiddle);
  321. BufferWriteMessage(pBuff, g_hModule, MSG_RASDIAG_REPORT_TOC);
  322. BufferWriteFileStrW(pBuff, g_pwszAnEnd);
  323. BufferWriteFileCharW(pBuff, g_pwszRBracket);
  324. return;
  325. }
  326. VOID
  327. WriteHtmlSection(
  328. IN BUFFER_WRITE_FILE* pBuff,
  329. IN LPCWSTR pwszAnchor,
  330. IN DWORD dwMsgId)
  331. {
  332. BufferWriteFileStrW(pBuff, g_pwszAnNameStart);
  333. BufferWriteFileStrW(pBuff, pwszAnchor);
  334. BufferWriteFileStrW(pBuff, g_pwszAnNameMiddle);
  335. BufferWriteMessage(pBuff, g_hModule, dwMsgId);
  336. WriteLinkBackToToc(pBuff);
  337. BufferWriteFileStrW(pBuff, g_pwszAnNameEnd);
  338. }
  339. DWORD
  340. WriteUnicodeMarker(
  341. IN BUFFER_WRITE_FILE* pBuff)
  342. {
  343. return BufferWriteFile(
  344. pBuff,
  345. (LPBYTE)&g_wchUnicodeMarker,
  346. sizeof(g_wchUnicodeMarker));
  347. }
  348. DWORD
  349. WriteNewLine(
  350. IN BUFFER_WRITE_FILE* pBuff)
  351. {
  352. return BufferWriteFileStrW(pBuff, g_pwszNewLine);
  353. }
  354. VOID
  355. WriteHeaderSep(
  356. IN BUFFER_WRITE_FILE* pBuff,
  357. IN LPCWSTR pwszTitle)
  358. {
  359. BufferWriteFileStrW(pBuff, g_pwszHeaderSep);
  360. BufferWriteFileStrW(pBuff, pwszTitle);
  361. WriteNewLine(pBuff);
  362. BufferWriteFileStrW(pBuff, g_pwszHeaderSep);
  363. }
  364. VOID
  365. WriteEventLogEntry(
  366. IN BUFFER_WRITE_FILE* pBuff,
  367. IN PEVENTLOGRECORD pevlr,
  368. IN LPCWSTR pwszDescr,
  369. IN LPCWSTR pwszCategory)
  370. {
  371. PSID psid;
  372. DWORD dwName = MAX_USERNAME_SIZE, dwDomain = MAX_DOMAIN_SIZE, dwArg;
  373. WCHAR wszName[MAX_USERNAME_SIZE + 1], wszDomain[MAX_DOMAIN_SIZE + 1],
  374. wszDate[TIMEDATESTR], wszTime[TIMEDATESTR];
  375. PWCHAR pwszSource, pwszComputer, pwszType = NULL, pwszTemp,
  376. pwszCat = NULL, pwszName = NULL;
  377. SID_NAME_USE snu;
  378. switch (pevlr->EventType)
  379. {
  380. case EVENTLOG_SUCCESS:
  381. dwArg = MSG_RASDIAG_SHOW_EVENT_SUCCESS;
  382. break;
  383. case EVENTLOG_ERROR_TYPE:
  384. dwArg = MSG_RASDIAG_SHOW_EVENT_ERROR;
  385. break;
  386. case EVENTLOG_WARNING_TYPE:
  387. dwArg = MSG_RASDIAG_SHOW_EVENT_WARNING;
  388. break;
  389. case EVENTLOG_INFORMATION_TYPE:
  390. dwArg = MSG_RASDIAG_SHOW_EVENT_INFO;
  391. break;
  392. case EVENTLOG_AUDIT_SUCCESS:
  393. dwArg = MSG_RASDIAG_SHOW_EVENT_SAUDIT;
  394. break;
  395. case EVENTLOG_AUDIT_FAILURE:
  396. dwArg = MSG_RASDIAG_SHOW_EVENT_FAUDIT;
  397. break;
  398. default:
  399. dwArg = 0;
  400. break;
  401. }
  402. if (dwArg)
  403. {
  404. pwszType = LoadStringFromHinst(g_hModule, dwArg);
  405. }
  406. pwszSource = (PWCHAR)((LPBYTE) pevlr + sizeof(EVENTLOGRECORD));
  407. if (!pwszCategory)
  408. {
  409. pwszCat = LoadStringFromHinst(g_hModule, MSG_RASDIAG_SHOW_EVENT_NONE);
  410. }
  411. RutlGetDateStr(
  412. pevlr->TimeGenerated,
  413. wszDate,
  414. TIMEDATESTR);
  415. RutlGetTimeStr(
  416. pevlr->TimeGenerated,
  417. wszTime,
  418. TIMEDATESTR);
  419. psid = (PSID) (((PBYTE) pevlr) + pevlr->UserSidOffset);
  420. if (!LookupAccountSid(
  421. NULL,
  422. psid,
  423. wszName,
  424. &dwName,
  425. wszDomain,
  426. &dwDomain,
  427. &snu)
  428. )
  429. {
  430. wszName[0] = g_pwszNull;
  431. wszDomain[0] = g_pwszNull;
  432. pwszName = LoadStringFromHinst(g_hModule, MSG_RASDIAG_SHOW_EVENT_NA);
  433. }
  434. pwszTemp = pwszSource;
  435. while(*pwszTemp++ != g_pwszNull);
  436. pwszComputer = pwszTemp;
  437. if (wszDomain[0] != g_pwszNull)
  438. {
  439. BufferWriteMessage(
  440. pBuff,
  441. g_hModule,
  442. MSG_RASDIAG_SHOW_EVENT_LOG_USERDOM,
  443. pwszType ? pwszType : g_pwszEmpty,
  444. pwszSource,
  445. (pwszCat ? pwszCat :
  446. (pwszCategory ? pwszCategory : g_pwszEmpty)),
  447. pevlr->EventID,
  448. wszDate,
  449. wszTime,
  450. wszDomain,
  451. pwszName ? pwszName : wszName,
  452. pwszComputer,
  453. pwszDescr);
  454. }
  455. else
  456. {
  457. BufferWriteMessage(
  458. pBuff,
  459. g_hModule,
  460. MSG_RASDIAG_SHOW_EVENT_LOG_USER,
  461. pwszType ? pwszType : g_pwszEmpty,
  462. pwszSource,
  463. (pwszCat ? pwszCat :
  464. (pwszCategory ? pwszCategory : g_pwszEmpty)),
  465. pevlr->EventID,
  466. wszDate,
  467. wszTime,
  468. pwszName ? pwszName : wszName,
  469. pwszComputer,
  470. pwszDescr);
  471. }
  472. //
  473. // Clean up
  474. //
  475. FreeStringFromHinst(pwszName);
  476. FreeStringFromHinst(pwszCat);
  477. FreeStringFromHinst(pwszType);
  478. return;
  479. }
  480. DWORD
  481. AllocBufferWriteFile(
  482. IN BUFFER_WRITE_FILE* pBuff)
  483. {
  484. DWORD dwErr = NO_ERROR;
  485. do
  486. {
  487. if (!pBuff || !pBuff->hFile ||
  488. pBuff->hFile == INVALID_HANDLE_VALUE)
  489. {
  490. dwErr = ERROR_INVALID_PARAMETER;
  491. break;
  492. }
  493. pBuff->lpBuff = RutlAlloc(BUF_WRITE_SIZE, FALSE);
  494. if (!pBuff->lpBuff)
  495. {
  496. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  497. break;
  498. }
  499. pBuff->dwPosition = 0;
  500. } while (FALSE);
  501. return dwErr;
  502. }
  503. VOID
  504. FreeBufferWriteFile(
  505. IN BUFFER_WRITE_FILE* pBuff)
  506. {
  507. //
  508. // Whistler .NET BUG: 492078
  509. //
  510. if (pBuff->dwPosition && pBuff->lpBuff)
  511. {
  512. DWORD dwTemp;
  513. WriteFile(
  514. pBuff->hFile,
  515. pBuff->lpBuff,
  516. pBuff->dwPosition,
  517. &dwTemp,
  518. NULL);
  519. pBuff->dwPosition = 0;
  520. RutlFree(pBuff->lpBuff);
  521. pBuff->lpBuff = NULL;
  522. }
  523. return;
  524. }
  525. DWORD
  526. BufferWriteFile(
  527. IN BUFFER_WRITE_FILE* pBuff,
  528. IN CONST LPBYTE lpBuff,
  529. IN DWORD dwSize)
  530. {
  531. DWORD dwErr = NO_ERROR, dwCurSize, dwCopy, dwTemp;
  532. LPBYTE lpEnd, lpCurrent;
  533. do
  534. {
  535. if (!pBuff || !lpBuff || !dwSize)
  536. {
  537. dwErr = ERROR_INVALID_PARAMETER;
  538. break;
  539. }
  540. lpEnd = lpBuff + dwSize;
  541. lpCurrent = lpBuff;
  542. dwCurSize = dwSize;
  543. for (;;)
  544. {
  545. dwCopy = min(dwCurSize, BUF_WRITE_SIZE - pBuff->dwPosition);
  546. CopyMemory(pBuff->lpBuff + pBuff->dwPosition, lpCurrent, dwCopy);
  547. pBuff->dwPosition += dwCopy;
  548. if (pBuff->dwPosition == BUF_WRITE_SIZE)
  549. {
  550. if (!WriteFile(
  551. pBuff->hFile,
  552. pBuff->lpBuff,
  553. BUF_WRITE_SIZE,
  554. &dwTemp,
  555. NULL))
  556. {
  557. dwErr = GetLastError();
  558. break;
  559. }
  560. pBuff->dwPosition = 0;
  561. }
  562. lpCurrent += dwCopy;
  563. if (lpCurrent == lpEnd)
  564. {
  565. break;
  566. }
  567. dwCurSize = (DWORD)(lpEnd - lpCurrent);
  568. }
  569. } while (FALSE);
  570. return dwErr;
  571. }
  572. //
  573. // Remove HTML escape characters from buffer
  574. //
  575. DWORD
  576. BufferWriteToHtml(
  577. IN BUFFER_WRITE_FILE* pBuff,
  578. IN CONST LPBYTE lpBuff,
  579. IN DWORD dwSize)
  580. {
  581. DWORD i, dwTemp = 0, dwErr = NO_ERROR;
  582. LPBYTE lpTemp = NULL, lpCurrent;
  583. PWCHAR pwszReplace;
  584. //For .Net 506188
  585. PWCHAR pwCheck = NULL;
  586. lpCurrent = lpBuff;
  587. for (i = 0; i < dwSize; i += sizeof(WCHAR))
  588. {
  589. //For .Net 506188
  590. pwCheck = (WCHAR *) (lpCurrent+i);
  591. switch ( *(pwCheck) )
  592. {
  593. case L'\"':
  594. pwszReplace = (PWCHAR)g_wszQuoteHtm;
  595. break;
  596. case L'@':
  597. pwszReplace = (PWCHAR)g_wszAmpHtm;
  598. break;
  599. case L'<':
  600. pwszReplace = (PWCHAR)g_wszLeftHtm;
  601. break;
  602. case L'>':
  603. pwszReplace = (PWCHAR)g_wszRightHtm;
  604. break;
  605. default:
  606. pwszReplace = NULL;
  607. break;
  608. }
  609. if (pwszReplace)
  610. {
  611. //
  612. // Flush out stuff we are not going to replace
  613. //
  614. if (lpTemp && dwTemp)
  615. {
  616. dwErr = BufferWriteFile(
  617. pBuff,
  618. lpTemp,
  619. dwTemp * sizeof(WCHAR));
  620. lpTemp = NULL;
  621. dwTemp = 0;
  622. BREAK_ON_DWERR(dwErr);
  623. }
  624. //
  625. // Write out the converted escape seq
  626. //
  627. dwErr = BufferWriteFile(
  628. pBuff,
  629. (LPBYTE)pwszReplace,
  630. lstrlen(pwszReplace) * sizeof(WCHAR));
  631. BREAK_ON_DWERR(dwErr);
  632. }
  633. else
  634. {
  635. //
  636. // Not an escape seq, continue
  637. //
  638. if (!lpTemp)
  639. {
  640. lpTemp = lpCurrent + i;
  641. }
  642. dwTemp++;
  643. }
  644. }
  645. //
  646. // Make sure we didn't leave any around to write out
  647. //
  648. if (lpTemp && dwTemp)
  649. {
  650. dwErr = BufferWriteFile(
  651. pBuff,
  652. lpTemp,
  653. dwTemp * sizeof(WCHAR));
  654. }
  655. return dwErr;
  656. }
  657. DWORD
  658. BufferWriteToHtmlA(
  659. IN BUFFER_WRITE_FILE* pBuff,
  660. IN CONST LPBYTE lpBuff,
  661. IN DWORD dwSize)
  662. {
  663. UINT i;
  664. DWORD dwErr = NO_ERROR;
  665. LPWSTR pTempBuff = NULL;
  666. DWORD dwNewSize = 0;
  667. do
  668. {
  669. if (!dwSize)
  670. {
  671. dwErr = ERROR_INVALID_PARAMETER;
  672. break;
  673. }
  674. //
  675. // First call MultiByteToWideChar to get how large of a Unicode string
  676. // will result from conversion.
  677. //
  678. dwNewSize = MultiByteToWideChar(CP_ACP, 0, lpBuff, dwSize, NULL, 0);
  679. if (0 == dwNewSize)
  680. {
  681. dwErr = GetLastError();
  682. break;
  683. }
  684. //
  685. // Okay, now allocate enough memory for the new string
  686. //
  687. pTempBuff = RutlAlloc((dwNewSize * sizeof(WCHAR)), FALSE);
  688. if (!pTempBuff)
  689. {
  690. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  691. break;
  692. }
  693. //
  694. // Now do the conversion by calling MultiByteToWideChar again
  695. //
  696. if (0 == MultiByteToWideChar(CP_ACP, 0, lpBuff, dwSize, pTempBuff, dwNewSize))
  697. {
  698. dwErr = GetLastError();
  699. break;
  700. }
  701. //
  702. // Finally, write out the buffer to the html file
  703. //
  704. dwErr = BufferWriteToHtml(
  705. pBuff,
  706. (LPBYTE)pTempBuff,
  707. dwNewSize * sizeof(WCHAR));
  708. } while (FALSE);
  709. //
  710. // Clean up
  711. //
  712. RutlFree(pTempBuff);
  713. return dwErr;
  714. }
  715. DWORD
  716. BufferWriteFileStrWtoA(
  717. IN BUFFER_WRITE_FILE* pBuff,
  718. IN LPCWSTR pwszString)
  719. {
  720. PCHAR pszString = NULL;
  721. DWORD dwErr = NO_ERROR;
  722. if (!pwszString)
  723. {
  724. return ERROR_INVALID_PARAMETER;
  725. }
  726. pszString = RutlStrDupAFromW(pwszString);
  727. if (!pszString)
  728. {
  729. return ERROR_NOT_ENOUGH_MEMORY;
  730. }
  731. dwErr = BufferWriteFile(
  732. pBuff,
  733. (LPBYTE)pszString,
  734. lstrlenA(pszString));
  735. RutlFree(pszString);
  736. return dwErr;
  737. }
  738. DWORD
  739. BufferWriteFileStrW(
  740. IN BUFFER_WRITE_FILE* pBuff,
  741. IN LPCWSTR pwszString)
  742. {
  743. if (!pwszString)
  744. {
  745. return ERROR_INVALID_PARAMETER;
  746. }
  747. return BufferWriteFile(
  748. pBuff,
  749. (LPBYTE)pwszString,
  750. lstrlen(pwszString) * sizeof(WCHAR));
  751. }
  752. DWORD
  753. BufferWriteFileCharW(
  754. IN BUFFER_WRITE_FILE* pBuff,
  755. IN CONST WCHAR wszChar)
  756. {
  757. return BufferWriteFile(pBuff, (LPBYTE)&wszChar, sizeof(WCHAR));
  758. }
  759. DWORD
  760. BufferWriteMessageVA(
  761. IN BUFFER_WRITE_FILE* pBuff,
  762. IN LPCWSTR pwszFormat,
  763. IN va_list* parglist)
  764. {
  765. DWORD dwErr = NO_ERROR, dwMsgLen = 0;
  766. LPWSTR pwszOutput = NULL;
  767. do
  768. {
  769. dwMsgLen = FormatMessage(
  770. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  771. FORMAT_MESSAGE_FROM_STRING,
  772. pwszFormat,
  773. 0,
  774. 0L,
  775. (LPWSTR)&pwszOutput,
  776. 0,
  777. parglist);
  778. if(!dwMsgLen)
  779. {
  780. dwErr = GetLastError();
  781. break;
  782. }
  783. dwErr = BufferWriteFile(
  784. pBuff,
  785. (LPBYTE)pwszOutput,
  786. dwMsgLen * sizeof(WCHAR));
  787. } while (FALSE);
  788. if (pwszOutput)
  789. {
  790. LocalFree(pwszOutput);
  791. }
  792. return dwErr;
  793. }
  794. DWORD
  795. BufferWriteMessage(
  796. IN BUFFER_WRITE_FILE* pBuff,
  797. IN HANDLE hModule,
  798. IN DWORD dwMsgId,
  799. ...)
  800. {
  801. WCHAR rgwcInput[MAX_MSG_LENGTH + 1];
  802. va_list arglist;
  803. if (!LoadString(hModule, dwMsgId, rgwcInput, MAX_MSG_LENGTH))
  804. {
  805. return GetLastError();
  806. }
  807. va_start(arglist, dwMsgId);
  808. return BufferWriteMessageVA(pBuff, rgwcInput, &arglist);
  809. }
  810. LPBYTE
  811. ParseRasLogForTime(
  812. IN LPBYTE pBuff,
  813. IN DWORD dwSize,
  814. IN DWORD dwHours)
  815. {
  816. CHAR szTime[TIMESIZE + 1];
  817. LPBYTE pCurrent, pEnd, pStart, pTemp, pLast = NULL, pReturn = NULL;
  818. CONST PCHAR c_pszRasLogString = "\r\n[";
  819. CONST UINT c_ulRasLogStringSize = strlen(c_pszRasLogString);
  820. pStart = pBuff;
  821. pCurrent = pEnd = pBuff + dwSize;
  822. do
  823. {
  824. if (pCurrent + TIMESIZE + 4 > pEnd)
  825. {
  826. pCurrent -= TIMESIZE + 4;
  827. continue;
  828. }
  829. if (!strncmp(pCurrent, c_pszRasLogString, c_ulRasLogStringSize))
  830. {
  831. pTemp = pCurrent + c_ulRasLogStringSize;
  832. //
  833. // Find the space before the time
  834. //
  835. while ((*pTemp++ != ' ') &&
  836. (*pTemp != g_pwszNull)
  837. );
  838. //
  839. // Check for colons then the period before mil sec
  840. //
  841. if ((pTemp + TIMESIZE + 1 > pEnd) ||
  842. (*(pTemp + 2) != ':') ||
  843. (*(pTemp + 5) != ':') ||
  844. (*(pTemp + TIMESIZE ) != ':')
  845. )
  846. {
  847. continue;
  848. }
  849. strncpy(szTime, pTemp, TIMESIZE);
  850. szTime[TIMESIZE] = '\0';
  851. if (ProcessTimeString(szTime, dwHours) == -1)
  852. {
  853. pReturn = pLast;
  854. break;
  855. }
  856. else
  857. {
  858. pLast = pCurrent + 2;
  859. continue;
  860. }
  861. }
  862. } while (--pCurrent >= pStart);
  863. //
  864. // Since we parsed the whole file, display the whole file
  865. //
  866. if (pCurrent < pStart)
  867. {
  868. pReturn = pStart;
  869. }
  870. return pReturn;
  871. }
  872. LPBYTE
  873. ParseModemLogForTime(
  874. IN LPBYTE pBuff,
  875. IN DWORD dwSize,
  876. IN DWORD dwHours)
  877. {
  878. PCHAR pszTimeA = NULL;
  879. WCHAR wszTime[TIMESIZE + 1];
  880. PWCHAR pCurrent, pEnd, pStart, pTemp, pLast = NULL, pReturn = NULL;
  881. pStart = (PWCHAR)pBuff;
  882. pCurrent = pEnd = (PWCHAR)((LPBYTE)pBuff + dwSize);
  883. do
  884. {
  885. if (pCurrent + TIMESIZE + 4 > pEnd)
  886. {
  887. pCurrent -= TIMESIZE + 4;
  888. continue;
  889. }
  890. if ((*pCurrent == '\r') &&
  891. (*(pCurrent + 1) == '\n') &&
  892. (*(pCurrent + 4) == '-') &&
  893. (*(pCurrent + 7) == '-')
  894. )
  895. {
  896. pTemp = pCurrent;
  897. //
  898. // Find the space
  899. //
  900. while ((*pTemp++ != ' ') &&
  901. (*pTemp != g_pwszNull)
  902. );
  903. //
  904. // Check for colons then the period before mil sec
  905. //
  906. if ((pTemp + TIMESIZE > pEnd) ||
  907. (*(pTemp + 2) != ':') ||
  908. (*(pTemp + 5) != ':') ||
  909. (*(pTemp + TIMESIZE ) != '.')
  910. )
  911. {
  912. continue;
  913. }
  914. //
  915. // it seems that lstrcpyn subtracts 1 from the size for the NULL on
  916. // your behalf then appends a NULL to the end
  917. //
  918. lstrcpyn(wszTime, pTemp, TIMESIZE + 1);
  919. pszTimeA = RutlStrDupAFromWAnsi(wszTime);
  920. if (!pszTimeA)
  921. {
  922. continue;
  923. }
  924. if (ProcessTimeString(pszTimeA, dwHours) == -1)
  925. {
  926. RutlFree(pszTimeA);
  927. pszTimeA = NULL;
  928. pReturn = pLast;
  929. break;
  930. }
  931. else
  932. {
  933. RutlFree(pszTimeA);
  934. pszTimeA = NULL;
  935. pLast = pCurrent + 2;
  936. continue;
  937. }
  938. }
  939. } while (--pCurrent >= pStart);
  940. //
  941. // Since we parsed the whole file, display the whole file
  942. // Also, This is a unicode file so we need to chop off the garbage in front
  943. //
  944. if (pCurrent < pStart)
  945. {
  946. pReturn = pStart + 1;
  947. }
  948. //
  949. // Clean up
  950. //
  951. RutlFree(pszTimeA);
  952. return (LPBYTE)pReturn;
  953. }
  954. PWCHAR
  955. FindLastCmLogHeader(
  956. IN LPCWSTR pStart,
  957. IN LPCWSTR pEnd,
  958. IN LPCWSTR pCurrent)
  959. {
  960. PWCHAR pCurrentCopy, pReturn = NULL;
  961. CONST PWCHAR c_pwszCmLogString = L"\r\n*";
  962. CONST UINT c_ulCmLogStringSize = lstrlen(c_pwszCmLogString);
  963. pCurrentCopy = (PWCHAR)pCurrent;
  964. do
  965. {
  966. if (!RutlStrNCmp(pCurrentCopy, c_pwszCmLogString, c_ulCmLogStringSize))
  967. {
  968. pReturn = pCurrentCopy + 2;
  969. break;
  970. }
  971. } while (--pCurrentCopy >= pStart);
  972. return pReturn;
  973. }
  974. LPBYTE
  975. ParseCmLogForTime(
  976. IN LPBYTE pBuff,
  977. IN DWORD dwSize,
  978. IN DWORD dwHours)
  979. {
  980. PCHAR pszTimeA = NULL;
  981. WCHAR wszTime[TIMESIZE + 1];
  982. PWCHAR pCurrent, pEnd, pStart, pTemp, pLast = NULL, pReturn = NULL;
  983. CONST PWCHAR c_pwszCmLogString = L"\r\n\tStart Date/Time : ";
  984. CONST UINT c_ulCmLogStringSize = lstrlen(c_pwszCmLogString);
  985. pStart = (PWCHAR)pBuff;
  986. pCurrent = pEnd = (PWCHAR)((LPBYTE)pBuff + dwSize);
  987. do
  988. {
  989. if (pCurrent + TIMESIZE + 35 > pEnd)
  990. {
  991. pCurrent -= TIMESIZE + 35;
  992. continue;
  993. }
  994. if (!RutlStrNCmp(pCurrent, c_pwszCmLogString, c_ulCmLogStringSize))
  995. {
  996. pTemp = pCurrent + c_ulCmLogStringSize;
  997. //
  998. // Find the space
  999. //
  1000. while ((*pTemp++ != ' ') &&
  1001. (*pTemp != g_pwszNull)
  1002. );
  1003. //
  1004. // Check for colons then the period before mil sec
  1005. //
  1006. if ((pTemp + TIMESIZE > pEnd) ||
  1007. (*(pTemp + 2) != ':') ||
  1008. (*(pTemp + 5) != ':') ||
  1009. (*(pTemp + TIMESIZE ) != '\r')
  1010. )
  1011. {
  1012. continue;
  1013. }
  1014. //
  1015. // it seems that lstrcpyn subtracts 1 from the size for the NULL on
  1016. // your behalf then appends a NULL to the end
  1017. //
  1018. lstrcpyn(wszTime, pTemp, TIMESIZE + 1);
  1019. pszTimeA = RutlStrDupAFromWAnsi(wszTime);
  1020. if (!pszTimeA)
  1021. {
  1022. continue;
  1023. }
  1024. if (ProcessTimeString(pszTimeA, dwHours) == -1)
  1025. {
  1026. RutlFree(pszTimeA);
  1027. pszTimeA = NULL;
  1028. pReturn = pLast;
  1029. break;
  1030. }
  1031. else
  1032. {
  1033. RutlFree(pszTimeA);
  1034. pszTimeA = NULL;
  1035. pLast = FindLastCmLogHeader(pStart, pEnd, pCurrent - 1);
  1036. //
  1037. // If we are unable to find a CM log header above, we assume we
  1038. // have hit the start of the log. we add one because of unicode
  1039. // garbabe at front of file
  1040. //
  1041. if (!pLast)
  1042. {
  1043. pReturn = pStart + 1;
  1044. break;
  1045. }
  1046. continue;
  1047. }
  1048. }
  1049. } while (--pCurrent >= pStart);
  1050. //
  1051. // Clean up
  1052. //
  1053. RutlFree(pszTimeA);
  1054. return (LPBYTE)pReturn;
  1055. }
  1056. LPBYTE
  1057. ParseIpsecLogForTime(
  1058. IN LPBYTE pBuff,
  1059. IN DWORD dwSize,
  1060. IN DWORD dwHours)
  1061. {
  1062. CHAR szTime[TIMESIZE + 1];
  1063. LPBYTE pCurrent, pEnd, pStart, pTemp, pLast = NULL, pReturn = NULL;
  1064. CONST PCHAR c_pszIpsecLogString = "\r\n ";
  1065. CONST UINT c_ulIpsecLogStringSize = strlen(c_pszIpsecLogString);
  1066. pStart = pBuff;
  1067. pCurrent = pEnd = pBuff + dwSize;
  1068. do
  1069. {
  1070. if (pCurrent + TIMESIZE + 4 > pEnd)
  1071. {
  1072. pCurrent -= TIMESIZE + 4;
  1073. continue;
  1074. }
  1075. if (!strncmp(pCurrent, c_pszIpsecLogString, c_ulIpsecLogStringSize))
  1076. {
  1077. pTemp = pCurrent + c_ulIpsecLogStringSize;
  1078. //
  1079. // Find the space before the time
  1080. //
  1081. while ((*pTemp++ != ' ') &&
  1082. (*pTemp != g_pwszNull)
  1083. );
  1084. //
  1085. // Check for colons then the period before mil sec
  1086. //
  1087. if ((pTemp + TIMESIZE + 1 > pEnd) ||
  1088. (*(pTemp + 2) != ':') ||
  1089. (*(pTemp + 5) != ':') ||
  1090. (*(pTemp + TIMESIZE ) != ':')
  1091. )
  1092. {
  1093. continue;
  1094. }
  1095. strncpy(szTime, pTemp, TIMESIZE);
  1096. szTime[TIMESIZE] = '\0';
  1097. if (ProcessTimeString(szTime, dwHours) == -1)
  1098. {
  1099. pReturn = pLast;
  1100. break;
  1101. }
  1102. else
  1103. {
  1104. pLast = pCurrent + 2;
  1105. continue;
  1106. }
  1107. }
  1108. } while (--pCurrent >= pStart);
  1109. //
  1110. // Since we parsed the whole file, display the whole file
  1111. //
  1112. if (pCurrent < pStart)
  1113. {
  1114. pReturn = pStart;
  1115. }
  1116. return pReturn;
  1117. }
  1118. DWORD
  1119. PrintFile(
  1120. IN REPORT_INFO* pInfo,
  1121. IN LPCWSTR pwszFile,
  1122. IN BOOL fWritePath,
  1123. IN RAS_PRINTFILE_FUNC_CB pCallback)
  1124. {
  1125. BOOL bIsWide = FALSE;
  1126. DWORD dwErr = NO_ERROR, dwFileSize = 0, dwBytesRead;
  1127. HANDLE hFile = NULL;
  1128. LPBYTE lpBuff = NULL, pFound = NULL;
  1129. do
  1130. {
  1131. if (!pInfo || !pwszFile)
  1132. {
  1133. dwErr = ERROR_INVALID_PARAMETER;
  1134. break;
  1135. }
  1136. hFile = CreateFile(
  1137. pwszFile,
  1138. GENERIC_READ | GENERIC_WRITE,
  1139. FILE_SHARE_READ | FILE_SHARE_WRITE,
  1140. NULL,
  1141. OPEN_EXISTING,
  1142. FILE_ATTRIBUTE_NORMAL,
  1143. NULL);
  1144. if(INVALID_HANDLE_VALUE == hFile)
  1145. {
  1146. dwErr = GetLastError();
  1147. break;
  1148. }
  1149. dwFileSize = GetFileSize(hFile, NULL);
  1150. if ((dwFileSize < sizeof(g_wchUnicodeMarker)) ||
  1151. (INVALID_FILE_SIZE == dwFileSize)
  1152. )
  1153. {
  1154. dwErr = ERROR_INVALID_PARAMETER;
  1155. break;
  1156. }
  1157. lpBuff = RutlAlloc(dwFileSize, FALSE);
  1158. if (!lpBuff)
  1159. {
  1160. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1161. break;
  1162. }
  1163. if((!ReadFile(hFile, lpBuff, dwFileSize, &dwBytesRead, NULL)) ||
  1164. (dwBytesRead != dwFileSize)
  1165. )
  1166. {
  1167. dwErr = GetLastError();
  1168. break;
  1169. }
  1170. //
  1171. // If we got this far it is safe to go ahead and print the path
  1172. //
  1173. if (fWritePath)
  1174. {
  1175. WriteHeaderSep(pInfo->pBuff, pwszFile);
  1176. }
  1177. //
  1178. // check to see if the file is unicode
  1179. //
  1180. if (!memcmp(&g_wchUnicodeMarker, lpBuff, sizeof(g_wchUnicodeMarker)))
  1181. {
  1182. bIsWide = TRUE;
  1183. }
  1184. if (!pCallback || !pInfo->dwHours)
  1185. {
  1186. if (bIsWide)
  1187. {
  1188. //
  1189. // Unicode file has 2 bytes of leading stuff
  1190. //
  1191. pFound = lpBuff + sizeof(g_wchUnicodeMarker);
  1192. }
  1193. else
  1194. {
  1195. pFound = lpBuff;
  1196. }
  1197. }
  1198. else
  1199. {
  1200. //
  1201. // Call the callback
  1202. //
  1203. pFound = pCallback(lpBuff, dwFileSize, pInfo->dwHours);
  1204. if (!pFound)
  1205. {
  1206. dwErr = ERROR_FILE_NOT_FOUND;
  1207. break;
  1208. }
  1209. }
  1210. if (bIsWide)
  1211. {
  1212. dwErr = BufferWriteToHtml(
  1213. pInfo->pBuff,
  1214. pFound,
  1215. (DWORD)((lpBuff + dwFileSize) - pFound));
  1216. }
  1217. else
  1218. {
  1219. dwErr = BufferWriteToHtmlA(
  1220. pInfo->pBuff,
  1221. pFound,
  1222. (DWORD)((lpBuff + dwFileSize) - pFound));
  1223. }
  1224. WriteNewLine(pInfo->pBuff);
  1225. } while (FALSE);
  1226. //
  1227. // Clean up
  1228. //
  1229. RutlFree(lpBuff);
  1230. if (hFile)
  1231. {
  1232. CloseHandle(hFile);
  1233. }
  1234. return dwErr;
  1235. }
  1236. PWCHAR
  1237. GetCMLoggingPath(
  1238. IN LPCWSTR pwcszCMPFile)
  1239. {
  1240. DWORD dwSize;
  1241. WCHAR wszTemp[MAX_PATH + 1], wszFile[MAX_PATH + 1];
  1242. PWCHAR pwszCMSPath = NULL, pwszReturn = NULL;
  1243. CONST PWCHAR pwszCM = L"Connection Manager";
  1244. CONST PWCHAR pwszCMS = L"CMSFile";
  1245. CONST PWCHAR pwszFileDir = L"FileDirectory";
  1246. CONST PWCHAR pwszTempDir = L"%TEMP%\\";
  1247. do
  1248. {
  1249. if (!pwcszCMPFile ||
  1250. !ExpandEnvironmentStrings(
  1251. pwcszCMPFile,
  1252. wszTemp,
  1253. MAX_PATH)
  1254. )
  1255. {
  1256. break;
  1257. }
  1258. if (!GetPrivateProfileString(
  1259. pwszCM,
  1260. pwszCMS,
  1261. g_pwszEmpty,
  1262. wszFile,
  1263. MAX_PATH,
  1264. wszTemp)
  1265. )
  1266. {
  1267. break;
  1268. }
  1269. if (!GetCommonFolderPath(ALL_USERS_PROF | GET_FOR_CM, wszTemp))
  1270. {
  1271. break;
  1272. }
  1273. dwSize = lstrlen(wszFile) + lstrlen(wszTemp) + 1;
  1274. if (dwSize < 2)
  1275. {
  1276. break;
  1277. }
  1278. pwszCMSPath = RutlAlloc(dwSize * sizeof(WCHAR), TRUE);
  1279. if (!pwszCMSPath)
  1280. {
  1281. break;
  1282. }
  1283. lstrcpy(pwszCMSPath, wszTemp);
  1284. lstrcat(pwszCMSPath, wszFile);
  1285. if (!GetPrivateProfileString(
  1286. g_pwszLogging,
  1287. pwszFileDir,
  1288. pwszTempDir,
  1289. wszFile,
  1290. MAX_PATH,
  1291. pwszCMSPath)
  1292. )
  1293. {
  1294. break;
  1295. }
  1296. if (!ExpandEnvironmentStrings(
  1297. wszFile,
  1298. wszTemp,
  1299. MAX_PATH))
  1300. {
  1301. break;
  1302. }
  1303. //
  1304. // Must guarentee string ends with '\'
  1305. //
  1306. dwSize = lstrlen(wszTemp);
  1307. if (g_pwszBackSlash != wszTemp[dwSize - 1])
  1308. {
  1309. if (dwSize + 1 <= MAX_PATH)
  1310. {
  1311. wszTemp[dwSize - 1] = g_pwszBackSlash;
  1312. wszTemp[dwSize] = g_pwszNull;
  1313. }
  1314. else
  1315. {
  1316. break;
  1317. }
  1318. }
  1319. pwszReturn = RutlStrDup(wszTemp);
  1320. } while (FALSE);
  1321. //
  1322. // Clean up
  1323. //
  1324. RutlFree(pwszCMSPath);
  1325. return pwszReturn;
  1326. }
  1327. BOOL
  1328. GetCMLoggingSearchPath(
  1329. IN HANDLE hKey,
  1330. IN LPCWSTR pwszName,
  1331. IN LPCWSTR* ppwszLogPath,
  1332. IN LPCWSTR* ppwszSeach)
  1333. {
  1334. HKEY hMappings = NULL;
  1335. BOOL fRet = FALSE;
  1336. DWORD dwSize;
  1337. PWCHAR pwszCMPFile = NULL;
  1338. do
  1339. {
  1340. if (!ppwszLogPath || !ppwszSeach)
  1341. {
  1342. break;
  1343. }
  1344. *ppwszLogPath = NULL;
  1345. *ppwszSeach = NULL;
  1346. if (RegOpenKeyEx(
  1347. hKey,
  1348. g_pwszCmMappings,
  1349. 0,
  1350. KEY_READ,
  1351. &hMappings) ||
  1352. RutlRegReadString(
  1353. hMappings,
  1354. pwszName,
  1355. &pwszCMPFile)
  1356. )
  1357. {
  1358. break;
  1359. }
  1360. *ppwszLogPath = GetCMLoggingPath(pwszCMPFile);
  1361. if (!(*ppwszLogPath))
  1362. {
  1363. break;
  1364. }
  1365. dwSize = lstrlen(pwszName) + lstrlen(g_pwszLogSrchStr) + 1;
  1366. if (dwSize < 2)
  1367. {
  1368. break;
  1369. }
  1370. *ppwszSeach = RutlAlloc(dwSize * sizeof(WCHAR), FALSE);
  1371. if (!(*ppwszSeach))
  1372. {
  1373. break;
  1374. }
  1375. lstrcpy((PWCHAR)(*ppwszSeach), pwszName);
  1376. lstrcat((PWCHAR)(*ppwszSeach), g_pwszLogSrchStr);
  1377. fRet = TRUE;
  1378. } while (FALSE);
  1379. //
  1380. // Clean up
  1381. //
  1382. RutlFree(pwszCMPFile);
  1383. return fRet;
  1384. }
  1385. PWCHAR
  1386. GetTracingDir()
  1387. {
  1388. DWORD dwSize = 0;
  1389. WCHAR wszWindir[MAX_PATH + 1];
  1390. PWCHAR pwszReturn = NULL;
  1391. CONST WCHAR c_pwszTracingPath[] = L"\\tracing\\";
  1392. do
  1393. {
  1394. dwSize = GetSystemWindowsDirectory(wszWindir, MAX_PATH);
  1395. if (!dwSize)
  1396. {
  1397. break;
  1398. }
  1399. dwSize += lstrlen(c_pwszTracingPath) + 1;
  1400. pwszReturn = RutlAlloc(dwSize * sizeof(WCHAR), TRUE);
  1401. if (!pwszReturn)
  1402. {
  1403. break;
  1404. }
  1405. lstrcpy(pwszReturn, wszWindir);
  1406. lstrcat(pwszReturn, c_pwszTracingPath);
  1407. } while (FALSE);
  1408. return pwszReturn;
  1409. }
  1410. PWCHAR
  1411. CreateErrorString(
  1412. IN WORD wNumStrs,
  1413. IN LPCWSTR pswzStrings,
  1414. IN LPCWSTR pswzErrorMsg)
  1415. {
  1416. UINT i, ulSize = 0, ulStrCount = 0;
  1417. PWCHAR pwszReturn = NULL, pwszCurrent, pwszEnd;
  1418. PWCHAR pswzStrs = (PWCHAR)pswzStrings, pswzError = (PWCHAR)pswzErrorMsg;
  1419. PWCHAR* ppwszStrArray = NULL;
  1420. do
  1421. {
  1422. //
  1423. // only handle between 1 - 99 strings
  1424. //
  1425. if ((wNumStrs < 1) ||
  1426. (wNumStrs > 99) ||
  1427. (!pswzStrs || !pswzError)
  1428. )
  1429. {
  1430. break;
  1431. }
  1432. ppwszStrArray = RutlAlloc(wNumStrs * sizeof(PWCHAR), TRUE);
  1433. if (!ppwszStrArray)
  1434. {
  1435. break;
  1436. }
  1437. for (i = 0; i < wNumStrs; i++)
  1438. {
  1439. ppwszStrArray[i] = pswzStrs;
  1440. ulSize += lstrlen(pswzStrs);
  1441. while(*pswzStrs++ != g_pwszNull);
  1442. }
  1443. ulSize += lstrlen(pswzError) + 1;
  1444. pwszReturn = RutlAlloc(ulSize * sizeof(WCHAR), TRUE);
  1445. if (!pwszReturn)
  1446. {
  1447. break;
  1448. }
  1449. //
  1450. // Walk through the string and replacing any inserts with proper string
  1451. //
  1452. pwszCurrent = pswzError;
  1453. pwszEnd = pswzError + lstrlen(pswzError);
  1454. while((*pwszCurrent != g_pwszNull) &&
  1455. (pwszCurrent + 1 <= pwszEnd) &&
  1456. (ulStrCount < wNumStrs)
  1457. )
  1458. {
  1459. if ((*pwszCurrent == L'%') &&
  1460. (*(pwszCurrent + 1) >= L'0') &&
  1461. (*(pwszCurrent + 1) <= L'9')
  1462. )
  1463. {
  1464. *pwszCurrent = g_pwszNull;
  1465. if ((pwszCurrent + 2 <= pwszEnd) &&
  1466. (*(pwszCurrent + 2) >= L'0') &&
  1467. (*(pwszCurrent + 2) <= L'9')
  1468. )
  1469. {
  1470. pwszCurrent += 3;
  1471. }
  1472. else
  1473. {
  1474. pwszCurrent += 2;
  1475. }
  1476. lstrcat(pwszReturn, pswzError);
  1477. lstrcat(pwszReturn, ppwszStrArray[ulStrCount++]);
  1478. pswzError = pwszCurrent;
  1479. }
  1480. else
  1481. {
  1482. pwszCurrent++;
  1483. }
  1484. }
  1485. if (pwszEnd > pswzError)
  1486. {
  1487. lstrcat(pwszReturn, pswzError);
  1488. }
  1489. } while (FALSE);
  1490. //
  1491. // Clean up
  1492. //
  1493. RutlFree(ppwszStrArray);
  1494. return pwszReturn;
  1495. }
  1496. PWCHAR
  1497. FormatMessageFromMod(
  1498. IN HANDLE hModule,
  1499. IN DWORD dwId)
  1500. {
  1501. PWCHAR pwszReturn = NULL;
  1502. FormatMessage(
  1503. FORMAT_MESSAGE_IGNORE_INSERTS |
  1504. FORMAT_MESSAGE_MAX_WIDTH_MASK |
  1505. FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1506. FORMAT_MESSAGE_FROM_HMODULE,
  1507. hModule,
  1508. dwId,
  1509. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  1510. (LPWSTR)&pwszReturn,
  1511. 0,
  1512. NULL);
  1513. return pwszReturn;
  1514. }
  1515. VOID
  1516. FreeFormatMessageFromMod(
  1517. IN LPCWSTR pwszMessage)
  1518. {
  1519. if (pwszMessage)
  1520. {
  1521. LocalFree((PWCHAR)pwszMessage);
  1522. }
  1523. }
  1524. PWCHAR
  1525. LoadStringFromHinst(
  1526. IN HINSTANCE hInst,
  1527. IN DWORD dwId)
  1528. {
  1529. WCHAR rgwcInput[MAX_MSG_LENGTH + 1];
  1530. PWCHAR pwszReturn = NULL;
  1531. if (LoadString(hInst, dwId, rgwcInput, MAX_MSG_LENGTH))
  1532. {
  1533. pwszReturn = RutlStrDup(rgwcInput);
  1534. }
  1535. return pwszReturn;
  1536. }
  1537. VOID
  1538. FreeStringFromHinst(
  1539. IN LPCWSTR pwszMessage)
  1540. {
  1541. RutlFree((PWCHAR)pwszMessage);
  1542. }
  1543. DWORD
  1544. CopyAndCallCB(
  1545. IN REPORT_INFO* pInfo,
  1546. IN DWORD dwId)
  1547. {
  1548. DWORD dwErr = NO_ERROR;
  1549. PWCHAR pwszTemp = NULL;
  1550. GET_REPORT_STRING_CB* pCbInfo = pInfo->pCbInfo;
  1551. if (pCbInfo->pwszState)
  1552. {
  1553. pwszTemp = LoadStringFromHinst(g_hModule, dwId);
  1554. if (pwszTemp)
  1555. {
  1556. lstrcpyn(pCbInfo->pwszState, pwszTemp, MAX_MSG_LENGTH);
  1557. FreeStringFromHinst(pwszTemp);
  1558. }
  1559. else
  1560. {
  1561. pCbInfo->pwszState[0] = g_pwszNull;
  1562. }
  1563. }
  1564. pCbInfo->dwPercent += ADD_PERCENT_DONE(pInfo->fVerbose);
  1565. //
  1566. // Call the callback
  1567. //
  1568. dwErr = pInfo->pCallback(pCbInfo);
  1569. //
  1570. // Ignore all errors except ERROR_CANCELLED
  1571. //
  1572. if (dwErr && dwErr != ERROR_CANCELLED)
  1573. {
  1574. dwErr = NO_ERROR;
  1575. }
  1576. return dwErr;
  1577. }
  1578. //
  1579. // Get a temp filename of at most MAX_PATH
  1580. //
  1581. DWORD
  1582. CopyTempFileName(
  1583. OUT LPCWSTR pwszTempFileName)
  1584. {
  1585. WCHAR wszTempBuffer[MAX_PATH + 1];
  1586. if (!GetTempPath(MAX_PATH, wszTempBuffer) ||
  1587. !GetTempFileName(wszTempBuffer, L"RAS", 0, (PWCHAR)pwszTempFileName)
  1588. )
  1589. {
  1590. return GetLastError();
  1591. }
  1592. else
  1593. {
  1594. //
  1595. // Delete the temp file that was created by GetTempFileName
  1596. //
  1597. DeleteFile(pwszTempFileName);
  1598. return NO_ERROR;
  1599. }
  1600. }
  1601. PWCHAR
  1602. CreateHtmFileName(
  1603. IN LPCWSTR pwszFile)
  1604. {
  1605. DWORD dwSize = 0;
  1606. WCHAR wszTemp[MAX_PATH] = L"\0";
  1607. PWCHAR pwszSearch, pwszReturn = NULL;
  1608. static CONST WCHAR c_pwszHtmExt[] = L".htm";
  1609. static CONST WCHAR c_pwszHtmlExt[] = L".html";
  1610. do
  1611. {
  1612. dwSize = lstrlen(pwszFile);
  1613. if (!dwSize)
  1614. {
  1615. break;
  1616. }
  1617. //
  1618. // .Net bug# 523850 SECURITY: Specifying the diagnostics report file
  1619. // with more than 255 characters causes a buffer overrun
  1620. //
  1621. // CreateFile fails if you have more than 258 characters in the path
  1622. //
  1623. if (!ExpandEnvironmentStrings(
  1624. pwszFile,
  1625. wszTemp,
  1626. (sizeof(wszTemp) / sizeof(WCHAR)) - lstrlen(c_pwszHtmExt) - 1)
  1627. )
  1628. {
  1629. break;
  1630. }
  1631. //
  1632. // If string already has .htm, get outta here
  1633. //
  1634. pwszSearch = (PWCHAR)(pwszFile + dwSize - lstrlen(c_pwszHtmExt));
  1635. if (lstrcmpi(pwszSearch, c_pwszHtmExt) == 0)
  1636. {
  1637. pwszReturn = RutlStrDup(pwszFile);
  1638. break;
  1639. }
  1640. //
  1641. // If string already has .html, get outta here
  1642. //
  1643. pwszSearch = (PWCHAR)(pwszFile + dwSize - lstrlen(c_pwszHtmlExt));
  1644. if (lstrcmpi(pwszSearch, c_pwszHtmlExt) == 0)
  1645. {
  1646. pwszReturn = RutlStrDup(pwszFile);
  1647. break;
  1648. }
  1649. lstrcat(wszTemp, c_pwszHtmExt);
  1650. pwszReturn = RutlStrDup(wszTemp);
  1651. } while (FALSE);
  1652. return pwszReturn;
  1653. }
  1654. DWORD
  1655. CreateReportFile(
  1656. IN BUFFER_WRITE_FILE* pBuff,
  1657. IN LPCWSTR pwszReport)
  1658. {
  1659. DWORD dwErr = NO_ERROR;
  1660. do
  1661. {
  1662. if (!pBuff || !pwszReport)
  1663. {
  1664. dwErr = ERROR_INVALID_PARAMETER;
  1665. break;
  1666. }
  1667. pBuff->hFile = CreateFile(
  1668. pwszReport,
  1669. GENERIC_READ | GENERIC_WRITE,
  1670. 0,
  1671. NULL,
  1672. CREATE_ALWAYS,
  1673. FILE_ATTRIBUTE_NORMAL,
  1674. NULL);
  1675. if(pBuff->hFile == INVALID_HANDLE_VALUE)
  1676. {
  1677. dwErr = GetLastError();
  1678. pBuff->hFile = NULL;
  1679. break;
  1680. }
  1681. //
  1682. // .Net bug# 523037 SECURITY: Specifying the diagnostics report file as
  1683. // the Printer Port (LPT1) will cause netsh to hang
  1684. //
  1685. else if (GetFileType(pBuff->hFile) != FILE_TYPE_DISK)
  1686. {
  1687. dwErr = ERROR_FILE_NOT_FOUND;
  1688. break;
  1689. }
  1690. dwErr = AllocBufferWriteFile(pBuff);
  1691. BREAK_ON_DWERR(dwErr);
  1692. dwErr = WriteUnicodeMarker(pBuff);
  1693. BREAK_ON_DWERR(dwErr);
  1694. } while (FALSE);
  1695. if (dwErr)
  1696. {
  1697. CloseReportFile(pBuff);
  1698. }
  1699. return dwErr;
  1700. }
  1701. VOID
  1702. CloseReportFile(
  1703. IN BUFFER_WRITE_FILE* pBuff)
  1704. {
  1705. //
  1706. // Whistler .NET BUG: 492078
  1707. //
  1708. if (pBuff && pBuff->hFile)
  1709. {
  1710. FreeBufferWriteFile(pBuff);
  1711. CloseHandle(pBuff->hFile);
  1712. pBuff->hFile = NULL;
  1713. }
  1714. }
  1715. DWORD
  1716. RasDiagShowAll(
  1717. IN REPORT_INFO* pInfo)
  1718. {
  1719. DWORD dwErr = NO_ERROR;
  1720. do
  1721. {
  1722. dwErr = TraceCollectAll(pInfo);
  1723. BREAK_ON_DWERR(dwErr);
  1724. dwErr = RasDiagShowInstallation(pInfo);
  1725. BREAK_ON_DWERR(dwErr);
  1726. dwErr = RasDiagShowConfiguration(pInfo);
  1727. BREAK_ON_DWERR(dwErr);
  1728. } while (FALSE);
  1729. return dwErr;
  1730. }
  1731. VOID
  1732. PrintHtmlHeader(
  1733. IN BUFFER_WRITE_FILE* pBuff)
  1734. {
  1735. static CONST WCHAR c_pwszHtmlStart[] = L"<html><head><title> ";
  1736. static CONST WCHAR c_pwszBodyStart[] =
  1737. L" </title></head><body bgcolor=\"#FFFFE8\" text=\"#000088\"><h1>";
  1738. static CONST WCHAR c_pwszBodyEnd[] = L"</body></html>";
  1739. static CONST WCHAR c_pwszH1End[] = L"</h1>";
  1740. BufferWriteFileStrW(pBuff, c_pwszHtmlStart);
  1741. BufferWriteMessage(pBuff, g_hModule, MSG_RASDIAG_REPORT_TITLE);
  1742. BufferWriteFileStrW(pBuff, c_pwszBodyStart);
  1743. BufferWriteMessage(pBuff, g_hModule, MSG_RASDIAG_REPORT_TITLE);
  1744. BufferWriteFileStrW(pBuff, c_pwszH1End);
  1745. return;
  1746. }
  1747. VOID
  1748. PrintHtmlFooter(
  1749. IN BUFFER_WRITE_FILE* pBuff)
  1750. {
  1751. static CONST WCHAR c_pwszBodyEnd[] = L"</body></html>";
  1752. BufferWriteFileStrW(pBuff, c_pwszBodyEnd);
  1753. return;
  1754. }
  1755. PWCHAR
  1756. GetSystemInfoString()
  1757. {
  1758. PWCHAR Return = NULL;
  1759. SYSTEM_INFO siSysInfo;
  1760. ZeroMemory(&siSysInfo, sizeof(SYSTEM_INFO));
  1761. GetSystemInfo(&siSysInfo);
  1762. switch (siSysInfo.wProcessorArchitecture)
  1763. {
  1764. case PROCESSOR_ARCHITECTURE_INTEL:
  1765. Return = (PWCHAR)g_pwszx86;
  1766. break;
  1767. case PROCESSOR_ARCHITECTURE_IA64:
  1768. Return = (PWCHAR)g_pwszIA64;
  1769. break;
  1770. case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
  1771. Return = (PWCHAR)g_pwszIA32;
  1772. break;
  1773. case PROCESSOR_ARCHITECTURE_AMD64:
  1774. Return = (PWCHAR)g_pwszAMD64;
  1775. break;
  1776. default:
  1777. Return = (PWCHAR)g_pwszEmpty;
  1778. break;
  1779. }
  1780. return Return;
  1781. }
  1782. PWCHAR
  1783. GetVersionExString(
  1784. OUT PDWORD pdwBuild)
  1785. {
  1786. PWCHAR Return = NULL;
  1787. OSVERSIONINFOEX osvi;
  1788. ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
  1789. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  1790. GetVersionEx((OSVERSIONINFO*)&osvi);
  1791. switch (osvi.wProductType)
  1792. {
  1793. case VER_NT_WORKSTATION:
  1794. if(osvi.wSuiteMask & VER_SUITE_PERSONAL)
  1795. {
  1796. Return = (PWCHAR)g_pwszPER;
  1797. }
  1798. else
  1799. {
  1800. Return = (PWCHAR)g_pwszPRO;
  1801. }
  1802. break;
  1803. case VER_NT_SERVER:
  1804. if(osvi.wSuiteMask & VER_SUITE_DATACENTER)
  1805. {
  1806. Return = (PWCHAR)g_pwszDTC;
  1807. }
  1808. else if(osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
  1809. {
  1810. Return = (PWCHAR)g_pwszADS;
  1811. }
  1812. else
  1813. {
  1814. Return = (PWCHAR)g_pwszSRV;
  1815. }
  1816. break;
  1817. default:
  1818. Return = (PWCHAR)g_pwszEmpty;
  1819. break;
  1820. }
  1821. if (pdwBuild)
  1822. {
  1823. *pdwBuild = osvi.dwBuildNumber;
  1824. }
  1825. return Return;
  1826. }
  1827. VOID
  1828. PrintTableOfContents(
  1829. IN REPORT_INFO* pInfo,
  1830. IN DWORD dwFlag)
  1831. {
  1832. WCHAR wszTime[TIMEDATESTR], wszDate[TIMEDATESTR], wszUsername[UNLEN + 1],
  1833. wszComputer[MAX_COMPUTERNAME_LENGTH + 1], wszWindir[MAX_PATH + 1];
  1834. DWORD dwBuild = 0;
  1835. PWCHAR pwszSuite = NULL, pwszProc = NULL;
  1836. static CONST WCHAR c_pwszTableStart[] = L"<table border=\"0\">";
  1837. static CONST WCHAR c_pwszTableEnd[] = L"</table>";
  1838. static CONST WCHAR c_pwszFieldStart[] = L"<fieldset>";
  1839. static CONST WCHAR c_pwszFieldEnd[] = L"</fieldset>";
  1840. static CONST WCHAR c_pwszH3Start[] = L"<h3> ";
  1841. static CONST WCHAR c_pwszH3End[] = L" </h3>";
  1842. static CONST WCHAR c_pwszUlStart[] = L"<ul>";
  1843. static CONST WCHAR c_pwszUlEnd[] = L"</ul>";
  1844. {
  1845. SYSTEMTIME st;
  1846. GetLocalTime(&st);
  1847. if (!GetDateFormat(LOCALE_USER_DEFAULT,
  1848. DATE_SHORTDATE,
  1849. &st,
  1850. NULL,
  1851. wszDate,
  1852. TIMEDATESTR))
  1853. {
  1854. wszDate[0] = g_pwszNull;
  1855. }
  1856. if (!GetTimeFormat(LOCALE_USER_DEFAULT,
  1857. 0,
  1858. &st,
  1859. NULL,
  1860. wszTime,
  1861. TIMEDATESTR))
  1862. {
  1863. wszTime[0] = g_pwszNull;
  1864. }
  1865. }
  1866. {
  1867. DWORD dwSize = UNLEN;
  1868. if (!GetUserNameEx(NameSamCompatible, wszUsername, &dwSize))
  1869. {
  1870. wszUsername[0] = g_pwszNull;
  1871. }
  1872. dwSize = MAX_COMPUTERNAME_LENGTH;
  1873. if (!GetComputerName(wszComputer, &dwSize))
  1874. {
  1875. wszComputer[0] = g_pwszNull;
  1876. }
  1877. if (!GetSystemWindowsDirectory(wszWindir, MAX_PATH))
  1878. {
  1879. wszWindir[0] = g_pwszNull;
  1880. }
  1881. }
  1882. pwszSuite = GetVersionExString(&dwBuild);
  1883. pwszProc = GetSystemInfoString();
  1884. BufferWriteFileStrW(pInfo->pBuff, c_pwszTableStart);
  1885. BufferWriteMessage(
  1886. pInfo->pBuff,
  1887. g_hModule,
  1888. MSG_RASDIAG_REPORT_HTMLTOC,
  1889. RASDIAG_VERSION,
  1890. wszDate,
  1891. wszTime,
  1892. wszUsername,
  1893. wszComputer,
  1894. wszWindir,
  1895. dwBuild,
  1896. pwszSuite,
  1897. pwszProc);
  1898. BufferWriteFileStrW(pInfo->pBuff, c_pwszTableEnd);
  1899. BufferWriteFileStrW(pInfo->pBuff, g_pwszNewLineHtml);
  1900. BufferWriteFileStrW(pInfo->pBuff, c_pwszFieldStart);
  1901. BufferWriteFileStrW(pInfo->pBuff, c_pwszH3Start);
  1902. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameStart);
  1903. BufferWriteFileStrW(pInfo->pBuff, g_pwszTableOfContents);
  1904. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameMiddle);
  1905. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TOC);
  1906. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameEnd);
  1907. BufferWriteFileStrW(pInfo->pBuff, c_pwszH3End);
  1908. //
  1909. // show logs
  1910. //
  1911. if (dwFlag & SHOW_LOGS)
  1912. {
  1913. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TRACEEVENT);
  1914. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlStart);
  1915. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1916. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1917. BufferWriteFileStrW(pInfo->pBuff, g_pwszTraceCollectTracingLogs);
  1918. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1919. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TRACE);
  1920. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1921. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1922. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlStart);
  1923. WriteTracingLogsToc(pInfo);
  1924. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1925. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1926. BufferWriteFileStrW(pInfo->pBuff, g_pwszTraceCollectModemLogs);
  1927. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1928. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TRACE_MODEM);
  1929. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1930. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1931. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1932. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1933. BufferWriteFileStrW(pInfo->pBuff, g_pwszTraceCollectCmLogs);
  1934. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1935. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TRACE_CM);
  1936. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1937. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1938. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1939. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1940. BufferWriteFileStrW(pInfo->pBuff, g_pwszTraceCollectIpsecLogs);
  1941. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1942. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TRACE_IPSEC);
  1943. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1944. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1945. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlEnd);
  1946. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1947. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1948. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintRasEventLogs);
  1949. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1950. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASEVENT);
  1951. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1952. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1953. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1954. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1955. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintSecurityEventLogs);
  1956. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1957. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_SECEVENT);
  1958. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1959. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1960. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlEnd);
  1961. }
  1962. //
  1963. // show installation
  1964. //
  1965. if (dwFlag & SHOW_INSTALL)
  1966. {
  1967. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_INSTALL);
  1968. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlStart);
  1969. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1970. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1971. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintRasInfData);
  1972. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1973. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASINF);
  1974. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1975. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1976. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1977. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1978. BufferWriteFileStrW(pInfo->pBuff, g_pwszHrValidateRas);
  1979. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1980. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASCHK);
  1981. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1982. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1983. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1984. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1985. BufferWriteFileStrW(pInfo->pBuff, g_pwszHrShowNetComponentsAll);
  1986. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1987. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_NETINST);
  1988. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1989. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1990. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  1991. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  1992. BufferWriteFileStrW(pInfo->pBuff, g_pwszCheckRasRegistryKeys);
  1993. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  1994. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASREG);
  1995. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  1996. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  1997. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlEnd);
  1998. }
  1999. //
  2000. // show configuration
  2001. //
  2002. if (dwFlag & SHOW_CONFIG)
  2003. {
  2004. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_CONFIG);
  2005. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlStart);
  2006. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  2007. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  2008. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintRasEnumDevices);
  2009. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  2010. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASENUM);
  2011. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  2012. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  2013. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  2014. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  2015. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintProcessInfo);
  2016. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  2017. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_TLIST);
  2018. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  2019. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  2020. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  2021. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  2022. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintConsoleUtils);
  2023. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  2024. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_CONSOLE);
  2025. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  2026. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  2027. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlStart);
  2028. PrintConsoleUtilsToc(pInfo->pBuff);
  2029. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlEnd);
  2030. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  2031. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  2032. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintAllRasPbks);
  2033. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  2034. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_RASPBK);
  2035. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  2036. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  2037. if (pInfo->fVerbose)
  2038. {
  2039. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiStart);
  2040. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnStart);
  2041. BufferWriteFileStrW(pInfo->pBuff, g_pwszPrintWinMsdReport);
  2042. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnMiddle);
  2043. BufferWriteMessage(pInfo->pBuff, g_hModule, MSG_RASDIAG_REPORT_WINMSD);
  2044. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnEnd);
  2045. BufferWriteFileStrW(pInfo->pBuff, g_pwszLiEnd);
  2046. }
  2047. BufferWriteFileStrW(pInfo->pBuff, c_pwszUlEnd);
  2048. }
  2049. BufferWriteFileStrW(pInfo->pBuff, c_pwszFieldEnd);
  2050. return;
  2051. }
  2052. //
  2053. //
  2054. //
  2055. VOID
  2056. PrintConsoleUtilsToc(
  2057. IN BUFFER_WRITE_FILE* pBuff)
  2058. {
  2059. UINT i;
  2060. for (i = 0; i < g_ulNumCmdLines; i++)
  2061. {
  2062. BufferWriteFileStrW(pBuff, g_pwszLiStart);
  2063. BufferWriteFileStrW(pBuff, g_pwszAnStart);
  2064. BufferWriteFileStrW(pBuff, g_CmdLineUtils[i].pwszAnchor);
  2065. BufferWriteFileStrW(pBuff, g_pwszAnMiddle);
  2066. BufferWriteFileStrW(pBuff, g_CmdLineUtils[i].pwszCmdLine);
  2067. BufferWriteFileStrW(pBuff, g_pwszAnEnd);
  2068. BufferWriteFileStrW(pBuff, g_pwszLiEnd);
  2069. }
  2070. return;
  2071. }
  2072. //
  2073. //
  2074. //
  2075. DWORD
  2076. RasDiagShowInstallation(
  2077. IN REPORT_INFO* pInfo)
  2078. {
  2079. DWORD dwErr = NO_ERROR;
  2080. do
  2081. {
  2082. //
  2083. // RAS Inf files
  2084. //
  2085. WriteHtmlSection(
  2086. pInfo->pBuff,
  2087. g_pwszPrintRasInfData,
  2088. MSG_RASDIAG_REPORT_RASINF);
  2089. if (pInfo->fDisplay)
  2090. {
  2091. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_RASINF);
  2092. PrintMessage(g_pwszDispNewLine);
  2093. }
  2094. else if (pInfo->pCallback)
  2095. {
  2096. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_RASINF);
  2097. BREAK_ON_DWERR(dwErr);
  2098. }
  2099. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2100. PrintRasInfData(pInfo->pBuff);
  2101. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2102. //
  2103. // Inetcfg Ras Verify
  2104. //
  2105. WriteHtmlSection(
  2106. pInfo->pBuff,
  2107. g_pwszHrValidateRas,
  2108. MSG_RASDIAG_REPORT_RASCHK);
  2109. if (pInfo->fDisplay)
  2110. {
  2111. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_RASCHK);
  2112. PrintMessage(g_pwszDispNewLine);
  2113. }
  2114. else if (pInfo->pCallback)
  2115. {
  2116. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_RASCHK);
  2117. BREAK_ON_DWERR(dwErr);
  2118. }
  2119. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2120. HrValidateRas(pInfo->pBuff);
  2121. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2122. //
  2123. // Installed networking components
  2124. //
  2125. WriteHtmlSection(
  2126. pInfo->pBuff,
  2127. g_pwszHrShowNetComponentsAll,
  2128. MSG_RASDIAG_REPORT_NETINST);
  2129. if (pInfo->fDisplay)
  2130. {
  2131. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_NETINST);
  2132. PrintMessage(g_pwszDispNewLine);
  2133. }
  2134. else if (pInfo->pCallback)
  2135. {
  2136. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_NETINST);
  2137. BREAK_ON_DWERR(dwErr);
  2138. }
  2139. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2140. HrShowNetComponentsAll(pInfo->pBuff);
  2141. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2142. //
  2143. // RAS Registry Keys
  2144. //
  2145. WriteHtmlSection(
  2146. pInfo->pBuff,
  2147. g_pwszCheckRasRegistryKeys,
  2148. MSG_RASDIAG_REPORT_RASREG);
  2149. if (pInfo->fDisplay)
  2150. {
  2151. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_RASREG);
  2152. PrintMessage(g_pwszDispNewLine);
  2153. }
  2154. else if (pInfo->pCallback)
  2155. {
  2156. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_RASREG);
  2157. BREAK_ON_DWERR(dwErr);
  2158. }
  2159. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2160. PrintRasRegistryKeys(pInfo->pBuff);
  2161. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2162. } while (FALSE);
  2163. return dwErr;
  2164. }
  2165. //
  2166. //
  2167. //
  2168. DWORD
  2169. RasDiagShowConfiguration(
  2170. IN REPORT_INFO* pInfo)
  2171. {
  2172. DWORD dwErr = NO_ERROR;
  2173. do
  2174. {
  2175. //
  2176. // RAS Enum Devices
  2177. //
  2178. WriteHtmlSection(
  2179. pInfo->pBuff,
  2180. g_pwszPrintRasEnumDevices,
  2181. MSG_RASDIAG_REPORT_RASENUM);
  2182. if (pInfo->fDisplay)
  2183. {
  2184. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_RASENUM);
  2185. PrintMessage(g_pwszDispNewLine);
  2186. }
  2187. else if (pInfo->pCallback)
  2188. {
  2189. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_RASENUM);
  2190. BREAK_ON_DWERR(dwErr);
  2191. }
  2192. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2193. PrintRasEnumDevices(pInfo->pBuff);
  2194. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2195. //
  2196. // Process information
  2197. //
  2198. WriteHtmlSection(
  2199. pInfo->pBuff,
  2200. g_pwszPrintProcessInfo,
  2201. MSG_RASDIAG_REPORT_TLIST);
  2202. if (pInfo->fDisplay)
  2203. {
  2204. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_TLIST);
  2205. PrintMessage(g_pwszDispNewLine);
  2206. }
  2207. else if (pInfo->pCallback)
  2208. {
  2209. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_TLIST);
  2210. BREAK_ON_DWERR(dwErr);
  2211. }
  2212. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2213. PrintProcessInfo(pInfo->pBuff);
  2214. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2215. //
  2216. // Console utilities
  2217. //
  2218. WriteHtmlSection(
  2219. pInfo->pBuff,
  2220. g_pwszPrintConsoleUtils,
  2221. MSG_RASDIAG_REPORT_CONSOLE);
  2222. if (pInfo->fDisplay)
  2223. {
  2224. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_CONSOLE);
  2225. PrintMessage(g_pwszDispNewLine);
  2226. }
  2227. else if (pInfo->pCallback)
  2228. {
  2229. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_CONSOLE);
  2230. BREAK_ON_DWERR(dwErr);
  2231. }
  2232. PrintConsoleUtils(pInfo);
  2233. //
  2234. // PBK Files
  2235. //
  2236. WriteHtmlSection(
  2237. pInfo->pBuff,
  2238. g_pwszPrintAllRasPbks,
  2239. MSG_RASDIAG_REPORT_RASPBK);
  2240. if (pInfo->fDisplay)
  2241. {
  2242. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_RASPBK);
  2243. PrintMessage(g_pwszDispNewLine);
  2244. }
  2245. else if (pInfo->pCallback)
  2246. {
  2247. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_RASPBK);
  2248. BREAK_ON_DWERR(dwErr);
  2249. }
  2250. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2251. PrintAllRasPbks(pInfo);
  2252. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2253. //
  2254. // MS Info32 report
  2255. //
  2256. if (pInfo->fVerbose)
  2257. {
  2258. WriteHtmlSection(
  2259. pInfo->pBuff,
  2260. g_pwszPrintWinMsdReport,
  2261. MSG_RASDIAG_REPORT_WINMSD);
  2262. if (pInfo->fDisplay)
  2263. {
  2264. DisplayMessage(g_hModule, MSG_RASDIAG_REPORT_WINMSD);
  2265. PrintMessage(g_pwszDispNewLine);
  2266. }
  2267. else if (pInfo->pCallback)
  2268. {
  2269. dwErr = CopyAndCallCB(pInfo, MSG_RASDIAG_REPORT_WINMSD);
  2270. BREAK_ON_DWERR(dwErr);
  2271. }
  2272. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  2273. PrintWinMsdReport(pInfo);
  2274. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  2275. }
  2276. } while (FALSE);
  2277. return dwErr;
  2278. }
  2279. //
  2280. // Write any existing WPP filenames out to the makecab ddf
  2281. //
  2282. CabCompressWppFileCb(
  2283. IN LPCWSTR pszName,
  2284. IN HKEY hKey,
  2285. IN HANDLE hData)
  2286. {
  2287. PWCHAR pwszFile;
  2288. WPP_LOG_INFO WppLog;
  2289. BUFFER_WRITE_FILE* pBuff = (BUFFER_WRITE_FILE*)hData;
  2290. do
  2291. {
  2292. if (!pBuff)
  2293. {
  2294. break;
  2295. }
  2296. ZeroMemory(&WppLog, sizeof(WPP_LOG_INFO));
  2297. lstrcpyn(WppLog.wszSessionName, pszName, MAX_PATH + 1);
  2298. if (!InitWppData(&WppLog))
  2299. {
  2300. break;
  2301. }
  2302. pwszFile = (PWCHAR )((PBYTE )WppLog.pProperties +
  2303. WppLog.pProperties->LogFileNameOffset);
  2304. if (pwszFile[0] != L'\0')
  2305. {
  2306. BufferWriteFileStrWtoA(pBuff, pwszFile);
  2307. BufferWriteFileStrWtoA(pBuff, g_pwszNewLine);
  2308. }
  2309. } while (FALSE);
  2310. //
  2311. // Clean up
  2312. //
  2313. CleanupWppData(&WppLog);
  2314. return NO_ERROR;
  2315. }
  2316. //
  2317. // We want to CAB up the HTML report as well as any WPP tracing logs (which are
  2318. // not human readable in their native state). This can be done from the cmdline
  2319. // or from the UI (which gets attached to an email)
  2320. //
  2321. PWCHAR
  2322. CabCompressFile(
  2323. IN LPCWSTR pwszFile)
  2324. {
  2325. BOOL fEnabled = FALSE;
  2326. DWORD dwRet, dwSize;
  2327. WCHAR wszTemp[MAX_PATH + 1] = L"\0", wszCabFile[MAX_PATH + 1] = L"\0",
  2328. wszDdf[MAX_PATH + 1] = L"\0";
  2329. PWCHAR pwszReturn = NULL;
  2330. BUFFER_WRITE_FILE Buff;
  2331. static CONST WCHAR pwszCabExt[] = L".cab";
  2332. do
  2333. {
  2334. if (!pwszFile || pwszFile[0] == L'\0')
  2335. {
  2336. break;
  2337. }
  2338. dwSize = (sizeof(wszTemp) / sizeof(WCHAR)) - lstrlen(pwszCabExt);
  2339. dwRet = GetFullPathName(
  2340. pwszFile,
  2341. dwSize,
  2342. wszTemp,
  2343. NULL);
  2344. if (!dwRet || dwRet > dwSize)
  2345. {
  2346. break;
  2347. }
  2348. //
  2349. // Get the cab file's name
  2350. //
  2351. _snwprintf(
  2352. wszCabFile,
  2353. MAX_PATH,
  2354. L"%s%s",
  2355. wszTemp,
  2356. pwszCabExt);
  2357. //
  2358. // Get a temp file to serve as our makecab DDF
  2359. //
  2360. if (CopyTempFileName(wszDdf))
  2361. {
  2362. break;
  2363. }
  2364. ZeroMemory(&Buff, sizeof(BUFFER_WRITE_FILE));
  2365. //
  2366. // Create the DDF file
  2367. //
  2368. Buff.hFile = CreateFile(
  2369. wszDdf,
  2370. GENERIC_WRITE,
  2371. 0,
  2372. NULL,
  2373. CREATE_ALWAYS,
  2374. FILE_ATTRIBUTE_NORMAL,
  2375. NULL);
  2376. if(Buff.hFile == INVALID_HANDLE_VALUE)
  2377. {
  2378. Buff.hFile = NULL;
  2379. break;
  2380. }
  2381. else if (GetFileType(Buff.hFile) != FILE_TYPE_DISK)
  2382. {
  2383. break;
  2384. }
  2385. //
  2386. // Wrap the file with a buffer write wrapper to make life easier
  2387. //
  2388. if (AllocBufferWriteFile(&Buff))
  2389. {
  2390. break;
  2391. }
  2392. //
  2393. // Write out some stuff we know to the DDF file
  2394. //
  2395. {
  2396. PWCHAR pwszCabFile = NULL, pEnd, pStart;
  2397. pwszCabFile = RutlStrDup(wszCabFile);
  2398. if (!pwszCabFile)
  2399. {
  2400. break;
  2401. }
  2402. pStart = pwszCabFile;
  2403. pEnd = pStart + lstrlen(pStart);
  2404. //
  2405. // Rewind to the start of the filename
  2406. //
  2407. while(*pEnd != L'\\' && pEnd-- > pStart)
  2408. ;
  2409. //
  2410. // Something went wrong on our file path to the cab file
  2411. //
  2412. if (pEnd <= pStart)
  2413. {
  2414. break;
  2415. }
  2416. *pEnd = L'\0';
  2417. pEnd++;
  2418. _snwprintf(
  2419. wszTemp,
  2420. MAX_PATH,
  2421. L".set CabinetNameTemplate=%s",
  2422. pEnd);
  2423. BufferWriteFileStrWtoA(&Buff, wszTemp);
  2424. BufferWriteFileStrWtoA(&Buff, g_pwszNewLine);
  2425. _snwprintf(
  2426. wszTemp,
  2427. MAX_PATH,
  2428. L".set DiskDirectoryTemplate=%s",
  2429. pStart);
  2430. BufferWriteFileStrWtoA(&Buff, wszTemp);
  2431. BufferWriteFileStrWtoA(&Buff, g_pwszNewLine);
  2432. BufferWriteFileStrWtoA(&Buff, L".set RptFileName=NUL");
  2433. BufferWriteFileStrWtoA(&Buff, g_pwszNewLine);
  2434. BufferWriteFileStrWtoA(&Buff, L".set InfFileName=NUL");
  2435. BufferWriteFileStrWtoA(&Buff, g_pwszNewLine);
  2436. RutlFree(pwszCabFile);
  2437. }
  2438. //
  2439. // Before we move forward we need to know if tracing is enabled, based
  2440. // on this we will re-enable it or not
  2441. //
  2442. fEnabled = DiagGetState();
  2443. //
  2444. // Disable all wpp tracing
  2445. //
  2446. TraceEnableDisableAllWpp(FALSE);
  2447. //
  2448. // Now we need to add the list of filenames to the DDF
  2449. //
  2450. BufferWriteFileStrWtoA(&Buff, pwszFile);
  2451. BufferWriteFileStrWtoA(&Buff, g_pwszNewLine);
  2452. EnumWppTracing(CabCompressWppFileCb, &Buff);
  2453. //
  2454. // Done writing to the file
  2455. //
  2456. FreeBufferWriteFile(&Buff);
  2457. CloseHandle(Buff.hFile);
  2458. Buff.hFile = NULL;
  2459. //
  2460. // Ok, the DDF file is cool, we now need to launch makecab
  2461. //
  2462. {
  2463. DWORD dwErr;
  2464. WCHAR wszCmdLine[MAX_PATH + 1] = L"\0";
  2465. STARTUPINFO si;
  2466. PROCESS_INFORMATION pi;
  2467. //
  2468. // Create the create process cmdline
  2469. //
  2470. _snwprintf(
  2471. wszCmdLine,
  2472. MAX_PATH,
  2473. L"makecab.exe /f %s",
  2474. wszDdf);
  2475. //
  2476. // Init the create process stuff
  2477. //
  2478. ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
  2479. ZeroMemory(&si, sizeof(STARTUPINFO));
  2480. si.cb = sizeof(STARTUPINFO);
  2481. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  2482. si.wShowWindow = SW_HIDE;
  2483. //
  2484. // Compress baby
  2485. //
  2486. if (!CreateProcess(
  2487. NULL,
  2488. wszCmdLine,
  2489. NULL,
  2490. NULL,
  2491. TRUE,
  2492. 0,
  2493. NULL,
  2494. NULL,
  2495. &si,
  2496. &pi)
  2497. )
  2498. {
  2499. break;
  2500. }
  2501. //
  2502. // Wait until the cows come home
  2503. //
  2504. WaitForSingleObject(pi.hProcess, INFINITE);
  2505. GetExitCodeProcess(pi.hProcess, &dwErr);
  2506. //
  2507. // Clean up
  2508. //
  2509. CloseHandle(pi.hThread);
  2510. CloseHandle(pi.hProcess);
  2511. //
  2512. // Whack the ddf
  2513. //
  2514. DeleteFile(wszDdf);
  2515. //
  2516. // Figure out if we have reached the success nirvana state
  2517. //
  2518. if (!dwErr)
  2519. {
  2520. //
  2521. // Makecab returned success, create a copy of the cab file name
  2522. //
  2523. pwszReturn = RutlStrDup(wszCabFile);
  2524. }
  2525. else
  2526. {
  2527. //
  2528. // If cab was somehow written, kill it
  2529. //
  2530. DeleteFile(wszCabFile);
  2531. break;
  2532. }
  2533. }
  2534. } while (FALSE);
  2535. //
  2536. // Clean up
  2537. //
  2538. if (Buff.hFile)
  2539. {
  2540. FreeBufferWriteFile(&Buff);
  2541. CloseHandle(Buff.hFile);
  2542. }
  2543. if (fEnabled)
  2544. {
  2545. //
  2546. // We need to re-enable wpp tracing
  2547. //
  2548. TraceEnableDisableAllWpp(TRUE);
  2549. }
  2550. return pwszReturn;
  2551. }
  2552. DWORD
  2553. MapiSendMail(
  2554. IN LPCWSTR pwszEmailAdr,
  2555. IN LPCWSTR pwszTempFile)
  2556. {
  2557. DWORD dwErr = NO_ERROR;
  2558. PCHAR pszEmailAdr = NULL, pszTempFile = NULL, pszTitle = NULL;
  2559. PWCHAR pwszTitle = NULL;
  2560. HINSTANCE hInst = NULL;
  2561. LPMAPISENDMAIL pSend = NULL;
  2562. static CONST WCHAR pwszMAPI[] = L"mapi32.dll";
  2563. static CONST CHAR pszSndMail[] = "MAPISendMail";
  2564. MapiFileDesc attachment =
  2565. {
  2566. 0, // ulReserved, must be 0
  2567. 0, // no flags; this is a data file
  2568. (ULONG)-1, // position not specified
  2569. NULL,
  2570. NULL,
  2571. NULL // MapiFileTagExt unused
  2572. };
  2573. MapiRecipDesc recips =
  2574. {
  2575. 0, // reserved
  2576. MAPI_TO, // class
  2577. NULL,
  2578. NULL,
  2579. 0, // entry id size
  2580. NULL // entry id
  2581. };
  2582. MapiMessage note =
  2583. {
  2584. 0, // reserved, must be 0
  2585. NULL, // subject
  2586. NULL, // Body
  2587. NULL, // NULL = interpersonal message
  2588. NULL, // no date; MAPISendMail ignores it
  2589. NULL, // no conversation ID
  2590. 0L, // no flags, MAPISendMail ignores it
  2591. NULL, // no originator, this is ignored too
  2592. 1, // 1 recipients
  2593. &recips, // recipient array
  2594. 1, // one attachment
  2595. &attachment // the attachment
  2596. };
  2597. do
  2598. {
  2599. if (!pwszEmailAdr || !pwszTempFile)
  2600. {
  2601. dwErr = ERROR_INVALID_PARAMETER;
  2602. break;
  2603. }
  2604. pszTempFile = RutlStrDupAFromWAnsi(pwszTempFile);
  2605. if (!pszTempFile)
  2606. {
  2607. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2608. break;
  2609. }
  2610. attachment.lpszPathName = pszTempFile;
  2611. pszEmailAdr = RutlStrDupAFromWAnsi(pwszEmailAdr);
  2612. if (!pszEmailAdr)
  2613. {
  2614. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2615. break;
  2616. }
  2617. recips.lpszName = pszEmailAdr;
  2618. pwszTitle = LoadStringFromHinst(g_hModule, MSG_RASDIAG_REPORT_TITLE);
  2619. if (!pwszTitle)
  2620. {
  2621. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2622. break;
  2623. }
  2624. pszTitle = RutlStrDupAFromWAnsi(pwszTitle);
  2625. if (!pszTitle)
  2626. {
  2627. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2628. break;
  2629. }
  2630. note.lpszSubject = pszTitle;
  2631. note.lpszNoteText = pszTitle;
  2632. hInst = LoadLibrary(pwszMAPI);
  2633. if (!hInst)
  2634. {
  2635. dwErr = GetLastError();
  2636. break;
  2637. }
  2638. pSend = (LPMAPISENDMAIL) GetProcAddress(hInst, pszSndMail);
  2639. if (!pSend)
  2640. {
  2641. dwErr = GetLastError();
  2642. break;
  2643. }
  2644. dwErr = pSend(
  2645. 0L, // use implicit session.
  2646. 0L, // ulUIParam; 0 is always valid
  2647. &note, // the message being sent
  2648. 0, // allow the user to edit the message
  2649. 0L); // reserved; must be 0
  2650. } while (FALSE);
  2651. //
  2652. // Clean up
  2653. //
  2654. if (hInst)
  2655. {
  2656. FreeLibrary(hInst);
  2657. }
  2658. RutlFree(pszTitle);
  2659. FreeStringFromHinst(pwszTitle);
  2660. RutlFree(pszTempFile);
  2661. RutlFree(pszEmailAdr);
  2662. return dwErr;
  2663. }
  2664. //
  2665. //
  2666. //
  2667. BOOL
  2668. GetCommonFolderPath(
  2669. IN DWORD dwMode,
  2670. OUT TCHAR* pszPathBuf)
  2671. {
  2672. BOOL bSuccess = FALSE;
  2673. UINT cch;
  2674. HANDLE hToken = NULL;
  2675. if ((OpenThreadToken(
  2676. GetCurrentThread(),
  2677. TOKEN_QUERY | TOKEN_IMPERSONATE,
  2678. TRUE,
  2679. &hToken) ||
  2680. OpenProcessToken(
  2681. GetCurrentProcess(),
  2682. TOKEN_QUERY | TOKEN_IMPERSONATE,
  2683. &hToken)))
  2684. {
  2685. HRESULT hr;
  2686. INT csidl = CSIDL_APPDATA;
  2687. if (dwMode & ALL_USERS_PROF)
  2688. {
  2689. csidl = CSIDL_COMMON_APPDATA;
  2690. }
  2691. else if (dwMode & GET_FOR_MSINFO)
  2692. {
  2693. csidl = CSIDL_PROGRAM_FILES;
  2694. }
  2695. hr = SHGetFolderPath(NULL, csidl, hToken, 0, pszPathBuf);
  2696. if (SUCCEEDED(hr))
  2697. {
  2698. if (dwMode & GET_FOR_RAS)
  2699. {
  2700. if(lstrlen(pszPathBuf) <= (MAX_PATH - lstrlen(g_pwszRasUser)))
  2701. {
  2702. lstrcat(pszPathBuf, g_pwszRasUser);
  2703. bSuccess = TRUE;
  2704. }
  2705. }
  2706. else if (dwMode & GET_FOR_CM)
  2707. {
  2708. if(lstrlen(pszPathBuf) <= (MAX_PATH - lstrlen(g_pwszCmUser)))
  2709. {
  2710. lstrcat(pszPathBuf, g_pwszCmUser);
  2711. bSuccess = TRUE;
  2712. }
  2713. }
  2714. else if (dwMode & GET_FOR_MSINFO)
  2715. {
  2716. if(lstrlen(pszPathBuf) <= (MAX_PATH - lstrlen(g_pwszMsinfo)))
  2717. {
  2718. lstrcat(pszPathBuf, g_pwszMsinfo);
  2719. bSuccess = TRUE;
  2720. }
  2721. }
  2722. }
  2723. CloseHandle(hToken);
  2724. }
  2725. return bSuccess;
  2726. }
  2727. //
  2728. // String must appear as 00:00:00\0
  2729. //
  2730. LONG
  2731. ProcessTimeString(
  2732. IN PCHAR pszTime,
  2733. IN DWORD dwHours)
  2734. {
  2735. UINT ulFound = 0, ulLoop = 0;
  2736. PCHAR pszStart, pszCurrent;
  2737. WORD wHours = (WORD)dwHours;
  2738. FILETIME ft1, ft2;
  2739. SYSTEMTIME st1, st2;
  2740. GetLocalTime(&st1);
  2741. CopyMemory(&st2, &st1, sizeof(SYSTEMTIME));
  2742. pszStart = pszCurrent = pszTime;
  2743. while (ulLoop++ <= 8)
  2744. {
  2745. if (*pszCurrent == g_pwszNull)
  2746. {
  2747. st1.wSecond = (WORD)atoi(pszStart);
  2748. break;
  2749. }
  2750. else if (*pszCurrent == ':')
  2751. {
  2752. *pszCurrent = '\0';
  2753. if (ulFound++ == 0)
  2754. {
  2755. st1.wHour = (WORD)atoi(pszStart);
  2756. }
  2757. else
  2758. {
  2759. st1.wMinute = (WORD)atoi(pszStart);
  2760. }
  2761. pszStart = ++pszCurrent;
  2762. continue;
  2763. }
  2764. pszCurrent++;
  2765. }
  2766. SystemTimeToFileTime(&st1, &ft1);
  2767. //
  2768. // Get the time from the past
  2769. //
  2770. if (st1.wHour > st2.wHour)
  2771. {
  2772. if ((st2.wHour - wHours) >= 0)
  2773. {
  2774. st2.wHour -= wHours;
  2775. SystemTimeToFileTime(&st2, &ft2);
  2776. return CompareFileTime(&ft2,&ft1);
  2777. }
  2778. else
  2779. {
  2780. st2.wHour = 24 + (st2.wHour - wHours);
  2781. SystemTimeToFileTime(&st2, &ft2);
  2782. return CompareFileTime(&ft1, &ft2);
  2783. }
  2784. }
  2785. else
  2786. {
  2787. if ((st2.wHour - wHours) >= 0)
  2788. {
  2789. st2.wHour -= wHours;
  2790. SystemTimeToFileTime(&st2, &ft2);
  2791. return CompareFileTime(&ft1, &ft2);
  2792. }
  2793. else
  2794. {
  2795. st2.wHour = 24 + (st2.wHour - wHours);
  2796. SystemTimeToFileTime(&st2, &ft2);
  2797. return CompareFileTime(&ft2,&ft1);
  2798. }
  2799. }
  2800. }
  2801. BOOL
  2802. CALLBACK
  2803. EnumWindowsProc(
  2804. HWND hwnd,
  2805. LPARAM lParam)
  2806. {
  2807. DWORD dwPid = 0, i, dwNumTasks;
  2808. WCHAR szBuf[TITLE_SIZE + 1];
  2809. PTASK_LIST_ENUM te = (PTASK_LIST_ENUM)lParam;
  2810. PTASK_LIST tlist = te->tlist;
  2811. dwNumTasks = te->dwNumTasks;
  2812. //
  2813. // Use try/except block when enumerating windows,
  2814. // as a window may be destroyed by another thread
  2815. // when being enumerated.
  2816. //
  2817. try {
  2818. //
  2819. // get the processid for this window
  2820. //
  2821. if (!GetWindowThreadProcessId(hwnd, &dwPid))
  2822. {
  2823. return TRUE;
  2824. }
  2825. if ((GetWindow(hwnd, GW_OWNER)) ||
  2826. (!(GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE)) && te->bFirstLoop)
  2827. {
  2828. //
  2829. // not a top level window
  2830. //
  2831. return TRUE;
  2832. }
  2833. //
  2834. // look for the task in the task list for this window
  2835. // If this is the second time let invisible windows through if we don't
  2836. // have a window already
  2837. //
  2838. for (i = 0; i < dwNumTasks; i++)
  2839. {
  2840. if ((tlist[i].dwProcessId == dwPid) &&
  2841. (te->bFirstLoop || (tlist[i].hwnd == 0))
  2842. )
  2843. {
  2844. tlist[i].hwnd = hwnd;
  2845. tlist[i].lpszWinSta = te->lpszWinSta;
  2846. tlist[i].lpszDesk = te->lpszDesk;
  2847. //
  2848. // we found the task now lets try to get the window text
  2849. //
  2850. if (GetWindowText(tlist[i].hwnd, szBuf, TITLE_SIZE))
  2851. {
  2852. //
  2853. // got it, so lets save it
  2854. //
  2855. lstrcpy(tlist[i].szWindowTitle, szBuf);
  2856. }
  2857. break;
  2858. }
  2859. }
  2860. } except(EXCEPTION_EXECUTE_HANDLER){}
  2861. //
  2862. // continue the enumeration
  2863. //
  2864. return TRUE;
  2865. }
  2866. BOOL
  2867. EnumMessageWindows(
  2868. WNDENUMPROC lpEnumFunc,
  2869. LPARAM lParam)
  2870. {
  2871. HWND hwnd = NULL;
  2872. do
  2873. {
  2874. hwnd = FindWindowEx(HWND_MESSAGE, hwnd, NULL, NULL);
  2875. if (hwnd)
  2876. {
  2877. if (!(*lpEnumFunc)(hwnd, lParam))
  2878. {
  2879. break;
  2880. }
  2881. }
  2882. } while (hwnd);
  2883. return TRUE;
  2884. }
  2885. BOOL
  2886. CALLBACK
  2887. EnumDesktopProc(
  2888. LPTSTR lpszDesktop,
  2889. LPARAM lParam)
  2890. {
  2891. BOOL bRetValue = FALSE;
  2892. HDESK hDesk = NULL, hDeskSave = NULL;
  2893. PTASK_LIST_ENUM te = (PTASK_LIST_ENUM)lParam;
  2894. do
  2895. {
  2896. //
  2897. // open the desktop
  2898. //
  2899. hDesk = OpenDesktop(lpszDesktop, 0, FALSE, MAXIMUM_ALLOWED);
  2900. if (!hDesk)
  2901. {
  2902. break;
  2903. }
  2904. //
  2905. // save the current desktop
  2906. //
  2907. hDeskSave = GetThreadDesktop(GetCurrentThreadId());
  2908. //
  2909. // change the context to the new desktop
  2910. //
  2911. SetThreadDesktop(hDesk);
  2912. te->lpszDesk = RutlStrDup(lpszDesktop);
  2913. if (!(te->lpszDesk))
  2914. {
  2915. break;
  2916. }
  2917. //
  2918. // enumerate all windows in the new desktop
  2919. //
  2920. te->bFirstLoop = TRUE;
  2921. EnumWindows((WNDENUMPROC)EnumWindowsProc, lParam);
  2922. EnumMessageWindows((WNDENUMPROC)EnumWindowsProc, lParam);
  2923. te->bFirstLoop = FALSE;
  2924. EnumWindows((WNDENUMPROC)EnumWindowsProc, lParam);
  2925. EnumMessageWindows((WNDENUMPROC)EnumWindowsProc, lParam);
  2926. //
  2927. // restore the previous desktop
  2928. //
  2929. if (hDesk != hDeskSave)
  2930. {
  2931. SetThreadDesktop(hDeskSave);
  2932. CloseDesktop(hDesk);
  2933. hDesk = NULL;
  2934. }
  2935. bRetValue = TRUE;
  2936. } while (FALSE);
  2937. //
  2938. // Clean up
  2939. //
  2940. if (hDesk)
  2941. {
  2942. CloseDesktop(hDesk);
  2943. }
  2944. return bRetValue;
  2945. }
  2946. BOOL
  2947. CALLBACK
  2948. EnumWindowStationProc(
  2949. LPTSTR lpszWindowStation,
  2950. LPARAM lParam)
  2951. {
  2952. BOOL bRetValue = FALSE;
  2953. HWINSTA hWinSta = NULL, hWinStaSave = NULL;
  2954. PTASK_LIST_ENUM te = (PTASK_LIST_ENUM)lParam;
  2955. do
  2956. {
  2957. //
  2958. // open the windowstation
  2959. //
  2960. hWinSta = OpenWindowStation(lpszWindowStation, FALSE, MAXIMUM_ALLOWED);
  2961. if (!hWinSta)
  2962. {
  2963. break;
  2964. }
  2965. //
  2966. // save the current windowstation
  2967. //
  2968. hWinStaSave = GetProcessWindowStation();
  2969. //
  2970. // change the context to the new windowstation
  2971. //
  2972. SetProcessWindowStation(hWinSta);
  2973. te->lpszWinSta = RutlStrDup(lpszWindowStation);
  2974. if (!(te->lpszWinSta))
  2975. {
  2976. break;
  2977. }
  2978. //
  2979. // enumerate all the desktops for this windowstation
  2980. //
  2981. EnumDesktops(hWinSta, EnumDesktopProc, lParam);
  2982. //
  2983. // restore the context to the previous windowstation
  2984. //
  2985. if (hWinSta != hWinStaSave)
  2986. {
  2987. SetProcessWindowStation(hWinStaSave);
  2988. CloseWindowStation(hWinSta);
  2989. hWinSta = NULL;
  2990. }
  2991. //
  2992. // continue the enumeration
  2993. //
  2994. bRetValue = TRUE;
  2995. } while (FALSE);
  2996. //
  2997. // Clean up
  2998. //
  2999. if (hWinSta)
  3000. {
  3001. CloseWindowStation(hWinSta);
  3002. }
  3003. return bRetValue;
  3004. }
  3005. VOID
  3006. GetWindowTitles(
  3007. PTASK_LIST_ENUM te)
  3008. {
  3009. //
  3010. // enumerate all windows and try to get the window
  3011. // titles for each task
  3012. //
  3013. EnumWindowStations(EnumWindowStationProc, (LPARAM)te);
  3014. }
  3015. VOID
  3016. PrintRasInfData(
  3017. IN BUFFER_WRITE_FILE* pBuff)
  3018. {
  3019. BOOL fOk = FALSE;
  3020. UINT i, uiWindirLen;
  3021. WCHAR wszWindir[MAX_PATH + 1];
  3022. static CONST PWCHAR c_pwszRasInfs[] =
  3023. {
  3024. L"\\inf\\netrasa.inf",
  3025. L"\\inf\\netrass.inf",
  3026. L"\\inf\\netrast.inf"
  3027. };
  3028. static CONST UINT c_ulNumRasInfs = sizeof(c_pwszRasInfs) / sizeof(PWCHAR);
  3029. do
  3030. {
  3031. if (!GetSystemWindowsDirectory(wszWindir, MAX_PATH))
  3032. {
  3033. break;
  3034. }
  3035. uiWindirLen = lstrlen(wszWindir);
  3036. if (!uiWindirLen)
  3037. {
  3038. break;
  3039. }
  3040. for (i = 0; i < c_ulNumRasInfs; i++)
  3041. {
  3042. UINT uiInfLen = lstrlen(c_pwszRasInfs[i]);
  3043. WCHAR wszInfPath[MAX_PATH + 1];
  3044. FILETIME ftLastWrite, ftCreation;
  3045. SYSTEMTIME stLastWrite, stCreation;
  3046. WIN32_FILE_ATTRIBUTE_DATA attr;
  3047. if ((!uiInfLen) || ((uiWindirLen + uiInfLen) > MAX_PATH))
  3048. {
  3049. break;
  3050. }
  3051. lstrcpy(wszInfPath, wszWindir);
  3052. lstrcat(wszInfPath, c_pwszRasInfs[i]);
  3053. ZeroMemory(&attr, sizeof(attr));
  3054. if (!GetFileAttributesEx(wszInfPath, GetFileExInfoStandard, &attr)
  3055. || !FileTimeToLocalFileTime(&attr.ftLastWriteTime, &ftLastWrite)
  3056. || !FileTimeToSystemTime(&ftLastWrite, &stLastWrite)
  3057. || !FileTimeToLocalFileTime(&attr.ftCreationTime, &ftCreation)
  3058. || !FileTimeToSystemTime(&ftCreation, &stCreation))
  3059. {
  3060. break;
  3061. }
  3062. BufferWriteMessage(
  3063. pBuff,
  3064. g_hModule,
  3065. MSG_RASDIAG_SHOW_RASCHK_FILE,
  3066. wszInfPath,
  3067. stLastWrite.wMonth,
  3068. stLastWrite.wDay,
  3069. stLastWrite.wYear,
  3070. stLastWrite.wHour,
  3071. stLastWrite.wMinute,
  3072. stCreation.wMonth,
  3073. stCreation.wDay,
  3074. stCreation.wYear,
  3075. stCreation.wHour,
  3076. stCreation.wMinute,
  3077. attr.nFileSizeLow);
  3078. fOk = TRUE;
  3079. }
  3080. } while (FALSE);
  3081. if (!fOk)
  3082. {
  3083. BufferWriteMessage(pBuff, g_hModule, EMSG_RASDIAG_SHOW_RASCHK_FILE);
  3084. }
  3085. return;
  3086. }
  3087. VOID
  3088. PrintRasEnumDevices(
  3089. IN BUFFER_WRITE_FILE* pBuff)
  3090. {
  3091. BOOL fOk = FALSE;
  3092. DWORD dwErr = NO_ERROR, dwBytes, dwDevices, i;
  3093. LPRASDEVINFO pRdi = NULL;
  3094. do
  3095. {
  3096. dwErr = RasEnumDevices(pRdi, &dwBytes, &dwDevices);
  3097. if ((dwErr != ERROR_BUFFER_TOO_SMALL) ||
  3098. (dwBytes < 1))
  3099. {
  3100. break;
  3101. }
  3102. pRdi = RutlAlloc(dwBytes, TRUE);
  3103. if (!pRdi)
  3104. {
  3105. break;
  3106. }
  3107. pRdi->dwSize = sizeof(RASDEVINFO);
  3108. dwErr = RasEnumDevices(pRdi, &dwBytes, &dwDevices);
  3109. if (dwErr || !dwDevices)
  3110. {
  3111. break;
  3112. }
  3113. for(i = 0; i < dwDevices; i++)
  3114. {
  3115. BufferWriteMessage(
  3116. pBuff,
  3117. g_hModule,
  3118. MSG_RASDIAG_SHOW_CONFIG_RASENUM,
  3119. i+ 1,
  3120. pRdi[i].szDeviceName,
  3121. pRdi[i].szDeviceType);
  3122. }
  3123. fOk = TRUE;
  3124. } while (FALSE);
  3125. //
  3126. // Clean up
  3127. //
  3128. RutlFree(pRdi);
  3129. if (!fOk)
  3130. {
  3131. BufferWriteMessage(pBuff, g_hModule, EMSG_RASDIAG_SHOW_CONFIG_RASENUM);
  3132. }
  3133. return;
  3134. }
  3135. VOID
  3136. PrintProcessInfo(
  3137. IN BUFFER_WRITE_FILE* pBuff)
  3138. {
  3139. BOOL fOk = FALSE;
  3140. DWORD dwErr = NO_ERROR, dwNumServices, dwResume = 0;
  3141. UINT ulAttempts = 0, ulNumSysProc, i;
  3142. ULONG uBuffSize = 2 * 1024, TotalOffset;
  3143. PBYTE lpByte = NULL;
  3144. SC_HANDLE hScm = NULL;
  3145. PTASK_LIST pt = NULL;
  3146. TASK_LIST_ENUM te;
  3147. PSYSTEM_PROCESS_INFORMATION pFirst, pCurrent;
  3148. LPENUM_SERVICE_STATUS_PROCESS pInfo = NULL;
  3149. CONST PWCHAR c_pwszSystem = L"System Process";
  3150. CONST PWCHAR c_pwszService = L"Svcs";
  3151. CONST PWCHAR c_pwszTitle = L"Title";
  3152. do
  3153. {
  3154. hScm = OpenSCManager(
  3155. NULL,
  3156. NULL,
  3157. SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
  3158. if (!hScm)
  3159. {
  3160. break;
  3161. }
  3162. do
  3163. {
  3164. RutlFree(pInfo);
  3165. pInfo = NULL;
  3166. pInfo = RutlAlloc(uBuffSize, TRUE);
  3167. if (!pInfo)
  3168. {
  3169. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  3170. break;
  3171. }
  3172. dwErr = NO_ERROR;
  3173. if (!EnumServicesStatusEx(
  3174. hScm,
  3175. SC_ENUM_PROCESS_INFO,
  3176. SERVICE_WIN32,
  3177. SERVICE_ACTIVE,
  3178. (LPBYTE)pInfo,
  3179. uBuffSize,
  3180. &uBuffSize,
  3181. &dwNumServices,
  3182. &dwResume,
  3183. NULL))
  3184. {
  3185. dwErr = GetLastError();
  3186. }
  3187. } while ((ERROR_MORE_DATA == dwErr) && (++ulAttempts < 2));
  3188. if (dwErr || dwNumServices < 1)
  3189. {
  3190. break;
  3191. }
  3192. lpByte = GetSystemProcessInfo();
  3193. if (!lpByte)
  3194. {
  3195. break;
  3196. }
  3197. //
  3198. // Count the number of System Proccesses
  3199. //
  3200. pFirst = pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[0];
  3201. for (ulNumSysProc = TotalOffset = 0; pCurrent->NextEntryOffset;
  3202. TotalOffset += pCurrent->NextEntryOffset)
  3203. {
  3204. pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[TotalOffset];
  3205. ulNumSysProc++;
  3206. }
  3207. pt = RutlAlloc(ulNumSysProc * sizeof(TASK_LIST), TRUE);
  3208. if (!pt)
  3209. {
  3210. break;
  3211. }
  3212. //
  3213. // Init TASK_LIST
  3214. //
  3215. pFirst = pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[0];
  3216. for (i = TotalOffset = 0; pCurrent->NextEntryOffset;
  3217. TotalOffset += pCurrent->NextEntryOffset)
  3218. {
  3219. pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[TotalOffset];
  3220. pt[i++].dwProcessId = PtrToUlong(pCurrent->UniqueProcessId);
  3221. }
  3222. te.tlist = pt;
  3223. te.dwNumTasks = ulNumSysProc;
  3224. GetWindowTitles(&te);
  3225. pFirst = pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[0];
  3226. for (TotalOffset = 0; pCurrent->NextEntryOffset;
  3227. TotalOffset += pCurrent->NextEntryOffset)
  3228. {
  3229. BOOL bPrinted = FALSE;
  3230. DWORD dwCurrentPid;
  3231. fOk = TRUE;
  3232. pCurrent = (PSYSTEM_PROCESS_INFORMATION)&lpByte[TotalOffset];
  3233. dwCurrentPid = PtrToUlong(pCurrent->UniqueProcessId);
  3234. BufferWriteMessage(
  3235. pBuff,
  3236. g_hModule,
  3237. MSG_RASDIAG_SHOW_PROCESS,
  3238. dwCurrentPid,
  3239. pCurrent->ImageName.Buffer ?
  3240. pCurrent->ImageName.Buffer : c_pwszSystem);
  3241. for (i = 0; i < dwNumServices; i++)
  3242. {
  3243. if(pInfo[i].ServiceStatusProcess.dwProcessId == dwCurrentPid)
  3244. {
  3245. if (!bPrinted)
  3246. {
  3247. BufferWriteMessage(
  3248. pBuff,
  3249. g_hModule,
  3250. MSG_RASDIAG_SHOW_PROCESS_TITLE,
  3251. c_pwszService,
  3252. pInfo[i].lpServiceName);
  3253. bPrinted = TRUE;
  3254. }
  3255. else
  3256. {
  3257. BufferWriteMessage(
  3258. pBuff,
  3259. g_hModule,
  3260. MSG_RASDIAG_SHOW_PROCESS_SVCNAME,
  3261. pInfo[i].lpServiceName);
  3262. }
  3263. }
  3264. }
  3265. if (bPrinted)
  3266. {
  3267. WriteNewLine(pBuff);
  3268. continue;
  3269. }
  3270. for (i = 0; i < te.dwNumTasks; i++)
  3271. {
  3272. if(((te.tlist)[i].dwProcessId == dwCurrentPid)
  3273. && (te.tlist)[i].hwnd)
  3274. {
  3275. BufferWriteMessage(
  3276. pBuff,
  3277. g_hModule,
  3278. MSG_RASDIAG_SHOW_PROCESS_TITLE,
  3279. c_pwszTitle,
  3280. (te.tlist)[i].szWindowTitle);
  3281. WriteNewLine(pBuff);
  3282. bPrinted = TRUE;
  3283. }
  3284. }
  3285. if (!bPrinted)
  3286. {
  3287. WriteNewLine(pBuff);
  3288. }
  3289. }
  3290. } while (FALSE);
  3291. //
  3292. // Clean up
  3293. //
  3294. RutlFree(pt);
  3295. RutlFree(te.lpszWinSta);
  3296. RutlFree(te.lpszDesk);
  3297. FreeSystemProcessInfo(lpByte);
  3298. RutlFree(pInfo);
  3299. if (hScm)
  3300. {
  3301. CloseServiceHandle(hScm);
  3302. }
  3303. if (!fOk)
  3304. {
  3305. BufferWriteMessage(pBuff, g_hModule, EMSG_RASDIAG_SHOW_CONFIG_PROC);
  3306. }
  3307. return;
  3308. }
  3309. VOID
  3310. PrintConsoleUtils(
  3311. IN REPORT_INFO* pInfo)
  3312. {
  3313. UINT i;
  3314. DWORD dwWritten;
  3315. WCHAR wszTempBuffer[MAX_PATH + 1], wszTempFileName[MAX_PATH + 1];
  3316. HANDLE hFile = NULL;
  3317. STARTUPINFO si;
  3318. PROCESS_INFORMATION pi;
  3319. do
  3320. {
  3321. ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
  3322. ZeroMemory(&si, sizeof(STARTUPINFO));
  3323. si.cb = sizeof(STARTUPINFO);
  3324. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  3325. si.wShowWindow = SW_HIDE;
  3326. if (CopyTempFileName(wszTempFileName))
  3327. {
  3328. break;
  3329. }
  3330. hFile = CreateFile(
  3331. wszTempFileName,
  3332. GENERIC_READ | GENERIC_WRITE,
  3333. FILE_SHARE_READ | FILE_SHARE_WRITE,
  3334. NULL,
  3335. CREATE_ALWAYS,
  3336. FILE_ATTRIBUTE_TEMPORARY,
  3337. NULL);
  3338. if(hFile == INVALID_HANDLE_VALUE)
  3339. {
  3340. break;
  3341. }
  3342. if (!DuplicateHandle(
  3343. GetCurrentProcess(),
  3344. hFile,
  3345. GetCurrentProcess(),
  3346. &si.hStdOutput,
  3347. 0,
  3348. TRUE,
  3349. DUPLICATE_SAME_ACCESS) ||
  3350. (!(si.hStdOutput)) || (si.hStdOutput == INVALID_HANDLE_VALUE)
  3351. )
  3352. {
  3353. break;
  3354. }
  3355. for (i = 0; i < g_ulNumCmdLines; i++)
  3356. {
  3357. lstrcpyn(wszTempBuffer, g_CmdLineUtils[i].pwszCmdLine, MAX_PATH);
  3358. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameStart);
  3359. BufferWriteFileStrW(pInfo->pBuff, g_CmdLineUtils[i].pwszAnchor);
  3360. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameMiddle);
  3361. BufferWriteFileStrW(pInfo->pBuff, wszTempBuffer);
  3362. WriteLinkBackToToc(pInfo->pBuff);
  3363. BufferWriteFileStrW(pInfo->pBuff, g_pwszAnNameEnd);
  3364. if (!CreateProcess(
  3365. NULL,
  3366. wszTempBuffer,
  3367. NULL,
  3368. NULL,
  3369. TRUE,
  3370. 0,
  3371. NULL,
  3372. NULL,
  3373. &si,
  3374. &pi)
  3375. )
  3376. {
  3377. continue;
  3378. }
  3379. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreStart);
  3380. //
  3381. // let the util work for up to 1 min, then kill it
  3382. //
  3383. if (WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, 60 * 1000L))
  3384. {
  3385. TerminateProcess(pi.hProcess, 0);
  3386. BufferWriteMessage(
  3387. pInfo->pBuff,
  3388. g_hModule,
  3389. EMSG_RASDIAG_SHOW_CONFIG_CONSOLE_TIMOUT);
  3390. }
  3391. else if (PrintFile(pInfo, wszTempFileName, FALSE, NULL))
  3392. {
  3393. BufferWriteMessage(
  3394. pInfo->pBuff,
  3395. g_hModule,
  3396. EMSG_RASDIAG_SHOW_CONFIG_CONSOLE);
  3397. }
  3398. BufferWriteFileStrW(pInfo->pBuff, g_pwszPreEnd);
  3399. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  3400. SetEndOfFile(hFile);
  3401. CloseHandle(pi.hThread);
  3402. CloseHandle(pi.hProcess);
  3403. }
  3404. CloseHandle(si.hStdOutput);
  3405. CloseHandle(hFile);
  3406. si.hStdOutput = hFile = NULL;
  3407. //
  3408. // Delete the temp file
  3409. //
  3410. DeleteFile(wszTempFileName);
  3411. } while (FALSE);
  3412. //
  3413. // Clean up
  3414. //
  3415. if (si.hStdOutput)
  3416. {
  3417. CloseHandle(si.hStdOutput);
  3418. }
  3419. if (hFile)
  3420. {
  3421. CloseHandle(hFile);
  3422. }
  3423. return;
  3424. }
  3425. VOID
  3426. PrintWinMsdReport(
  3427. IN REPORT_INFO* pInfo)
  3428. {
  3429. BOOL fOk = FALSE;
  3430. DWORD dwSize = 0;
  3431. WCHAR wszInfoPath[MAX_PATH + 1], wszTempFileName[MAX_PATH + 1];
  3432. PWCHAR pwszCmdLine = NULL;
  3433. STARTUPINFO si;
  3434. PROCESS_INFORMATION pi;
  3435. static CONST PWCHAR c_pwszWinMsd = L"msinfo32.exe /report ";
  3436. do
  3437. {
  3438. if (!GetCommonFolderPath(GET_FOR_MSINFO, wszInfoPath))
  3439. {
  3440. break;
  3441. }
  3442. if (CopyTempFileName(wszTempFileName))
  3443. {
  3444. break;
  3445. }
  3446. dwSize = lstrlen(wszInfoPath) + lstrlen(c_pwszWinMsd) +
  3447. lstrlen(wszTempFileName) + 1;
  3448. pwszCmdLine = RutlAlloc(dwSize * sizeof(WCHAR), TRUE);
  3449. if (!pwszCmdLine)
  3450. {
  3451. break;
  3452. }
  3453. lstrcpy(pwszCmdLine, wszInfoPath);
  3454. lstrcat(pwszCmdLine, c_pwszWinMsd);
  3455. lstrcat(pwszCmdLine, wszTempFileName);
  3456. ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
  3457. ZeroMemory(&si, sizeof(STARTUPINFO));
  3458. si.cb = sizeof(STARTUPINFO);
  3459. si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
  3460. si.wShowWindow = SW_HIDE;
  3461. if (!CreateProcess(
  3462. NULL,
  3463. pwszCmdLine,
  3464. NULL,
  3465. NULL,
  3466. TRUE,
  3467. 0,
  3468. NULL,
  3469. NULL,
  3470. &si,
  3471. &pi)
  3472. )
  3473. {
  3474. break;
  3475. }
  3476. //
  3477. // let the util work for up to 3 min, then kill it
  3478. //
  3479. if (WAIT_TIMEOUT == WaitForSingleObject(pi.hProcess, 180 * 1000L))
  3480. {
  3481. TerminateProcess(pi.hProcess, 0);
  3482. }
  3483. CloseHandle(pi.hThread);
  3484. CloseHandle(pi.hProcess);
  3485. if (!PrintFile(pInfo, wszTempFileName, FALSE, NULL))
  3486. {
  3487. fOk = TRUE;
  3488. }
  3489. DeleteFile(wszTempFileName);
  3490. } while (FALSE);
  3491. //
  3492. // Clean up
  3493. //
  3494. RutlFree(pwszCmdLine);
  3495. if (!fOk)
  3496. {
  3497. BufferWriteMessage(
  3498. pInfo->pBuff,
  3499. g_hModule,
  3500. EMSG_RASDIAG_SHOW_CONFIG_WINMSD);
  3501. }
  3502. return;
  3503. }
  3504. BOOL
  3505. PrintRasPbk(
  3506. IN REPORT_INFO* pInfo,
  3507. IN DWORD dwType)
  3508. {
  3509. BOOL fOk = FALSE;
  3510. DWORD dwSize = 0;
  3511. WCHAR wszTemp[MAX_PATH + 1];
  3512. PWCHAR pwszFilePath = NULL;
  3513. static CONST PWCHAR c_pwszRasphone = L"rasphone.pbk";
  3514. do
  3515. {
  3516. if (!GetCommonFolderPath(dwType | GET_FOR_RAS, wszTemp))
  3517. {
  3518. break;
  3519. }
  3520. dwSize = lstrlen(wszTemp) + lstrlen(c_pwszRasphone) + 1;
  3521. pwszFilePath = RutlAlloc(dwSize * sizeof(WCHAR), TRUE);
  3522. if (!pwszFilePath)
  3523. {
  3524. break;
  3525. }
  3526. lstrcpy(pwszFilePath, wszTemp);
  3527. lstrcat(pwszFilePath, c_pwszRasphone);
  3528. if (!PrintFile(pInfo, pwszFilePath, TRUE, NULL))
  3529. {
  3530. fOk = TRUE;
  3531. }
  3532. } while (FALSE);
  3533. //
  3534. // Clean up
  3535. //
  3536. RutlFree(pwszFilePath);
  3537. return fOk;
  3538. }
  3539. VOID
  3540. PrintAllRasPbks(
  3541. IN REPORT_INFO* pInfo)
  3542. {
  3543. BOOL fOk = FALSE;
  3544. if (PrintRasPbk(pInfo, ALL_USERS_PROF))
  3545. {
  3546. fOk = TRUE;
  3547. }
  3548. if (PrintRasPbk(pInfo, CURRENT_USER))
  3549. {
  3550. fOk = TRUE;
  3551. }
  3552. if (!fOk)
  3553. {
  3554. BufferWriteMessage(
  3555. pInfo->pBuff,
  3556. g_hModule,
  3557. EMSG_RASDIAG_SHOW_CONFIG_ALLPBK);
  3558. }
  3559. return;
  3560. }
  3561. //
  3562. // Return a block containing information about all processes
  3563. // currently running in the system.
  3564. //
  3565. PUCHAR
  3566. GetSystemProcessInfo()
  3567. {
  3568. ULONG ulcbLargeBuffer = 64 * 1024;
  3569. PUCHAR pLargeBuffer;
  3570. NTSTATUS status;
  3571. //
  3572. // Get the process list.
  3573. //
  3574. for (;;)
  3575. {
  3576. pLargeBuffer = VirtualAlloc(
  3577. NULL,
  3578. ulcbLargeBuffer, MEM_COMMIT, PAGE_READWRITE);
  3579. if (pLargeBuffer == NULL)
  3580. {
  3581. return NULL;
  3582. }
  3583. status = NtQuerySystemInformation(
  3584. SystemProcessInformation,
  3585. pLargeBuffer,
  3586. ulcbLargeBuffer,
  3587. NULL);
  3588. if (status == STATUS_SUCCESS)
  3589. {
  3590. break;
  3591. }
  3592. if (status == STATUS_INFO_LENGTH_MISMATCH)
  3593. {
  3594. VirtualFree(pLargeBuffer, 0, MEM_RELEASE);
  3595. ulcbLargeBuffer += 8192;
  3596. }
  3597. }
  3598. return pLargeBuffer;
  3599. }
  3600. VOID
  3601. FreeSystemProcessInfo(
  3602. IN PUCHAR pProcessInfo)
  3603. {
  3604. if (pProcessInfo)
  3605. {
  3606. VirtualFree(pProcessInfo, 0, MEM_RELEASE);
  3607. }
  3608. }