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.

964 lines
22 KiB

  1. /*
  2. File: rasdiag.c
  3. 'ras diag' sub context
  4. 07/26/01
  5. */
  6. #include "precomp.h"
  7. //
  8. // The guid for this context
  9. //
  10. GUID g_RasDiagGuid = RASDIAG_GUID;
  11. //
  12. // The commands supported in this context
  13. //
  14. CMD_ENTRY g_RasDiagSetCmdTable[] =
  15. {
  16. CREATE_CMD_ENTRY(RASDIAG_SET_RASTRACE, HandleTraceSet),
  17. CREATE_CMD_ENTRY(RASDIAG_SET_TRACEALL, RasDiagHandleSetTraceAll),
  18. CREATE_CMD_ENTRY(RASDIAG_SET_MODEMTRACE, RasDiagHandleSetModemTrace),
  19. CREATE_CMD_ENTRY(RASDIAG_SET_CMTRACE, RasDiagHandleSetCmTrace),
  20. CREATE_CMD_ENTRY(RASDIAG_SET_AUDITING, RasDiagHandleSetAuditing),
  21. };
  22. CMD_ENTRY g_RasDiagShowCmdTable[] =
  23. {
  24. CREATE_CMD_ENTRY(RASDIAG_SHOW_RASTRACE, HandleTraceShow),
  25. CREATE_CMD_ENTRY(RASDIAG_SHOW_TRACEALL, RasDiagHandleShowTraceAll),
  26. CREATE_CMD_ENTRY(RASDIAG_SHOW_MODEMTRACE, RasDiagHandleShowModemTrace),
  27. CREATE_CMD_ENTRY(RASDIAG_SHOW_CMTRACE, RasDiagHandleShowCmTrace),
  28. CREATE_CMD_ENTRY(RASDIAG_SHOW_AUDITING, RasDiagHandleShowAuditing),
  29. CREATE_CMD_ENTRY(RASDIAG_SHOW_LOGS, RasDiagHandleShowLogs),
  30. CREATE_CMD_ENTRY(RASDIAG_SHOW_ALL, RasDiagHandleShowAll),
  31. CREATE_CMD_ENTRY(RASDIAG_SHOW_RASCHK, RasDiagHandleShowInstallation),
  32. CREATE_CMD_ENTRY(RASDIAG_SHOW_CONFIG, RasDiagHandleShowConfiguration),
  33. };
  34. CMD_GROUP_ENTRY g_RasDiagCmdGroups[] =
  35. {
  36. CREATE_CMD_GROUP_ENTRY(GROUP_SET, g_RasDiagSetCmdTable),
  37. CREATE_CMD_GROUP_ENTRY(GROUP_SHOW, g_RasDiagShowCmdTable),
  38. };
  39. static CONST ULONG g_ulRasDiagNumGroups = sizeof(g_RasDiagCmdGroups) /
  40. sizeof(CMD_GROUP_ENTRY);
  41. //
  42. // This command was never approved or properly tested, disabling but not
  43. // removing (for future consideration).
  44. //
  45. /*CMD_ENTRY g_TopCmds[] =
  46. {
  47. CREATE_CMD_ENTRY_EX(RASDIAG_REPAIR, RasDiagHandleRepairRas, CMD_FLAG_HIDDEN),
  48. };
  49. static CONST ULONG g_ulNumOfTopCmds = sizeof(g_TopCmds) / sizeof(CMD_ENTRY);*/
  50. //
  51. // Declarations from rasnetcfg
  52. //
  53. HRESULT
  54. HrInstallRas(
  55. IN CONST PWCHAR pszFilePath);
  56. HRESULT
  57. HrUninstallRas();
  58. PWCHAR
  59. RasDiagVerifyAnswerFile(
  60. IN CONST PWCHAR pwszFilePath);
  61. //
  62. // Local declarations
  63. //
  64. DWORD
  65. RasDiagHandleReport(
  66. IN RASDIAG_HANDLE_REPORT_FUNC_CB pCallback,
  67. IN OUT LPWSTR* ppwcArguments,
  68. IN DWORD dwCurrentIndex,
  69. IN DWORD dwArgCount,
  70. OUT BOOL* pbDone);
  71. //
  72. // Entry called by rasmontr to register this context
  73. //
  74. DWORD
  75. WINAPI
  76. RasDiagStartHelper(
  77. IN CONST GUID* pguidParent,
  78. IN DWORD dwVersion)
  79. {
  80. DWORD dwErr = NO_ERROR;
  81. NS_CONTEXT_ATTRIBUTES attMyAttributes;
  82. //
  83. // Initialize
  84. //
  85. ZeroMemory(&attMyAttributes, sizeof(attMyAttributes));
  86. attMyAttributes.dwVersion = RASDIAG_VERSION;
  87. attMyAttributes.pwszContext = L"diagnostics";
  88. attMyAttributes.guidHelper = g_RasDiagGuid;
  89. attMyAttributes.dwFlags = CMD_FLAG_LOCAL | CMD_FLAG_ONLINE;
  90. // attMyAttributes.ulNumTopCmds = g_ulNumOfTopCmds;
  91. // attMyAttributes.pTopCmds = (CMD_ENTRY (*)[])&g_TopCmds;
  92. attMyAttributes.ulNumGroups = g_ulRasDiagNumGroups;
  93. attMyAttributes.pCmdGroups = (CMD_GROUP_ENTRY (*)[])&g_RasDiagCmdGroups;
  94. attMyAttributes.pfnDumpFn = RasDiagDump;
  95. dwErr = RegisterContext(&attMyAttributes);
  96. return dwErr;
  97. }
  98. DWORD
  99. RasDiagDumpScriptHeader()
  100. {
  101. DisplayMessage(g_hModule, MSG_RASDIAG_SCRIPTHEADER);
  102. DisplayMessageT(DMP_RASDIAG_PUSHD);
  103. return NO_ERROR;
  104. }
  105. DWORD
  106. RasDiagDumpScriptFooter()
  107. {
  108. DisplayMessageT(DMP_RAS_POPD);
  109. DisplayMessage(g_hModule, MSG_RASDIAG_SCRIPTFOOTER);
  110. return NO_ERROR;
  111. }
  112. DWORD
  113. WINAPI
  114. RasDiagDump(
  115. IN LPCWSTR pwszRouter,
  116. IN OUT LPWSTR* ppwcArguments,
  117. IN DWORD dwArgCount,
  118. IN LPCVOID pvData)
  119. {
  120. RasDiagDumpScriptHeader();
  121. TraceDumpConfig();
  122. DisplayMessageT(MSG_NEWLINE);
  123. TraceDumpModem();
  124. DisplayMessageT(MSG_NEWLINE);
  125. TraceDumpCm();
  126. DisplayMessageT(MSG_NEWLINE);
  127. TraceDumpAuditing();
  128. DisplayMessageT(MSG_NEWLINE);
  129. RasDiagDumpScriptFooter();
  130. return NO_ERROR;
  131. }
  132. DWORD
  133. RasDiagHandleSetTraceAll(
  134. IN LPCWSTR pwszMachine,
  135. IN OUT LPWSTR* ppwcArguments,
  136. IN DWORD dwCurrentIndex,
  137. IN DWORD dwArgCount,
  138. IN DWORD dwFlags,
  139. IN LPCVOID pvData,
  140. OUT BOOL* pbDone)
  141. {
  142. DWORD dwErr = NO_ERROR, dwEnable;
  143. TOKEN_VALUE rgEnumState[] =
  144. {
  145. {TOKEN_DISABLED, 0},
  146. {TOKEN_ENABLED, 1},
  147. {TOKEN_CLEARED, 2}
  148. };
  149. RASMON_CMD_ARG pArgs[] =
  150. {
  151. {
  152. RASMONTR_CMD_TYPE_ENUM,
  153. {TOKEN_STATE, TRUE, FALSE},
  154. rgEnumState,
  155. sizeof(rgEnumState) / sizeof(*rgEnumState),
  156. NULL
  157. }
  158. };
  159. do
  160. {
  161. //
  162. // Parse the command line
  163. //
  164. dwErr = RutlParse(
  165. ppwcArguments,
  166. dwCurrentIndex,
  167. dwArgCount,
  168. pbDone,
  169. pArgs,
  170. sizeof(pArgs) / sizeof(*pArgs));
  171. BREAK_ON_DWERR(dwErr);
  172. //
  173. // Get EnumState
  174. //
  175. dwEnable = RASMON_CMD_ARG_GetDword(&pArgs[0]);
  176. if (dwEnable != 2)
  177. {
  178. DiagSetAll(dwEnable ? TRUE : FALSE, TRUE);
  179. }
  180. else
  181. {
  182. DiagClearAll(TRUE);
  183. }
  184. } while (FALSE);
  185. return dwErr;
  186. }
  187. DWORD
  188. RasDiagHandleShowTraceAll(
  189. IN LPCWSTR pwszMachine,
  190. IN OUT LPWSTR* ppwcArguments,
  191. IN DWORD dwCurrentIndex,
  192. IN DWORD dwArgCount,
  193. IN DWORD dwFlags,
  194. IN LPCVOID pvData,
  195. OUT BOOL* pbDone)
  196. {
  197. DWORD dwErr = NO_ERROR;
  198. do
  199. {
  200. //
  201. // Verify zero args
  202. //
  203. if ((dwArgCount - dwCurrentIndex) > 0)
  204. {
  205. dwErr = ERROR_INVALID_SYNTAX;
  206. break;
  207. }
  208. TraceShowAll();
  209. } while (FALSE);
  210. return dwErr;
  211. }
  212. DWORD
  213. RasDiagHandleSetModemTrace(
  214. IN LPCWSTR pwszMachine,
  215. IN OUT LPWSTR* ppwcArguments,
  216. IN DWORD dwCurrentIndex,
  217. IN DWORD dwArgCount,
  218. IN DWORD dwFlags,
  219. IN LPCVOID pvData,
  220. OUT BOOL* pbDone)
  221. {
  222. DWORD dwErr = NO_ERROR, dwEnable;
  223. TOKEN_VALUE rgEnumState[] =
  224. {
  225. {TOKEN_DISABLED, 0},
  226. {TOKEN_ENABLED, 1},
  227. };
  228. RASMON_CMD_ARG pArgs[] =
  229. {
  230. {
  231. RASMONTR_CMD_TYPE_ENUM,
  232. {TOKEN_STATE, TRUE, FALSE},
  233. rgEnumState,
  234. sizeof(rgEnumState) / sizeof(*rgEnumState),
  235. NULL
  236. }
  237. };
  238. do
  239. {
  240. //
  241. // Parse the command line
  242. //
  243. dwErr = RutlParse(
  244. ppwcArguments,
  245. dwCurrentIndex,
  246. dwArgCount,
  247. pbDone,
  248. pArgs,
  249. sizeof(pArgs) / sizeof(*pArgs));
  250. BREAK_ON_DWERR(dwErr);
  251. //
  252. // Get EnumState
  253. //
  254. dwEnable = RASMON_CMD_ARG_GetDword(&pArgs[0]);
  255. if (TraceEnableDisableModem(dwEnable ? TRUE : FALSE))
  256. {
  257. DisplayMessage(g_hModule, MSG_RASDIAG_SET_MODEMTRACE_OK);
  258. }
  259. else
  260. {
  261. DisplayMessage(g_hModule, EMSG_RASDIAG_SET_MODEMTRACE_FAIL);
  262. }
  263. } while (FALSE);
  264. return dwErr;
  265. }
  266. DWORD
  267. RasDiagHandleShowModemTrace(
  268. IN LPCWSTR pwszMachine,
  269. IN OUT LPWSTR* ppwcArguments,
  270. IN DWORD dwCurrentIndex,
  271. IN DWORD dwArgCount,
  272. IN DWORD dwFlags,
  273. IN LPCVOID pvData,
  274. OUT BOOL* pbDone)
  275. {
  276. DWORD dwErr = NO_ERROR;
  277. do
  278. {
  279. //
  280. // Verify zero args
  281. //
  282. if ((dwArgCount - dwCurrentIndex) > 0)
  283. {
  284. dwErr = ERROR_INVALID_SYNTAX;
  285. break;
  286. }
  287. if (TraceShowModem())
  288. {
  289. DisplayMessage(g_hModule, MSG_RASDIAG_SHOW_MODEMTRACE_ENABLED);
  290. }
  291. else
  292. {
  293. DisplayMessage(g_hModule, EMSG_RASDIAG_SHOW_MODEMTRACE_DISABLED);
  294. }
  295. } while (FALSE);
  296. return dwErr;
  297. }
  298. DWORD
  299. RasDiagHandleSetCmTrace(
  300. IN LPCWSTR pwszMachine,
  301. IN OUT LPWSTR* ppwcArguments,
  302. IN DWORD dwCurrentIndex,
  303. IN DWORD dwArgCount,
  304. IN DWORD dwFlags,
  305. IN LPCVOID pvData,
  306. OUT BOOL* pbDone)
  307. {
  308. DWORD dwErr = NO_ERROR, dwEnable;
  309. TOKEN_VALUE rgEnumState[] =
  310. {
  311. {TOKEN_DISABLED, 0},
  312. {TOKEN_ENABLED, 1},
  313. };
  314. RASMON_CMD_ARG pArgs[] =
  315. {
  316. {
  317. RASMONTR_CMD_TYPE_ENUM,
  318. {TOKEN_STATE, TRUE, FALSE},
  319. rgEnumState,
  320. sizeof(rgEnumState) / sizeof(*rgEnumState),
  321. NULL
  322. }
  323. };
  324. do
  325. {
  326. //
  327. // Parse the command line
  328. //
  329. dwErr = RutlParse(
  330. ppwcArguments,
  331. dwCurrentIndex,
  332. dwArgCount,
  333. pbDone,
  334. pArgs,
  335. sizeof(pArgs) / sizeof(*pArgs));
  336. BREAK_ON_DWERR(dwErr);
  337. //
  338. // Get EnumState
  339. //
  340. dwEnable = RASMON_CMD_ARG_GetDword(&pArgs[0]);
  341. if (TraceEnableDisableCm(dwEnable ? TRUE : FALSE))
  342. {
  343. DisplayMessage(g_hModule, MSG_RASDIAG_SET_CMTRACE_OK);
  344. }
  345. else
  346. {
  347. DisplayMessage(g_hModule, EMSG_RASDIAG_SET_CMTRACE_FAIL);
  348. }
  349. } while (FALSE);
  350. return dwErr;
  351. }
  352. DWORD
  353. RasDiagHandleShowCmTrace(
  354. IN LPCWSTR pwszMachine,
  355. IN OUT LPWSTR* ppwcArguments,
  356. IN DWORD dwCurrentIndex,
  357. IN DWORD dwArgCount,
  358. IN DWORD dwFlags,
  359. IN LPCVOID pvData,
  360. OUT BOOL* pbDone)
  361. {
  362. DWORD dwErr = NO_ERROR;
  363. do
  364. {
  365. //
  366. // Verify zero args
  367. //
  368. if ((dwArgCount - dwCurrentIndex) > 0)
  369. {
  370. dwErr = ERROR_INVALID_SYNTAX;
  371. break;
  372. }
  373. if (TraceShowCm())
  374. {
  375. DisplayMessage(g_hModule, MSG_RASDIAG_SHOW_CMTRACE_ENABLED);
  376. }
  377. else
  378. {
  379. DisplayMessage(g_hModule, EMSG_RASDIAG_SHOW_CMTRACE_DISABLED);
  380. }
  381. } while (FALSE);
  382. return dwErr;
  383. }
  384. DWORD
  385. RasDiagHandleSetAuditing(
  386. IN LPCWSTR pwszMachine,
  387. IN OUT LPWSTR* ppwcArguments,
  388. IN DWORD dwCurrentIndex,
  389. IN DWORD dwArgCount,
  390. IN DWORD dwFlags,
  391. IN LPCVOID pvData,
  392. OUT BOOL* pbDone)
  393. {
  394. DWORD dwErr = NO_ERROR, dwEnable;
  395. TOKEN_VALUE rgEnumState[] =
  396. {
  397. {TOKEN_DISABLED, 0},
  398. {TOKEN_ENABLED, 1},
  399. };
  400. RASMON_CMD_ARG pArgs[] =
  401. {
  402. {
  403. RASMONTR_CMD_TYPE_ENUM,
  404. {TOKEN_STATE, TRUE, FALSE},
  405. rgEnumState,
  406. sizeof(rgEnumState) / sizeof(*rgEnumState),
  407. NULL
  408. }
  409. };
  410. do
  411. {
  412. //
  413. // Parse the command line
  414. //
  415. dwErr = RutlParse(
  416. ppwcArguments,
  417. dwCurrentIndex,
  418. dwArgCount,
  419. pbDone,
  420. pArgs,
  421. sizeof(pArgs) / sizeof(*pArgs));
  422. BREAK_ON_DWERR(dwErr);
  423. //
  424. // Get EnumState
  425. //
  426. dwEnable = RASMON_CMD_ARG_GetDword(&pArgs[0]);
  427. if (TraceEnableDisableAuditing(FALSE, dwEnable ? TRUE : FALSE))
  428. {
  429. DisplayMessage(g_hModule, MSG_RASDIAG_SET_AUDITING_OK);
  430. }
  431. else
  432. {
  433. DisplayMessage(g_hModule, EMSG_RASDIAG_SET_AUDITING_FAIL);
  434. }
  435. } while (FALSE);
  436. return dwErr;
  437. }
  438. DWORD
  439. RasDiagHandleShowAuditing(
  440. IN LPCWSTR pwszMachine,
  441. IN OUT LPWSTR* ppwcArguments,
  442. IN DWORD dwCurrentIndex,
  443. IN DWORD dwArgCount,
  444. IN DWORD dwFlags,
  445. IN LPCVOID pvData,
  446. OUT BOOL* pbDone)
  447. {
  448. DWORD dwErr = NO_ERROR;
  449. do
  450. {
  451. //
  452. // Verify zero args
  453. //
  454. if ((dwArgCount - dwCurrentIndex) > 0)
  455. {
  456. dwErr = ERROR_INVALID_SYNTAX;
  457. break;
  458. }
  459. if (TraceEnableDisableAuditing(TRUE, FALSE))
  460. {
  461. DisplayMessage(g_hModule, MSG_RASDIAG_SHOW_AUDITING_ENABLED);
  462. }
  463. else
  464. {
  465. DisplayMessage(g_hModule, EMSG_RASDIAG_SHOW_AUDITING_DISABLED);
  466. }
  467. } while (FALSE);
  468. return dwErr;
  469. }
  470. VOID
  471. RasDiagHandleShowLogsCb(
  472. IN REPORT_INFO* pInfo)
  473. {
  474. PrintTableOfContents(pInfo, SHOW_LOGS);
  475. TraceCollectAll(pInfo);
  476. return;
  477. }
  478. DWORD
  479. RasDiagHandleShowLogs(
  480. IN LPCWSTR pwszMachine,
  481. IN OUT LPWSTR* ppwcArguments,
  482. IN DWORD dwCurrentIndex,
  483. IN DWORD dwArgCount,
  484. IN DWORD dwFlags,
  485. IN LPCVOID pvData,
  486. OUT BOOL* pbDone)
  487. {
  488. return RasDiagHandleReport(
  489. RasDiagHandleShowLogsCb,
  490. ppwcArguments,
  491. dwCurrentIndex,
  492. dwArgCount,
  493. pbDone);
  494. }
  495. VOID
  496. RasDiagHandleShowAllCb(
  497. IN REPORT_INFO* pInfo)
  498. {
  499. PrintTableOfContents(pInfo, SHOW_ALL);
  500. RasDiagShowAll(pInfo);
  501. return;
  502. }
  503. DWORD
  504. RasDiagHandleShowAll(
  505. IN LPCWSTR pwszMachine,
  506. IN OUT LPWSTR* ppwcArguments,
  507. IN DWORD dwCurrentIndex,
  508. IN DWORD dwArgCount,
  509. IN DWORD dwFlags,
  510. IN LPCVOID pvData,
  511. OUT BOOL* pbDone)
  512. {
  513. return RasDiagHandleReport(
  514. RasDiagHandleShowAllCb,
  515. ppwcArguments,
  516. dwCurrentIndex,
  517. dwArgCount,
  518. pbDone);
  519. }
  520. VOID
  521. RasDiagHandleShowInstallationCb(
  522. IN REPORT_INFO* pInfo)
  523. {
  524. PrintTableOfContents(pInfo, SHOW_INSTALL);
  525. RasDiagShowInstallation(pInfo);
  526. return;
  527. }
  528. DWORD
  529. RasDiagHandleShowInstallation(
  530. IN LPCWSTR pwszMachine,
  531. IN OUT LPWSTR* ppwcArguments,
  532. IN DWORD dwCurrentIndex,
  533. IN DWORD dwArgCount,
  534. IN DWORD dwFlags,
  535. IN LPCVOID pvData,
  536. OUT BOOL* pbDone)
  537. {
  538. return RasDiagHandleReport(
  539. RasDiagHandleShowInstallationCb,
  540. ppwcArguments,
  541. dwCurrentIndex,
  542. dwArgCount,
  543. pbDone);
  544. }
  545. VOID
  546. RasDiagHandleShowConfigurationCb(
  547. IN REPORT_INFO* pInfo)
  548. {
  549. PrintTableOfContents(pInfo, SHOW_CONFIG);
  550. RasDiagShowConfiguration(pInfo);
  551. return;
  552. }
  553. DWORD
  554. RasDiagHandleShowConfiguration(
  555. IN LPCWSTR pwszMachine,
  556. IN OUT LPWSTR* ppwcArguments,
  557. IN DWORD dwCurrentIndex,
  558. IN DWORD dwArgCount,
  559. IN DWORD dwFlags,
  560. IN LPCVOID pvData,
  561. OUT BOOL* pbDone)
  562. {
  563. return RasDiagHandleReport(
  564. RasDiagHandleShowConfigurationCb,
  565. ppwcArguments,
  566. dwCurrentIndex,
  567. dwArgCount,
  568. pbDone);
  569. }
  570. DWORD
  571. RasDiagHandleRepairRas(
  572. IN LPCWSTR pwszMachine,
  573. IN OUT LPWSTR* ppwcArguments,
  574. IN DWORD dwCurrentIndex,
  575. IN DWORD dwArgCount,
  576. IN DWORD dwFlags,
  577. IN LPCVOID pvData,
  578. OUT BOOL* pbDone)
  579. {
  580. DWORD dwErr = NO_ERROR;
  581. PWCHAR pszFilePath = NULL;
  582. HRESULT hr = S_OK;
  583. RASMON_CMD_ARG pArgs[] =
  584. {
  585. {
  586. RASMONTR_CMD_TYPE_STRING,
  587. {TOKEN_ANSWERFILE, FALSE, FALSE},
  588. NULL,
  589. 0,
  590. NULL
  591. }
  592. };
  593. do
  594. {
  595. //
  596. // Parse the command line
  597. //
  598. dwErr = RutlParse(
  599. ppwcArguments,
  600. dwCurrentIndex,
  601. dwArgCount,
  602. pbDone,
  603. pArgs,
  604. sizeof(pArgs) / sizeof(*pArgs));
  605. BREAK_ON_DWERR(dwErr);
  606. //
  607. // Check for answer file
  608. //
  609. if (RASMON_CMD_ARG_Present(&pArgs[0]))
  610. {
  611. pszFilePath = RasDiagVerifyAnswerFile(
  612. RASMON_CMD_ARG_GetPsz(&pArgs[0]));
  613. if (!pszFilePath)
  614. {
  615. DisplayMessage(g_hModule, EMSG_RASDIAG_BAD_ANSWERFILE);
  616. break;
  617. }
  618. }
  619. hr = HrUninstallRas();
  620. if (SUCCEEDED(hr))
  621. {
  622. hr = HrInstallRas(pszFilePath);
  623. if (SUCCEEDED(hr))
  624. {
  625. DisplayMessage(g_hModule, MSG_RASDIAG_REPAIR_SUCCESS_REBOOT);
  626. }
  627. else
  628. {
  629. DisplayMessage(g_hModule, EMSG_RASDIAG_REPAIR_FAIL);
  630. }
  631. }
  632. else
  633. {
  634. DisplayMessage(g_hModule, EMSG_RASDIAG_REPAIR_FAIL);
  635. }
  636. } while (FALSE);
  637. //
  638. // Cleanup
  639. //
  640. RutlFree(pszFilePath);
  641. return dwErr;
  642. }
  643. DWORD
  644. RasDiagHandleReport(
  645. IN RASDIAG_HANDLE_REPORT_FUNC_CB pCallback,
  646. IN OUT LPWSTR* ppwcArguments,
  647. IN DWORD dwCurrentIndex,
  648. IN DWORD dwArgCount,
  649. OUT BOOL* pbDone)
  650. {
  651. DWORD dwErr = NO_ERROR, dwCompress = 0, dwDest;
  652. WCHAR wszTempFileName[MAX_PATH + 1];
  653. PWCHAR pwszDest = NULL, pwszCabFile = NULL, pwszTempFile = NULL;
  654. REPORT_INFO ReportInfo;
  655. BUFFER_WRITE_FILE Buff;
  656. TOKEN_VALUE rgEnumDest[] =
  657. {
  658. {TOKEN_FILE, 0},
  659. {TOKEN_EMAIL, 1},
  660. };
  661. TOKEN_VALUE rgEnumCompress[] =
  662. {
  663. {TOKEN_DISABLED, 0},
  664. {TOKEN_ENABLED, 1},
  665. };
  666. TOKEN_VALUE rgEnumVerbose[] =
  667. {
  668. {TOKEN_DISABLED, 0},
  669. {TOKEN_ENABLED, 1},
  670. };
  671. RASMON_CMD_ARG pArgs[] =
  672. {
  673. {
  674. RASMONTR_CMD_TYPE_ENUM,
  675. {TOKEN_TYPE, TRUE, FALSE},
  676. rgEnumDest,
  677. sizeof(rgEnumDest) / sizeof(*rgEnumDest),
  678. NULL
  679. },
  680. {
  681. RASMONTR_CMD_TYPE_STRING,
  682. {TOKEN_DESTINATION, TRUE, FALSE},
  683. NULL,
  684. 0,
  685. NULL
  686. },
  687. {
  688. RASMONTR_CMD_TYPE_ENUM,
  689. {TOKEN_COMPRESSION, FALSE, FALSE},
  690. rgEnumCompress,
  691. sizeof(rgEnumCompress) / sizeof(*rgEnumCompress),
  692. NULL
  693. },
  694. {
  695. RASMONTR_CMD_TYPE_DWORD,
  696. {TOKEN_HOURS, FALSE, FALSE},
  697. NULL,
  698. 0,
  699. NULL
  700. },
  701. {
  702. RASMONTR_CMD_TYPE_ENUM,
  703. {TOKEN_VERBOSE, FALSE, FALSE},
  704. rgEnumVerbose,
  705. sizeof(rgEnumVerbose) / sizeof(*rgEnumVerbose),
  706. NULL
  707. },
  708. };
  709. do
  710. {
  711. if (!pCallback)
  712. {
  713. dwErr = ERROR_INVALID_SYNTAX;
  714. break;
  715. }
  716. //
  717. // Parse the command line
  718. //
  719. dwErr = RutlParse(
  720. ppwcArguments,
  721. dwCurrentIndex,
  722. dwArgCount,
  723. pbDone,
  724. pArgs,
  725. sizeof(pArgs) / sizeof(*pArgs));
  726. BREAK_ON_DWERR(dwErr);
  727. //
  728. // Init the Report Information structure
  729. //
  730. ZeroMemory(&ReportInfo, sizeof(REPORT_INFO));
  731. ZeroMemory(&Buff, sizeof(BUFFER_WRITE_FILE));
  732. ReportInfo.fDisplay = TRUE;
  733. ReportInfo.pBuff = &Buff;
  734. dwDest = RASMON_CMD_ARG_GetEnum(&pArgs[0]);
  735. pwszDest = RASMON_CMD_ARG_GetPsz(&pArgs[1]);
  736. if (!pwszDest)
  737. {
  738. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  739. break;
  740. }
  741. if (RASMON_CMD_ARG_Present(&pArgs[2]))
  742. {
  743. dwCompress = RASMON_CMD_ARG_GetEnum(&pArgs[2]);
  744. }
  745. else if (dwDest)
  746. {
  747. //
  748. // def is to compress for email
  749. //
  750. dwCompress = 1;
  751. }
  752. if (RASMON_CMD_ARG_Present(&pArgs[3]))
  753. {
  754. ReportInfo.dwHours = RASMON_CMD_ARG_GetDword(&pArgs[3]);
  755. if (ReportInfo.dwHours < 1 ||
  756. ReportInfo.dwHours > 24)
  757. {
  758. dwErr = ERROR_INVALID_SYNTAX;
  759. break;
  760. }
  761. }
  762. if (RASMON_CMD_ARG_Present(&pArgs[4]) &&
  763. RASMON_CMD_ARG_GetDword(&pArgs[4]))
  764. {
  765. ReportInfo.fVerbose = TRUE;
  766. }
  767. //
  768. // email or display
  769. //
  770. if (dwDest)
  771. {
  772. dwErr = CopyTempFileName(wszTempFileName);
  773. BREAK_ON_DWERR(dwErr);
  774. pwszTempFile = CreateHtmFileName(wszTempFileName);
  775. if (!pwszTempFile)
  776. {
  777. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  778. break;
  779. }
  780. }
  781. else
  782. {
  783. pwszTempFile = CreateHtmFileName(pwszDest);
  784. if (!pwszTempFile)
  785. {
  786. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  787. break;
  788. }
  789. }
  790. if (CreateReportFile(ReportInfo.pBuff, pwszTempFile))
  791. {
  792. DisplayMessage(
  793. g_hModule,
  794. EMSG_RASDIAG_REPORT_FAIL,
  795. pwszTempFile);
  796. break;
  797. }
  798. PrintHtmlHeader(ReportInfo.pBuff);
  799. //
  800. // Call the callback
  801. //
  802. pCallback(&ReportInfo);
  803. PrintHtmlFooter(ReportInfo.pBuff);
  804. CloseReportFile(ReportInfo.pBuff);
  805. if (dwCompress)
  806. {
  807. pwszCabFile = CabCompressFile(pwszTempFile);
  808. if (!pwszCabFile)
  809. {
  810. DisplayMessage(
  811. g_hModule,
  812. EMSG_RASDIAG_REPORT_CAB_FAIL,
  813. pwszTempFile);
  814. break;
  815. }
  816. }
  817. if (dwDest)
  818. {
  819. if (!MapiSendMail(
  820. pwszDest,
  821. pwszCabFile ? pwszCabFile : pwszTempFile))
  822. {
  823. DisplayMessage(
  824. g_hModule,
  825. MSG_RASDIAG_REPORT_EMAIL_OK,
  826. pwszDest);
  827. }
  828. else
  829. {
  830. DisplayMessage(
  831. g_hModule,
  832. EMSG_RASDIAG_REPORT_EMAIL_FAIL,
  833. pwszDest);
  834. }
  835. if (pwszCabFile)
  836. {
  837. DeleteFile(pwszCabFile);
  838. }
  839. DeleteFile(pwszTempFile);
  840. }
  841. else
  842. {
  843. DisplayMessage(
  844. g_hModule,
  845. MSG_RASDIAG_REPORT_OK,
  846. pwszCabFile ? pwszCabFile : pwszTempFile);
  847. if (pwszCabFile)
  848. {
  849. DeleteFile(pwszTempFile);
  850. }
  851. }
  852. } while (FALSE);
  853. //
  854. // Clean up
  855. //
  856. RutlFree(pwszCabFile);
  857. RutlFree(pwszTempFile);
  858. RutlFree(pwszDest);
  859. return dwErr;
  860. }