/*++ Microsoft Confidential Copyright (c) 1992-1997 Microsoft Corporation All rights reserved Module Name: perf.c Abstract: Implements the Performance dialog of the System Control Panel Applet Author: Eric Flo (ericflo) 19-Jun-1995 Revision History: 15-Oct-1997 scotthal Complete overhaul 10-Jul-2000 SilviuC Added the LargeSystemCache setting. --*/ #include #include #define PROCESS_PRIORITY_SEPARATION_MASK 0x00000003 #define PROCESS_PRIORITY_SEPARATION_MAX 0x00000002 #define PROCESS_PRIORITY_SEPARATION_MIN 0x00000000 #define PROCESS_QUANTUM_VARIABLE_MASK 0x0000000c #define PROCESS_QUANTUM_VARIABLE_DEF 0x00000000 #define PROCESS_QUANTUM_VARIABLE_VALUE 0x00000004 #define PROCESS_QUANTUM_FIXED_VALUE 0x00000008 #define PROCESS_QUANTUM_LONG_MASK 0x00000030 #define PROCESS_QUANTUM_LONG_DEF 0x00000000 #define PROCESS_QUANTUM_LONG_VALUE 0x00000010 #define PROCESS_QUANTUM_SHORT_VALUE 0x00000020 // // Globals // HKEY m_hKeyPerf = NULL; TCHAR m_szRegPriKey[] = TEXT( "SYSTEM\\CurrentControlSet\\Control\\PriorityControl" ); TCHAR m_szRegPriority[] = TEXT( "Win32PrioritySeparation" ); HKEY m_hKeyMemoryManagement = NULL; TCHAR m_szRegMemoryManagementKey[] = TEXT( "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management" ); TCHAR m_szRegLargeSystemCache[] = TEXT( "LargeSystemCache" ); // // Help ID's // // ISSUE: SilviuC: 07/11/2000: IDC_PERF_CACHE_XXX should get help IDs when help is written DWORD aPerformanceHelpIds[] = { IDC_STATIC, NO_HELP, IDC_PERF_VM_ALLOCD, (IDH_PERF + 1), IDC_PERF_VM_ALLOCD_LABEL, (IDH_PERF + 1), IDC_PERF_GROUP, NO_HELP, IDC_PERF_TEXT, (IDH_PERF + 3), IDC_PERF_TEXT2, NO_HELP, IDC_PERF_WORKSTATION, (IDH_PERF + 4), IDC_PERF_SERVER, (IDH_PERF + 5), IDC_PERF_VM_GROUP, NO_HELP, IDC_PERF_VM_ALLOCD_TEXT, NO_HELP, IDC_PERF_CHANGE, (IDH_PERF + 7), IDC_PERF_CACHE_GROUP, NO_HELP, IDC_PERF_CACHE_TEXT, NO_HELP, IDC_PERF_CACHE_TEXT2, NO_HELP, IDC_PERF_CACHE_APPLICATION, (IDH_PERF + 14), IDC_PERF_CACHE_SYSTEM, (IDH_PERF + 15), 0, 0 }; INT_PTR APIENTRY PerformanceDlgProc( IN HWND hDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam ) /*++ Routine Description: Handles messages sent to Performance dialog Arguments: hDlg - Supplies window handle uMsg - Supplies message being sent wParam - Supplies message parameter lParam - Supplies message parameter Return Value: TRUE if message was handled FALSE if message was unhandled --*/ { static int iNewChoice = 0; LONG RegRes; DWORD Type, Value, Length; DWORD CacheType, CacheValue, CacheLength; static int InitPos; static int InitRegVal, InitCacheRegVal; static int NewRegVal, NewCacheRegVal; static BOOL fVMInited = FALSE; static BOOL fTempPfWarningShown = FALSE; BOOL fTempPf; BOOL fWorkstationProduct = IsWorkstationProduct(); BOOL fAdministrator = IsUserAdmin(); BOOL fVariableQuanta = FALSE; BOOL fShortQuanta = FALSE; BOOL fFailedToOpenMmKey = FALSE; switch (uMsg) { case WM_INITDIALOG: InitPos = 0; InitRegVal = 0; InitCacheRegVal = 0; // // initialize from the registry // RegRes = RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_szRegPriKey, 0, fAdministrator ? KEY_QUERY_VALUE | KEY_SET_VALUE : KEY_QUERY_VALUE, &m_hKeyPerf ); if (RegRes == ERROR_SUCCESS) { Length = sizeof( Value ); RegRes = RegQueryValueEx( m_hKeyPerf, m_szRegPriority, NULL, &Type, (LPBYTE) &Value, &Length ); if (RegRes == ERROR_SUCCESS) { InitRegVal = Value; InitPos = InitRegVal & PROCESS_PRIORITY_SEPARATION_MASK; if (InitPos > PROCESS_PRIORITY_SEPARATION_MAX) { InitPos = PROCESS_PRIORITY_SEPARATION_MAX; } } } if ((RegRes != ERROR_SUCCESS) || (!fAdministrator)) { EnableWindow(GetDlgItem(hDlg, IDC_PERF_WORKSTATION), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PERF_SERVER), FALSE); } NewRegVal = InitRegVal; // // determine if we are using fixed or variable quantums // switch (InitRegVal & PROCESS_QUANTUM_VARIABLE_MASK) { case PROCESS_QUANTUM_VARIABLE_VALUE: fVariableQuanta = TRUE; break; case PROCESS_QUANTUM_FIXED_VALUE: fVariableQuanta = FALSE; break; case PROCESS_QUANTUM_VARIABLE_DEF: default: if (fWorkstationProduct) { fVariableQuanta = TRUE; } else { fVariableQuanta = FALSE; } break; } // // determine if we are using long or short // switch (InitRegVal & PROCESS_QUANTUM_LONG_MASK) { case PROCESS_QUANTUM_LONG_VALUE: fShortQuanta = FALSE; break; case PROCESS_QUANTUM_SHORT_VALUE: fShortQuanta = TRUE; break; case PROCESS_QUANTUM_LONG_DEF: default: if (fWorkstationProduct) { fShortQuanta = TRUE; } else { fShortQuanta = FALSE; } break; } // // Short, Variable Quanta == Workstation-like interactive response // Long, Fixed Quanta == Server-like interactive response // if (fVariableQuanta && fShortQuanta) { iNewChoice = PROCESS_PRIORITY_SEPARATION_MAX; CheckRadioButton( hDlg, IDC_PERF_WORKSTATION, IDC_PERF_SERVER, IDC_PERF_WORKSTATION ); } // if else { iNewChoice = PROCESS_PRIORITY_SEPARATION_MIN; CheckRadioButton( hDlg, IDC_PERF_WORKSTATION, IDC_PERF_SERVER, IDC_PERF_SERVER ); } // else // // Initialize the `memory usage' part. // fFailedToOpenMmKey = FALSE; RegRes = RegOpenKeyEx( HKEY_LOCAL_MACHINE, m_szRegMemoryManagementKey, 0, fAdministrator ? KEY_QUERY_VALUE | KEY_SET_VALUE : KEY_QUERY_VALUE, &m_hKeyMemoryManagement ); if (RegRes == ERROR_SUCCESS) { CacheValue = 0; CacheLength = sizeof( CacheValue ); RegRes = RegQueryValueEx( m_hKeyMemoryManagement, m_szRegLargeSystemCache, NULL, &CacheType, (LPBYTE) &CacheValue, &CacheLength ); if (RegRes == ERROR_SUCCESS && CacheValue != 0) { CheckRadioButton(hDlg, IDC_PERF_CACHE_APPLICATION, IDC_PERF_CACHE_SYSTEM, IDC_PERF_CACHE_SYSTEM); } else { CheckRadioButton(hDlg, IDC_PERF_CACHE_APPLICATION, IDC_PERF_CACHE_SYSTEM, IDC_PERF_CACHE_APPLICATION); } } else { fFailedToOpenMmKey = TRUE; } if (fFailedToOpenMmKey || (!fAdministrator)) { CheckRadioButton(hDlg, IDC_PERF_CACHE_APPLICATION, IDC_PERF_CACHE_SYSTEM, IDC_PERF_CACHE_APPLICATION); EnableWindow(GetDlgItem(hDlg, IDC_PERF_CACHE_APPLICATION), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_PERF_CACHE_SYSTEM), FALSE); } InitCacheRegVal = CacheValue; NewCacheRegVal = CacheValue; // // Init the virtual memory part // if (VirtualInitStructures()) { fVMInited = TRUE; SetDlgItemMB( hDlg, IDC_PERF_VM_ALLOCD, VirtualMemComputeAllocated(hDlg, &fTempPf) ); // // If the system created a temp pagefile, warn the user that // the total pagefile size may appear a bit large, but only // do so once per System Applet invokation. // if (fTempPf && !fTempPfWarningShown) { MsgBoxParam( hDlg, IDS_TEMP_PAGEFILE_WARN, IDS_SYSDM_TITLE, MB_ICONINFORMATION | MB_OK ); fTempPfWarningShown = TRUE; } // if (fTempPf... } break; case WM_DESTROY: // // If the dialog box is going away, then close the // registry key. // if (m_hKeyPerf) { RegCloseKey( m_hKeyPerf ); m_hKeyPerf = NULL; } if (m_hKeyMemoryManagement) { RegCloseKey( m_hKeyMemoryManagement ); m_hKeyMemoryManagement = NULL; } if (fVMInited) { VirtualFreeStructures(); } break; case WM_NOTIFY: switch (((NMHDR *)lParam)->code) { case PSN_APPLY: // // Save new time quantum stuff, if it has changed // NewRegVal &= ~PROCESS_PRIORITY_SEPARATION_MASK; NewRegVal |= iNewChoice; if (NewRegVal != InitRegVal) { Value = NewRegVal; if (m_hKeyPerf) { Type = REG_DWORD; Length = sizeof( Value ); RegSetValueEx( m_hKeyPerf, m_szRegPriority, 0, REG_DWORD, (LPBYTE) &Value, Length ); InitRegVal = Value; // // Kernel monitors this part of the // registry, so don't tell user he has to reboot // } } // // Save `LargeSystemCache' if value changed // if (InitCacheRegVal != NewCacheRegVal) { CacheValue = NewCacheRegVal; if (m_hKeyMemoryManagement) { CacheType = REG_DWORD; CacheLength = sizeof( CacheValue ); RegSetValueEx( m_hKeyMemoryManagement, m_szRegLargeSystemCache, 0, REG_DWORD, (LPBYTE) &CacheValue, CacheLength ); InitCacheRegVal = CacheValue; // // Request a reboot if things changed // MsgBoxParam( hDlg, IDS_SYSDM_RESTART, IDS_SYSDM_TITLE, MB_OK | MB_ICONINFORMATION ); g_fRebootRequired = TRUE; } } break; } break; case WM_COMMAND: { BOOL fEnableApply = (LOWORD(wParam) != IDC_PERF_CHANGE); LRESULT lres; switch (LOWORD(wParam)) { case IDC_PERF_CHANGE: { lres = DialogBox( hInstance, MAKEINTRESOURCE(DLG_VIRTUALMEM), hDlg, VirtualMemDlg ); if (fVMInited) { SetDlgItemMB( hDlg, IDC_PERF_VM_ALLOCD, VirtualMemComputeAllocated(hDlg, NULL) ); } if (lres != RET_NO_CHANGE) { fEnableApply = TRUE; if (lres != RET_CHANGE_NO_REBOOT) { MsgBoxParam( hDlg, IDS_SYSDM_RESTART, IDS_SYSDM_TITLE, MB_OK | MB_ICONINFORMATION ); g_fRebootRequired = TRUE; } } } break; case IDC_PERF_WORKSTATION: if (BN_CLICKED == HIWORD(wParam)) { // // Workstations have maximum foreground boost // iNewChoice = PROCESS_PRIORITY_SEPARATION_MAX; // // Workstations have variable, short quanta NewRegVal &= ~PROCESS_QUANTUM_VARIABLE_MASK; NewRegVal |= PROCESS_QUANTUM_VARIABLE_VALUE; NewRegVal &= ~PROCESS_QUANTUM_LONG_MASK; NewRegVal |= PROCESS_QUANTUM_SHORT_VALUE; } // if break; case IDC_PERF_SERVER: if (BN_CLICKED == HIWORD(wParam)) { // // Servers have minimum foreground boost // iNewChoice = PROCESS_PRIORITY_SEPARATION_MIN; // // Servers have fixed, long quanta // NewRegVal &= ~PROCESS_QUANTUM_VARIABLE_MASK; NewRegVal |= PROCESS_QUANTUM_FIXED_VALUE; NewRegVal &= ~PROCESS_QUANTUM_LONG_MASK; NewRegVal |= PROCESS_QUANTUM_LONG_VALUE; } // if break; case IDC_PERF_CACHE_APPLICATION: if (BN_CLICKED == HIWORD(wParam)) { NewCacheRegVal = 0; } // if break; case IDC_PERF_CACHE_SYSTEM: if (BN_CLICKED == HIWORD(wParam)) { NewCacheRegVal = 1; } // if break; } if (fEnableApply) { // Enable the "Apply" button because changes have happened. SendMessage(GetParent(hDlg), PSM_CHANGED, (WPARAM)hDlg, 0L); } } break; case WM_HELP: // F1 WinHelp((HWND)((LPHELPINFO) lParam)->hItemHandle, HELP_FILE, HELP_WM_HELP, (DWORD_PTR) (LPSTR) aPerformanceHelpIds); break; case WM_CONTEXTMENU: // right mouse click WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU, (DWORD_PTR) (LPSTR) aPerformanceHelpIds); break; default: return FALSE; } return TRUE; }