windows-nt/Source/XPSP1/NT/base/subsys/sm/sfc/cpl/sfccpl.c
2020-09-26 16:20:57 +08:00

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;
}