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 lstrcpy(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
)
306 TCHAR szMessage
[256];
308 pVirtMem
->bSave
= TRUE
;
310 Index
= (INT
)SendDlgItemMessage(pVirtMem
->hSelf
,
315 if (Index
< pVirtMem
->Count
)
317 /* check if custom settings are checked */
318 if (IsDlgButtonChecked(pVirtMem
->hSelf
,
319 IDC_CUSTOM
) == BST_CHECKED
)
321 InitValue
= GetDlgItemInt(pVirtMem
->hSelf
,
327 if (LoadString(hApplet
,
330 sizeof(szTitle
) / sizeof(szTitle
[0])) == 0)
331 _tcscpy(szTitle
, _T("System control panel applet"));
333 if (LoadString(hApplet
,
336 sizeof(szMessage
) / sizeof(szMessage
[0])) == 0)
337 _tcscpy(szMessage
, _T("Enter a numeric value for the initial size of the paging file."));
342 MB_ICONWARNING
| MB_OK
);
346 MaxValue
= GetDlgItemInt(pVirtMem
->hSelf
,
352 if (LoadString(hApplet
,
355 sizeof(szTitle
) / sizeof(szTitle
[0])) == 0)
356 _tcscpy(szTitle
, _T("System control panel applet"));
358 if (LoadString(hApplet
,
361 sizeof(szMessage
) / sizeof(szMessage
[0])) == 0)
362 _tcscpy(szMessage
, _T("Enter a numeric value for the maximum size of the paging file."));
367 MB_ICONWARNING
| MB_OK
);
371 /* FIXME: Add more file size checks! */
373 pVirtMem
->Pagefile
[Index
].InitialValue
= InitValue
;
374 pVirtMem
->Pagefile
[Index
].MaxValue
= MaxValue
;
375 pVirtMem
->Pagefile
[Index
].bUsed
= TRUE
;
380 pVirtMem
->Pagefile
[Index
].InitialValue
= pVirtMem
->Pagefile
[Index
].MaxValue
= 0;
382 // check to see if this drive is used for a paging file
383 if (IsDlgButtonChecked(pVirtMem
->hSelf
,
384 IDC_NOPAGEFILE
) == BST_UNCHECKED
)
386 pVirtMem
->Pagefile
[Index
].bUsed
= TRUE
;
390 pVirtMem
->Pagefile
[Index
].bUsed
= FALSE
;
398 OnSelChange(HWND hwndDlg
, PVIRTMEM pVirtMem
)
401 MEMORYSTATUSEX MemoryStatus
;
402 ULARGE_INTEGER FreeBytes
;
403 DWORDLONG FreeMemory
;
408 Index
= (INT
)SendDlgItemMessage(hwndDlg
,
413 if (Index
< pVirtMem
->Count
)
415 /* Set drive letter */
416 SetDlgItemText(hwndDlg
, IDC_DRIVE
,
417 pVirtMem
->Pagefile
[Index
].szDrive
);
419 /* Set available disk space */
420 if (GetDiskFreeSpaceEx(pVirtMem
->Pagefile
[Index
].szDrive
,
421 NULL
, NULL
, &FreeBytes
))
423 _stprintf(szBuffer
, _T("%I64u MB"), FreeBytes
.QuadPart
/ (1024 * 1024));
424 SetDlgItemText(hwndDlg
, IDC_SPACEAVAIL
, szBuffer
);
427 if (pVirtMem
->Pagefile
[Index
].InitialValue
!= 0 &&
428 pVirtMem
->Pagefile
[Index
].MaxValue
!= 0)
430 /* enable and fill the custom values */
431 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), TRUE
);
432 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), TRUE
);
434 SetDlgItemInt(pVirtMem
->hSelf
,
436 pVirtMem
->Pagefile
[Index
].InitialValue
,
439 SetDlgItemInt(pVirtMem
->hSelf
,
441 pVirtMem
->Pagefile
[Index
].MaxValue
,
444 CheckDlgButton(pVirtMem
->hSelf
,
450 /* It's not a custom value */
451 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_MAXSIZE
), FALSE
);
452 EnableWindow(GetDlgItem(pVirtMem
->hSelf
, IDC_INITIALSIZE
), FALSE
);
454 /* is it system managed */
455 if (pVirtMem
->Pagefile
[Index
].bUsed
)
457 CheckDlgButton(pVirtMem
->hSelf
,
463 CheckDlgButton(pVirtMem
->hSelf
,
469 /* Set minimum pagefile size */
470 SetDlgItemText(hwndDlg
, IDC_MINIMUM
, _T("2 MB"));
472 /* Set recommended pagefile size */
473 MemoryStatus
.dwLength
= sizeof(MEMORYSTATUSEX
);
474 if (GlobalMemoryStatusEx(&MemoryStatus
))
476 FreeMemory
= MemoryStatus
.ullTotalPhys
/ (1024 * 1024);
477 _stprintf(szBuffer
, _T("%I64u MB"), FreeMemory
+ (FreeMemory
/ 2));
478 SetDlgItemText(hwndDlg
, IDC_RECOMMENDED
, szBuffer
);
481 /* Set current pagefile size */
483 for (i
= 0; i
< 26; i
++)
485 FileSize
+= pVirtMem
->Pagefile
[i
].InitialValue
;
487 _stprintf(szBuffer
, _T("%u MB"), FileSize
);
488 SetDlgItemText(hwndDlg
, IDC_CURRENT
, szBuffer
);
496 OnOk(PVIRTMEM pVirtMem
)
498 if (pVirtMem
->bSave
== TRUE
)
500 WritePageFileSettings(pVirtMem
);
506 OnInitDialog(HWND hwnd
, PVIRTMEM pVirtMem
)
508 pVirtMem
->hSelf
= hwnd
;
509 pVirtMem
->hListBox
= GetDlgItem(hwnd
, IDC_PAGEFILELIST
);
510 pVirtMem
->bSave
= FALSE
;
512 SetListBoxColumns(pVirtMem
->hListBox
);
514 /* Load the pagefile systems from the reg */
515 if (ReadPageFileSettings(pVirtMem
))
517 /* Parse our settings and set up dialog */
518 ParseMemSettings(pVirtMem
);
524 VirtMemDlgProc(HWND hwndDlg
,
531 UNREFERENCED_PARAMETER(lParam
);
533 pVirtMem
= (PVIRTMEM
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
538 pVirtMem
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(VIRTMEM
));
539 if (pVirtMem
== NULL
)
541 EndDialog(hwndDlg
, 0);
545 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pVirtMem
);
547 OnInitDialog(hwndDlg
, pVirtMem
);
551 if (pVirtMem
->szPagingFiles
)
552 HeapFree(GetProcessHeap(), 0,
553 pVirtMem
->szPagingFiles
);
554 HeapFree(GetProcessHeap(), 0, pVirtMem
);
558 switch (LOWORD(wParam
))
561 EndDialog(hwndDlg
, 0);
566 EndDialog(hwndDlg
, 0);
570 OnNoPagingFile(pVirtMem
);
574 OnSysManSize(pVirtMem
);
585 case IDC_PAGEFILELIST
:
586 switch HIWORD(wParam
)
589 OnSelChange(hwndDlg
, pVirtMem
);