Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenvirtmem.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS system properties, control panel applet 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/cpl/sysdm/virtual.c 00005 * PURPOSE: Virtual memory control dialog 00006 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com> 00007 * 00008 */ 00009 00010 #include "precomp.h" 00011 00012 static BOOL OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem); 00013 static LPCTSTR lpKey = _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); 00014 00015 static BOOL 00016 ReadPageFileSettings(PVIRTMEM pVirtMem) 00017 { 00018 HKEY hkey = NULL; 00019 DWORD dwType; 00020 DWORD dwDataSize; 00021 BOOL bRet = FALSE; 00022 00023 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, 00024 lpKey, 00025 0, 00026 NULL, 00027 REG_OPTION_NON_VOLATILE, 00028 KEY_QUERY_VALUE, 00029 NULL, 00030 &hkey, 00031 NULL) == ERROR_SUCCESS) 00032 { 00033 if (RegQueryValueEx(hkey, 00034 _T("PagingFiles"), 00035 NULL, 00036 &dwType, 00037 NULL, 00038 &dwDataSize) == ERROR_SUCCESS) 00039 { 00040 pVirtMem->szPagingFiles = (LPTSTR)HeapAlloc(GetProcessHeap(), 00041 0, 00042 dwDataSize); 00043 if (pVirtMem->szPagingFiles != NULL) 00044 { 00045 ZeroMemory(pVirtMem->szPagingFiles, 00046 dwDataSize); 00047 if (RegQueryValueEx(hkey, 00048 _T("PagingFiles"), 00049 NULL, 00050 &dwType, 00051 (PBYTE)pVirtMem->szPagingFiles, 00052 &dwDataSize) == ERROR_SUCCESS) 00053 { 00054 bRet = TRUE; 00055 } 00056 } 00057 } 00058 } 00059 00060 if (!bRet) 00061 ShowLastWin32Error(pVirtMem->hSelf); 00062 00063 if (hkey != NULL) 00064 RegCloseKey(hkey); 00065 00066 return bRet; 00067 } 00068 00069 00070 static VOID 00071 GetPageFileSizes(LPTSTR lpPageFiles, 00072 LPINT lpInitialSize, 00073 LPINT lpMaximumSize) 00074 { 00075 INT i = 0; 00076 00077 *lpInitialSize = -1; 00078 *lpMaximumSize = -1; 00079 00080 while (*lpPageFiles != _T('\0')) 00081 { 00082 if (*lpPageFiles == _T(' ')) 00083 { 00084 lpPageFiles++; 00085 00086 switch (i) 00087 { 00088 case 0: 00089 *lpInitialSize = (INT)_ttoi(lpPageFiles); 00090 i = 1; 00091 break; 00092 00093 case 1: 00094 *lpMaximumSize = (INT)_ttoi(lpPageFiles); 00095 return; 00096 } 00097 } 00098 00099 lpPageFiles++; 00100 } 00101 } 00102 00103 00104 static VOID 00105 ParseMemSettings(PVIRTMEM pVirtMem) 00106 { 00107 TCHAR szDrives[1024]; // All drives 00108 LPTSTR DrivePtr = szDrives; 00109 TCHAR szDrive[3]; // Single drive 00110 TCHAR szVolume[MAX_PATH]; 00111 TCHAR *szDisplayString; 00112 INT InitialSize = 0; 00113 INT MaximumSize = 0; 00114 INT DriveLen; 00115 INT PgCnt = 0; 00116 00117 DriveLen = GetLogicalDriveStrings(1023, 00118 szDrives); 00119 00120 szDisplayString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (MAX_PATH * 2 + 69) * sizeof(TCHAR)); 00121 if (szDisplayString == NULL) 00122 return; 00123 00124 while (DriveLen != 0) 00125 { 00126 INT Len; 00127 00128 Len = lstrlen(DrivePtr) + 1; 00129 DriveLen -= Len; 00130 00131 DrivePtr = _tcsupr(DrivePtr); 00132 00133 /* Copy the 'X:' portion */ 00134 lstrcpyn(szDrive, DrivePtr, sizeof(szDrive) / sizeof(TCHAR)); 00135 00136 if (GetDriveType(DrivePtr) == DRIVE_FIXED) 00137 { 00138 /* Does drive match the one in the registry ? */ 00139 if (!_tcsncmp(pVirtMem->szPagingFiles, szDrive, 2)) 00140 { 00141 /* FIXME: We only check the first available pagefile in the reg */ 00142 GetPageFileSizes(pVirtMem->szPagingFiles, 00143 &InitialSize, 00144 &MaximumSize); 00145 00146 pVirtMem->Pagefile[PgCnt].InitialSize = InitialSize; 00147 pVirtMem->Pagefile[PgCnt].MaximumSize = MaximumSize; 00148 pVirtMem->Pagefile[PgCnt].bUsed = TRUE; 00149 lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); 00150 } 00151 else 00152 { 00153 pVirtMem->Pagefile[PgCnt].InitialSize = 0; 00154 pVirtMem->Pagefile[PgCnt].MaximumSize = 0; 00155 pVirtMem->Pagefile[PgCnt].bUsed = FALSE; 00156 lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); 00157 } 00158 00159 _tcscpy(szDisplayString, szDrive); 00160 _tcscat(szDisplayString, _T("\t")); 00161 00162 /* Set a volume label if there is one */ 00163 if (GetVolumeInformation(DrivePtr, 00164 szVolume, 00165 255, 00166 NULL, 00167 NULL, 00168 NULL, 00169 NULL, 00170 0)) 00171 { 00172 if (szVolume[0] != _T('\0')) 00173 { 00174 TCHAR szVol[MAX_PATH + 2]; 00175 _stprintf(szVol, _T("[%s]"), szVolume); 00176 _tcscat(szDisplayString, szVol); 00177 } 00178 } 00179 00180 if ((InitialSize != 0) || (MaximumSize != 0)) 00181 { 00182 TCHAR szSize[64]; 00183 00184 _stprintf(szSize, _T("%i - %i"), InitialSize, MaximumSize); 00185 _tcscat(szDisplayString, _T("\t")); 00186 _tcscat(szDisplayString, szSize); 00187 } 00188 00189 SendMessage(pVirtMem->hListBox, LB_ADDSTRING, (WPARAM)0, (LPARAM)szDisplayString); 00190 PgCnt++; 00191 } 00192 00193 DrivePtr += Len; 00194 } 00195 00196 SendMessage(pVirtMem->hListBox, LB_SETCURSEL, (WPARAM)0, (LPARAM)0); 00197 HeapFree(GetProcessHeap(), 0, szDisplayString); 00198 pVirtMem->Count = PgCnt; 00199 OnSelChange(pVirtMem->hSelf, pVirtMem); 00200 } 00201 00202 00203 static VOID 00204 WritePageFileSettings(PVIRTMEM pVirtMem) 00205 { 00206 HKEY hk = NULL; 00207 TCHAR szPagingFiles[2048]; 00208 TCHAR szText[256]; 00209 INT i, nPos = 0; 00210 BOOL bErr = TRUE; 00211 00212 for (i = 0; i < pVirtMem->Count; ++i) 00213 { 00214 if (pVirtMem->Pagefile[i].bUsed) 00215 { 00216 _stprintf(szText, _T("%s\\pagefile.sys %i %i"), 00217 pVirtMem->Pagefile[i].szDrive, 00218 pVirtMem->Pagefile[i].InitialSize, 00219 pVirtMem->Pagefile[i].MaximumSize); 00220 00221 /* Add it to our overall registry string */ 00222 lstrcpy(szPagingFiles + nPos, szText); 00223 00224 /* Record the position where the next string will start */ 00225 nPos += (INT)lstrlen(szText) + 1; 00226 00227 /* Add another NULL for REG_MULTI_SZ */ 00228 szPagingFiles[nPos] = _T('\0'); 00229 nPos++; 00230 } 00231 } 00232 00233 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, 00234 lpKey, 00235 0, 00236 NULL, 00237 REG_OPTION_NON_VOLATILE, 00238 KEY_WRITE, 00239 NULL, 00240 &hk, 00241 NULL) == ERROR_SUCCESS) 00242 { 00243 if (RegSetValueEx(hk, 00244 _T("PagingFiles"), 00245 0, 00246 REG_MULTI_SZ, 00247 (LPBYTE) szPagingFiles, 00248 (DWORD) nPos * sizeof(TCHAR)) == ERROR_SUCCESS) 00249 { 00250 bErr = FALSE; 00251 } 00252 00253 RegCloseKey(hk); 00254 } 00255 00256 if (bErr) 00257 ShowLastWin32Error(pVirtMem->hSelf); 00258 } 00259 00260 00261 static VOID 00262 SetListBoxColumns(HWND hwndListBox) 00263 { 00264 const INT tabs[2] = {30, 120}; 00265 00266 SendMessage(hwndListBox, LB_SETTABSTOPS, (WPARAM)2, (LPARAM)&tabs[0]); 00267 } 00268 00269 00270 static VOID 00271 OnNoPagingFile(PVIRTMEM pVirtMem) 00272 { 00273 /* Disable the page file custom size boxes */ 00274 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); 00275 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); 00276 } 00277 00278 00279 static VOID 00280 OnSysManSize(PVIRTMEM pVirtMem) 00281 { 00282 /* Disable the page file custom size boxes */ 00283 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); 00284 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); 00285 } 00286 00287 00288 static VOID 00289 OnCustom(PVIRTMEM pVirtMem) 00290 { 00291 /* Enable the page file custom size boxes */ 00292 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); 00293 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); 00294 } 00295 00296 00297 static VOID 00298 OnSet(PVIRTMEM pVirtMem) 00299 { 00300 INT Index; 00301 UINT InitialSize; 00302 UINT MaximumSize; 00303 BOOL bTranslated; 00304 TCHAR szTitle[64]; 00305 TCHAR szMessage[256]; 00306 00307 pVirtMem->bSave = TRUE; 00308 00309 Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, 00310 IDC_PAGEFILELIST, 00311 LB_GETCURSEL, 00312 0, 00313 0); 00314 if (Index >= 0 && Index < pVirtMem->Count) 00315 { 00316 /* Check if custom settings are checked */ 00317 if (IsDlgButtonChecked(pVirtMem->hSelf, 00318 IDC_CUSTOM) == BST_CHECKED) 00319 { 00320 InitialSize = GetDlgItemInt(pVirtMem->hSelf, 00321 IDC_INITIALSIZE, 00322 &bTranslated, 00323 FALSE); 00324 if (!bTranslated) 00325 { 00326 if (LoadString(hApplet, 00327 IDS_MESSAGEBOXTITLE, 00328 szTitle, 00329 sizeof(szTitle) / sizeof(szTitle[0])) == 0) 00330 _tcscpy(szTitle, _T("System control panel applet")); 00331 00332 if (LoadString(hApplet, 00333 IDS_WARNINITIALSIZE, 00334 szMessage, 00335 sizeof(szMessage) / sizeof(szMessage[0])) == 0) 00336 _tcscpy(szMessage, _T("Enter a numeric value for the initial size of the paging file.")); 00337 00338 MessageBox(NULL, 00339 szMessage, 00340 szTitle, 00341 MB_ICONWARNING | MB_OK); 00342 return; 00343 } 00344 00345 MaximumSize = GetDlgItemInt(pVirtMem->hSelf, 00346 IDC_MAXSIZE, 00347 &bTranslated, 00348 FALSE); 00349 if (!bTranslated) 00350 { 00351 if (LoadString(hApplet, 00352 IDS_MESSAGEBOXTITLE, 00353 szTitle, 00354 sizeof(szTitle) / sizeof(szTitle[0])) == 0) 00355 _tcscpy(szTitle, _T("System control panel applet")); 00356 00357 if (LoadString(hApplet, 00358 IDS_WARNMAXIMUMSIZE, 00359 szMessage, 00360 sizeof(szMessage) / sizeof(szMessage[0])) == 0) 00361 _tcscpy(szMessage, _T("Enter a numeric value for the maximum size of the paging file.")); 00362 00363 MessageBox(NULL, 00364 szMessage, 00365 szTitle, 00366 MB_ICONWARNING | MB_OK); 00367 return; 00368 } 00369 00370 /* Check the valid range of the inial size */ 00371 if (InitialSize < 2 || 00372 InitialSize > pVirtMem->Pagefile[Index].FreeSize) 00373 { 00374 if (LoadString(hApplet, 00375 IDS_MESSAGEBOXTITLE, 00376 szTitle, 00377 sizeof(szTitle) / sizeof(szTitle[0])) == 0) 00378 _tcscpy(szTitle, _T("System control panel applet")); 00379 00380 LoadString(hApplet, 00381 IDS_WARNINITIALRANGE, 00382 szMessage, 00383 sizeof(szMessage) / sizeof(szMessage[0])); 00384 00385 MessageBox(NULL, 00386 szMessage, 00387 szTitle, 00388 MB_ICONWARNING | MB_OK); 00389 return; 00390 } 00391 00392 /* Check the valid range of the maximum size */ 00393 if (MaximumSize < InitialSize || 00394 MaximumSize > pVirtMem->Pagefile[Index].FreeSize) 00395 { 00396 if (LoadString(hApplet, 00397 IDS_MESSAGEBOXTITLE, 00398 szTitle, 00399 sizeof(szTitle) / sizeof(szTitle[0])) == 0) 00400 _tcscpy(szTitle, _T("System control panel applet")); 00401 00402 LoadString(hApplet, 00403 IDS_WARNMAXIMUMRANGE, 00404 szMessage, 00405 sizeof(szMessage) / sizeof(szMessage[0])); 00406 00407 MessageBox(NULL, 00408 szMessage, 00409 szTitle, 00410 MB_ICONWARNING | MB_OK); 00411 return; 00412 } 00413 00414 pVirtMem->Pagefile[Index].InitialSize = InitialSize; 00415 pVirtMem->Pagefile[Index].MaximumSize = MaximumSize; 00416 pVirtMem->Pagefile[Index].bUsed = TRUE; 00417 } 00418 else 00419 { 00420 /* Set sizes to 0 */ 00421 pVirtMem->Pagefile[Index].InitialSize = 0; 00422 pVirtMem->Pagefile[Index].MaximumSize = 0; 00423 00424 // Check to see if this drive is used for a paging file 00425 if (IsDlgButtonChecked(pVirtMem->hSelf, 00426 IDC_NOPAGEFILE) == BST_UNCHECKED) 00427 { 00428 pVirtMem->Pagefile[Index].bUsed = TRUE; 00429 } 00430 else 00431 { 00432 pVirtMem->Pagefile[Index].bUsed = FALSE; 00433 } 00434 } 00435 } 00436 } 00437 00438 00439 static BOOL 00440 OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem) 00441 { 00442 TCHAR szBuffer[64]; 00443 MEMORYSTATUSEX MemoryStatus; 00444 ULARGE_INTEGER FreeDiskSpace; 00445 UINT i, FreeMemMb, PageFileSizeMb; 00446 INT Index; 00447 00448 Index = (INT)SendDlgItemMessage(hwndDlg, 00449 IDC_PAGEFILELIST, 00450 LB_GETCURSEL, 00451 0, 00452 0); 00453 if (Index >= 0 && Index < pVirtMem->Count) 00454 { 00455 /* Set drive letter */ 00456 SetDlgItemText(hwndDlg, IDC_DRIVE, 00457 pVirtMem->Pagefile[Index].szDrive); 00458 00459 /* Set available disk space */ 00460 if (GetDiskFreeSpaceEx(pVirtMem->Pagefile[Index].szDrive, 00461 NULL, NULL, &FreeDiskSpace)) 00462 { 00463 pVirtMem->Pagefile[Index].FreeSize = (UINT)(FreeDiskSpace.QuadPart / (1024 * 1024)); 00464 _stprintf(szBuffer, _T("%u MB"), pVirtMem->Pagefile[Index].FreeSize); 00465 SetDlgItemText(hwndDlg, IDC_SPACEAVAIL, szBuffer); 00466 } 00467 00468 if (pVirtMem->Pagefile[Index].InitialSize != 0 && 00469 pVirtMem->Pagefile[Index].MaximumSize != 0) 00470 { 00471 /* Enable and fill the custom values */ 00472 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); 00473 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); 00474 00475 SetDlgItemInt(pVirtMem->hSelf, 00476 IDC_INITIALSIZE, 00477 pVirtMem->Pagefile[Index].InitialSize, 00478 FALSE); 00479 00480 SetDlgItemInt(pVirtMem->hSelf, 00481 IDC_MAXSIZE, 00482 pVirtMem->Pagefile[Index].MaximumSize, 00483 FALSE); 00484 00485 CheckDlgButton(pVirtMem->hSelf, 00486 IDC_CUSTOM, 00487 BST_CHECKED); 00488 } 00489 else 00490 { 00491 /* It's not a custom value */ 00492 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); 00493 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); 00494 00495 /* Is it system managed */ 00496 if (pVirtMem->Pagefile[Index].bUsed) 00497 { 00498 CheckDlgButton(pVirtMem->hSelf, 00499 IDC_SYSMANSIZE, 00500 BST_CHECKED); 00501 } 00502 else 00503 { 00504 CheckDlgButton(pVirtMem->hSelf, 00505 IDC_NOPAGEFILE, 00506 BST_CHECKED); 00507 } 00508 } 00509 00510 /* Set minimum pagefile size */ 00511 SetDlgItemText(hwndDlg, IDC_MINIMUM, _T("2 MB")); 00512 00513 /* Set recommended pagefile size */ 00514 MemoryStatus.dwLength = sizeof(MEMORYSTATUSEX); 00515 if (GlobalMemoryStatusEx(&MemoryStatus)) 00516 { 00517 FreeMemMb = (UINT)(MemoryStatus.ullTotalPhys / (1024 * 1024)); 00518 _stprintf(szBuffer, _T("%u MB"), FreeMemMb + (FreeMemMb / 2)); 00519 SetDlgItemText(hwndDlg, IDC_RECOMMENDED, szBuffer); 00520 } 00521 00522 /* Set current pagefile size */ 00523 PageFileSizeMb = 0; 00524 for (i = 0; i < 26; i++) 00525 { 00526 PageFileSizeMb += pVirtMem->Pagefile[i].InitialSize; 00527 } 00528 _stprintf(szBuffer, _T("%u MB"), PageFileSizeMb); 00529 SetDlgItemText(hwndDlg, IDC_CURRENT, szBuffer); 00530 } 00531 00532 return TRUE; 00533 } 00534 00535 00536 static VOID 00537 OnOk(PVIRTMEM pVirtMem) 00538 { 00539 if (pVirtMem->bSave == TRUE) 00540 { 00541 WritePageFileSettings(pVirtMem); 00542 } 00543 } 00544 00545 00546 static VOID 00547 OnInitDialog(HWND hwnd, PVIRTMEM pVirtMem) 00548 { 00549 pVirtMem->hSelf = hwnd; 00550 pVirtMem->hListBox = GetDlgItem(hwnd, IDC_PAGEFILELIST); 00551 pVirtMem->bSave = FALSE; 00552 00553 SetListBoxColumns(pVirtMem->hListBox); 00554 00555 /* Load the pagefile systems from the reg */ 00556 if (ReadPageFileSettings(pVirtMem)) 00557 { 00558 /* Parse our settings and set up dialog */ 00559 ParseMemSettings(pVirtMem); 00560 } 00561 } 00562 00563 00564 INT_PTR CALLBACK 00565 VirtMemDlgProc(HWND hwndDlg, 00566 UINT uMsg, 00567 WPARAM wParam, 00568 LPARAM lParam) 00569 { 00570 PVIRTMEM pVirtMem; 00571 00572 UNREFERENCED_PARAMETER(lParam); 00573 00574 pVirtMem = (PVIRTMEM)GetWindowLongPtr(hwndDlg, DWLP_USER); 00575 00576 switch (uMsg) 00577 { 00578 case WM_INITDIALOG: 00579 pVirtMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VIRTMEM)); 00580 if (pVirtMem == NULL) 00581 { 00582 EndDialog(hwndDlg, 0); 00583 return FALSE; 00584 } 00585 00586 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pVirtMem); 00587 00588 OnInitDialog(hwndDlg, pVirtMem); 00589 break; 00590 00591 case WM_DESTROY: 00592 if (pVirtMem->szPagingFiles) 00593 HeapFree(GetProcessHeap(), 0, 00594 pVirtMem->szPagingFiles); 00595 HeapFree(GetProcessHeap(), 0, pVirtMem); 00596 break; 00597 00598 case WM_COMMAND: 00599 switch (LOWORD(wParam)) 00600 { 00601 case IDCANCEL: 00602 EndDialog(hwndDlg, 0); 00603 return TRUE; 00604 00605 case IDOK: 00606 OnOk(pVirtMem); 00607 EndDialog(hwndDlg, 0); 00608 return TRUE; 00609 00610 case IDC_NOPAGEFILE: 00611 OnNoPagingFile(pVirtMem); 00612 return TRUE; 00613 00614 case IDC_SYSMANSIZE: 00615 OnSysManSize(pVirtMem); 00616 return TRUE; 00617 00618 case IDC_CUSTOM: 00619 OnCustom(pVirtMem); 00620 return TRUE; 00621 00622 case IDC_SET: 00623 OnSet(pVirtMem); 00624 return TRUE; 00625 00626 case IDC_PAGEFILELIST: 00627 switch HIWORD(wParam) 00628 { 00629 case LBN_SELCHANGE: 00630 OnSelChange(hwndDlg, pVirtMem); 00631 return TRUE; 00632 } 00633 break; 00634 } 00635 break; 00636 } 00637 00638 return FALSE; 00639 } Generated on Sat May 26 2012 04:19:46 for ReactOS by
1.7.6.1
|