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.

959 lines
32 KiB

  1. /******************************************************************************
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. syscfg.cpp
  5. Abstract:
  6. This file contains SRGetCplPropPage function for System Control Panel.
  7. Revision History:
  8. Seong Kook Khang (SKKhang) 07/19/00
  9. created
  10. ******************************************************************************/
  11. #include "stdwin.h"
  12. #include "rstrcore.h"
  13. #include "resource.h"
  14. #include "helpids.h"
  15. #define SRHELPURL L"hcp://services/subsite?node=TopLevelBucket_4/Fixing_a_problem&select=TopLevelBucket_4/Fixing_a_problem/Using_System_Restore_to_undo_changes"
  16. /////////////////////////////////////////////////////////////////////////////
  17. //
  18. // Static Variables
  19. //
  20. /////////////////////////////////////////////////////////////////////////////
  21. WCHAR s_szDrvStatus[5][MAX_STATUS] = { L"---" };
  22. #define SRHELPFILE L"sysrestore.hlp"
  23. static const DWORD MAIN_HELP_MAP[] =
  24. {
  25. IDC_TURN_OFF, IDH_SR_TURN_OFF, // Turn off all drives (check box)
  26. IDC_DRIVE_LIST, IDH_SR_SELECT_VOLUME, // Volume list (list view)
  27. IDC_DRIVE_SETTINGS, IDH_SR_CHANGE_SETTINGS, // Change settings (pushbutton)
  28. 0, 0
  29. };
  30. static const DWORD DRIVE_HELP_MAP[] =
  31. {
  32. IDC_TURN_OFF, IDH_SR_TURN_OFF_DRIVE,
  33. IDOK, IDH_SR_CONFIRM_CHANGE, // OK or Apply
  34. IDCANCEL, IDH_SR_CANCEL, // Cancel
  35. 0, 0
  36. };
  37. extern CSRClientLoader g_CSRClientLoader;
  38. /////////////////////////////////////////////////////////////////////////////
  39. //
  40. // Helper Functions
  41. //
  42. /////////////////////////////////////////////////////////////////////////////
  43. void
  44. EnableControls( HWND hDlg, int nFirst, int nLast, BOOL fEnable )
  45. {
  46. int i;
  47. for ( i = nFirst; i <= nLast; i++ )
  48. ::EnableWindow( ::GetDlgItem( hDlg, i ), fEnable );
  49. }
  50. LPCWSTR
  51. GetDriveStatusText( CRstrDriveInfo *pRDI )
  52. {
  53. if ( pRDI->IsOffline() )
  54. return( s_szDrvStatus[4] );
  55. else if ( pRDI->IsExcluded() )
  56. return( s_szDrvStatus[3] );
  57. else if ( pRDI->IsFrozen() )
  58. return( s_szDrvStatus[2] );
  59. else
  60. return( s_szDrvStatus[1] );
  61. }
  62. void
  63. UpdateDriveStatus( HWND hwndList, CRDIArray *paryDrv )
  64. {
  65. TraceFunctEnter("UpdateDriveStatus");
  66. int i;
  67. WCHAR szStat[256];
  68. LVITEM lvi;
  69. if ( ::UpdateDriveList( *paryDrv ) )
  70. {
  71. for ( i = paryDrv->GetUpperBound(); i >= 0; i-- )
  72. {
  73. ::lstrcpy( szStat, ::GetDriveStatusText( paryDrv->GetItem( i ) ) );
  74. lvi.mask = LVIF_TEXT;
  75. lvi.iItem = i;
  76. lvi.iSubItem = 1;
  77. lvi.pszText = szStat;
  78. ::SendMessage( hwndList, LVM_SETITEM, 0, (LPARAM)&lvi );
  79. }
  80. }
  81. TraceFunctLeave();
  82. }
  83. void
  84. ApplySettings( CRstrDriveInfo *pRDI )
  85. {
  86. MessageBox(NULL, pRDI->GetMount(), L"SR", MB_OK);
  87. }
  88. /////////////////////////////////////////////////////////////////////////////
  89. //
  90. // Drive Settings Dialog for Multiple Drives
  91. //
  92. /////////////////////////////////////////////////////////////////////////////
  93. BOOL CALLBACK
  94. SRCfgDriveSettingsDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  95. {
  96. TraceFunctEnter("SRCfgDriveSettingsDlgProc");
  97. static BOOL s_fDirty = FALSE;
  98. static UINT s_uUsage;
  99. BOOL fRet = FALSE;
  100. CRstrDriveInfo *pRDI;
  101. WCHAR szMsg[MAX_STR+2*MAX_PATH];
  102. WCHAR szDCU[MAX_STR];
  103. HWND hCtrl;
  104. BOOL fCheck;
  105. UINT uPos;
  106. DWORD dwRet;
  107. DWORD dwDSMin;
  108. if ( uMsg == WM_INITDIALOG )
  109. {
  110. ::SetWindowLong( hDlg, DWL_USER, lParam );
  111. pRDI = (CRstrDriveInfo*)lParam;
  112. }
  113. else
  114. {
  115. pRDI = (CRstrDriveInfo*)::GetWindowLong( hDlg, DWL_USER );
  116. }
  117. switch ( uMsg )
  118. {
  119. case WM_INITDIALOG :
  120. s_fDirty = FALSE;
  121. // Set Dialog Title
  122. ::SRFormatMessage( szMsg, IDS_DRIVEPROP_TITLE, pRDI->GetMount() );
  123. ::SetWindowText( hDlg, szMsg );
  124. // Set Dialog Heading
  125. if (lstrlen(pRDI->GetLabel()) != 0)
  126. {
  127. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY, pRDI->GetLabel(), pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  128. }
  129. else
  130. {
  131. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY_NO_LABEL, pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  132. }
  133. ::SetDlgItemText( hDlg, IDC_DRIVE_SUMMARY, szMsg );
  134. // Read the SR_DEFAULT_DSMIN from the registry
  135. if ( !::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszSRRegKey, s_cszDSMin, &dwDSMin ) )
  136. dwDSMin = SR_DEFAULT_DSMIN;
  137. if ( pRDI->IsSystem() )
  138. {
  139. // Set Explaination About System Drive Cannot Be Off
  140. if (lstrlen(pRDI->GetLabel()) != 0)
  141. {
  142. ::SRFormatMessage( szMsg, IDS_SYSDRV_CANNOT_OFF, pRDI->GetLabel(), pRDI->GetMount() );
  143. }
  144. else
  145. {
  146. ::SRFormatMessage( szMsg, IDS_SYSDRV_CANNOT_OFF_NO_LABEL, pRDI->GetMount());
  147. }
  148. ::SetDlgItemText( hDlg, IDC_SYSDRV_CANNOT_OFF, szMsg );
  149. //format IDC_SYSTEM_DCU_HOWTO text for the System Drive
  150. if( !::GetDlgItemText( hDlg, IDC_SYSTEM_DCU_HOWTO, szDCU, MAX_STR ) )
  151. ErrorTrace( 0, "GetDlgItemText failed for IDC_SYSTEM_DCU_HOWTO: %s", (LPCSTR)szMsg );
  152. wsprintf( szMsg, szDCU, dwDSMin );
  153. ::SetDlgItemText( hDlg, IDC_SYSTEM_DCU_HOWTO, szMsg );
  154. }
  155. else
  156. {
  157. fCheck = pRDI->IsExcluded();
  158. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fCheck ? BST_CHECKED : BST_UNCHECKED );
  159. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, !fCheck );
  160. //format IDC_NORMAL_DCU_HOWTO text for the Normal Drive
  161. if( !::GetDlgItemText( hDlg, IDC_NORMAL_DCU_HOWTO, szDCU, MAX_STR ) )
  162. ErrorTrace( 0, "GetDlgItemText failed for IDC_NORMAL_DCU_HOWTO: %s", (LPCSTR)szMsg );
  163. wsprintf( szMsg, szDCU, dwDSMin );
  164. ::SetDlgItemText( hDlg, IDC_NORMAL_DCU_HOWTO, szMsg );
  165. }
  166. hCtrl = ::GetDlgItem( hDlg, IDC_USAGE_SLIDER );
  167. ::SendMessage( hCtrl, TBM_SETRANGE, 0, MAKELONG( 0, DSUSAGE_SLIDER_FREQ ) );
  168. //::SendMessage( hCtrl, TBM_SETTICFREQ, 10, 0 );
  169. s_uUsage = pRDI->GetDSUsage();
  170. ::SendMessage( hCtrl, TBM_SETPOS, TRUE, s_uUsage );
  171. pRDI->GetUsageText( szMsg );
  172. ::SetDlgItemText( hDlg, IDC_USAGE_VALUE, szMsg );
  173. // Check the policy to see if local config is enabled
  174. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableConfig, &dwRet ) )
  175. {
  176. ErrorTrace(0, "Group Policy disables SR configuration...");
  177. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, FALSE );
  178. ::LoadString( g_hInst, IDS_GROUP_POLICY_CONFIG_ON_OFF, szMsg,
  179. sizeof(szMsg)/sizeof(WCHAR) );
  180. ::SetDlgItemText( hDlg, IDC_TURN_OFF, szMsg );
  181. EnableWindow( ::GetDlgItem( hDlg, IDC_TURN_OFF ), FALSE );
  182. }
  183. break;
  184. case WM_COMMAND :
  185. switch ( LOWORD(wParam) )
  186. {
  187. case IDC_TURN_OFF :
  188. fCheck = ::IsDlgButtonChecked( hDlg, IDC_TURN_OFF );
  189. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, !fCheck );
  190. pRDI->SetCfgExcluded( fCheck );
  191. s_fDirty = TRUE;
  192. break;
  193. case IDC_DCU_INVOKE :
  194. if ( HIWORD(wParam) == BN_CLICKED )
  195. {
  196. WCHAR szDrv[4] = L"";
  197. szDrv[0] = (pRDI->GetMount())[0];
  198. szDrv[1] = L'\0';
  199. InvokeDiskCleanup( szDrv );
  200. }
  201. break;
  202. case IDOK :
  203. if ( s_fDirty )
  204. if ( !pRDI->ApplyConfig( hDlg ) )
  205. {
  206. // refresh the on/off button in case the user cancelled
  207. BOOL fCheck = pRDI->IsExcluded();
  208. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fCheck ?
  209. BST_CHECKED : BST_UNCHECKED );
  210. }
  211. ::EndDialog( hDlg, IDOK );
  212. break;
  213. case IDCANCEL :
  214. ::EndDialog( hDlg, IDCANCEL );
  215. break;
  216. }
  217. break;
  218. case WM_HSCROLL :
  219. hCtrl = ::GetDlgItem( hDlg, IDC_USAGE_SLIDER );
  220. uPos = ::SendMessage( hCtrl, TBM_GETPOS, 0, 0 );
  221. if ( uPos != s_uUsage )
  222. {
  223. s_uUsage = uPos;
  224. pRDI->SetCfgDSUsage( uPos );
  225. ::SendMessage( hCtrl, TBM_SETPOS, TRUE, uPos );
  226. // Set Usage Text
  227. pRDI->GetUsageText( szMsg );
  228. ::SetDlgItemText( hDlg, IDC_USAGE_VALUE, szMsg );
  229. s_fDirty = TRUE;
  230. }
  231. break;
  232. case WM_CONTEXTMENU:
  233. if ( !::WinHelp ( (HWND) wParam,
  234. SRHELPFILE,
  235. HELP_CONTEXTMENU,
  236. (DWORD_PTR) DRIVE_HELP_MAP) )
  237. {
  238. trace (0, "! WinHelp : %ld", GetLastError());
  239. }
  240. break;
  241. case WM_HELP:
  242. if (((LPHELPINFO) lParam)->hItemHandle)
  243. {
  244. if ( !::WinHelp ( (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  245. SRHELPFILE,
  246. HELP_WM_HELP,
  247. (DWORD_PTR) DRIVE_HELP_MAP) )
  248. {
  249. trace (0, "! WinHelp : %ld", GetLastError());
  250. }
  251. }
  252. break;
  253. default:
  254. goto Exit;
  255. }
  256. fRet = TRUE;
  257. Exit:
  258. TraceFunctLeave();
  259. return( fRet );
  260. }
  261. /////////////////////////////////////////////////////////////////////////////
  262. //
  263. // Property Page Proc for Multiple Drives
  264. //
  265. /////////////////////////////////////////////////////////////////////////////
  266. BOOL CALLBACK
  267. SRCfgMultiDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  268. {
  269. TraceFunctEnter("SRCfgMultiDlgProc");
  270. BOOL fRet = FALSE;
  271. HWND hCtrl;
  272. LVCOLUMN lvc;
  273. WCHAR szColText[256];
  274. CRDIArray *paryDrv;
  275. CRstrDriveInfo *pRDI;
  276. HIMAGELIST himl;
  277. HICON hIcon;
  278. int i;
  279. int nIdx;
  280. LONG lRet;
  281. LVITEM lvi;
  282. WCHAR szName[2*MAX_PATH];
  283. int nItem;
  284. WCHAR szStat[256];
  285. BOOL fDisable;
  286. DWORD dwRet;
  287. if ( uMsg == WM_INITDIALOG )
  288. {
  289. PROPSHEETPAGE *pPSP;
  290. pPSP = (PROPSHEETPAGE*)lParam;
  291. paryDrv = (CRDIArray*)pPSP->lParam;
  292. ::SetWindowLong( hDlg, DWL_USER, (LPARAM)paryDrv );
  293. }
  294. else
  295. {
  296. paryDrv = (CRDIArray*)::GetWindowLong( hDlg, DWL_USER );
  297. }
  298. // if drive info is not available, skip our code.
  299. if ( paryDrv == NULL )
  300. goto Exit;
  301. switch ( uMsg )
  302. {
  303. case WM_INITDIALOG :
  304. hCtrl = ::GetDlgItem( hDlg, IDC_DRIVE_LIST );
  305. // Set full row selection
  306. //::SendMessage( hCtrl, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT );
  307. // Set column headers
  308. lvc.mask = LVCF_TEXT | LVCF_WIDTH;
  309. lvc.cx = 150;
  310. ::LoadString( g_hInst, IDS_DRVLIST_COL_NAME, szColText,
  311. sizeof(szColText)/sizeof(WCHAR) );
  312. lvc.pszText = szColText;
  313. ::SendMessage( hCtrl, LVM_INSERTCOLUMN, 0, (LPARAM)&lvc );
  314. lvc.mask = LVCF_SUBITEM | LVCF_TEXT | LVCF_WIDTH;
  315. lvc.cx = 80;
  316. ::LoadString( g_hInst, IDS_DRVLIST_COL_STATUS, szColText,
  317. sizeof(szColText)/sizeof(WCHAR) );
  318. lvc.pszText = szColText;
  319. lvc.iSubItem = 1;
  320. ::SendMessage( hCtrl, LVM_INSERTCOLUMN, 1, (LPARAM)&lvc );
  321. // Create and set ImageList
  322. himl = ::ImageList_Create( 16, 16, ILC_COLOR | ILC_MASK, paryDrv->GetSize(), 0 );
  323. for ( i = 0; i < paryDrv->GetSize(); i++ )
  324. {
  325. pRDI = paryDrv->GetItem( i );
  326. ::ImageList_AddIcon( himl, pRDI->GetIcon( TRUE ) );
  327. ::wsprintf( szName, L"%ls (%ls)", pRDI->GetLabel(), pRDI->GetMount() );
  328. ::lstrcpy( szStat, ::GetDriveStatusText( pRDI ) );
  329. lvi.mask = LVIF_TEXT | LVIF_IMAGE;
  330. lvi.iItem = i;
  331. lvi.iSubItem = 0;
  332. lvi.pszText = szName;
  333. lvi.iImage = i;
  334. nItem = ::SendMessage( hCtrl, LVM_INSERTITEM, 0, (LPARAM)&lvi );
  335. lvi.mask = LVIF_TEXT;
  336. lvi.iItem = nItem;
  337. lvi.iSubItem = 1;
  338. lvi.pszText = szStat;
  339. ::SendMessage( hCtrl, LVM_SETITEM, 0, (LPARAM)&lvi );
  340. }
  341. ListView_SetItemState( hCtrl, 0, LVIS_SELECTED, LVIS_SELECTED );
  342. ::SendMessage( hCtrl, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl );
  343. ::ShowWindow( hCtrl, SW_SHOW );
  344. fDisable = paryDrv->GetItem( 0 )->IsExcluded();
  345. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fDisable );
  346. ::EnableControls( hDlg, IDC_DRIVE_GROUPBOX, IDC_DRIVE_SETTINGS, !fDisable );
  347. //Group Policy
  348. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableSR, &dwRet ) )
  349. {
  350. ::CheckDlgButton( hDlg, IDC_TURN_OFF, dwRet != 0 );
  351. ::LoadString( g_hInst, IDS_GROUP_POLICY_ON_OFF, szColText,
  352. sizeof(szColText)/sizeof(WCHAR) );
  353. ::SetDlgItemText( hDlg, IDC_TURN_OFF, szColText );
  354. ::EnableWindow( ::GetDlgItem( hDlg, IDC_TURN_OFF ), FALSE );
  355. }
  356. // Check the policy to see if local config is enabled
  357. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableConfig, &dwRet ) )
  358. {
  359. ErrorTrace(0, "Group Policy disables SR configuration...");
  360. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, FALSE );
  361. ::LoadString( g_hInst, IDS_GROUP_POLICY_ON_OFF, szColText,
  362. sizeof(szColText)/sizeof(WCHAR) );
  363. ::SetDlgItemText( hDlg, IDC_TURN_OFF, szColText );
  364. EnableWindow( ::GetDlgItem( hDlg, IDC_TURN_OFF ), FALSE );
  365. }
  366. break;
  367. case WM_COMMAND :
  368. switch ( LOWORD(wParam ) )
  369. {
  370. case IDC_TURN_OFF :
  371. if ( HIWORD(wParam) == BN_CLICKED )
  372. {
  373. fDisable = ( ::IsDlgButtonChecked( hDlg, IDC_TURN_OFF ) == BST_CHECKED );
  374. //
  375. // if safemode, cannot re-enable
  376. //
  377. if (fDisable == FALSE &&
  378. paryDrv->GetItem(0)->IsExcluded() )
  379. {
  380. if (0 != GetSystemMetrics(SM_CLEANBOOT))
  381. {
  382. ShowSRErrDlg(IDS_ERR_SR_SAFEMODE);
  383. ::CheckDlgButton( hDlg, IDC_TURN_OFF, TRUE );
  384. break;
  385. }
  386. }
  387. //::EnableControls( hDlg, IDC_DRIVE_GROUPBOX, IDC_DRIVE_SETTINGS, !fDisable );
  388. paryDrv->GetItem( 0 )->SetCfgExcluded( fDisable );
  389. //::UpdateDriveStatus( ::GetDlgItem( hDlg, IDC_DRIVE_LIST ), paryDrv );
  390. PropSheet_Changed( ::GetParent(hDlg), hDlg );
  391. }
  392. break;
  393. case IDC_DRIVE_SETTINGS :
  394. if ( HIWORD(wParam) == BN_CLICKED )
  395. {
  396. UINT uRet;
  397. UINT uDlgId;
  398. hCtrl = ::GetDlgItem( hDlg, IDC_DRIVE_LIST );
  399. nIdx = ::SendMessage( hCtrl, LVM_GETNEXTITEM, -1, LVNI_SELECTED );
  400. pRDI = paryDrv->GetItem( nIdx );
  401. if ( pRDI->IsFrozen() )
  402. {
  403. if ( pRDI->IsSystem() )
  404. uDlgId = IDD_SYSPROP_SYSTEM_FROZEN;
  405. else
  406. uDlgId = IDD_SYSPROP_NORMAL_FROZEN;
  407. }
  408. else
  409. {
  410. if ( pRDI->IsSystem() )
  411. uDlgId = IDD_SYSPROP_SYSTEM;
  412. else
  413. uDlgId = IDD_SYSPROP_NORMAL;
  414. }
  415. uRet = ::DialogBoxParam( g_hInst,
  416. MAKEINTRESOURCE(uDlgId),
  417. ::GetParent( hDlg ),
  418. SRCfgDriveSettingsDlgProc,
  419. (LPARAM)pRDI );
  420. if ( uRet == IDOK )
  421. {
  422. ::UpdateDriveStatus( hCtrl, paryDrv );
  423. }
  424. pRDI->SetCfgDSUsage (pRDI->GetDSUsage() );
  425. }
  426. break;
  427. }
  428. break;
  429. case WM_NOTIFY :
  430. switch ( ((LPNMHDR)lParam)->code )
  431. {
  432. case LVN_ITEMCHANGED :
  433. hCtrl = ::GetDlgItem( hDlg, IDC_DRIVE_LIST );
  434. nIdx = ::SendMessage( hCtrl, LVM_GETNEXTITEM, -1, LVNI_SELECTED );
  435. fDisable = ( nIdx < 0 ) ||
  436. paryDrv->GetItem( nIdx )->IsOffline();
  437. ::EnableWindow( ::GetDlgItem( hDlg, IDC_DRIVE_SETTINGS ), !fDisable );
  438. break;
  439. case PSN_APPLY :
  440. if ( paryDrv->GetItem( 0 )->ApplyConfig( ::GetParent( hDlg ) ) )
  441. lRet = PSNRET_NOERROR;
  442. else
  443. lRet = PSNRET_INVALID;
  444. fDisable = paryDrv->GetItem( 0 )->IsExcluded();
  445. ::UpdateDriveStatus( ::GetDlgItem( hDlg, IDC_DRIVE_LIST ), paryDrv );
  446. ::EnableControls( hDlg, IDC_DRIVE_GROUPBOX, IDC_DRIVE_SETTINGS, !fDisable );
  447. // refresh the on/off button in case the user cancelled
  448. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fDisable ? BST_CHECKED : BST_UNCHECKED );
  449. ::SetWindowLong( hDlg, DWL_MSGRESULT, lRet );
  450. break;
  451. case NM_CLICK:
  452. case NM_RETURN:
  453. if (wParam == IDC_RESTOREHELP_LINK)
  454. {
  455. // launch help
  456. ShellExecuteW(NULL, L"open",
  457. SRHELPURL,
  458. NULL, NULL, SW_SHOW);
  459. }
  460. break;
  461. }
  462. break;
  463. case WM_CONTEXTMENU:
  464. if ( !::WinHelp ( (HWND) wParam,
  465. SRHELPFILE,
  466. HELP_CONTEXTMENU,
  467. (DWORD_PTR) MAIN_HELP_MAP) )
  468. {
  469. trace (0, "! WinHelp : %ld", GetLastError());
  470. }
  471. break;
  472. case WM_HELP:
  473. if (((LPHELPINFO) lParam)->hItemHandle)
  474. {
  475. if ( !::WinHelp ( (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  476. SRHELPFILE,
  477. HELP_WM_HELP,
  478. (DWORD_PTR) MAIN_HELP_MAP) )
  479. {
  480. trace (0, "! WinHelp : %ld", GetLastError());
  481. }
  482. }
  483. break;
  484. case WM_NCDESTROY :
  485. paryDrv->ReleaseAll();
  486. delete paryDrv;
  487. ::SetWindowLong( hDlg, DWL_USER, NULL );
  488. break;
  489. default:
  490. goto Exit;
  491. }
  492. fRet = TRUE;
  493. Exit:
  494. TraceFunctLeave();
  495. return( fRet );
  496. }
  497. /////////////////////////////////////////////////////////////////////////////
  498. //
  499. // Property Page Proc for Single Drive
  500. //
  501. /////////////////////////////////////////////////////////////////////////////
  502. BOOL CALLBACK
  503. SRCfgSingleDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  504. {
  505. TraceFunctEnter("SRCfgSingleDlgProc");
  506. static UINT s_uUsage;
  507. BOOL fRet = FALSE;
  508. HWND hCtrl;
  509. CRstrDriveInfo *pRDI;
  510. HDC hDC;
  511. PAINTSTRUCT ps;
  512. RECT rcCtrl;
  513. POINT ptIcon;
  514. WCHAR szMsg[MAX_STR+2*MAX_PATH];
  515. WCHAR szDCU[MAX_STR];
  516. BOOL fCheck;
  517. UINT uPos;
  518. LONG lRet;
  519. DWORD dwRet;
  520. DWORD dwDSMin;
  521. if ( uMsg == WM_INITDIALOG )
  522. {
  523. PROPSHEETPAGE *pPSP;
  524. pPSP = (PROPSHEETPAGE*)lParam;
  525. pRDI = (CRstrDriveInfo*)pPSP->lParam;
  526. ::SetWindowLong( hDlg, DWL_USER, (LPARAM)pRDI );
  527. }
  528. else
  529. {
  530. pRDI = (CRstrDriveInfo*)::GetWindowLong( hDlg, DWL_USER );
  531. }
  532. // if drive info is not available, skip our code.
  533. if ( pRDI == NULL )
  534. goto Exit;
  535. switch ( uMsg )
  536. {
  537. case WM_INITDIALOG :
  538. // hide DCU if SR is not frozen
  539. if ( !pRDI->IsFrozen() )
  540. {
  541. ::ShowWindow( ::GetDlgItem( hDlg, IDC_DCU_HOWTO ), SW_HIDE );
  542. ::ShowWindow( ::GetDlgItem( hDlg, IDC_DCU_INVOKE ), SW_HIDE );
  543. }
  544. else // format IDC_DCU_HOWTO if SR is frozen
  545. {
  546. if ( !::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszSRRegKey, s_cszDSMin, &dwDSMin ) )
  547. dwDSMin = SR_DEFAULT_DSMIN;
  548. if ( !::GetDlgItemText( hDlg, IDC_DCU_HOWTO, szDCU, MAX_STR ) )
  549. ErrorTrace( 0, "GetDlgItemText failed for IDC_DCU_HOWTO: %s", (LPCSTR)szMsg );
  550. wsprintf( szMsg, szDCU, dwDSMin );
  551. ::SetDlgItemText( hDlg, IDC_DCU_HOWTO, szMsg );
  552. }
  553. // drive icon
  554. hCtrl = ::GetDlgItem( hDlg, IDC_SD_ICON );
  555. ::ShowWindow( hCtrl, SW_HIDE );
  556. // drive status
  557. if (lstrlen(pRDI->GetLabel()) != 0)
  558. {
  559. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY, pRDI->GetLabel(), pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  560. }
  561. else
  562. {
  563. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY_NO_LABEL, pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  564. }
  565. ::SetDlgItemText( hDlg, IDC_SD_STATUS, szMsg );
  566. hCtrl = ::GetDlgItem( hDlg, IDC_USAGE_SLIDER );
  567. ::SendMessage( hCtrl, TBM_SETRANGE, 0, MAKELONG( 0, DSUSAGE_SLIDER_FREQ ) );
  568. //::SendMessage( hCtrl, TBM_SETTICFREQ, 10, 0 );
  569. s_uUsage = pRDI->GetDSUsage();
  570. ::SendMessage( hCtrl, TBM_SETPOS, TRUE, s_uUsage );
  571. pRDI->GetUsageText( szMsg );
  572. ::SetDlgItemText( hDlg, IDC_USAGE_VALUE, szMsg );
  573. fCheck = pRDI->IsExcluded();
  574. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fCheck );
  575. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, ! fCheck);
  576. //Group Policy
  577. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableSR, &dwRet ))
  578. {
  579. ::CheckDlgButton( hDlg, IDC_TURN_OFF, dwRet != 0 );
  580. ::LoadString( g_hInst, IDS_GROUP_POLICY_ON_OFF, szMsg,
  581. sizeof(szMsg)/sizeof(WCHAR) );
  582. ::SetDlgItemText( hDlg, IDC_TURN_OFF, szMsg );
  583. ::EnableWindow( ::GetDlgItem( hDlg, IDC_TURN_OFF ), FALSE );
  584. }
  585. // Check the policy to see if local config is enabled
  586. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableConfig, &dwRet ) )
  587. {
  588. ErrorTrace(0, "Group Policy disables SR configuration...");
  589. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, FALSE );
  590. ::LoadString( g_hInst, IDS_GROUP_POLICY_ON_OFF, szMsg,
  591. sizeof(szMsg)/sizeof(WCHAR) );
  592. ::SetDlgItemText( hDlg, IDC_TURN_OFF, szMsg );
  593. EnableWindow( ::GetDlgItem( hDlg, IDC_TURN_OFF ), FALSE );
  594. }
  595. break;
  596. case WM_PAINT :
  597. hDC = ::BeginPaint( hDlg, &ps );
  598. ::GetWindowRect( ::GetDlgItem( hDlg, IDC_SD_ICON ), &rcCtrl );
  599. ptIcon.x = rcCtrl.left;
  600. ptIcon.y = rcCtrl.top;
  601. ::ScreenToClient( hDlg, &ptIcon );
  602. ::DrawIconEx( hDC, ptIcon.x, ptIcon.y, pRDI->GetIcon(TRUE), 0, 0, 0, NULL, DI_NORMAL );
  603. ::EndPaint( hDlg, &ps );
  604. case WM_COMMAND :
  605. switch ( LOWORD(wParam ) )
  606. {
  607. case IDC_TURN_OFF :
  608. if ( HIWORD(wParam) == BN_CLICKED )
  609. {
  610. fCheck = ::IsDlgButtonChecked( hDlg, IDC_TURN_OFF );
  611. //
  612. // if safemode, cannot re-enable
  613. //
  614. if (fCheck == FALSE &&
  615. pRDI->IsExcluded())
  616. {
  617. if (0 != GetSystemMetrics(SM_CLEANBOOT))
  618. {
  619. ShowSRErrDlg(IDS_ERR_SR_SAFEMODE);
  620. ::CheckDlgButton( hDlg, IDC_TURN_OFF, TRUE );
  621. break;
  622. }
  623. }
  624. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, !fCheck );
  625. pRDI->SetCfgExcluded( fCheck );
  626. PropSheet_Changed( ::GetParent(hDlg), hDlg );
  627. }
  628. break;
  629. case IDC_DCU_INVOKE :
  630. if ( HIWORD(wParam) == BN_CLICKED )
  631. {
  632. InvokeDiskCleanup( NULL );
  633. }
  634. break;
  635. }
  636. break;
  637. case WM_NOTIFY :
  638. if ( ((LPNMHDR)lParam)->code == PSN_APPLY )
  639. {
  640. if ( pRDI->ApplyConfig( ::GetParent(hDlg) ) )
  641. lRet = PSNRET_NOERROR;
  642. else
  643. lRet = PSNRET_INVALID;
  644. fCheck = pRDI->IsExcluded();
  645. //
  646. // update drive status
  647. //
  648. if (lstrlen(pRDI->GetLabel()) != 0)
  649. {
  650. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY, pRDI->GetLabel(), pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  651. }
  652. else
  653. {
  654. ::SRFormatMessage( szMsg, IDS_DRIVE_SUMMARY_NO_LABEL, pRDI->GetMount(), ::GetDriveStatusText( pRDI ) );
  655. }
  656. ::SetDlgItemText( hDlg, IDC_SD_STATUS, szMsg );
  657. ::CheckDlgButton( hDlg, IDC_TURN_OFF, fCheck );
  658. EnableControls( hDlg, IDC_USAGE_GROUPBOX, IDC_USAGE_VALUE, ! fCheck);
  659. ::SetWindowLong( hDlg, DWL_MSGRESULT, lRet );
  660. }
  661. else if ( ((LPNMHDR)lParam)->code == NM_CLICK ||
  662. ((LPNMHDR)lParam)->code == NM_RETURN )
  663. {
  664. if (wParam == IDC_RESTOREHELP_LINK)
  665. {
  666. // launch help
  667. ShellExecuteW(NULL, L"open",
  668. SRHELPURL,
  669. NULL, NULL, SW_SHOW);
  670. }
  671. }
  672. break;
  673. case WM_HSCROLL :
  674. hCtrl = ::GetDlgItem( hDlg, IDC_USAGE_SLIDER );
  675. uPos = ::SendMessage( hCtrl, TBM_GETPOS, 0, 0 );
  676. if ( uPos != s_uUsage )
  677. {
  678. s_uUsage = uPos;
  679. pRDI->SetCfgDSUsage( uPos );
  680. ::SendMessage( hCtrl, TBM_SETPOS, TRUE, uPos );
  681. // Set Usage Text
  682. pRDI->GetUsageText( szMsg );
  683. ::SetDlgItemText( hDlg, IDC_USAGE_VALUE, szMsg );
  684. PropSheet_Changed( ::GetParent(hDlg), hDlg );
  685. }
  686. break;
  687. case WM_CONTEXTMENU:
  688. if ( !::WinHelp ( (HWND) wParam,
  689. SRHELPFILE,
  690. HELP_CONTEXTMENU,
  691. (DWORD_PTR) MAIN_HELP_MAP) )
  692. {
  693. trace (0, "! WinHelp : %ld", GetLastError());
  694. }
  695. break;
  696. case WM_HELP:
  697. if (((LPHELPINFO) lParam)->hItemHandle)
  698. {
  699. if ( !::WinHelp ( (HWND) ((LPHELPINFO) lParam)->hItemHandle,
  700. SRHELPFILE,
  701. HELP_WM_HELP,
  702. (DWORD_PTR) MAIN_HELP_MAP) )
  703. {
  704. trace (0, "! WinHelp : %ld", GetLastError());
  705. }
  706. }
  707. break;
  708. case WM_NCDESTROY :
  709. pRDI->Release();
  710. ::SetWindowLong( hDlg, DWL_USER, NULL );
  711. break;
  712. default:
  713. goto Exit;
  714. }
  715. fRet = TRUE;
  716. Exit:
  717. TraceFunctLeave();
  718. return( fRet );
  719. }
  720. /////////////////////////////////////////////////////////////////////////////
  721. //
  722. // SRGetCplPropPage
  723. //
  724. // This routine creates a property page for System Restore tab of
  725. // System Control Panel.
  726. //
  727. /////////////////////////////////////////////////////////////////////////////
  728. HPROPSHEETPAGE APIENTRY
  729. SRGetCplPropPage()
  730. {
  731. EnsureTrace();
  732. TraceFunctEnter("SRGetCplPropPage");
  733. DWORD dwRet=0;
  734. HPROPSHEETPAGE hPSP = NULL;
  735. LPCWSTR cszErr;
  736. PROPSHEETPAGE psp;
  737. CRDIArray *paryDrv = NULL;
  738. DWORD dwDisable;
  739. // Load SRClient
  740. g_CSRClientLoader.LoadSrClient();
  741. // Check credential
  742. if ( !::CheckPrivilegesForRestore() )
  743. goto Exit;
  744. // Check the policy to see if SR is enabled
  745. if ( ::SRGetRegDword( HKEY_LOCAL_MACHINE, s_cszGroupPolicy, s_cszDisableSR, &dwRet ) )
  746. if ( dwRet != 0 )
  747. {
  748. ErrorTrace(0, "Group Policy disables SR...");
  749. goto Exit;
  750. }
  751. // if the registry says that SR is enabled, make sure we are
  752. // enabled correctly (service is started, startup mode is correct)
  753. // if registry says we are enabled, but service start type is disabled
  754. // disable us now
  755. if (::SRGetRegDword( HKEY_LOCAL_MACHINE,
  756. s_cszSRRegKey,
  757. s_cszDisableSR,
  758. &dwDisable ) )
  759. {
  760. DWORD dwStart;
  761. if (0 == dwDisable)
  762. {
  763. if (ERROR_SUCCESS == GetServiceStartup(s_cszServiceName, &dwStart) &&
  764. (dwStart == SERVICE_DISABLED || dwStart == SERVICE_DEMAND_START))
  765. {
  766. EnableSREx(NULL, TRUE);
  767. DisableSR(NULL);
  768. }
  769. else
  770. {
  771. EnableSR(NULL);
  772. }
  773. }
  774. }
  775. paryDrv = new CRDIArray;
  776. if ( paryDrv == NULL )
  777. {
  778. FatalTrace(0, "Insufficient memory...");
  779. goto Exit;
  780. }
  781. if ( !::CreateDriveList( -1, *paryDrv, TRUE ) )
  782. goto Exit;
  783. if ( paryDrv->GetSize() == 0 )
  784. {
  785. ErrorTrace(0, "Drive List is empty...???");
  786. goto Exit;
  787. }
  788. // Load resource strings for drive status
  789. ::LoadString( g_hInst, IDS_DRVSTAT_ACTIVE, s_szDrvStatus[1], MAX_STATUS );
  790. ::LoadString( g_hInst, IDS_DRVSTAT_FROZEN, s_szDrvStatus[2], MAX_STATUS );
  791. ::LoadString( g_hInst, IDS_DRVSTAT_EXCLUDED, s_szDrvStatus[3], MAX_STATUS );
  792. ::LoadString( g_hInst, IDS_DRVSTAT_OFFLINE, s_szDrvStatus[4], MAX_STATUS );
  793. ::ZeroMemory( &psp, sizeof(PROPSHEETPAGE) );
  794. psp.dwSize = sizeof(PROPSHEETPAGE);
  795. psp.dwFlags = PSP_DEFAULT;
  796. psp.hInstance = g_hInst;
  797. psp.pszTitle = NULL;
  798. if ( paryDrv->GetSize() > 1 )
  799. {
  800. // property page for multiple drives
  801. psp.lParam = (LPARAM)paryDrv;
  802. psp.pszTemplate = MAKEINTRESOURCE(IDD_SYSPROP_MULTI);
  803. psp.pfnDlgProc = SRCfgMultiDlgProc;
  804. }
  805. else
  806. {
  807. // property page for single drive
  808. psp.lParam = (LPARAM)paryDrv->GetItem( 0 );
  809. psp.pszTemplate = MAKEINTRESOURCE(IDD_SYSPROP_SINGLE);
  810. psp.pfnDlgProc = SRCfgSingleDlgProc;
  811. }
  812. hPSP = ::CreatePropertySheetPage( &psp );
  813. if ( hPSP == NULL )
  814. {
  815. cszErr = ::GetSysErrStr();
  816. ErrorTrace(0, "::CreatePropertySheetPage failed - %ls", cszErr);
  817. goto Exit;
  818. }
  819. Exit:
  820. if ( hPSP == NULL )
  821. SAFE_DELETE(paryDrv);
  822. TraceFunctLeave();
  823. ReleaseTrace();
  824. return( hPSP );
  825. }
  826. // end of file