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.

636 lines
16 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. init.c
  5. Abstract:
  6. Implementation of System File Checker initialization code.
  7. Author:
  8. Wesley Witt (wesw) 18-Dec-1998
  9. Revision History:
  10. --*/
  11. #include <windows.h>
  12. #include <commctrl.h>
  13. #include <cpl.h>
  14. #include <stdlib.h>
  15. #include <sfcapip.h>
  16. #include "resource.h"
  17. #define DLLCACHE_DIR L"%SystemRoot%\\system32\\DllCache"
  18. #define DLGFORWARD(_nm) INT_PTR CALLBACK _nm(HWND,UINT,WPARAM,LPARAM)
  19. #define MySetDlgItemText(hDlg, itemId, msgText) { \
  20. insideSetDlgItemText = TRUE; \
  21. SetDlgItemText(hDlg, itemId, msgText); \
  22. insideSetDlgItemText = FALSE; \
  23. }
  24. #define MySetDlgItemInt(hDlg, itemId, msgText,signed) { \
  25. insideSetDlgItemText = TRUE; \
  26. SetDlgItemInt(hDlg, itemId, msgText,signed); \
  27. insideSetDlgItemText = FALSE; \
  28. }
  29. typedef struct _SFC_PAGES {
  30. DWORD ResId;
  31. DLGPROC DlgProc;
  32. } SFC_PAGES, *PSFC_PAGES;
  33. HMODULE SfcInstanceHandle;
  34. BOOL insideSetDlgItemText;
  35. HANDLE RpcHandle;
  36. DLGFORWARD(SfcDisableDlgProc);
  37. DLGFORWARD(SfcScanDlgProc);
  38. DLGFORWARD(SfcMiscDlgProc);
  39. SFC_PAGES SfcPages[] =
  40. {
  41. { IDD_SFC_DISABLE, SfcDisableDlgProc },
  42. { IDD_SFC_SCAN, SfcScanDlgProc },
  43. { IDD_SFC_MISC, SfcMiscDlgProc }
  44. };
  45. #define CountPages (sizeof(SfcPages)/sizeof(SFC_PAGES))
  46. ULONG SFCQuota;
  47. ULONG SFCDisable;
  48. ULONG SFCScan;
  49. ULONG SFCBugcheck;
  50. ULONG SFCNoPopUps;
  51. ULONG SFCDebug;
  52. ULONG SFCShowProgress;
  53. ULONG SFCChangeLog;
  54. WCHAR SFCDllCacheDir[MAX_PATH*2];
  55. DWORD
  56. SfcDllEntry(
  57. HINSTANCE hInstance,
  58. DWORD Reason,
  59. LPVOID Context
  60. )
  61. {
  62. if (Reason == DLL_PROCESS_ATTACH) {
  63. SfcInstanceHandle = hInstance;
  64. DisableThreadLibraryCalls( hInstance );
  65. }
  66. return TRUE;
  67. }
  68. void
  69. SetChangeFlag(
  70. HWND hDlg,
  71. BOOL Enable
  72. )
  73. {
  74. HWND hwndPropSheet = GetParent( hDlg );
  75. if (Enable) {
  76. PropSheet_Changed( hwndPropSheet, hDlg );
  77. } else {
  78. PropSheet_UnChanged( hwndPropSheet, hDlg );
  79. }
  80. }
  81. DWORD
  82. SfcQueryRegDword(
  83. LPWSTR KeyName,
  84. LPWSTR ValueName
  85. )
  86. {
  87. HKEY hKey;
  88. DWORD val;
  89. DWORD sz = sizeof(DWORD);
  90. if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
  91. return 0;
  92. }
  93. if (RegQueryValueEx( hKey, ValueName, NULL, NULL, (LPBYTE)&val, &sz ) != ERROR_SUCCESS) {
  94. RegCloseKey( hKey );
  95. return 0;
  96. }
  97. RegCloseKey( hKey );
  98. return val;
  99. }
  100. PWSTR
  101. SfcQueryRegString(
  102. LPWSTR KeyName,
  103. LPWSTR ValueName
  104. )
  105. {
  106. HKEY hKey;
  107. DWORD sz = 0;
  108. PWSTR val;
  109. if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
  110. return 0;
  111. }
  112. if (RegQueryValueEx( hKey, ValueName, NULL, NULL, NULL, &sz ) != ERROR_SUCCESS) {
  113. RegCloseKey( hKey );
  114. return NULL;
  115. }
  116. val = malloc( sz+16 );
  117. if (val == NULL) {
  118. return NULL;
  119. }
  120. if (RegQueryValueEx( hKey, ValueName, NULL, NULL, (LPBYTE)val, &sz ) != ERROR_SUCCESS) {
  121. RegCloseKey( hKey );
  122. return NULL;
  123. }
  124. RegCloseKey( hKey );
  125. return val;
  126. }
  127. DWORD
  128. SfcWriteRegDword(
  129. LPWSTR KeyName,
  130. LPWSTR ValueName,
  131. ULONG Value
  132. )
  133. {
  134. HKEY hKey;
  135. if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
  136. return 0;
  137. }
  138. if (RegSetValueEx( hKey, ValueName, 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD) ) != ERROR_SUCCESS) {
  139. RegCloseKey( hKey );
  140. return 0;
  141. }
  142. RegCloseKey( hKey );
  143. return 0;
  144. }
  145. DWORD
  146. SfcWriteRegString(
  147. LPWSTR KeyName,
  148. LPWSTR ValueName,
  149. PWSTR Value
  150. )
  151. {
  152. HKEY hKey;
  153. if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
  154. return 0;
  155. }
  156. if (RegSetValueEx( hKey, ValueName, 0, REG_SZ, (LPBYTE)Value, (wcslen(Value)+1)*sizeof(WCHAR) ) != ERROR_SUCCESS) {
  157. RegCloseKey( hKey );
  158. return 0;
  159. }
  160. RegCloseKey( hKey );
  161. return 0;
  162. }
  163. void
  164. SaveRegValues(
  165. void
  166. )
  167. {
  168. SfcWriteRegDword(
  169. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  170. L"SFCDebug",
  171. SFCDebug
  172. );
  173. SfcWriteRegDword(
  174. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  175. L"SFCDisable",
  176. SFCDisable
  177. );
  178. SfcWriteRegDword(
  179. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  180. L"SFCScan",
  181. SFCScan
  182. );
  183. SfcWriteRegDword(
  184. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  185. L"SFCQuota",
  186. SFCQuota
  187. );
  188. SfcWriteRegDword(
  189. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  190. L"SFCBugcheck",
  191. SFCBugcheck
  192. );
  193. SfcWriteRegDword(
  194. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  195. L"SfcShowProgress",
  196. SFCShowProgress
  197. );
  198. SfcWriteRegDword(
  199. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  200. L"SfcChangeLog",
  201. SFCChangeLog
  202. );
  203. SfcWriteRegString(
  204. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  205. L"SFCDllCacheDir",
  206. SFCDllCacheDir
  207. );
  208. }
  209. void
  210. InititlaizeRegValues(
  211. void
  212. )
  213. {
  214. PWSTR s;
  215. SFCDebug = SfcQueryRegDword(
  216. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  217. L"SFCDebug"
  218. );
  219. SFCDisable = SfcQueryRegDword(
  220. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  221. L"SFCDisable"
  222. );
  223. SFCScan = SfcQueryRegDword(
  224. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  225. L"SFCScan"
  226. );
  227. SFCQuota = SfcQueryRegDword(
  228. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  229. L"SFCQuota"
  230. );
  231. SFCBugcheck = SfcQueryRegDword(
  232. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  233. L"SFCBugcheck"
  234. );
  235. SFCShowProgress = SfcQueryRegDword(
  236. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  237. L"SfcShowProgress"
  238. );
  239. SFCChangeLog = SfcQueryRegDword(
  240. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  241. L"SfcChangeLog"
  242. );
  243. s = SfcQueryRegString(
  244. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
  245. L"SFCDllCacheDir"
  246. );
  247. if (s == NULL) {
  248. //ExpandEnvironmentStrings( DLLCACHE_DIR, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
  249. wcscpy( SFCDllCacheDir, DLLCACHE_DIR );
  250. } else {
  251. //ExpandEnvironmentStrings( s, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
  252. wcscpy( SFCDllCacheDir, s );
  253. free( s );
  254. }
  255. }
  256. INT_PTR
  257. CALLBACK
  258. SfcDisableDlgProc(
  259. HWND hwndDlg,
  260. UINT uMsg,
  261. WPARAM wParam,
  262. LPARAM lParam
  263. )
  264. {
  265. switch(uMsg) {
  266. case WM_INITDIALOG:
  267. switch (SFCDisable) {
  268. case SFC_DISABLE_NORMAL:
  269. CheckDlgButton( hwndDlg, IDC_DISABLE_NORMAL, BST_CHECKED );
  270. break;
  271. case SFC_DISABLE_ASK:
  272. CheckDlgButton( hwndDlg, IDC_DISABLE_ASK, BST_CHECKED );
  273. break;
  274. case SFC_DISABLE_ONCE:
  275. CheckDlgButton( hwndDlg, IDC_DISABLE_ONCE, BST_CHECKED );
  276. break;
  277. case SFC_DISABLE_NOPOPUPS:
  278. CheckDlgButton( hwndDlg, IDC_DISABLE_NOPOPUPS, BST_CHECKED );
  279. break;
  280. }
  281. return TRUE;
  282. case WM_COMMAND:
  283. switch (LOWORD(wParam)) {
  284. case IDC_DISABLE_NORMAL:
  285. case IDC_DISABLE_ASK:
  286. case IDC_DISABLE_ONCE:
  287. case IDC_DISABLE_NOPOPUPS:
  288. SetChangeFlag( hwndDlg, TRUE );
  289. break;
  290. default:
  291. return FALSE;
  292. }
  293. break;
  294. case WM_NOTIFY:
  295. switch (((NMHDR *) lParam)->code) {
  296. case PSN_SETACTIVE:
  297. break;
  298. case PSN_APPLY:
  299. if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_NORMAL )) {
  300. SFCDisable = SFC_DISABLE_NORMAL;
  301. } else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_ASK )) {
  302. SFCDisable = SFC_DISABLE_ASK;
  303. } else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_ONCE )) {
  304. SFCDisable = SFC_DISABLE_ONCE;
  305. } else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_NOPOPUPS )) {
  306. SFCDisable = SFC_DISABLE_NOPOPUPS;
  307. }
  308. SaveRegValues();
  309. SetChangeFlag( hwndDlg, FALSE );
  310. return PSNRET_NOERROR;
  311. }
  312. break;
  313. }
  314. return FALSE;
  315. }
  316. INT_PTR
  317. CALLBACK
  318. SfcScanDlgProc(
  319. HWND hwndDlg,
  320. UINT uMsg,
  321. WPARAM wParam,
  322. LPARAM lParam
  323. )
  324. {
  325. switch(uMsg) {
  326. case WM_INITDIALOG:
  327. switch (SFCScan) {
  328. case SFC_SCAN_NORMAL:
  329. CheckDlgButton( hwndDlg, IDC_SCAN_NORMAL, BST_CHECKED );
  330. break;
  331. case SFC_SCAN_ALWAYS:
  332. CheckDlgButton( hwndDlg, IDC_SCAN_ALWAYS, BST_CHECKED );
  333. break;
  334. case SFC_SCAN_ONCE:
  335. CheckDlgButton( hwndDlg, IDC_SCAN_ONCE, BST_CHECKED );
  336. break;
  337. }
  338. CheckDlgButton( hwndDlg, IDC_SHOW_PROGRESS, SFCShowProgress ? BST_CHECKED : BST_UNCHECKED );
  339. return TRUE;
  340. case WM_COMMAND:
  341. switch (LOWORD(wParam)) {
  342. case IDC_SCAN_NORMAL:
  343. case IDC_SCAN_NOW:
  344. case IDC_SCAN_ALWAYS:
  345. case IDC_SCAN_ONCE:
  346. case IDC_SHOW_PROGRESS:
  347. SetChangeFlag( hwndDlg, TRUE );
  348. break;
  349. default:
  350. return FALSE;
  351. }
  352. break;
  353. case WM_NOTIFY:
  354. switch (((NMHDR *) lParam)->code) {
  355. case PSN_SETACTIVE:
  356. break;
  357. case PSN_APPLY:
  358. if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_NOW )) {
  359. SfcInitiateScan( RpcHandle, 0 );
  360. SetChangeFlag( hwndDlg, FALSE );
  361. return PSNRET_NOERROR;
  362. }
  363. if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_NORMAL )) {
  364. SFCScan = SFC_SCAN_NORMAL;
  365. } else if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_ALWAYS )) {
  366. SFCScan = SFC_SCAN_ALWAYS;
  367. } else if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_ONCE )) {
  368. SFCScan = SFC_SCAN_ONCE;
  369. }
  370. if (IsDlgButtonChecked( hwndDlg, IDC_SHOW_PROGRESS )) {
  371. SFCShowProgress = 1;
  372. } else {
  373. SFCShowProgress = 0;
  374. }
  375. SaveRegValues();
  376. SetChangeFlag( hwndDlg, FALSE );
  377. return PSNRET_NOERROR;
  378. }
  379. break;
  380. }
  381. return FALSE;
  382. }
  383. INT_PTR
  384. CALLBACK
  385. SfcMiscDlgProc(
  386. HWND hwndDlg,
  387. UINT uMsg,
  388. WPARAM wParam,
  389. LPARAM lParam
  390. )
  391. {
  392. switch(uMsg) {
  393. case WM_INITDIALOG:
  394. MySetDlgItemInt( hwndDlg, IDC_QUOTA, SFCQuota, FALSE );
  395. MySetDlgItemText( hwndDlg, IDC_CACHE_DIR, SFCDllCacheDir );
  396. MySetDlgItemInt( hwndDlg, IDC_DEBUG_LEVEL, SFCDebug, FALSE );
  397. CheckDlgButton( hwndDlg, IDC_BUGCHECK, SFCBugcheck ? BST_CHECKED : BST_UNCHECKED );
  398. CheckDlgButton( hwndDlg, IDC_CHANGE_LOG, SFCChangeLog ? BST_CHECKED : BST_UNCHECKED );
  399. return TRUE;
  400. case WM_COMMAND:
  401. switch (LOWORD(wParam)) {
  402. case IDC_BUGCHECK:
  403. case IDC_CHANGE_LOG:
  404. SetChangeFlag( hwndDlg, TRUE );
  405. return TRUE;
  406. case IDC_QUOTA:
  407. case IDC_DEBUG_LEVEL:
  408. case IDC_CACHE_DIR:
  409. if (HIWORD(wParam) == EN_CHANGE && !insideSetDlgItemText) {
  410. SetChangeFlag( hwndDlg, TRUE );
  411. return TRUE;
  412. }
  413. break;
  414. default:
  415. return FALSE;
  416. }
  417. break;
  418. case WM_NOTIFY:
  419. switch (((NMHDR *) lParam)->code) {
  420. case PSN_SETACTIVE:
  421. break;
  422. case PSN_APPLY:
  423. if (IsDlgButtonChecked( hwndDlg, IDC_BUGCHECK )) {
  424. SFCBugcheck = 1;
  425. } else {
  426. SFCBugcheck = 0;
  427. }
  428. if (IsDlgButtonChecked( hwndDlg, IDC_CHANGE_LOG )) {
  429. SFCChangeLog = 1;
  430. } else {
  431. SFCChangeLog = 0;
  432. }
  433. SFCQuota = GetDlgItemInt( hwndDlg, IDC_QUOTA, NULL, FALSE );
  434. SFCDebug = GetDlgItemInt( hwndDlg, IDC_DEBUG_LEVEL, NULL, FALSE );
  435. GetDlgItemText( hwndDlg, IDC_CACHE_DIR, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
  436. SaveRegValues();
  437. SetChangeFlag( hwndDlg, FALSE );
  438. return PSNRET_NOERROR;
  439. }
  440. break;
  441. }
  442. return FALSE;
  443. }
  444. void
  445. CreateSfcProperySheet(
  446. HWND hwnd
  447. )
  448. {
  449. DWORD i;
  450. PROPSHEETHEADER psh;
  451. LPPROPSHEETPAGE psp;
  452. RpcHandle = SfcConnectToServer( NULL );
  453. psp = malloc( sizeof(PROPSHEETPAGE)*CountPages );
  454. if (psp == NULL) {
  455. return;
  456. }
  457. for (i=0; i<CountPages; i++) {
  458. psp[i].dwSize = sizeof(PROPSHEETPAGE);
  459. psp[i].dwFlags = i == 0 ? PSP_PREMATURE : PSP_DEFAULT;
  460. psp[i].hInstance = SfcInstanceHandle;
  461. psp[i].pszTemplate = MAKEINTRESOURCE(SfcPages[i].ResId);
  462. psp[i].pszIcon = NULL;
  463. psp[i].pszTitle = NULL;
  464. psp[i].pfnDlgProc = SfcPages[i].DlgProc;
  465. psp[i].lParam = 0;
  466. psp[i].pfnCallback = NULL;
  467. psp[i].pcRefParent = NULL;
  468. psp[i].pszHeaderTitle = NULL;
  469. psp[i].pszHeaderSubTitle = NULL;
  470. }
  471. psh.dwSize = sizeof(PROPSHEETHEADER);
  472. psh.dwFlags = PSH_PROPSHEETPAGE;
  473. psh.hwndParent = hwnd;
  474. psh.hInstance = SfcInstanceHandle;
  475. psh.pszIcon = MAKEINTRESOURCE(IDI_SFCCPL);
  476. psh.pszCaption = MAKEINTRESOURCE(IDS_SFCCPL_DESC);
  477. psh.nPages = CountPages;
  478. psh.nStartPage = 0;
  479. psh.ppsp = psp;
  480. psh.pfnCallback = NULL;
  481. psh.pszbmWatermark = NULL;
  482. psh.hplWatermark = NULL;
  483. psh.pszbmHeader = NULL;
  484. PropertySheet( &psh );
  485. }
  486. LONG
  487. CALLBACK
  488. CPlApplet(
  489. HWND hwndCPl,
  490. UINT uMsg,
  491. LPARAM lParam1,
  492. LPARAM lParam2
  493. )
  494. {
  495. int i;
  496. LPCPLINFO CPlInfo;
  497. i = (int) lParam1;
  498. switch (uMsg) {
  499. case CPL_INIT:
  500. InititlaizeRegValues();
  501. return TRUE;
  502. case CPL_GETCOUNT:
  503. return 1;
  504. case CPL_INQUIRE:
  505. CPlInfo = (LPCPLINFO) lParam2;
  506. CPlInfo->lData = 0;
  507. CPlInfo->idIcon = IDI_SFCCPL;
  508. CPlInfo->idName = IDS_SFCCPL_NAME;
  509. CPlInfo->idInfo = IDS_SFCCPL_DESC;
  510. break;
  511. case CPL_DBLCLK:
  512. CreateSfcProperySheet( hwndCPl );
  513. break;
  514. case CPL_STOP:
  515. break;
  516. case CPL_EXIT:
  517. break;
  518. default:
  519. break;
  520. }
  521. return 0;
  522. }