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.

1002 lines
29 KiB

  1. //
  2. // SIGVERIF.C
  3. //
  4. #define SIGVERIF_DOT_C
  5. #include "sigverif.h"
  6. // Allocate our global data structure
  7. GAPPDATA g_App;
  8. //
  9. // Load a resource string into a buffer that is assumed to be MAX_PATH bytes.
  10. //
  11. void
  12. MyLoadString(
  13. LPTSTR lpString,
  14. ULONG CchStringSize,
  15. UINT uId
  16. )
  17. {
  18. LoadString(g_App.hInstance, uId, lpString, CchStringSize);
  19. }
  20. //
  21. // Pop an OK messagebox with a specific string
  22. //
  23. void
  24. MyMessageBox(
  25. LPTSTR lpString
  26. )
  27. {
  28. TCHAR szBuffer[MAX_PATH];
  29. MyLoadString(szBuffer, cA(szBuffer), IDS_MSGBOX);
  30. MessageBox(g_App.hDlg, lpString, szBuffer, MB_OK);
  31. }
  32. //
  33. // Pop an OK messagebox with a resource string ID
  34. //
  35. void
  36. MyMessageBoxId(
  37. UINT uId
  38. )
  39. {
  40. TCHAR szBuffer[MAX_PATH];
  41. MyLoadString(szBuffer, cA(szBuffer), uId);
  42. MyMessageBox(szBuffer);
  43. }
  44. //
  45. // Pop an error messagebox with a specific string
  46. //
  47. void
  48. MyErrorBox(
  49. LPTSTR lpString
  50. )
  51. {
  52. TCHAR szBuffer[MAX_PATH];
  53. MyLoadString(szBuffer, cA(szBuffer), IDS_ERRORBOX);
  54. MessageBox(g_App.hDlg, lpString, szBuffer, MB_OK);
  55. }
  56. //
  57. // Pop an error messagebox with a resource string ID
  58. //
  59. void
  60. MyErrorBoxId(
  61. UINT uId
  62. )
  63. {
  64. TCHAR szBuffer[MAX_PATH];
  65. MyLoadString(szBuffer, cA(szBuffer), uId);
  66. MyErrorBox(szBuffer);
  67. }
  68. void
  69. MyErrorBoxIdWithErrorCode(
  70. UINT uId,
  71. DWORD ErrorCode
  72. )
  73. {
  74. TCHAR szBuffer[MAX_PATH];
  75. ULONG cchSize;
  76. HRESULT hr;
  77. PTSTR errorMessage = NULL;
  78. LPVOID lpLastError = NULL;
  79. //
  80. // Get the error text for the error code.
  81. //
  82. if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
  83. FORMAT_MESSAGE_FROM_SYSTEM |
  84. FORMAT_MESSAGE_IGNORE_INSERTS,
  85. NULL,
  86. ErrorCode,
  87. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  88. (LPTSTR)&lpLastError,
  89. 0,
  90. NULL) != 0) {
  91. if (lpLastError) {
  92. MyLoadString(szBuffer, cA(szBuffer), uId);
  93. cchSize = lstrlen(szBuffer) + lstrlen(lpLastError) + 1;
  94. errorMessage = MALLOC(cchSize * sizeof(TCHAR));
  95. if (errorMessage) {
  96. hr = StringCchCopy(errorMessage, cchSize, szBuffer);
  97. if (SUCCEEDED(hr)) {
  98. hr = StringCchCat(errorMessage, cchSize, lpLastError);
  99. }
  100. //
  101. // We want to show the error message, even if the
  102. // buffer was truncated.
  103. //
  104. if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) {
  105. MyMessageBox(errorMessage);
  106. }
  107. FREE(errorMessage);
  108. }
  109. LocalFree(lpLastError);
  110. }
  111. }
  112. }
  113. //
  114. // Since Multi-User Windows will give me back a Profile directory, I need to get the real Windows directory
  115. // Dlg_OnInitDialog initializes g_App.szWinDir with the real Windows directory, so I just use that.
  116. //
  117. UINT
  118. MyGetWindowsDirectory(
  119. LPTSTR lpDirName,
  120. UINT DirNameCchSize
  121. )
  122. {
  123. UINT uRet = 0;
  124. if (lpDirName) {
  125. if (SUCCEEDED(StringCchCopy(lpDirName, DirNameCchSize, g_App.szWinDir))) {
  126. uRet = lstrlen(lpDirName);
  127. } else {
  128. //
  129. // If the directory name can't fit in the buffer that the caller
  130. // provided, then set it to 0 (if they provided a buffer of at
  131. // least size 1) since we don't want to return a truncated
  132. // directory to the caller.
  133. //
  134. if (DirNameCchSize > 0) {
  135. *lpDirName = 0;
  136. }
  137. uRet = 0;
  138. }
  139. }
  140. return uRet;
  141. }
  142. //
  143. // Initialization of main dialog.
  144. //
  145. BOOL
  146. Dlg_OnInitDialog(
  147. HWND hwnd
  148. )
  149. {
  150. DWORD Err = ERROR_SUCCESS;
  151. HKEY hKey;
  152. LONG lRes;
  153. DWORD dwType, dwFlags, cbData;
  154. TCHAR szBuffer[MAX_PATH];
  155. LPTSTR lpCommandLine, lpStart, lpEnd;
  156. ULONG cchSize;
  157. //
  158. // Initialize global hDlg to current hwnd.
  159. //
  160. g_App.hDlg = hwnd;
  161. //
  162. // Set the window class to have the icon in the resource file
  163. //
  164. if (g_App.hIcon) {
  165. SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR) g_App.hIcon);
  166. }
  167. //
  168. // Make sure the IDC_STATUS control is hidden until something happens.
  169. //
  170. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_HIDE);
  171. //
  172. // Set the range for the custom progress bar to 0-100.
  173. //
  174. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELPARAM(0, 100));
  175. //
  176. // Set the global lpLogName to the one that's given in the resource file
  177. //
  178. MyLoadString(g_App.szLogFile, cA(g_App.szLogFile), IDS_LOGNAME);
  179. //
  180. // Figure out what the real Windows directory is and store it in g_App.szWinDir
  181. // This is required because Hydra makes GetWindowsDirectory return a PROFILE directory
  182. //
  183. // We store the original CurrentDirectory in szBuffer so we can restore it after this hack.
  184. // Next we switch into the SYSTEM/SYSTEM32 directory and then into its parent directory.
  185. // This is what we want to store in g_App.szWinDir.
  186. //
  187. GetCurrentDirectory(cA(szBuffer), szBuffer);
  188. GetSystemDirectory(g_App.szWinDir, cA(g_App.szWinDir));
  189. SetCurrentDirectory(g_App.szWinDir);
  190. SetCurrentDirectory(TEXT(".."));
  191. GetCurrentDirectory(cA(g_App.szWinDir), g_App.szWinDir);
  192. SetCurrentDirectory(szBuffer);
  193. //
  194. // Set the global search folder to %WinDir%
  195. //
  196. MyGetWindowsDirectory(g_App.szScanPath, cA(g_App.szScanPath));
  197. //
  198. // Set the global search pattern to "*.*"
  199. //
  200. MyLoadString(g_App.szScanPattern, cA(g_App.szScanPattern), IDS_ALL);
  201. //
  202. // Reset the progress bar back to zero percent
  203. //
  204. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
  205. //
  206. // By default, we want to turn logging and set the logging mode to OVERWRITE
  207. //
  208. g_App.bLoggingEnabled = TRUE;
  209. g_App.bOverwrite = TRUE;
  210. //
  211. // Look in the registry for any settings from the last SigVerif session
  212. //
  213. lRes = RegOpenKeyEx(HKEY_CURRENT_USER,
  214. SIGVERIF_KEY,
  215. 0,
  216. KEY_READ,
  217. &hKey);
  218. if (lRes == ERROR_SUCCESS) {
  219. cbData = sizeof(DWORD);
  220. lRes = RegQueryValueEx( hKey,
  221. SIGVERIF_FLAGS,
  222. NULL,
  223. &dwType,
  224. (LPBYTE) &dwFlags,
  225. &cbData);
  226. if (lRes == ERROR_SUCCESS) {
  227. g_App.bLoggingEnabled = (dwFlags & 0x1);
  228. g_App.bOverwrite = (dwFlags & 0x2);
  229. }
  230. cbData = sizeof(szBuffer);
  231. lRes = RegQueryValueEx( hKey,
  232. SIGVERIF_LOGNAME,
  233. NULL,
  234. &dwType,
  235. (LPBYTE) szBuffer,
  236. &cbData);
  237. if (lRes == ERROR_SUCCESS && dwType == REG_SZ) {
  238. //
  239. // This should never happen unless the code is changed
  240. // so that szBuffer is larger then g_App.szLogFile, but
  241. // for safety if we can't copy szBuffer fully into
  242. // g_App.szLogFile, then set g_App.szLogFile to 0 so we
  243. // don't log to a truncated location.
  244. //
  245. if (FAILED(StringCchCopy(g_App.szLogFile, cA(g_App.szLogFile), szBuffer))) {
  246. g_App.szLogFile[0] = 0;
  247. }
  248. }
  249. RegCloseKey(hKey);
  250. }
  251. //
  252. // If the user specified the LOGDIR flag, we want to create the log
  253. // file in that directory.
  254. //
  255. //
  256. // SECURITY: Verify that LOGDIR exists and the user has the correct access
  257. // to it, and if they don't then fail up front.
  258. //
  259. MyLoadString(szBuffer, cA(szBuffer), IDS_LOGDIR);
  260. if (SUCCEEDED(StringCchCat(szBuffer, cA(szBuffer), TEXT(":"))) &&
  261. ((lpStart = MyStrStr(GetCommandLine(), szBuffer)) != NULL)) {
  262. lpStart += lstrlen(szBuffer);
  263. if (lpStart && *lpStart) {
  264. //
  265. // The string in lpStart is the directory that we want to log
  266. // into.
  267. //
  268. cchSize = lstrlen(lpStart) + 1;
  269. lpCommandLine = MALLOC(cchSize * sizeof(TCHAR));
  270. if (lpCommandLine) {
  271. if (SUCCEEDED(StringCchCopy(lpCommandLine, cchSize, lpStart))) {
  272. lpStart = lpCommandLine;
  273. //
  274. // First skip any white space.
  275. //
  276. while (*lpStart && (isspace(*lpStart))) {
  277. lpStart++;
  278. }
  279. //
  280. // We will deal with two cases, one where the path
  281. // starts with a quote, and the other where it does
  282. // not.
  283. //
  284. if (*lpStart) {
  285. if (*lpStart == TEXT('\"')) {
  286. //
  287. // The log path starts with a quote. This means that
  288. // we will use all of the string until we either hit
  289. // the end of the string, or we find another quote.
  290. //
  291. lpStart++;
  292. lpEnd = lpStart;
  293. while (*lpEnd && (*lpEnd != TEXT('\"'))) {
  294. lpEnd++;
  295. }
  296. } else {
  297. //
  298. // The log path does NOT start with a quote, so
  299. // use the characters until we come to the end
  300. // of the string or a space.
  301. //
  302. lpEnd = lpStart;
  303. while (*lpEnd && (isspace(*lpEnd))) {
  304. lpEnd++;
  305. }
  306. }
  307. *lpEnd = TEXT('\0');
  308. if (FAILED(StringCchCopy(g_App.szLogDir, cA(g_App.szLogDir), lpStart))) {
  309. //
  310. // The user probably typed in too many characters for
  311. // the log dir.
  312. //
  313. Err = ERROR_DIRECTORY;
  314. } else {
  315. //
  316. // Verify that the log dir exists and is a directory.
  317. //
  318. DWORD attributes;
  319. attributes = GetFileAttributes(g_App.szLogDir);
  320. if (attributes == INVALID_FILE_ATTRIBUTES) {
  321. Err = ERROR_DIRECTORY;
  322. } else if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
  323. Err = ERROR_DIRECTORY;
  324. }
  325. }
  326. }
  327. }
  328. FREE(lpCommandLine);
  329. }
  330. }
  331. if (Err != ERROR_SUCCESS) {
  332. MyMessageBoxId(IDS_LOGDIRERROR);
  333. }
  334. }
  335. //
  336. // If the user specified the FULLSCAN flag we want to scan the specified
  337. // directory and all of its subdirectories.
  338. //
  339. MyLoadString(szBuffer, cA(szBuffer), IDS_FULLSCAN);
  340. if (SUCCEEDED(StringCchCat(szBuffer, cA(szBuffer), TEXT(":"))) &&
  341. ((lpStart = MyStrStr(GetCommandLine(), szBuffer)) != NULL)) {
  342. Err = ERROR_SUCCESS;
  343. lpStart += lstrlen(szBuffer);
  344. if (lpStart && *lpStart) {
  345. //
  346. // The string in lpStart is the directory that we want to scan.
  347. //
  348. cchSize = lstrlen(lpStart) + 1;
  349. lpCommandLine = MALLOC(cchSize * sizeof(TCHAR));
  350. if (lpCommandLine) {
  351. if (SUCCEEDED(StringCchCopy(lpCommandLine, cchSize, lpStart))) {
  352. lpStart = lpCommandLine;
  353. //
  354. // First skip any white space.
  355. //
  356. while (*lpStart && (isspace(*lpStart))) {
  357. lpStart++;
  358. }
  359. //
  360. // We will deal with two cases, one where the path
  361. // starts with a quote, and the other where it does
  362. // not.
  363. //
  364. if (*lpStart) {
  365. if (*lpStart == TEXT('\"')) {
  366. //
  367. // The scan path starts with a quote. This means that
  368. // we will use all of the string until we either hit
  369. // the end of the string, or we find another quote.
  370. //
  371. lpStart++;
  372. lpEnd = lpStart;
  373. while (*lpEnd && (*lpEnd != TEXT('\"'))) {
  374. lpEnd++;
  375. }
  376. } else {
  377. //
  378. // The scan path does NOT start with a quote, so
  379. // use the characters until we come to the end
  380. // of the string or a space.
  381. //
  382. lpEnd = lpStart;
  383. while (*lpEnd && (!isspace(*lpEnd))) {
  384. lpEnd++;
  385. }
  386. }
  387. *lpEnd = TEXT('\0');
  388. if (FAILED(StringCchCopy(g_App.szScanPath, cA(g_App.szScanPath), lpStart))) {
  389. //
  390. // The user probably typed in too many characters for
  391. // the scan dir.
  392. //
  393. Err = ERROR_DIRECTORY;
  394. } else {
  395. //
  396. // Verify that the scan dir exists and is a directory.
  397. //
  398. DWORD attributes;
  399. attributes = GetFileAttributes(g_App.szScanPath);
  400. if (attributes == INVALID_FILE_ATTRIBUTES) {
  401. Err = ERROR_DIRECTORY;
  402. } else if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
  403. Err = ERROR_DIRECTORY;
  404. }
  405. }
  406. }
  407. }
  408. FREE(lpCommandLine);
  409. }
  410. }
  411. if (Err == ERROR_SUCCESS) {
  412. g_App.bAutomatedScan = TRUE;
  413. g_App.bLoggingEnabled = TRUE;
  414. g_App.bUserScan = TRUE;
  415. g_App.bSubFolders = TRUE;
  416. //
  417. // Now that everything is set up, simulate a click to the START button...
  418. //
  419. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM)0);
  420. } else {
  421. MyMessageBoxId(IDS_FULLSCANERROR);
  422. }
  423. }
  424. //
  425. // If the user specified the DEFSCAN flag, we want to automatically do a
  426. // default scan and log the results.
  427. //
  428. MyLoadString(szBuffer, cA(szBuffer), IDS_DEFSCAN);
  429. if (MyStrStr(GetCommandLine(), szBuffer)) {
  430. g_App.bAutomatedScan = TRUE;
  431. g_App.bLoggingEnabled = TRUE;
  432. //
  433. // Now that everything is set up, simulate a click to the START button...
  434. //
  435. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM) 0);
  436. }
  437. if (Err == ERROR_SUCCESS) {
  438. return TRUE;
  439. } else {
  440. g_App.LastError = Err;
  441. return FALSE;
  442. }
  443. }
  444. //
  445. // Build file list according to dialog settings, then verify the files in the list
  446. //
  447. void WINAPI
  448. ProcessFileList(void)
  449. {
  450. DWORD Err = ERROR_SUCCESS;
  451. TCHAR szBuffer[MAX_PATH];
  452. //
  453. // Set the scanning flag to TRUE, so we don't double-scan
  454. //
  455. g_App.bScanning = TRUE;
  456. // Assume a successfull scan.
  457. g_App.LastError = ERROR_SUCCESS;
  458. //
  459. // Change the "Start" to "Stop"
  460. //
  461. MyLoadString(szBuffer, cA(szBuffer), IDS_STOP);
  462. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  463. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), FALSE);
  464. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), FALSE);
  465. //
  466. // Display the text that says "Building file list..."
  467. //
  468. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_BUILD);
  469. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  470. //
  471. // Make sure the IDC_STATUS text item visible
  472. //
  473. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_SHOW);
  474. //
  475. // Free any memory that we may have allocated for the g_App.lpFileList
  476. //
  477. DestroyFileList(TRUE);
  478. //
  479. // Now actually build the g_App.lpFileList list given the dialog settings
  480. //
  481. if (g_App.bUserScan) {
  482. Err = BuildFileList(g_App.szScanPath);
  483. } else {
  484. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  485. Err = BuildDriverFileList();
  486. }
  487. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  488. Err = BuildPrinterFileList();
  489. }
  490. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  491. Err = BuildCoreFileList();
  492. }
  493. }
  494. if (!g_App.bAutomatedScan &&
  495. (Err != ERROR_SUCCESS) &&
  496. (Err != ERROR_CANCELLED)) {
  497. g_App.LastError = Err;
  498. MyErrorBoxIdWithErrorCode(IDS_BUILDLISTERROR, Err);
  499. }
  500. //
  501. // If we encountered an error building the file list then don't bother
  502. // scanning the files.
  503. //
  504. if (Err == ERROR_SUCCESS) {
  505. //
  506. // Check if there is even a file list to verify.
  507. //
  508. if (g_App.lpFileList) {
  509. if (!g_App.bStopScan) {
  510. //
  511. // Display the "Scanning File List..." text
  512. //
  513. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_SCAN);
  514. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  515. //
  516. // Reset the progress bar back to zero percent while it's invisible.
  517. //
  518. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
  519. //
  520. // WooHoo! Let's display the progress bar and start cranking on the file list!
  521. //
  522. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_SHOW);
  523. VerifyFileList();
  524. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_HIDE);
  525. }
  526. } else {
  527. //
  528. // The IDC_NOTMS code displays it's own error message, so only display
  529. // an error dialog if we are doing a System Integrity Scan
  530. //
  531. if (!g_App.bStopScan && !g_App.bUserScan) {
  532. MyMessageBoxId(IDS_NOSYSTEMFILES);
  533. }
  534. }
  535. //
  536. // Disable the start button while we clean up the g_App.lpFileList
  537. //
  538. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), FALSE);
  539. //
  540. // Log the results. Note that sigverif will do this even if we encountered
  541. // an error building or scanning the list, since the logfile may help
  542. // figure out which file is causing the problem. Only log the results
  543. // if we found any files to scan.
  544. //
  545. if (!g_App.bStopScan) {
  546. //
  547. // Display the text that says "Writing Log File..."
  548. //
  549. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_LOG);
  550. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  551. //
  552. // Write the results to the log file
  553. //
  554. if (!PrintFileList()) {
  555. //
  556. // We failed while logging for some reason, probably permissions
  557. // or out of disk space. Let the user know that we could not finish
  558. // logging all of the files.
  559. //
  560. Err = GetLastError();
  561. if (Err != ERROR_SUCCESS) {
  562. MyErrorBoxIdWithErrorCode(IDS_LOGERROR, Err);
  563. }
  564. }
  565. } else {
  566. //
  567. // If the user clicked STOP, let them know about it.
  568. //
  569. MyMessageBoxId(IDS_SCANSTOPPED);
  570. }
  571. }
  572. //
  573. // Display the text that says "Freeing File List..."
  574. //
  575. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_FREE);
  576. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  577. //
  578. // Hide the IDC_STATUS text item so it doesn't cover IDC_STATUS
  579. //
  580. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_HIDE);
  581. //
  582. // Change the "Stop" button back to "Start"
  583. //
  584. MyLoadString(szBuffer, cA(szBuffer), IDS_START);
  585. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  586. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), TRUE);
  587. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), TRUE);
  588. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), TRUE);
  589. //
  590. // Free all the memory that we allocated for the g_App.lpFileList
  591. //
  592. DestroyFileList(FALSE);
  593. //
  594. // Clear the scanning flag
  595. //
  596. g_App.bScanning = FALSE;
  597. g_App.bStopScan = FALSE;
  598. //
  599. // If the user started SigVerif with the /DEFSCAN flag, then we exit.
  600. //
  601. if (g_App.bAutomatedScan) {
  602. PostMessage(g_App.hDlg, WM_CLOSE, (WPARAM) 0, (LPARAM) 0);
  603. }
  604. }
  605. //
  606. // Spawns a thread to do the scan so the GUI remains responsive.
  607. //
  608. void
  609. Dlg_OnPushStartButton(
  610. HWND hwnd
  611. )
  612. {
  613. HANDLE hThread;
  614. DWORD dwThreadId;
  615. UNREFERENCED_PARAMETER(hwnd);
  616. //
  617. // Check if we are already scanning... if so, bail.
  618. //
  619. if (g_App.bScanning) {
  620. return;
  621. }
  622. //
  623. // Create a thread where Search_ProcessFileList can go without tying up the GUI thread.
  624. //
  625. hThread = CreateThread(NULL,
  626. 0,
  627. (LPTHREAD_START_ROUTINE) ProcessFileList,
  628. 0,
  629. 0,
  630. &dwThreadId);
  631. }
  632. //
  633. // Handle any WM_COMMAND messages sent to the search dialog
  634. //
  635. void
  636. Dlg_OnCommand(
  637. HWND hwnd,
  638. int id,
  639. HWND hwndCtl,
  640. UINT codeNotify
  641. )
  642. {
  643. UNREFERENCED_PARAMETER(hwndCtl);
  644. UNREFERENCED_PARAMETER(codeNotify);
  645. switch(id) {
  646. //
  647. // The user clicked ID_START, so if we aren't scanning start scanning.
  648. // If we are scanning, then stop the tests because the button actually says "Stop"
  649. //
  650. case ID_START:
  651. if (!g_App.bScanning) {
  652. Dlg_OnPushStartButton(hwnd);
  653. } else if (!g_App.bStopScan) {
  654. g_App.bStopScan = TRUE;
  655. g_App.LastError = ERROR_CANCELLED;
  656. }
  657. break;
  658. //
  659. // The user clicked IDCANCEL, so if the tests are running try to stop them before exiting.
  660. //
  661. case IDCANCEL:
  662. if (g_App.bScanning) {
  663. g_App.bStopScan = TRUE;
  664. g_App.LastError = ERROR_CANCELLED;
  665. } else {
  666. SendMessage(hwnd, WM_CLOSE, 0, 0);
  667. }
  668. break;
  669. // Pop up the IDD_SETTINGS dialog so the user can change their log settings.
  670. case ID_ADVANCED:
  671. if (!g_App.bScanning) {
  672. AdvancedPropertySheet(hwnd);
  673. }
  674. break;
  675. }
  676. }
  677. void
  678. SigVerif_Help(
  679. HWND hwnd,
  680. UINT uMsg,
  681. WPARAM wParam,
  682. LPARAM lParam,
  683. BOOL bContext
  684. )
  685. {
  686. static DWORD SigVerif_HelpIDs[] =
  687. {
  688. IDC_SCAN, IDH_SIGVERIF_SEARCH_CHECK_SYSTEM,
  689. IDC_NOTMS, IDH_SIGVERIF_SEARCH_LOOK_FOR,
  690. IDC_TYPE, IDH_SIGVERIF_SEARCH_SCAN_FILES,
  691. IDC_FOLDER, IDH_SIGVERIF_SEARCH_LOOK_IN_FOLDER,
  692. IDC_SUBFOLDERS, IDH_SIGVERIF_SEARCH_INCLUDE_SUBFOLDERS,
  693. IDC_ENABLELOG, IDH_SIGVERIF_LOGGING_ENABLE_LOGGING,
  694. IDC_APPEND, IDH_SIGVERIF_LOGGING_APPEND,
  695. IDC_OVERWRITE, IDH_SIGVERIF_LOGGING_OVERWRITE,
  696. IDC_LOGNAME, IDH_SIGVERIF_LOGGING_FILENAME,
  697. IDC_VIEWLOG, IDH_SIGVERIF_LOGGING_VIEW_LOG,
  698. 0,0
  699. };
  700. static DWORD Windows_HelpIDs[] =
  701. {
  702. ID_BROWSE, IDH_BROWSE,
  703. 0,0
  704. };
  705. HWND hItem = NULL;
  706. LPHELPINFO lphi = NULL;
  707. POINT point;
  708. switch (uMsg) {
  709. case WM_HELP:
  710. lphi = (LPHELPINFO) lParam;
  711. if (lphi && (lphi->iContextType == HELPINFO_WINDOW)) {
  712. hItem = (HWND) lphi->hItemHandle;
  713. }
  714. break;
  715. case WM_CONTEXTMENU:
  716. hItem = (HWND) wParam;
  717. point.x = GET_X_LPARAM(lParam);
  718. point.y = GET_Y_LPARAM(lParam);
  719. if (ScreenToClient(hwnd, &point)) {
  720. hItem = ChildWindowFromPoint(hwnd, point);
  721. }
  722. break;
  723. }
  724. if (hItem) {
  725. if (GetWindowLong(hItem, GWL_ID) == ID_BROWSE) {
  726. WinHelp(hItem,
  727. (LPCTSTR) WINDOWS_HELPFILE,
  728. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  729. (ULONG_PTR) Windows_HelpIDs);
  730. } else {
  731. WinHelp(hItem,
  732. (LPCTSTR) SIGVERIF_HELPFILE,
  733. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  734. (ULONG_PTR) SigVerif_HelpIDs);
  735. }
  736. }
  737. }
  738. //
  739. // The main dialog procedure. Needs to handle WM_INITDIALOG, WM_COMMAND, and WM_CLOSE/WM_DESTROY.
  740. //
  741. INT_PTR CALLBACK
  742. DlgProc(
  743. HWND hwnd,
  744. UINT uMsg,
  745. WPARAM wParam,
  746. LPARAM lParam
  747. )
  748. {
  749. BOOL fProcessed = TRUE;
  750. switch (uMsg) {
  751. HANDLE_MSG(hwnd, WM_COMMAND, Dlg_OnCommand);
  752. case WM_INITDIALOG:
  753. fProcessed = Dlg_OnInitDialog(hwnd);
  754. break;
  755. case WM_CLOSE:
  756. if (g_App.bScanning) {
  757. g_App.bStopScan = TRUE;
  758. g_App.LastError = ERROR_CANCELLED;
  759. } else {
  760. EndDialog(hwnd, IDCANCEL);
  761. }
  762. break;
  763. default:
  764. fProcessed = FALSE;
  765. }
  766. return fProcessed;
  767. }
  768. //
  769. // Program entry point. Set up for creation of IDD_DIALOG.
  770. //
  771. WINAPI
  772. WinMain(
  773. HINSTANCE hInstance,
  774. HINSTANCE hPrevInstance,
  775. LPSTR lpszCmdParam,
  776. int nCmdShow
  777. )
  778. {
  779. HWND hwnd;
  780. TCHAR szAppName[MAX_PATH];
  781. UNREFERENCED_PARAMETER(hPrevInstance);
  782. UNREFERENCED_PARAMETER(lpszCmdParam);
  783. UNREFERENCED_PARAMETER(nCmdShow);
  784. ZeroMemory(&g_App, sizeof(GAPPDATA));
  785. g_App.hInstance = hInstance;
  786. //
  787. // Look for any existing instances of SigVerif...
  788. //
  789. MyLoadString(szAppName, cA(szAppName), IDS_SIGVERIF);
  790. hwnd = FindWindow(NULL, szAppName);
  791. if (!hwnd) {
  792. //
  793. // We definitely need this for the progress bar, and maybe other stuff too.
  794. //
  795. InitCommonControls();
  796. //
  797. // Register the custom control we use for the progress bar
  798. //
  799. Progress_InitRegisterClass();
  800. //
  801. // Load the icon from the resource file that we will use everywhere
  802. //
  803. g_App.hIcon = LoadIcon(g_App.hInstance, MAKEINTRESOURCE(IDI_ICON1));
  804. //
  805. // Create the IDD_DIALOG and use DlgProc as the main procedure
  806. //
  807. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
  808. if (g_App.hIcon) {
  809. DestroyIcon(g_App.hIcon);
  810. g_App.hIcon = NULL;
  811. }
  812. } else {
  813. //
  814. // If there is already an instance of SigVerif running, make that one
  815. // foreground and we exit.
  816. //
  817. SetForegroundWindow(hwnd);
  818. }
  819. //
  820. // If we encountered any errors during our scan, then return the error code,
  821. // otherwise return 0 if all the files are signed or 1 if we found any
  822. // unsigned files.
  823. //
  824. if (g_App.LastError != ERROR_SUCCESS) {
  825. return g_App.LastError;
  826. } else {
  827. return ((g_App.dwUnsigned > 0) ? 1 : 0);
  828. }
  829. }