637 lines
16 KiB
C
637 lines
16 KiB
C
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
init.c
|
|
|
|
Abstract:
|
|
|
|
Implementation of System File Checker initialization code.
|
|
|
|
Author:
|
|
|
|
Wesley Witt (wesw) 18-Dec-1998
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <windows.h>
|
|
#include <commctrl.h>
|
|
#include <cpl.h>
|
|
#include <stdlib.h>
|
|
#include <sfcapip.h>
|
|
#include "resource.h"
|
|
|
|
|
|
#define DLLCACHE_DIR L"%SystemRoot%\\system32\\DllCache"
|
|
#define DLGFORWARD(_nm) INT_PTR CALLBACK _nm(HWND,UINT,WPARAM,LPARAM)
|
|
|
|
#define MySetDlgItemText(hDlg, itemId, msgText) { \
|
|
insideSetDlgItemText = TRUE; \
|
|
SetDlgItemText(hDlg, itemId, msgText); \
|
|
insideSetDlgItemText = FALSE; \
|
|
}
|
|
|
|
#define MySetDlgItemInt(hDlg, itemId, msgText,signed) { \
|
|
insideSetDlgItemText = TRUE; \
|
|
SetDlgItemInt(hDlg, itemId, msgText,signed); \
|
|
insideSetDlgItemText = FALSE; \
|
|
}
|
|
|
|
|
|
typedef struct _SFC_PAGES {
|
|
DWORD ResId;
|
|
DLGPROC DlgProc;
|
|
} SFC_PAGES, *PSFC_PAGES;
|
|
|
|
|
|
HMODULE SfcInstanceHandle;
|
|
BOOL insideSetDlgItemText;
|
|
HANDLE RpcHandle;
|
|
|
|
DLGFORWARD(SfcDisableDlgProc);
|
|
DLGFORWARD(SfcScanDlgProc);
|
|
DLGFORWARD(SfcMiscDlgProc);
|
|
|
|
SFC_PAGES SfcPages[] =
|
|
{
|
|
{ IDD_SFC_DISABLE, SfcDisableDlgProc },
|
|
{ IDD_SFC_SCAN, SfcScanDlgProc },
|
|
{ IDD_SFC_MISC, SfcMiscDlgProc }
|
|
};
|
|
|
|
#define CountPages (sizeof(SfcPages)/sizeof(SFC_PAGES))
|
|
|
|
ULONG SFCQuota;
|
|
ULONG SFCDisable;
|
|
ULONG SFCScan;
|
|
ULONG SFCBugcheck;
|
|
ULONG SFCNoPopUps;
|
|
ULONG SFCDebug;
|
|
ULONG SFCShowProgress;
|
|
ULONG SFCChangeLog;
|
|
WCHAR SFCDllCacheDir[MAX_PATH*2];
|
|
|
|
|
|
DWORD
|
|
SfcDllEntry(
|
|
HINSTANCE hInstance,
|
|
DWORD Reason,
|
|
LPVOID Context
|
|
)
|
|
{
|
|
if (Reason == DLL_PROCESS_ATTACH) {
|
|
SfcInstanceHandle = hInstance;
|
|
DisableThreadLibraryCalls( hInstance );
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
SetChangeFlag(
|
|
HWND hDlg,
|
|
BOOL Enable
|
|
)
|
|
{
|
|
HWND hwndPropSheet = GetParent( hDlg );
|
|
if (Enable) {
|
|
PropSheet_Changed( hwndPropSheet, hDlg );
|
|
} else {
|
|
PropSheet_UnChanged( hwndPropSheet, hDlg );
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
SfcQueryRegDword(
|
|
LPWSTR KeyName,
|
|
LPWSTR ValueName
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
DWORD val;
|
|
DWORD sz = sizeof(DWORD);
|
|
|
|
|
|
if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
if (RegQueryValueEx( hKey, ValueName, NULL, NULL, (LPBYTE)&val, &sz ) != ERROR_SUCCESS) {
|
|
RegCloseKey( hKey );
|
|
return 0;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
return val;
|
|
}
|
|
|
|
|
|
PWSTR
|
|
SfcQueryRegString(
|
|
LPWSTR KeyName,
|
|
LPWSTR ValueName
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
DWORD sz = 0;
|
|
PWSTR val;
|
|
|
|
|
|
if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
if (RegQueryValueEx( hKey, ValueName, NULL, NULL, NULL, &sz ) != ERROR_SUCCESS) {
|
|
RegCloseKey( hKey );
|
|
return NULL;
|
|
}
|
|
|
|
val = malloc( sz+16 );
|
|
if (val == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
if (RegQueryValueEx( hKey, ValueName, NULL, NULL, (LPBYTE)val, &sz ) != ERROR_SUCCESS) {
|
|
RegCloseKey( hKey );
|
|
return NULL;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
return val;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SfcWriteRegDword(
|
|
LPWSTR KeyName,
|
|
LPWSTR ValueName,
|
|
ULONG Value
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
|
|
|
|
if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
if (RegSetValueEx( hKey, ValueName, 0, REG_DWORD, (LPBYTE)&Value, sizeof(DWORD) ) != ERROR_SUCCESS) {
|
|
RegCloseKey( hKey );
|
|
return 0;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
return 0;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SfcWriteRegString(
|
|
LPWSTR KeyName,
|
|
LPWSTR ValueName,
|
|
PWSTR Value
|
|
)
|
|
{
|
|
HKEY hKey;
|
|
|
|
|
|
if (RegOpenKey( HKEY_LOCAL_MACHINE, KeyName, &hKey ) != ERROR_SUCCESS) {
|
|
return 0;
|
|
}
|
|
|
|
if (RegSetValueEx( hKey, ValueName, 0, REG_SZ, (LPBYTE)Value, (wcslen(Value)+1)*sizeof(WCHAR) ) != ERROR_SUCCESS) {
|
|
RegCloseKey( hKey );
|
|
return 0;
|
|
}
|
|
|
|
RegCloseKey( hKey );
|
|
return 0;
|
|
}
|
|
|
|
|
|
void
|
|
SaveRegValues(
|
|
void
|
|
)
|
|
{
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDebug",
|
|
SFCDebug
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDisable",
|
|
SFCDisable
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCScan",
|
|
SFCScan
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCQuota",
|
|
SFCQuota
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCBugcheck",
|
|
SFCBugcheck
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SfcShowProgress",
|
|
SFCShowProgress
|
|
);
|
|
|
|
SfcWriteRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SfcChangeLog",
|
|
SFCChangeLog
|
|
);
|
|
|
|
SfcWriteRegString(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDllCacheDir",
|
|
SFCDllCacheDir
|
|
);
|
|
}
|
|
|
|
|
|
void
|
|
InititlaizeRegValues(
|
|
void
|
|
)
|
|
{
|
|
PWSTR s;
|
|
|
|
|
|
SFCDebug = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDebug"
|
|
);
|
|
|
|
SFCDisable = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDisable"
|
|
);
|
|
|
|
SFCScan = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCScan"
|
|
);
|
|
|
|
SFCQuota = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCQuota"
|
|
);
|
|
|
|
SFCBugcheck = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCBugcheck"
|
|
);
|
|
|
|
SFCShowProgress = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SfcShowProgress"
|
|
);
|
|
|
|
SFCChangeLog = SfcQueryRegDword(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SfcChangeLog"
|
|
);
|
|
|
|
s = SfcQueryRegString(
|
|
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon",
|
|
L"SFCDllCacheDir"
|
|
);
|
|
if (s == NULL) {
|
|
//ExpandEnvironmentStrings( DLLCACHE_DIR, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
|
|
wcscpy( SFCDllCacheDir, DLLCACHE_DIR );
|
|
} else {
|
|
//ExpandEnvironmentStrings( s, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
|
|
wcscpy( SFCDllCacheDir, s );
|
|
free( s );
|
|
}
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
SfcDisableDlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch(uMsg) {
|
|
case WM_INITDIALOG:
|
|
switch (SFCDisable) {
|
|
case SFC_DISABLE_NORMAL:
|
|
CheckDlgButton( hwndDlg, IDC_DISABLE_NORMAL, BST_CHECKED );
|
|
break;
|
|
|
|
case SFC_DISABLE_ASK:
|
|
CheckDlgButton( hwndDlg, IDC_DISABLE_ASK, BST_CHECKED );
|
|
break;
|
|
|
|
case SFC_DISABLE_ONCE:
|
|
CheckDlgButton( hwndDlg, IDC_DISABLE_ONCE, BST_CHECKED );
|
|
break;
|
|
|
|
case SFC_DISABLE_NOPOPUPS:
|
|
CheckDlgButton( hwndDlg, IDC_DISABLE_NOPOPUPS, BST_CHECKED );
|
|
break;
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam)) {
|
|
case IDC_DISABLE_NORMAL:
|
|
case IDC_DISABLE_ASK:
|
|
case IDC_DISABLE_ONCE:
|
|
case IDC_DISABLE_NOPOPUPS:
|
|
SetChangeFlag( hwndDlg, TRUE );
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR *) lParam)->code) {
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_NORMAL )) {
|
|
SFCDisable = SFC_DISABLE_NORMAL;
|
|
} else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_ASK )) {
|
|
SFCDisable = SFC_DISABLE_ASK;
|
|
} else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_ONCE )) {
|
|
SFCDisable = SFC_DISABLE_ONCE;
|
|
} else if (IsDlgButtonChecked( hwndDlg, IDC_DISABLE_NOPOPUPS )) {
|
|
SFCDisable = SFC_DISABLE_NOPOPUPS;
|
|
}
|
|
SaveRegValues();
|
|
SetChangeFlag( hwndDlg, FALSE );
|
|
return PSNRET_NOERROR;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
SfcScanDlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch(uMsg) {
|
|
case WM_INITDIALOG:
|
|
switch (SFCScan) {
|
|
case SFC_SCAN_NORMAL:
|
|
CheckDlgButton( hwndDlg, IDC_SCAN_NORMAL, BST_CHECKED );
|
|
break;
|
|
|
|
case SFC_SCAN_ALWAYS:
|
|
CheckDlgButton( hwndDlg, IDC_SCAN_ALWAYS, BST_CHECKED );
|
|
break;
|
|
|
|
case SFC_SCAN_ONCE:
|
|
CheckDlgButton( hwndDlg, IDC_SCAN_ONCE, BST_CHECKED );
|
|
break;
|
|
}
|
|
CheckDlgButton( hwndDlg, IDC_SHOW_PROGRESS, SFCShowProgress ? BST_CHECKED : BST_UNCHECKED );
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam)) {
|
|
case IDC_SCAN_NORMAL:
|
|
case IDC_SCAN_NOW:
|
|
case IDC_SCAN_ALWAYS:
|
|
case IDC_SCAN_ONCE:
|
|
case IDC_SHOW_PROGRESS:
|
|
SetChangeFlag( hwndDlg, TRUE );
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR *) lParam)->code) {
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_NOW )) {
|
|
SfcInitiateScan( RpcHandle, 0 );
|
|
SetChangeFlag( hwndDlg, FALSE );
|
|
return PSNRET_NOERROR;
|
|
}
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_NORMAL )) {
|
|
SFCScan = SFC_SCAN_NORMAL;
|
|
} else if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_ALWAYS )) {
|
|
SFCScan = SFC_SCAN_ALWAYS;
|
|
} else if (IsDlgButtonChecked( hwndDlg, IDC_SCAN_ONCE )) {
|
|
SFCScan = SFC_SCAN_ONCE;
|
|
}
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_SHOW_PROGRESS )) {
|
|
SFCShowProgress = 1;
|
|
} else {
|
|
SFCShowProgress = 0;
|
|
}
|
|
SaveRegValues();
|
|
SetChangeFlag( hwndDlg, FALSE );
|
|
return PSNRET_NOERROR;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
INT_PTR
|
|
CALLBACK
|
|
SfcMiscDlgProc(
|
|
HWND hwndDlg,
|
|
UINT uMsg,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
switch(uMsg) {
|
|
case WM_INITDIALOG:
|
|
MySetDlgItemInt( hwndDlg, IDC_QUOTA, SFCQuota, FALSE );
|
|
MySetDlgItemText( hwndDlg, IDC_CACHE_DIR, SFCDllCacheDir );
|
|
MySetDlgItemInt( hwndDlg, IDC_DEBUG_LEVEL, SFCDebug, FALSE );
|
|
CheckDlgButton( hwndDlg, IDC_BUGCHECK, SFCBugcheck ? BST_CHECKED : BST_UNCHECKED );
|
|
CheckDlgButton( hwndDlg, IDC_CHANGE_LOG, SFCChangeLog ? BST_CHECKED : BST_UNCHECKED );
|
|
return TRUE;
|
|
|
|
case WM_COMMAND:
|
|
switch (LOWORD(wParam)) {
|
|
case IDC_BUGCHECK:
|
|
case IDC_CHANGE_LOG:
|
|
SetChangeFlag( hwndDlg, TRUE );
|
|
return TRUE;
|
|
|
|
case IDC_QUOTA:
|
|
case IDC_DEBUG_LEVEL:
|
|
case IDC_CACHE_DIR:
|
|
if (HIWORD(wParam) == EN_CHANGE && !insideSetDlgItemText) {
|
|
SetChangeFlag( hwndDlg, TRUE );
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
case WM_NOTIFY:
|
|
switch (((NMHDR *) lParam)->code) {
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_BUGCHECK )) {
|
|
SFCBugcheck = 1;
|
|
} else {
|
|
SFCBugcheck = 0;
|
|
}
|
|
if (IsDlgButtonChecked( hwndDlg, IDC_CHANGE_LOG )) {
|
|
SFCChangeLog = 1;
|
|
} else {
|
|
SFCChangeLog = 0;
|
|
}
|
|
SFCQuota = GetDlgItemInt( hwndDlg, IDC_QUOTA, NULL, FALSE );
|
|
SFCDebug = GetDlgItemInt( hwndDlg, IDC_DEBUG_LEVEL, NULL, FALSE );
|
|
GetDlgItemText( hwndDlg, IDC_CACHE_DIR, SFCDllCacheDir, sizeof(SFCDllCacheDir)/sizeof(WCHAR) );
|
|
SaveRegValues();
|
|
SetChangeFlag( hwndDlg, FALSE );
|
|
return PSNRET_NOERROR;
|
|
}
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void
|
|
CreateSfcProperySheet(
|
|
HWND hwnd
|
|
)
|
|
{
|
|
DWORD i;
|
|
PROPSHEETHEADER psh;
|
|
LPPROPSHEETPAGE psp;
|
|
|
|
|
|
RpcHandle = SfcConnectToServer( NULL );
|
|
|
|
psp = malloc( sizeof(PROPSHEETPAGE)*CountPages );
|
|
if (psp == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (i=0; i<CountPages; i++) {
|
|
psp[i].dwSize = sizeof(PROPSHEETPAGE);
|
|
psp[i].dwFlags = i == 0 ? PSP_PREMATURE : PSP_DEFAULT;
|
|
psp[i].hInstance = SfcInstanceHandle;
|
|
psp[i].pszTemplate = MAKEINTRESOURCE(SfcPages[i].ResId);
|
|
psp[i].pszIcon = NULL;
|
|
psp[i].pszTitle = NULL;
|
|
psp[i].pfnDlgProc = SfcPages[i].DlgProc;
|
|
psp[i].lParam = 0;
|
|
psp[i].pfnCallback = NULL;
|
|
psp[i].pcRefParent = NULL;
|
|
psp[i].pszHeaderTitle = NULL;
|
|
psp[i].pszHeaderSubTitle = NULL;
|
|
}
|
|
|
|
psh.dwSize = sizeof(PROPSHEETHEADER);
|
|
psh.dwFlags = PSH_PROPSHEETPAGE;
|
|
psh.hwndParent = hwnd;
|
|
psh.hInstance = SfcInstanceHandle;
|
|
psh.pszIcon = MAKEINTRESOURCE(IDI_SFCCPL);
|
|
psh.pszCaption = MAKEINTRESOURCE(IDS_SFCCPL_DESC);
|
|
psh.nPages = CountPages;
|
|
psh.nStartPage = 0;
|
|
psh.ppsp = psp;
|
|
psh.pfnCallback = NULL;
|
|
psh.pszbmWatermark = NULL;
|
|
psh.hplWatermark = NULL;
|
|
psh.pszbmHeader = NULL;
|
|
|
|
PropertySheet( &psh );
|
|
}
|
|
|
|
|
|
LONG
|
|
CALLBACK
|
|
CPlApplet(
|
|
HWND hwndCPl,
|
|
UINT uMsg,
|
|
LPARAM lParam1,
|
|
LPARAM lParam2
|
|
)
|
|
{
|
|
int i;
|
|
LPCPLINFO CPlInfo;
|
|
|
|
i = (int) lParam1;
|
|
|
|
switch (uMsg) {
|
|
case CPL_INIT:
|
|
InititlaizeRegValues();
|
|
return TRUE;
|
|
|
|
case CPL_GETCOUNT:
|
|
return 1;
|
|
|
|
case CPL_INQUIRE:
|
|
CPlInfo = (LPCPLINFO) lParam2;
|
|
CPlInfo->lData = 0;
|
|
CPlInfo->idIcon = IDI_SFCCPL;
|
|
CPlInfo->idName = IDS_SFCCPL_NAME;
|
|
CPlInfo->idInfo = IDS_SFCCPL_DESC;
|
|
break;
|
|
|
|
case CPL_DBLCLK:
|
|
CreateSfcProperySheet( hwndCPl );
|
|
break;
|
|
|
|
case CPL_STOP:
|
|
break;
|
|
|
|
case CPL_EXIT:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|