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.

562 lines
16 KiB

  1. /*++
  2. Microsoft Confidential
  3. Copyright (c) 1992-1997 Microsoft Corporation
  4. All rights reserved
  5. Module Name:
  6. perf.c
  7. Abstract:
  8. Implements the Performance dialog of the System Control Panel Applet
  9. Author:
  10. Eric Flo (ericflo) 19-Jun-1995
  11. Revision History:
  12. 15-Oct-1997 scotthal
  13. Complete overhaul
  14. 10-Jul-2000 SilviuC
  15. Added the LargeSystemCache setting.
  16. --*/
  17. #include <sysdm.h>
  18. #include <help.h>
  19. #define PROCESS_PRIORITY_SEPARATION_MASK 0x00000003
  20. #define PROCESS_PRIORITY_SEPARATION_MAX 0x00000002
  21. #define PROCESS_PRIORITY_SEPARATION_MIN 0x00000000
  22. #define PROCESS_QUANTUM_VARIABLE_MASK 0x0000000c
  23. #define PROCESS_QUANTUM_VARIABLE_DEF 0x00000000
  24. #define PROCESS_QUANTUM_VARIABLE_VALUE 0x00000004
  25. #define PROCESS_QUANTUM_FIXED_VALUE 0x00000008
  26. #define PROCESS_QUANTUM_LONG_MASK 0x00000030
  27. #define PROCESS_QUANTUM_LONG_DEF 0x00000000
  28. #define PROCESS_QUANTUM_LONG_VALUE 0x00000010
  29. #define PROCESS_QUANTUM_SHORT_VALUE 0x00000020
  30. //
  31. // Globals
  32. //
  33. HKEY m_hKeyPerf = NULL;
  34. TCHAR m_szRegPriKey[] = TEXT( "SYSTEM\\CurrentControlSet\\Control\\PriorityControl" );
  35. TCHAR m_szRegPriority[] = TEXT( "Win32PrioritySeparation" );
  36. HKEY m_hKeyMemoryManagement = NULL;
  37. TCHAR m_szRegMemoryManagementKey[] = TEXT( "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management" );
  38. TCHAR m_szRegLargeSystemCache[] = TEXT( "LargeSystemCache" );
  39. //
  40. // Help ID's
  41. //
  42. // ISSUE: SilviuC: 07/11/2000: IDC_PERF_CACHE_XXX should get help IDs when help is written
  43. DWORD aPerformanceHelpIds[] =
  44. {
  45. IDC_STATIC, NO_HELP,
  46. IDC_PERF_VM_ALLOCD, (IDH_PERF + 1),
  47. IDC_PERF_VM_ALLOCD_LABEL, (IDH_PERF + 1),
  48. IDC_PERF_GROUP, NO_HELP,
  49. IDC_PERF_TEXT, (IDH_PERF + 3),
  50. IDC_PERF_TEXT2, NO_HELP,
  51. IDC_PERF_WORKSTATION, (IDH_PERF + 4),
  52. IDC_PERF_SERVER, (IDH_PERF + 5),
  53. IDC_PERF_VM_GROUP, NO_HELP,
  54. IDC_PERF_VM_ALLOCD_TEXT, NO_HELP,
  55. IDC_PERF_CHANGE, (IDH_PERF + 7),
  56. IDC_PERF_CACHE_GROUP, NO_HELP,
  57. IDC_PERF_CACHE_TEXT, NO_HELP,
  58. IDC_PERF_CACHE_TEXT2, NO_HELP,
  59. IDC_PERF_CACHE_APPLICATION, (IDH_PERF + 14),
  60. IDC_PERF_CACHE_SYSTEM, (IDH_PERF + 15),
  61. 0, 0
  62. };
  63. INT_PTR
  64. APIENTRY
  65. PerformanceDlgProc(
  66. IN HWND hDlg,
  67. IN UINT uMsg,
  68. IN WPARAM wParam,
  69. IN LPARAM lParam
  70. )
  71. /*++
  72. Routine Description:
  73. Handles messages sent to Performance dialog
  74. Arguments:
  75. hDlg -
  76. Supplies window handle
  77. uMsg -
  78. Supplies message being sent
  79. wParam -
  80. Supplies message parameter
  81. lParam -
  82. Supplies message parameter
  83. Return Value:
  84. TRUE if message was handled
  85. FALSE if message was unhandled
  86. --*/
  87. {
  88. static int iNewChoice = 0;
  89. LONG RegRes;
  90. DWORD Type, Value, Length;
  91. DWORD CacheType, CacheValue, CacheLength;
  92. static int InitPos;
  93. static int InitRegVal, InitCacheRegVal;
  94. static int NewRegVal, NewCacheRegVal;
  95. static BOOL fVMInited = FALSE;
  96. static BOOL fTempPfWarningShown = FALSE;
  97. BOOL fTempPf;
  98. BOOL fWorkstationProduct = IsWorkstationProduct();
  99. BOOL fAdministrator = IsUserAdmin();
  100. BOOL fVariableQuanta = FALSE;
  101. BOOL fShortQuanta = FALSE;
  102. BOOL fFailedToOpenMmKey = FALSE;
  103. switch (uMsg)
  104. {
  105. case WM_INITDIALOG:
  106. InitPos = 0;
  107. InitRegVal = 0;
  108. InitCacheRegVal = 0;
  109. //
  110. // initialize from the registry
  111. //
  112. RegRes = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  113. m_szRegPriKey,
  114. 0,
  115. fAdministrator ? KEY_QUERY_VALUE | KEY_SET_VALUE : KEY_QUERY_VALUE,
  116. &m_hKeyPerf );
  117. if (RegRes == ERROR_SUCCESS)
  118. {
  119. Length = sizeof( Value );
  120. RegRes = RegQueryValueEx( m_hKeyPerf,
  121. m_szRegPriority,
  122. NULL,
  123. &Type,
  124. (LPBYTE) &Value,
  125. &Length );
  126. if (RegRes == ERROR_SUCCESS)
  127. {
  128. InitRegVal = Value;
  129. InitPos = InitRegVal & PROCESS_PRIORITY_SEPARATION_MASK;
  130. if (InitPos > PROCESS_PRIORITY_SEPARATION_MAX)
  131. {
  132. InitPos = PROCESS_PRIORITY_SEPARATION_MAX;
  133. }
  134. }
  135. }
  136. if ((RegRes != ERROR_SUCCESS) || (!fAdministrator))
  137. {
  138. EnableWindow(GetDlgItem(hDlg, IDC_PERF_WORKSTATION), FALSE);
  139. EnableWindow(GetDlgItem(hDlg, IDC_PERF_SERVER), FALSE);
  140. }
  141. NewRegVal = InitRegVal;
  142. //
  143. // determine if we are using fixed or variable quantums
  144. //
  145. switch (InitRegVal & PROCESS_QUANTUM_VARIABLE_MASK)
  146. {
  147. case PROCESS_QUANTUM_VARIABLE_VALUE:
  148. fVariableQuanta = TRUE;
  149. break;
  150. case PROCESS_QUANTUM_FIXED_VALUE:
  151. fVariableQuanta = FALSE;
  152. break;
  153. case PROCESS_QUANTUM_VARIABLE_DEF:
  154. default:
  155. if (fWorkstationProduct)
  156. {
  157. fVariableQuanta = TRUE;
  158. }
  159. else
  160. {
  161. fVariableQuanta = FALSE;
  162. }
  163. break;
  164. }
  165. //
  166. // determine if we are using long or short
  167. //
  168. switch (InitRegVal & PROCESS_QUANTUM_LONG_MASK)
  169. {
  170. case PROCESS_QUANTUM_LONG_VALUE:
  171. fShortQuanta = FALSE;
  172. break;
  173. case PROCESS_QUANTUM_SHORT_VALUE:
  174. fShortQuanta = TRUE;
  175. break;
  176. case PROCESS_QUANTUM_LONG_DEF:
  177. default:
  178. if (fWorkstationProduct)
  179. {
  180. fShortQuanta = TRUE;
  181. }
  182. else
  183. {
  184. fShortQuanta = FALSE;
  185. }
  186. break;
  187. }
  188. //
  189. // Short, Variable Quanta == Workstation-like interactive response
  190. // Long, Fixed Quanta == Server-like interactive response
  191. //
  192. if (fVariableQuanta && fShortQuanta)
  193. {
  194. iNewChoice = PROCESS_PRIORITY_SEPARATION_MAX;
  195. CheckRadioButton(
  196. hDlg,
  197. IDC_PERF_WORKSTATION,
  198. IDC_PERF_SERVER,
  199. IDC_PERF_WORKSTATION
  200. );
  201. } // if
  202. else
  203. {
  204. iNewChoice = PROCESS_PRIORITY_SEPARATION_MIN;
  205. CheckRadioButton(
  206. hDlg,
  207. IDC_PERF_WORKSTATION,
  208. IDC_PERF_SERVER,
  209. IDC_PERF_SERVER
  210. );
  211. } // else
  212. //
  213. // Initialize the `memory usage' part.
  214. //
  215. fFailedToOpenMmKey = FALSE;
  216. RegRes = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  217. m_szRegMemoryManagementKey,
  218. 0,
  219. fAdministrator ? KEY_QUERY_VALUE | KEY_SET_VALUE : KEY_QUERY_VALUE,
  220. &m_hKeyMemoryManagement );
  221. if (RegRes == ERROR_SUCCESS)
  222. {
  223. CacheValue = 0;
  224. CacheLength = sizeof( CacheValue );
  225. RegRes = RegQueryValueEx( m_hKeyMemoryManagement,
  226. m_szRegLargeSystemCache,
  227. NULL,
  228. &CacheType,
  229. (LPBYTE) &CacheValue,
  230. &CacheLength );
  231. if (RegRes == ERROR_SUCCESS && CacheValue != 0)
  232. {
  233. CheckRadioButton(hDlg,
  234. IDC_PERF_CACHE_APPLICATION,
  235. IDC_PERF_CACHE_SYSTEM,
  236. IDC_PERF_CACHE_SYSTEM);
  237. }
  238. else
  239. {
  240. CheckRadioButton(hDlg,
  241. IDC_PERF_CACHE_APPLICATION,
  242. IDC_PERF_CACHE_SYSTEM,
  243. IDC_PERF_CACHE_APPLICATION);
  244. }
  245. }
  246. else
  247. {
  248. fFailedToOpenMmKey = TRUE;
  249. }
  250. if (fFailedToOpenMmKey || (!fAdministrator))
  251. {
  252. CheckRadioButton(hDlg,
  253. IDC_PERF_CACHE_APPLICATION,
  254. IDC_PERF_CACHE_SYSTEM,
  255. IDC_PERF_CACHE_APPLICATION);
  256. EnableWindow(GetDlgItem(hDlg, IDC_PERF_CACHE_APPLICATION), FALSE);
  257. EnableWindow(GetDlgItem(hDlg, IDC_PERF_CACHE_SYSTEM), FALSE);
  258. }
  259. InitCacheRegVal = CacheValue;
  260. NewCacheRegVal = CacheValue;
  261. //
  262. // Init the virtual memory part
  263. //
  264. if (VirtualInitStructures())
  265. {
  266. fVMInited = TRUE;
  267. SetDlgItemMB( hDlg, IDC_PERF_VM_ALLOCD, VirtualMemComputeAllocated(hDlg, &fTempPf) );
  268. //
  269. // If the system created a temp pagefile, warn the user that
  270. // the total pagefile size may appear a bit large, but only
  271. // do so once per System Applet invokation.
  272. //
  273. if (fTempPf && !fTempPfWarningShown)
  274. {
  275. MsgBoxParam(
  276. hDlg,
  277. IDS_TEMP_PAGEFILE_WARN,
  278. IDS_SYSDM_TITLE,
  279. MB_ICONINFORMATION | MB_OK
  280. );
  281. fTempPfWarningShown = TRUE;
  282. } // if (fTempPf...
  283. }
  284. break;
  285. case WM_DESTROY:
  286. //
  287. // If the dialog box is going away, then close the
  288. // registry key.
  289. //
  290. if (m_hKeyPerf)
  291. {
  292. RegCloseKey( m_hKeyPerf );
  293. m_hKeyPerf = NULL;
  294. }
  295. if (m_hKeyMemoryManagement)
  296. {
  297. RegCloseKey( m_hKeyMemoryManagement );
  298. m_hKeyMemoryManagement = NULL;
  299. }
  300. if (fVMInited)
  301. {
  302. VirtualFreeStructures();
  303. }
  304. break;
  305. case WM_NOTIFY:
  306. switch (((NMHDR *)lParam)->code)
  307. {
  308. case PSN_APPLY:
  309. //
  310. // Save new time quantum stuff, if it has changed
  311. //
  312. NewRegVal &= ~PROCESS_PRIORITY_SEPARATION_MASK;
  313. NewRegVal |= iNewChoice;
  314. if (NewRegVal != InitRegVal)
  315. {
  316. Value = NewRegVal;
  317. if (m_hKeyPerf)
  318. {
  319. Type = REG_DWORD;
  320. Length = sizeof( Value );
  321. RegSetValueEx( m_hKeyPerf,
  322. m_szRegPriority,
  323. 0,
  324. REG_DWORD,
  325. (LPBYTE) &Value,
  326. Length );
  327. InitRegVal = Value;
  328. //
  329. // Kernel monitors this part of the
  330. // registry, so don't tell user he has to reboot
  331. //
  332. }
  333. }
  334. //
  335. // Save `LargeSystemCache' if value changed
  336. //
  337. if (InitCacheRegVal != NewCacheRegVal) {
  338. CacheValue = NewCacheRegVal;
  339. if (m_hKeyMemoryManagement) {
  340. CacheType = REG_DWORD;
  341. CacheLength = sizeof( CacheValue );
  342. RegSetValueEx( m_hKeyMemoryManagement,
  343. m_szRegLargeSystemCache,
  344. 0,
  345. REG_DWORD,
  346. (LPBYTE) &CacheValue,
  347. CacheLength );
  348. InitCacheRegVal = CacheValue;
  349. //
  350. // Request a reboot if things changed
  351. //
  352. MsgBoxParam(
  353. hDlg,
  354. IDS_SYSDM_RESTART,
  355. IDS_SYSDM_TITLE,
  356. MB_OK | MB_ICONINFORMATION
  357. );
  358. g_fRebootRequired = TRUE;
  359. }
  360. }
  361. break;
  362. }
  363. break;
  364. case WM_COMMAND:
  365. {
  366. BOOL fEnableApply = (LOWORD(wParam) != IDC_PERF_CHANGE);
  367. LRESULT lres;
  368. switch (LOWORD(wParam))
  369. {
  370. case IDC_PERF_CHANGE:
  371. {
  372. lres = DialogBox(
  373. hInstance,
  374. MAKEINTRESOURCE(DLG_VIRTUALMEM),
  375. hDlg,
  376. VirtualMemDlg
  377. );
  378. if (fVMInited)
  379. {
  380. SetDlgItemMB(
  381. hDlg,
  382. IDC_PERF_VM_ALLOCD,
  383. VirtualMemComputeAllocated(hDlg, NULL)
  384. );
  385. }
  386. if (lres != RET_NO_CHANGE)
  387. {
  388. fEnableApply = TRUE;
  389. if (lres != RET_CHANGE_NO_REBOOT)
  390. {
  391. MsgBoxParam(
  392. hDlg,
  393. IDS_SYSDM_RESTART,
  394. IDS_SYSDM_TITLE,
  395. MB_OK | MB_ICONINFORMATION
  396. );
  397. g_fRebootRequired = TRUE;
  398. }
  399. }
  400. }
  401. break;
  402. case IDC_PERF_WORKSTATION:
  403. if (BN_CLICKED == HIWORD(wParam))
  404. {
  405. //
  406. // Workstations have maximum foreground boost
  407. //
  408. iNewChoice = PROCESS_PRIORITY_SEPARATION_MAX;
  409. //
  410. // Workstations have variable, short quanta
  411. NewRegVal &= ~PROCESS_QUANTUM_VARIABLE_MASK;
  412. NewRegVal |= PROCESS_QUANTUM_VARIABLE_VALUE;
  413. NewRegVal &= ~PROCESS_QUANTUM_LONG_MASK;
  414. NewRegVal |= PROCESS_QUANTUM_SHORT_VALUE;
  415. } // if
  416. break;
  417. case IDC_PERF_SERVER:
  418. if (BN_CLICKED == HIWORD(wParam))
  419. {
  420. //
  421. // Servers have minimum foreground boost
  422. //
  423. iNewChoice = PROCESS_PRIORITY_SEPARATION_MIN;
  424. //
  425. // Servers have fixed, long quanta
  426. //
  427. NewRegVal &= ~PROCESS_QUANTUM_VARIABLE_MASK;
  428. NewRegVal |= PROCESS_QUANTUM_FIXED_VALUE;
  429. NewRegVal &= ~PROCESS_QUANTUM_LONG_MASK;
  430. NewRegVal |= PROCESS_QUANTUM_LONG_VALUE;
  431. } // if
  432. break;
  433. case IDC_PERF_CACHE_APPLICATION:
  434. if (BN_CLICKED == HIWORD(wParam))
  435. {
  436. NewCacheRegVal = 0;
  437. } // if
  438. break;
  439. case IDC_PERF_CACHE_SYSTEM:
  440. if (BN_CLICKED == HIWORD(wParam))
  441. {
  442. NewCacheRegVal = 1;
  443. } // if
  444. break;
  445. }
  446. if (fEnableApply)
  447. {
  448. // Enable the "Apply" button because changes have happened.
  449. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L);
  450. }
  451. }
  452. break;
  453. case WM_HELP: // F1
  454. WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP,
  455. (DWORD_PTR) (LPSTR) aPerformanceHelpIds);
  456. break;
  457. case WM_CONTEXTMENU: // right mouse click
  458. WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
  459. (DWORD_PTR) (LPSTR) aPerformanceHelpIds);
  460. break;
  461. default:
  462. return FALSE;
  463. }
  464. return TRUE;
  465. }