2 * PROJECT: ReactOS system properties, control panel applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/virtual.c
5 * PURPOSE: Virtual memory control dialog
6 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
12 static BOOL
OnSelChange(HWND hwndDlg
, PVIRTMEM pVirtMem
);
13 static LPCTSTR lpKey
= _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
16 ReadPageFileSettings(PVIRTMEM pVirtMem
)
23 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE
,
27 REG_OPTION_NON_VOLATILE
,
31 NULL
) == ERROR_SUCCESS
)
33 if (RegQueryValueEx(hkey
,
38 &dwDataSize
) == ERROR_SUCCESS
)
40 pVirtMem
->szPagingFiles
= (LPTSTR
)HeapAlloc(GetProcessHeap(),
43 if (pVirtMem
->szPagingFiles
!= NULL
)
45 ZeroMemory(pVirtMem
->szPagingFiles
,
47 if (RegQueryValueEx(hkey
,
51 (PBYTE
)pVirtMem
->szPagingFiles
,
52 &dwDataSize
) == ERROR_SUCCESS
)
61 ShowLastWin32Error(pVirtMem
->hSelf
);
71 GetPageFileSizes(LPTSTR lpPageFiles
,
80 while (*lpPageFiles
!= _T('\0'))
82 if (*lpPageFiles
== _T(' '))
89 *lpInitialSize
= (INT
)_ttoi(lpPageFiles
);
94 *lpMaximumSize
= (INT
)_ttoi(lpPageFiles
);
105 ParseMemSettings(PVIRTMEM pVirtMem
)
107 TCHAR szDrives
[1024]; // all drives
108 LPTSTR DrivePtr
= szDrives
;
109 TCHAR szDrive
[3]; // single drive
110 TCHAR szVolume
[MAX_PATH
];
111 TCHAR
*szDisplayString
;
117 DriveLen
= GetLogicalDriveStrings(1023,
120 szDisplayString
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, (MAX_PATH
* 2 + 69) * sizeof(TCHAR
));
121 if (szDisplayString
== NULL
)
124 while (DriveLen
!= 0)
128 Len
= lstrlen(DrivePtr
) + 1;
131 DrivePtr
= _tcsupr(DrivePtr
);
133 /* copy the 'X:' portion */
134 lstrcpyn(szDrive
, DrivePtr
, sizeof(szDrive
) / sizeof(TCHAR
));
136 if (GetDriveType(DrivePtr
) == DRIVE_FIXED
)
138 /* does drive match the one in the registry ? */
139 if (!_tcsncmp(pVirtMem
->szPagingFiles
, szDrive
, 2))
141 /* FIXME: we only check the first available pagefile in the reg */
142 GetPageFileSizes(pVirtMem
->szPagingFiles
,
146 pVirtMem
->Pagefile
[PgCnt
].InitialValue
= InitialSize
;
147 pVirtMem
->Pagefile
[PgCnt
].MaxValue
= MaxSize
;
148 pVirtMem
->Pagefile
[PgCnt
].bUsed
= TRUE
;
149 lstrcpy(pVirtMem
->Pagefile
[PgCnt
].szDrive
, szDrive
);
153 pVirtMem
->Pagefile
[PgCnt
].InitialValue
= 0;
154 pVirtMem
->Pagefile
[PgCnt
].MaxValue
= 0;
155 pVirtMem
->Pagefile
[PgCnt
].bUsed
= FALSE
;
156 lstrcpy(pVirtMem
->Pagefile
[PgCnt
].szDrive
, szDrive
);
159 _tcscpy(szDisplayString
, szDrive
);
160 _tcscat(szDisplayString
, _T("\t"));
162 /* set a volume label if there is one */
163 if (GetVolumeInformation(DrivePtr
,
172 if (szVolume
[0] != _T('\0'))
174 TCHAR szVol
[MAX_PATH
+ 2];
175 _stprintf(szVol
, _T("[%s]"), szVolume
);
176 _tcscat(szDisplayString
, szVol
);
180 if ((InitialSize
!= 0) || (MaxSize
!= 0))
184 _stprintf(szSize
, _T("%i - %i"), InitialSize
, MaxSize
);
185 _tcscat(szDisplayString
, _T("\t"));
186 _tcscat(szDisplayString
, szSize
);
189 SendMessage(pVirtMem
->hListBox
, LB_ADDSTRING
, (WPARAM
)0, (LPARAM
)szDisplayString
);
196 SendMessage(pVirtMem
->hListBox
, LB_SETCURSEL
, (WPARAM
)0, (LPARAM
)0);
197 HeapFree(GetProcessHeap(), 0, szDisplayString
);
198 pVirtMem
->Count
= PgCnt
;
199 OnSelChange(pVirtMem
->hSelf
, pVirtMem
);
204 WritePageFileSettings(PVIRTMEM pVirtMem
)
207 TCHAR szPagingFiles
[2048];
213 for (i
= 0; i
< pVirtMem
->Count
; ++i
)
215 if (pVirtMem
->Pagefile
[i
].bUsed
)
217 _stprintf(szText
, _T("%s\\pagefile.sys %i %i"),
218 pVirtMem
->Pagefile
[i
].szDrive
,
219 pVirtMem
->Pagefile
[i
].InitialValue
,
220 pVirtMem
->Pagefile
[i
].MaxValue
);
222 /* Add it to our overall registry string */
223 lstrcat(szPagingFiles
+ nPos
, szText
);
225 /* Record the position where the next string will start */
226 nPos
+= (INT
)lstrlen(szText
) + 1;
228 /* add another NULL for REG_MULTI_SZ */
229 szPagingFiles
[nPos
] = _T('\0');
234 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE
,
238 REG_OPTION_NON_VOLATILE
,
242 NULL
) == ERROR_SUCCESS
)
244 if (RegSetValueEx(hk
,
248 (LPBYTE
) szPagingFiles
,
249 (DWORD
) nPos
* sizeof(TCHAR
)) == ERROR_SUCCESS
)
258 ShowLastWin32Error(pVirtMem
->hSelf
);
263 SetListBoxColumns(HWND hwndListBox
)
265 const INT tabs
[2] = {30, 120};
267 SendMessage(hwndListBox
, LB_SETTABSTOPS
, (WPARAM
)2, (LPARAM
)&tabs
[0]);
272 OnNoPagingFile(PVIRTMEM pVirtMem
)
274 /* Disable the page file custom size boxes */
275 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), FALSE
);
276 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), FALSE
);
281 OnSysManSize(PVIRTMEM pVirtMem
)
283 /* Disable the page file custom size boxes */
284 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), FALSE
);
285 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), FALSE
);
290 OnCustom(PVIRTMEM pVirtMem
)
292 /* Enable the page file custom size boxes */
293 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), TRUE
);
294 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), TRUE
);
299 OnSet(PVIRTMEM pVirtMem
)
305 pVirtMem
->bSave
= TRUE
;
307 Index
= (INT
)SendDlgItemMessage(pVirtMem
->hSelf
,
312 if (Index
< pVirtMem
->Count
)
314 /* check if custom settings are checked */
315 if (IsDlgButtonChecked(pVirtMem
->hSelf
,
316 IDC_CUSTOM
) == BST_CHECKED
)
318 Value
= GetDlgItemInt(pVirtMem
->hSelf
,
324 /* FIXME: Show error message instead of setting the edit
325 field to the previous value */
326 SetDlgItemInt(pVirtMem
->hSelf
,
328 pVirtMem
->Pagefile
[Index
].InitialValue
,
333 pVirtMem
->Pagefile
[Index
].InitialValue
= Value
;
336 Value
= GetDlgItemInt(pVirtMem
->hSelf
,
342 /* FIXME: Show error message instead of setting the edit
343 field to the previous value */
344 SetDlgItemInt(pVirtMem
->hSelf
,
346 pVirtMem
->Pagefile
[Index
].MaxValue
,
351 pVirtMem
->Pagefile
[Index
].MaxValue
= Value
;
357 pVirtMem
->Pagefile
[Index
].InitialValue
= pVirtMem
->Pagefile
[Index
].MaxValue
= 0;
359 // check to see if this drive is used for a paging file
360 if (IsDlgButtonChecked(pVirtMem
->hSelf
,
361 IDC_NOPAGEFILE
) == BST_UNCHECKED
)
363 pVirtMem
->Pagefile
[Index
].bUsed
= TRUE
;
367 pVirtMem
->Pagefile
[Index
].bUsed
= FALSE
;
375 OnSelChange(HWND hwndDlg
, PVIRTMEM pVirtMem
)
378 MEMORYSTATUSEX MemoryStatus
;
379 ULARGE_INTEGER FreeBytes
;
380 DWORDLONG FreeMemory
;
385 Index
= (INT
)SendDlgItemMessage(hwndDlg
,
390 if (Index
< pVirtMem
->Count
)
392 /* Set drive letter */
393 SetDlgItemText(hwndDlg
, IDC_DRIVE
,
394 pVirtMem
->Pagefile
[Index
].szDrive
);
396 /* Set available disk space */
397 if (GetDiskFreeSpaceEx(pVirtMem
->Pagefile
[Index
].szDrive
,
398 NULL
, NULL
, &FreeBytes
))
400 _stprintf(szBuffer
, _T("%I64u MB"), FreeBytes
.QuadPart
/ (1024 * 1024));
401 SetDlgItemText(hwndDlg
, IDC_SPACEAVAIL
, szBuffer
);
404 if (pVirtMem
->Pagefile
[Index
].InitialValue
!= 0 &&
405 pVirtMem
->Pagefile
[Index
].MaxValue
!= 0)
407 /* enable and fill the custom values */
408 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), TRUE
);
409 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), TRUE
);
411 SetDlgItemInt(pVirtMem
->hSelf
,
413 pVirtMem
->Pagefile
[Index
].InitialValue
,
416 SetDlgItemInt(pVirtMem
->hSelf
,
418 pVirtMem
->Pagefile
[Index
].MaxValue
,
421 CheckDlgButton(pVirtMem
->hSelf
,
427 /* It's not a custom value */
428 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), FALSE
);
429 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), FALSE
);
431 /* is it system managed */
432 if (pVirtMem
->Pagefile
[Index
].bUsed
)
434 CheckDlgButton(pVirtMem
->hSelf
,
440 CheckDlgButton(pVirtMem
->hSelf
,
446 /* Set minimum pagefile size */
447 SetDlgItemText(hwndDlg
, IDC_MINIMUM
, _T("2 MB"));
449 /* Set recommended pagefile size */
450 MemoryStatus
.dwLength
= sizeof(MEMORYSTATUSEX
);
451 if (GlobalMemoryStatusEx(&MemoryStatus
))
453 FreeMemory
= MemoryStatus
.ullTotalPhys
/ (1024 * 1024);
454 _stprintf(szBuffer
, _T("%I64u MB"), FreeMemory
+ (FreeMemory
/ 2));
455 SetDlgItemText(hwndDlg
, IDC_RECOMMENDED
, szBuffer
);
458 /* Set current pagefile size */
460 for (i
= 0; i
< 26; i
++)
462 FileSize
+= pVirtMem
->Pagefile
[i
].InitialValue
;
464 _stprintf(szBuffer
, _T("%u MB"), FileSize
);
465 SetDlgItemText(hwndDlg
, IDC_CURRENT
, szBuffer
);
473 OnOk(PVIRTMEM pVirtMem
)
475 if (pVirtMem
->bSave
== TRUE
)
477 WritePageFileSettings(pVirtMem
);
483 OnInitDialog(HWND hwnd
, PVIRTMEM pVirtMem
)
485 pVirtMem
->hSelf
= hwnd
;
486 pVirtMem
->hListBox
= GetDlgItem(hwnd
, IDC_PAGEFILELIST
);
487 pVirtMem
->bSave
= FALSE
;
489 SetListBoxColumns(pVirtMem
->hListBox
);
491 /* Load the pagefile systems from the reg */
492 if (ReadPageFileSettings(pVirtMem
))
494 /* Parse our settings and set up dialog */
495 ParseMemSettings(pVirtMem
);
501 VirtMemDlgProc(HWND hwndDlg
,
508 UNREFERENCED_PARAMETER(lParam
);
510 pVirtMem
= (PVIRTMEM
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
515 pVirtMem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(VIRTMEM
));
516 if (pVirtMem
== NULL
)
518 EndDialog(hwndDlg
, 0);
522 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pVirtMem
);
524 OnInitDialog(hwndDlg
, pVirtMem
);
528 if (pVirtMem
->szPagingFiles
)
529 HeapFree(GetProcessHeap(), 0,
530 pVirtMem
->szPagingFiles
);
531 HeapFree(GetProcessHeap(), 0, pVirtMem
);
535 switch (LOWORD(wParam
))
538 EndDialog(hwndDlg
, 0);
543 EndDialog(hwndDlg
, 0);
547 OnNoPagingFile(pVirtMem
);
551 OnSysManSize(pVirtMem
);
562 case IDC_PAGEFILELIST
:
563 switch HIWORD(wParam
)
566 OnSelChange(hwndDlg
, pVirtMem
);