Source code of Windows XP (NT5)
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.

623 lines
18 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 MyLoadString(LPTSTR lpString, UINT uId)
  12. {
  13. LoadString(g_App.hInstance, uId, lpString, MAX_PATH);
  14. }
  15. //
  16. // Pop an OK messagebox with a specific string
  17. //
  18. void MyMessageBox(LPTSTR lpString)
  19. {
  20. TCHAR szBuffer[MAX_PATH];
  21. LPTSTR lpBuffer = szBuffer;
  22. MyLoadString(lpBuffer, IDS_MSGBOX);
  23. MessageBox(g_App.hDlg, lpString, lpBuffer, MB_OK);
  24. }
  25. //
  26. // Pop an OK messagebox with a resource string ID
  27. //
  28. void MyMessageBoxId(UINT uId)
  29. {
  30. TCHAR szBuffer[MAX_PATH];
  31. LPTSTR lpBuffer = szBuffer;
  32. MyLoadString(lpBuffer, uId);
  33. MyMessageBox(lpBuffer);
  34. }
  35. //
  36. // Pop an error messagebox with a specific string
  37. //
  38. void MyErrorBox(LPTSTR lpString)
  39. {
  40. TCHAR szBuffer[MAX_PATH];
  41. LPTSTR lpBuffer = szBuffer;
  42. MyLoadString(lpBuffer, IDS_ERRORBOX);
  43. MessageBox(g_App.hDlg, lpString, lpBuffer, MB_OK);
  44. }
  45. //
  46. // Pop an error messagebox with a resource string ID
  47. //
  48. void MyErrorBoxId(UINT uId)
  49. {
  50. TCHAR szBuffer[MAX_PATH];
  51. LPTSTR lpBuffer = szBuffer;
  52. MyLoadString(lpBuffer, uId);
  53. MyErrorBox(lpBuffer);
  54. }
  55. //
  56. // Since Multi-User Windows will give me back a Profile directory, I need to get the real Windows directory
  57. // Dlg_OnInitDialog initializes g_App.szWinDir with the real Windows directory, so I just use that.
  58. //
  59. UINT MyGetWindowsDirectory(LPTSTR lpDirName, UINT uSize)
  60. {
  61. UINT uRet = 0;
  62. if (lpDirName)
  63. {
  64. lstrcpy(lpDirName, g_App.szWinDir);
  65. uRet = lstrlen(lpDirName);
  66. }
  67. return uRet;
  68. }
  69. //
  70. // Initialization of main dialog.
  71. //
  72. BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
  73. {
  74. HKEY hKey;
  75. LONG lRes;
  76. DWORD dwDisp, dwType, dwFlags, cbData;
  77. TCHAR szBuffer[MAX_PATH];
  78. // Initialize global hDlg to current hwnd.
  79. g_App.hDlg = hwnd;
  80. // Set the window class to have the icon in the resource file
  81. if (g_App.hIcon)
  82. {
  83. SetClassLongPtr(hwnd, GCLP_HICON, (LONG_PTR) g_App.hIcon);
  84. }
  85. // Make sure the IDC_STATUS control is hidden until something happens.
  86. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_HIDE);
  87. // Set the range for the custom progress bar to 0-100.
  88. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELPARAM(0, 100));
  89. // Set the global lpLogName to the one that's given in the resource file
  90. MyLoadString(g_App.szLogFile, IDS_LOGNAME);
  91. //
  92. // Figure out what the real Windows directory is and store it in g_App.szWinDir
  93. // This is required because Hydra makes GetWindowsDirectory return a PROFILE directory
  94. //
  95. // We store the original CurrentDirectory in szBuffer so we can restore it after this hack.
  96. // Next we switch into the SYSTEM/SYSTEM32 directory and then into its parent directory.
  97. // This is what we want to store in g_App.szWinDir.
  98. //
  99. GetCurrentDirectory(MAX_PATH, szBuffer);
  100. GetSystemDirectory(g_App.szWinDir, MAX_PATH);
  101. SetCurrentDirectory(g_App.szWinDir);
  102. SetCurrentDirectory(TEXT(".."));
  103. GetCurrentDirectory(MAX_PATH, g_App.szWinDir);
  104. SetCurrentDirectory(szBuffer);
  105. // Set the global search folder to %WinDir%
  106. MyGetWindowsDirectory(g_App.szScanPath, MAX_PATH);
  107. // Set the global search pattern to "*.*"
  108. MyLoadString(g_App.szScanPattern, IDS_ALL);
  109. // Reset the progress bar back to zero percent
  110. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
  111. // By default, we want to turn logging and set the logging mode to OVERWRITE
  112. g_App.bLoggingEnabled = TRUE;
  113. g_App.bOverwrite = TRUE;
  114. //
  115. // Look in the registry for any settings from the last SigVerif session
  116. //
  117. lRes = RegCreateKeyEx( SIGVERIF_HKEY,
  118. SIGVERIF_KEY,
  119. 0,
  120. NULL,
  121. 0,
  122. KEY_ALL_ACCESS,
  123. NULL,
  124. &hKey,
  125. &dwDisp);
  126. if (lRes == ERROR_SUCCESS)
  127. {
  128. // If all we did was create a new key, then there must not be any data. Just close the key.
  129. if (dwDisp == REG_CREATED_NEW_KEY)
  130. {
  131. RegCloseKey(hKey);
  132. }
  133. else // Otherwise, query the values and set any values that we found.
  134. {
  135. cbData = sizeof(DWORD);
  136. lRes = RegQueryValueEx( hKey,
  137. SIGVERIF_FLAGS,
  138. NULL,
  139. &dwType,
  140. (LPBYTE) &dwFlags,
  141. &cbData);
  142. if (lRes == ERROR_SUCCESS)
  143. {
  144. g_App.bLoggingEnabled = (dwFlags & 0x1);
  145. g_App.bOverwrite = (dwFlags & 0x2);
  146. }
  147. cbData = MAX_PATH;
  148. lRes = RegQueryValueEx( hKey,
  149. SIGVERIF_LOGNAME,
  150. NULL,
  151. &dwType,
  152. (LPBYTE) szBuffer,
  153. &cbData);
  154. if (lRes == ERROR_SUCCESS && dwType == REG_SZ)
  155. {
  156. lstrcpy(g_App.szLogFile, szBuffer);
  157. }
  158. RegCloseKey(hKey);
  159. }
  160. }
  161. // Get the startup directory of SigVerif
  162. GetCurrentDirectory(MAX_PATH, g_App.szAppDir);
  163. //
  164. // Check if the user specified /NOBVT, /NODEV, or /NOPRN
  165. //
  166. MyLoadString(szBuffer, IDS_NOBVT);
  167. if (MyStrStr(GetCommandLine(), szBuffer))
  168. g_App.bNoBVT = TRUE;
  169. MyLoadString(szBuffer, IDS_NODEV);
  170. if (MyStrStr(GetCommandLine(), szBuffer))
  171. g_App.bNoDev = TRUE;
  172. MyLoadString(szBuffer, IDS_NOPRN);
  173. if (MyStrStr(GetCommandLine(), szBuffer))
  174. g_App.bNoPRN = TRUE;
  175. //
  176. // If the user specified the "LogDir" flag, we want to log the signed and unsigned filenames to the root.
  177. //
  178. MyLoadString(szBuffer, IDS_LOGDIR);
  179. lstrcat(szBuffer, TEXT(":"));
  180. if (MyStrStr(GetCommandLine(), szBuffer))
  181. {
  182. LPTSTR lpString;
  183. lpString = MyStrStr(GetCommandLine(), szBuffer);
  184. if (lpString) {
  185. lpString += lstrlen(szBuffer);
  186. }
  187. if (lpString && *lpString) {
  188. lstrcpy(g_App.szLogDir, lpString);
  189. lpString = MyStrStr(g_App.szLogDir, TEXT(" "));
  190. if (lpString) {
  191. *lpString = TEXT('\0');
  192. }
  193. }
  194. g_App.bLogToRoot = TRUE;
  195. } else {
  196. MyLoadString(szBuffer, IDS_LOGDIR);
  197. if (MyStrStr(GetCommandLine(), szBuffer)) {
  198. g_App.bLogToRoot = TRUE;
  199. }
  200. }
  201. //
  202. // If the user specified the FullSystemScan flag, we want to scan the entire system drive and log the results.
  203. //
  204. MyLoadString(szBuffer, IDS_FULLSCAN);
  205. lstrcat(szBuffer, TEXT(":"));
  206. if (MyStrStr(GetCommandLine(), szBuffer))
  207. {
  208. g_App.bFullSystemScan = TRUE;
  209. g_App.bLoggingEnabled = TRUE;
  210. g_App.bLogToRoot = TRUE;
  211. g_App.bUserScan = TRUE;
  212. g_App.bSubFolders = TRUE;
  213. lstrcpy(g_App.szScanPath, MyStrStr(GetCommandLine(), szBuffer) + lstrlen(szBuffer));
  214. // Now that everything is set up, simulate a click to the START button...
  215. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM) 0);
  216. }
  217. else
  218. {
  219. //
  220. // If the user specified the FullSystemScan flag, we want to scan the entire system drive and log the results.
  221. //
  222. MyLoadString(szBuffer, IDS_FULLSCAN);
  223. if (MyStrStr(GetCommandLine(), szBuffer))
  224. {
  225. g_App.bFullSystemScan = TRUE;
  226. g_App.bLoggingEnabled = TRUE;
  227. g_App.bLogToRoot = TRUE;
  228. g_App.bUserScan = TRUE;
  229. g_App.bSubFolders = TRUE;
  230. *(g_App.szScanPath + 3) = 0;
  231. // Now that everything is set up, simulate a click to the START button...
  232. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM) 0);
  233. }
  234. }
  235. //
  236. // If the user specified the DefaultSystemScan flag, we want to scan the entire system drive and log the results.
  237. //
  238. MyLoadString(szBuffer, IDS_DEFSCAN);
  239. if (MyStrStr(GetCommandLine(), szBuffer))
  240. {
  241. g_App.bFullSystemScan = TRUE;
  242. g_App.bLoggingEnabled = TRUE;
  243. g_App.bLogToRoot = TRUE;
  244. // Now that everything is set up, simulate a click to the START button...
  245. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM) 0);
  246. }
  247. return TRUE;
  248. }
  249. //
  250. // Build file list according to dialog settings, then verify the files in the list
  251. //
  252. void WINAPI ProcessFileList(void)
  253. {
  254. DWORD dwCount = 0;
  255. TCHAR szBuffer[MAX_PATH];
  256. // Set the scanning flag to TRUE, so we don't double-scan
  257. g_App.bScanning = TRUE;
  258. // Change the "Start" to "Stop"
  259. MyLoadString(szBuffer, IDS_STOP);
  260. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  261. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), FALSE);
  262. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), FALSE);
  263. // Display the text that says "Building file list..."
  264. MyLoadString(szBuffer, IDS_STATUS_BUILD);
  265. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  266. // Hide the IDC_INFOTEXT text item so it doesn't cover IDC_STATUS
  267. //ShowWindow(GetDlgItem(g_App.hDlg, IDC_INFOTEXT), SW_HIDE);
  268. // Make sure the IDC_STATUS text item visible
  269. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_SHOW);
  270. // Free any memory that we may have allocated for the g_App.lpFileList
  271. DestroyFileList();
  272. // Now actually build the g_App.lpFileList list given the dialog settings
  273. if (g_App.bUserScan)
  274. {
  275. BuildFileList(g_App.szScanPath);
  276. }
  277. else
  278. {
  279. if (!g_App.bNoBVT && !g_App.bStopScan)
  280. BuildCoreFileList();
  281. if (!g_App.bNoDev && !g_App.bStopScan)
  282. BuildDriverFileList();
  283. if (!g_App.bNoPRN && !g_App.bStopScan)
  284. BuildPrinterFileList();
  285. }
  286. // Hide the text that said "Building file list..."
  287. ShowWindow(GetDlgItem(g_App.hDlg, IDC_BUILDLIST), SW_HIDE);
  288. // Check if there is even a file list to verify.
  289. if (g_App.lpFileList)
  290. {
  291. if (!g_App.bStopScan)
  292. {
  293. // Display the "Scanning File List..." text
  294. MyLoadString(szBuffer, IDS_STATUS_SCAN);
  295. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  296. // Reset the progress bar back to zero percent while it's invisible.
  297. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
  298. //
  299. // WooHoo! Let's display the progress bar and start cranking on the file list!
  300. //
  301. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_SHOW);
  302. VerifyFileList();
  303. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_HIDE);
  304. }
  305. }
  306. else
  307. {
  308. //
  309. // The IDC_NOTMS code displays it's own error message, so only display
  310. // an error dialog if we are doing a System Integrity Scan
  311. //
  312. if (!g_App.bStopScan && !g_App.bUserScan)
  313. {
  314. MyMessageBoxId(IDS_NOSYSTEMFILES);
  315. }
  316. }
  317. // Disable the start button while we clean up the g_App.lpFileList
  318. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), FALSE);
  319. if (!g_App.bStopScan)
  320. {
  321. // Display the text that says "Writing Log File..."
  322. MyLoadString(szBuffer, IDS_STATUS_LOG);
  323. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  324. // Write the results to the log file
  325. PrintFileList();
  326. }
  327. else
  328. {
  329. // If the user clicked STOP, let them know about it.
  330. MyMessageBoxId(IDS_SCANSTOPPED);
  331. }
  332. // Display the text that says "Freeing File List..."
  333. MyLoadString(szBuffer, IDS_STATUS_FREE);
  334. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  335. // Free all the memory that we allocated for the g_App.lpFileList
  336. DestroyFileList();
  337. // Hide the IDC_STATUS text item so it doesn't cover IDC_STATUS
  338. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_HIDE);
  339. // Change the "Stop" button back to "Start"
  340. MyLoadString(szBuffer, IDS_START);
  341. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  342. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), TRUE);
  343. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), TRUE);
  344. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), TRUE);
  345. // Clear the scanning flag
  346. g_App.bScanning = FALSE;
  347. g_App.bStopScan = FALSE;
  348. //
  349. // If the user started SigVerif with the FullSystemScan flag, then we exit.
  350. //
  351. if (g_App.bFullSystemScan)
  352. {
  353. PostMessage(g_App.hDlg, WM_CLOSE, (WPARAM) 0, (LPARAM) 0);
  354. }
  355. }
  356. // Spawns a thread to do the scan so the GUI remains responsive.
  357. void Dlg_OnPushStartButton(HWND hwnd)
  358. {
  359. HANDLE hThread;
  360. DWORD dwThreadId;
  361. // Check if we are already scanning... if so, bail.
  362. if (g_App.bScanning)
  363. return;
  364. // Create a thread where Search_ProcessFileList can go without tying up the GUI thread.
  365. hThread = CreateThread(NULL,
  366. 0,
  367. (LPTHREAD_START_ROUTINE) ProcessFileList,
  368. 0,
  369. 0,
  370. &dwThreadId);
  371. }
  372. // Handle any WM_COMMAND messages sent to the search dialog
  373. void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
  374. {
  375. switch(id)
  376. {
  377. //
  378. // The user clicked ID_START, so if we aren't scanning start scanning.
  379. // If we are scanning, then stop the tests because the button actually says "Stop"
  380. //
  381. case ID_START:
  382. if (!g_App.bScanning)
  383. {
  384. Dlg_OnPushStartButton(hwnd);
  385. } else if (!g_App.bStopScan)
  386. g_App.bStopScan = TRUE;
  387. break;
  388. //
  389. // The user clicked IDCANCEL, so if the tests are running try to stop them before exiting.
  390. //
  391. case IDCANCEL:
  392. if (g_App.bScanning)
  393. {
  394. g_App.bStopScan = TRUE;
  395. } else SendMessage(hwnd, WM_CLOSE, 0, 0);
  396. break;
  397. // Pop up the IDD_SETTINGS dialog so the user can change their log settings.
  398. case ID_ADVANCED:
  399. if (!g_App.bScanning)
  400. {
  401. AdvancedPropertySheet(hwnd);
  402. }
  403. break;
  404. }
  405. }
  406. void SigVerif_Help(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL bContext)
  407. {
  408. static DWORD SigVerif_HelpIDs[] =
  409. {
  410. IDC_SCAN, IDH_SIGVERIF_SEARCH_CHECK_SYSTEM,
  411. IDC_NOTMS, IDH_SIGVERIF_SEARCH_LOOK_FOR,
  412. IDC_TYPE, IDH_SIGVERIF_SEARCH_SCAN_FILES,
  413. IDC_FOLDER, IDH_SIGVERIF_SEARCH_LOOK_IN_FOLDER,
  414. IDC_SUBFOLDERS, IDH_SIGVERIF_SEARCH_INCLUDE_SUBFOLDERS,
  415. IDC_ENABLELOG, IDH_SIGVERIF_LOGGING_ENABLE_LOGGING,
  416. IDC_APPEND, IDH_SIGVERIF_LOGGING_APPEND,
  417. IDC_OVERWRITE, IDH_SIGVERIF_LOGGING_OVERWRITE,
  418. IDC_LOGNAME, IDH_SIGVERIF_LOGGING_FILENAME,
  419. IDC_VIEWLOG, IDH_SIGVERIF_LOGGING_VIEW_LOG,
  420. 0,0
  421. };
  422. static DWORD Windows_HelpIDs[] =
  423. {
  424. ID_BROWSE, IDH_BROWSE,
  425. 0,0
  426. };
  427. HWND hItem = NULL;
  428. LPHELPINFO lphi = NULL;
  429. POINT point;
  430. switch (uMsg)
  431. {
  432. case WM_HELP:
  433. lphi = (LPHELPINFO) lParam;
  434. if (lphi && (lphi->iContextType == HELPINFO_WINDOW)) // must be for a control
  435. hItem = (HWND) lphi->hItemHandle;
  436. break;
  437. case WM_CONTEXTMENU:
  438. hItem = (HWND) wParam;
  439. point.x = GET_X_LPARAM(lParam);
  440. point.y = GET_Y_LPARAM(lParam);
  441. if (ScreenToClient(hwnd, &point))
  442. {
  443. hItem = ChildWindowFromPoint(hwnd, point);
  444. }
  445. break;
  446. }
  447. if (hItem)
  448. {
  449. if (GetWindowLong(hItem, GWL_ID) == ID_BROWSE)
  450. {
  451. WinHelp(hItem,
  452. (LPCTSTR) WINDOWS_HELPFILE,
  453. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  454. (ULONG_PTR) Windows_HelpIDs);
  455. }
  456. else
  457. {
  458. WinHelp(hItem,
  459. (LPCTSTR) SIGVERIF_HELPFILE,
  460. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  461. (ULONG_PTR) SigVerif_HelpIDs);
  462. }
  463. }
  464. }
  465. //
  466. // The main dialog procedure. Needs to handle WM_INITDIALOG, WM_COMMAND, and WM_CLOSE/WM_DESTROY.
  467. //
  468. INT_PTR CALLBACK DlgProc(HWND hwnd, UINT uMsg,
  469. WPARAM wParam, LPARAM lParam)
  470. {
  471. BOOL fProcessed = TRUE;
  472. switch (uMsg)
  473. {
  474. HANDLE_MSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
  475. HANDLE_MSG(hwnd, WM_COMMAND, Dlg_OnCommand);
  476. case WM_CLOSE:
  477. if (g_App.bScanning)
  478. g_App.bStopScan = TRUE;
  479. else
  480. EndDialog(hwnd, IDCANCEL);
  481. break;
  482. default: fProcessed = FALSE;
  483. }
  484. return fProcessed;
  485. }
  486. //
  487. // Program entry point. Set up for creation of IDD_DIALOG.
  488. //
  489. WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  490. LPSTR lpszCmdParam, int nCmdShow)
  491. {
  492. HWND hwnd;
  493. TCHAR szAppName[MAX_PATH];
  494. // Zero-Initialize our global data structure
  495. ZeroMemory(&g_App, sizeof(GAPPDATA));
  496. // Initialize global hInstance variable
  497. g_App.hInstance = hInstance;
  498. // Look for any existing instances of SigVerif...
  499. MyLoadString(szAppName, IDS_SIGVERIF);
  500. hwnd = FindWindow(NULL, szAppName);
  501. if (!hwnd)
  502. {
  503. // We definitely need this for the progress bar, and maybe other stuff too.
  504. InitCommonControls();
  505. // Register the custom control we use for the progress bar
  506. Progress_InitRegisterClass();
  507. // Load the icon from the resource file that we will use everywhere
  508. g_App.hIcon = LoadIcon(g_App.hInstance, MAKEINTRESOURCE(IDI_ICON1));
  509. // Create the IDD_DIALOG and use DlgProc as the main procedure
  510. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
  511. // Free the icon
  512. if (g_App.hIcon) {
  513. DestroyIcon(g_App.hIcon);
  514. }
  515. }
  516. else
  517. {
  518. // If there is already an instance of SigVerif running, make that one foreground and we exit.
  519. SetForegroundWindow(hwnd);
  520. }
  521. return 0;
  522. }