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.

899 lines
25 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. // By default we will consider Authenticode signed drivers as valid, but
  337. // if the user specifies the /NOAUTHENTICODE switch then Authenticode
  338. // signed drivers will not be valid.
  339. //
  340. MyLoadString(szBuffer, cA(szBuffer), IDS_NOAUTHENTICODE);
  341. if (MyStrStr(GetCommandLine(), szBuffer)) {
  342. g_App.bNoAuthenticode = TRUE;
  343. }
  344. //
  345. // If the user specified the DEFSCAN flag, we want to automatically do a
  346. // default scan and log the results.
  347. //
  348. MyLoadString(szBuffer, cA(szBuffer), IDS_DEFSCAN);
  349. if (MyStrStr(GetCommandLine(), szBuffer)) {
  350. g_App.bAutomatedScan = TRUE;
  351. g_App.bLoggingEnabled = TRUE;
  352. //
  353. // Now that everything is set up, simulate a click to the START button...
  354. //
  355. PostMessage(hwnd, WM_COMMAND, MAKEWPARAM(ID_START, 0), (LPARAM) 0);
  356. }
  357. if (Err == ERROR_SUCCESS) {
  358. return TRUE;
  359. } else {
  360. g_App.LastError = Err;
  361. return FALSE;
  362. }
  363. }
  364. //
  365. // Build file list according to dialog settings, then verify the files in the list
  366. //
  367. void WINAPI
  368. ProcessFileList(void)
  369. {
  370. DWORD Err = ERROR_SUCCESS;
  371. TCHAR szBuffer[MAX_PATH];
  372. ULONG cchSize;
  373. HRESULT hr;
  374. //
  375. // Set the scanning flag to TRUE, so we don't double-scan
  376. //
  377. g_App.bScanning = TRUE;
  378. // Assume a successfull scan.
  379. g_App.LastError = ERROR_SUCCESS;
  380. //
  381. // Change the "Start" to "Stop"
  382. //
  383. MyLoadString(szBuffer, cA(szBuffer), IDS_STOP);
  384. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  385. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), FALSE);
  386. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), FALSE);
  387. //
  388. // Display the text that says "Building file list..."
  389. //
  390. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_BUILD);
  391. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  392. //
  393. // Make sure the IDC_STATUS text item visible
  394. //
  395. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_SHOW);
  396. //
  397. // Free any memory that we may have allocated for the g_App.lpFileList
  398. //
  399. DestroyFileList(TRUE);
  400. //
  401. // Now actually build the g_App.lpFileList list given the dialog settings
  402. //
  403. if (g_App.bUserScan) {
  404. Err = BuildFileList(g_App.szScanPath);
  405. } else {
  406. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  407. Err = BuildDriverFileList();
  408. }
  409. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  410. Err = BuildPrinterFileList();
  411. }
  412. if (!g_App.bStopScan && (Err == ERROR_SUCCESS)) {
  413. Err = BuildCoreFileList();
  414. }
  415. }
  416. if (!g_App.bAutomatedScan &&
  417. (Err != ERROR_SUCCESS) &&
  418. (Err != ERROR_CANCELLED)) {
  419. g_App.LastError = Err;
  420. MyErrorBoxIdWithErrorCode(IDS_BUILDLISTERROR, Err);
  421. }
  422. //
  423. // If we encountered an error building the file list then don't bother
  424. // scanning the files.
  425. //
  426. if (Err == ERROR_SUCCESS) {
  427. //
  428. // Check if there is even a file list to verify.
  429. //
  430. if (g_App.lpFileList) {
  431. if (!g_App.bStopScan) {
  432. //
  433. // Display the "Scanning File List..." text
  434. //
  435. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_SCAN);
  436. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  437. //
  438. // Reset the progress bar back to zero percent while it's invisible.
  439. //
  440. SendMessage(GetDlgItem(g_App.hDlg, IDC_PROGRESS), PBM_SETPOS, (WPARAM) 0, (LPARAM) 0);
  441. //
  442. // WooHoo! Let's display the progress bar and start cranking on the file list!
  443. //
  444. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_SHOW);
  445. VerifyFileList();
  446. ShowWindow(GetDlgItem(g_App.hDlg, IDC_PROGRESS), SW_HIDE);
  447. }
  448. } else {
  449. //
  450. // The IDC_NOTMS code displays it's own error message, so only display
  451. // an error dialog if we are doing a System Integrity Scan
  452. //
  453. if (!g_App.bStopScan && !g_App.bUserScan) {
  454. MyMessageBoxId(IDS_NOSYSTEMFILES);
  455. }
  456. }
  457. //
  458. // Disable the start button while we clean up the g_App.lpFileList
  459. //
  460. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), FALSE);
  461. //
  462. // Log the results. Note that sigverif will do this even if we encountered
  463. // an error building or scanning the list, since the logfile may help
  464. // figure out which file is causing the problem. Only log the results
  465. // if we found any files to scan.
  466. //
  467. if (!g_App.bStopScan) {
  468. //
  469. // Display the text that says "Writing Log File..."
  470. //
  471. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_LOG);
  472. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  473. //
  474. // Write the results to the log file
  475. //
  476. if (!PrintFileList()) {
  477. //
  478. // We failed while logging for some reason, probably permissions
  479. // or out of disk space. Let the user know that we could not finish
  480. // logging all of the files.
  481. //
  482. Err = GetLastError();
  483. if (Err != ERROR_SUCCESS) {
  484. MyErrorBoxIdWithErrorCode(IDS_LOGERROR, Err);
  485. }
  486. }
  487. } else {
  488. //
  489. // If the user clicked STOP, let them know about it.
  490. //
  491. MyMessageBoxId(IDS_SCANSTOPPED);
  492. }
  493. }
  494. //
  495. // Display the text that says "Freeing File List..."
  496. //
  497. MyLoadString(szBuffer, cA(szBuffer), IDS_STATUS_FREE);
  498. SetDlgItemText(g_App.hDlg, IDC_STATUS, szBuffer);
  499. //
  500. // Hide the IDC_STATUS text item so it doesn't cover IDC_STATUS
  501. //
  502. ShowWindow(GetDlgItem(g_App.hDlg, IDC_STATUS), SW_HIDE);
  503. //
  504. // Change the "Stop" button back to "Start"
  505. //
  506. MyLoadString(szBuffer, cA(szBuffer), IDS_START);
  507. SetDlgItemText(g_App.hDlg, ID_START, szBuffer);
  508. EnableWindow(GetDlgItem(g_App.hDlg, ID_START), TRUE);
  509. EnableWindow(GetDlgItem(g_App.hDlg, ID_ADVANCED), TRUE);
  510. EnableWindow(GetDlgItem(g_App.hDlg, IDCANCEL), TRUE);
  511. //
  512. // Free all the memory that we allocated for the g_App.lpFileList
  513. //
  514. DestroyFileList(FALSE);
  515. //
  516. // Clear the scanning flag
  517. //
  518. g_App.bScanning = FALSE;
  519. g_App.bStopScan = FALSE;
  520. //
  521. // If the user started SigVerif with the /DEFSCAN flag, then we exit.
  522. //
  523. if (g_App.bAutomatedScan) {
  524. PostMessage(g_App.hDlg, WM_CLOSE, (WPARAM) 0, (LPARAM) 0);
  525. }
  526. }
  527. //
  528. // Spawns a thread to do the scan so the GUI remains responsive.
  529. //
  530. void
  531. Dlg_OnPushStartButton(
  532. HWND hwnd
  533. )
  534. {
  535. HANDLE hThread;
  536. DWORD dwThreadId;
  537. UNREFERENCED_PARAMETER(hwnd);
  538. //
  539. // Check if we are already scanning... if so, bail.
  540. //
  541. if (g_App.bScanning) {
  542. return;
  543. }
  544. //
  545. // Create a thread where Search_ProcessFileList can go without tying up the GUI thread.
  546. //
  547. hThread = CreateThread(NULL,
  548. 0,
  549. (LPTHREAD_START_ROUTINE) ProcessFileList,
  550. 0,
  551. 0,
  552. &dwThreadId);
  553. CloseHandle(hThread);
  554. }
  555. //
  556. // Handle any WM_COMMAND messages sent to the search dialog
  557. //
  558. void
  559. Dlg_OnCommand(
  560. HWND hwnd,
  561. int id,
  562. HWND hwndCtl,
  563. UINT codeNotify
  564. )
  565. {
  566. UNREFERENCED_PARAMETER(hwndCtl);
  567. UNREFERENCED_PARAMETER(codeNotify);
  568. switch(id) {
  569. //
  570. // The user clicked ID_START, so if we aren't scanning start scanning.
  571. // If we are scanning, then stop the tests because the button actually says "Stop"
  572. //
  573. case ID_START:
  574. if (!g_App.bScanning) {
  575. Dlg_OnPushStartButton(hwnd);
  576. } else if (!g_App.bStopScan) {
  577. g_App.bStopScan = TRUE;
  578. g_App.LastError = ERROR_CANCELLED;
  579. }
  580. break;
  581. //
  582. // The user clicked IDCANCEL, so if the tests are running try to stop them before exiting.
  583. //
  584. case IDCANCEL:
  585. if (g_App.bScanning) {
  586. g_App.bStopScan = TRUE;
  587. g_App.LastError = ERROR_CANCELLED;
  588. } else {
  589. SendMessage(hwnd, WM_CLOSE, 0, 0);
  590. }
  591. break;
  592. // Pop up the IDD_SETTINGS dialog so the user can change their log settings.
  593. case ID_ADVANCED:
  594. if (!g_App.bScanning) {
  595. AdvancedPropertySheet(hwnd);
  596. }
  597. break;
  598. }
  599. }
  600. void
  601. SigVerif_Help(
  602. HWND hwnd,
  603. UINT uMsg,
  604. WPARAM wParam,
  605. LPARAM lParam,
  606. BOOL bContext
  607. )
  608. {
  609. static DWORD SigVerif_HelpIDs[] =
  610. {
  611. IDC_SCAN, IDH_SIGVERIF_SEARCH_CHECK_SYSTEM,
  612. IDC_NOTMS, IDH_SIGVERIF_SEARCH_LOOK_FOR,
  613. IDC_TYPE, IDH_SIGVERIF_SEARCH_SCAN_FILES,
  614. IDC_FOLDER, IDH_SIGVERIF_SEARCH_LOOK_IN_FOLDER,
  615. IDC_SUBFOLDERS, IDH_SIGVERIF_SEARCH_INCLUDE_SUBFOLDERS,
  616. IDC_ENABLELOG, IDH_SIGVERIF_LOGGING_ENABLE_LOGGING,
  617. IDC_APPEND, IDH_SIGVERIF_LOGGING_APPEND,
  618. IDC_OVERWRITE, IDH_SIGVERIF_LOGGING_OVERWRITE,
  619. IDC_LOGNAME, IDH_SIGVERIF_LOGGING_FILENAME,
  620. IDC_VIEWLOG, IDH_SIGVERIF_LOGGING_VIEW_LOG,
  621. 0,0
  622. };
  623. static DWORD Windows_HelpIDs[] =
  624. {
  625. ID_BROWSE, IDH_BROWSE,
  626. 0,0
  627. };
  628. HWND hItem = NULL;
  629. LPHELPINFO lphi = NULL;
  630. POINT point;
  631. switch (uMsg) {
  632. case WM_HELP:
  633. lphi = (LPHELPINFO) lParam;
  634. if (lphi && (lphi->iContextType == HELPINFO_WINDOW)) {
  635. hItem = (HWND) lphi->hItemHandle;
  636. }
  637. break;
  638. case WM_CONTEXTMENU:
  639. hItem = (HWND) wParam;
  640. point.x = GET_X_LPARAM(lParam);
  641. point.y = GET_Y_LPARAM(lParam);
  642. if (ScreenToClient(hwnd, &point)) {
  643. hItem = ChildWindowFromPoint(hwnd, point);
  644. }
  645. break;
  646. }
  647. if (hItem) {
  648. if (GetWindowLong(hItem, GWL_ID) == ID_BROWSE) {
  649. WinHelp(hItem,
  650. (LPCTSTR) WINDOWS_HELPFILE,
  651. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  652. (ULONG_PTR) Windows_HelpIDs);
  653. } else {
  654. WinHelp(hItem,
  655. (LPCTSTR) SIGVERIF_HELPFILE,
  656. (bContext ? HELP_CONTEXTMENU : HELP_WM_HELP),
  657. (ULONG_PTR) SigVerif_HelpIDs);
  658. }
  659. }
  660. }
  661. //
  662. // The main dialog procedure. Needs to handle WM_INITDIALOG, WM_COMMAND, and WM_CLOSE/WM_DESTROY.
  663. //
  664. INT_PTR CALLBACK
  665. DlgProc(
  666. HWND hwnd,
  667. UINT uMsg,
  668. WPARAM wParam,
  669. LPARAM lParam
  670. )
  671. {
  672. BOOL fProcessed = TRUE;
  673. switch (uMsg) {
  674. HANDLE_MSG(hwnd, WM_COMMAND, Dlg_OnCommand);
  675. case WM_INITDIALOG:
  676. fProcessed = Dlg_OnInitDialog(hwnd);
  677. break;
  678. case WM_CLOSE:
  679. if (g_App.bScanning) {
  680. g_App.bStopScan = TRUE;
  681. g_App.LastError = ERROR_CANCELLED;
  682. } else {
  683. EndDialog(hwnd, IDCANCEL);
  684. }
  685. break;
  686. default:
  687. fProcessed = FALSE;
  688. }
  689. return fProcessed;
  690. }
  691. //
  692. // Program entry point. Set up for creation of IDD_DIALOG.
  693. //
  694. WINAPI
  695. WinMain(
  696. HINSTANCE hInstance,
  697. HINSTANCE hPrevInstance,
  698. LPSTR lpszCmdParam,
  699. int nCmdShow
  700. )
  701. {
  702. HWND hwnd;
  703. TCHAR szAppName[MAX_PATH];
  704. UNREFERENCED_PARAMETER(hPrevInstance);
  705. UNREFERENCED_PARAMETER(lpszCmdParam);
  706. UNREFERENCED_PARAMETER(nCmdShow);
  707. ZeroMemory(&g_App, sizeof(GAPPDATA));
  708. g_App.hInstance = hInstance;
  709. //
  710. // Look for any existing instances of SigVerif...
  711. //
  712. MyLoadString(szAppName, cA(szAppName), IDS_SIGVERIF);
  713. hwnd = FindWindow(NULL, szAppName);
  714. if (!hwnd) {
  715. //
  716. // We definitely need this for the progress bar, and maybe other stuff too.
  717. //
  718. InitCommonControls();
  719. //
  720. // Register the custom control we use for the progress bar
  721. //
  722. Progress_InitRegisterClass();
  723. //
  724. // Load the icon from the resource file that we will use everywhere
  725. //
  726. g_App.hIcon = LoadIcon(g_App.hInstance, MAKEINTRESOURCE(IDI_ICON1));
  727. //
  728. // Create the IDD_DIALOG and use DlgProc as the main procedure
  729. //
  730. DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
  731. if (g_App.hIcon) {
  732. DestroyIcon(g_App.hIcon);
  733. g_App.hIcon = NULL;
  734. }
  735. } else {
  736. //
  737. // If there is already an instance of SigVerif running, make that one
  738. // foreground and we exit.
  739. //
  740. SetForegroundWindow(hwnd);
  741. }
  742. //
  743. // If we encountered any errors during our scan, then return the error code,
  744. // otherwise return 0 if all the files are signed or 1 if we found any
  745. // unsigned files.
  746. //
  747. if (g_App.LastError != ERROR_SUCCESS) {
  748. return g_App.LastError;
  749. } else {
  750. return ((g_App.dwUnsigned > 0) ? 1 : 0);
  751. }
  752. }