Coding style clean-up. No code changes.
[reactos.git] / reactos / dll / cpl / sysdm / virtmem.c
1 /*
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>
7 *
8 */
9
10 #include "precomp.h"
11
12 static BOOL OnSelChange(PVIRTMEM pVirtMem);
13 static LPCTSTR lpKey = _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
14
15 static BOOL
16 ReadPageFileSettings(PVIRTMEM pVirtMem)
17 {
18 HKEY hkey = NULL;
19 DWORD dwType;
20 DWORD dwDataSize;
21 BOOL bRet = FALSE;
22
23 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
24 lpKey,
25 0,
26 NULL,
27 REG_OPTION_NON_VOLATILE,
28 KEY_QUERY_VALUE,
29 NULL,
30 &hkey,
31 NULL) == ERROR_SUCCESS)
32 {
33 if (RegQueryValueEx(hkey,
34 _T("PagingFiles"),
35 NULL,
36 &dwType,
37 NULL,
38 &dwDataSize) == ERROR_SUCCESS)
39 {
40 pVirtMem->szPagingFiles = (LPTSTR)HeapAlloc(GetProcessHeap(),
41 0,
42 dwDataSize);
43 if (pVirtMem->szPagingFiles != NULL)
44 {
45 ZeroMemory(pVirtMem->szPagingFiles,
46 dwDataSize);
47 if (RegQueryValueEx(hkey,
48 _T("PagingFiles"),
49 NULL,
50 &dwType,
51 (PBYTE)pVirtMem->szPagingFiles,
52 &dwDataSize) == ERROR_SUCCESS)
53 {
54 bRet = TRUE;
55 }
56 }
57 }
58 }
59
60 if (!bRet)
61 ShowLastWin32Error(pVirtMem->hSelf);
62
63 if (hkey != NULL)
64 RegCloseKey(hkey);
65
66 return bRet;
67 }
68
69
70 static INT
71 GetPageFileSizes(LPTSTR lpPageFiles)
72 {
73 while (*lpPageFiles != _T('\0'))
74 {
75 if (*lpPageFiles == _T(' '))
76 {
77 lpPageFiles++;
78 return (INT)_ttoi(lpPageFiles);
79 }
80
81 lpPageFiles++;
82 }
83
84 return -1;
85 }
86
87
88 static VOID
89 ParseMemSettings(PVIRTMEM pVirtMem)
90 {
91 TCHAR szDrives[1024]; // all drives
92 LPTSTR DrivePtr = szDrives;
93 TCHAR szDrive[3]; // single drive
94 TCHAR szVolume[MAX_PATH];
95 TCHAR *szDisplayString;
96 INT InitialSize = 0;
97 INT MaxSize = 0;
98 INT DriveLen;
99 INT PgCnt = 0;
100
101 DriveLen = GetLogicalDriveStrings(1023,
102 szDrives);
103
104 szDisplayString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (MAX_PATH * 2 + 69) * sizeof(TCHAR));
105 if (szDisplayString == NULL)
106 return;
107
108 while (DriveLen != 0)
109 {
110 INT Len;
111
112 Len = lstrlen(DrivePtr) + 1;
113 DriveLen -= Len;
114
115 DrivePtr = _tcsupr(DrivePtr);
116
117 /* copy the 'X:' portion */
118 lstrcpyn(szDrive, DrivePtr, sizeof(szDrive) / sizeof(TCHAR));
119
120 if (GetDriveType(DrivePtr) == DRIVE_FIXED)
121 {
122 /* does drive match the one in the registry ? */
123 if (!_tcsncmp(pVirtMem->szPagingFiles, szDrive, 2))
124 {
125 /* FIXME: we only check the first available pagefile in the reg */
126 InitialSize = GetPageFileSizes(pVirtMem->szPagingFiles);
127 MaxSize = GetPageFileSizes(pVirtMem->szPagingFiles);
128
129 pVirtMem->Pagefile[PgCnt].InitialValue = InitialSize;
130 pVirtMem->Pagefile[PgCnt].MaxValue = MaxSize;
131 pVirtMem->Pagefile[PgCnt].bUsed = TRUE;
132 lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive);
133 }
134 else
135 {
136 pVirtMem->Pagefile[PgCnt].InitialValue = 0;
137 pVirtMem->Pagefile[PgCnt].MaxValue = 0;
138 pVirtMem->Pagefile[PgCnt].bUsed = FALSE;
139 lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive);
140 }
141
142 _tcscpy(szDisplayString, szDrive);
143 _tcscat(szDisplayString, _T("\t"));
144
145 /* set a volume label if there is one */
146 if (GetVolumeInformation(DrivePtr,
147 szVolume,
148 255,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 0))
154 {
155 if (szVolume[0] != _T('\0'))
156 {
157 TCHAR szVol[MAX_PATH + 2];
158 _stprintf(szVol, _T("[%s]"), szVolume);
159 _tcscat(szDisplayString, szVol);
160 }
161 }
162
163 if ((InitialSize != 0) || (MaxSize != 0))
164 {
165 TCHAR szSize[64];
166
167 _stprintf(szSize, _T("%i - %i"), InitialSize, MaxSize);
168 _tcscat(szDisplayString, _T("\t"));
169 _tcscat(szDisplayString, szSize);
170 }
171
172 SendMessage(pVirtMem->hListBox, LB_ADDSTRING, (WPARAM)0, (LPARAM)szDisplayString);
173 PgCnt++;
174 }
175
176 DrivePtr += Len;
177 }
178
179 SendMessage(pVirtMem->hListBox, LB_SETCURSEL, (WPARAM)0, (LPARAM)0);
180 HeapFree(GetProcessHeap(), 0, szDisplayString);
181 pVirtMem->Count = PgCnt;
182 OnSelChange(pVirtMem);
183 }
184
185
186 static VOID
187 WritePageFileSettings(PVIRTMEM pVirtMem)
188 {
189 HKEY hk = NULL;
190 TCHAR szPagingFiles[2048];
191 TCHAR szText[256];
192 INT i;
193 INT nPos = 0;
194 BOOL bErr = TRUE;
195
196 for (i = 0; i < pVirtMem->Count; ++i)
197 {
198 if (pVirtMem->Pagefile[i].bUsed)
199 {
200 _stprintf(szText, _T("%s\\pagefile.sys %i %i"),
201 pVirtMem->Pagefile[i].szDrive,
202 pVirtMem->Pagefile[i].InitialValue,
203 pVirtMem->Pagefile[i].MaxValue);
204
205 /* Add it to our overall registry string */
206 lstrcat(szPagingFiles + nPos, szText);
207
208 /* Record the position where the next string will start */
209 nPos += (INT)lstrlen(szText) + 1;
210
211 /* add another NULL for REG_MULTI_SZ */
212 szPagingFiles[nPos] = _T('\0');
213 nPos++;
214 }
215 }
216
217 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
218 lpKey,
219 0,
220 NULL,
221 REG_OPTION_NON_VOLATILE,
222 KEY_WRITE,
223 NULL,
224 &hk,
225 NULL) == ERROR_SUCCESS)
226 {
227 if (RegSetValueEx(hk,
228 _T("PagingFiles"),
229 0,
230 REG_MULTI_SZ,
231 (LPBYTE) szPagingFiles,
232 (DWORD) nPos * sizeof(TCHAR)) == ERROR_SUCCESS)
233 {
234 bErr = FALSE;
235 }
236
237 RegCloseKey(hk);
238 }
239
240 if (bErr)
241 ShowLastWin32Error(pVirtMem->hSelf);
242 }
243
244
245 static VOID
246 SetListBoxColumns(HWND hwndListBox)
247 {
248 const INT tabs[2] = {30, 170};
249
250 SendMessage(hwndListBox, LB_SETTABSTOPS, (WPARAM)2, (LPARAM)&tabs[0]);
251 }
252
253
254 static VOID
255 OnNoPagingFile(PVIRTMEM pVirtMem)
256 {
257 /* Disable the page file custom size boxes */
258 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
259 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
260 }
261
262
263 static VOID
264 OnSysManSize(PVIRTMEM pVirtMem)
265 {
266 /* Disable the page file custom size boxes */
267 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
268 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
269 }
270
271
272 static VOID
273 OnCustom(PVIRTMEM pVirtMem)
274 {
275 /* Enable the page file custom size boxes */
276 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE);
277 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE);
278 }
279
280
281 static VOID
282 OnSet(PVIRTMEM pVirtMem)
283 {
284 INT Index;
285 UINT Value;
286 BOOL bTranslated;
287
288 pVirtMem->bSave = TRUE;
289
290 Index = (INT)SendDlgItemMessage(pVirtMem->hSelf,
291 IDC_PAGEFILELIST,
292 LB_GETCURSEL,
293 0,
294 0);
295 if (Index < pVirtMem->Count)
296 {
297 /* check if custom settings are checked */
298 if (IsDlgButtonChecked(pVirtMem->hSelf,
299 IDC_CUSTOM) == BST_CHECKED)
300 {
301 Value = GetDlgItemInt(pVirtMem->hSelf,
302 IDC_INITIALSIZE,
303 &bTranslated,
304 FALSE);
305 if (!bTranslated)
306 {
307 /* FIXME: Show error message instead of setting the edit
308 field to the previous value */
309 SetDlgItemInt(pVirtMem->hSelf,
310 IDC_INITIALSIZE,
311 pVirtMem->Pagefile[Index].InitialValue,
312 FALSE);
313 }
314 else
315 {
316 pVirtMem->Pagefile[Index].InitialValue = Value;
317 }
318
319 Value = GetDlgItemInt(pVirtMem->hSelf,
320 IDC_MAXSIZE,
321 &bTranslated,
322 FALSE);
323 if (!bTranslated)
324 {
325 /* FIXME: Show error message instead of setting the edit
326 field to the previous value */
327 SetDlgItemInt(pVirtMem->hSelf,
328 IDC_MAXSIZE,
329 pVirtMem->Pagefile[Index].MaxValue,
330 FALSE);
331 }
332 else
333 {
334 pVirtMem->Pagefile[Index].MaxValue = Value;
335 }
336 }
337 else
338 {
339 /* set sizes to 0 */
340 pVirtMem->Pagefile[Index].InitialValue = pVirtMem->Pagefile[Index].MaxValue = 0;
341
342 // check to see if this drive is used for a paging file
343 if (IsDlgButtonChecked(pVirtMem->hSelf,
344 IDC_NOPAGEFILE) == BST_UNCHECKED)
345 {
346 pVirtMem->Pagefile[Index].bUsed = TRUE;
347 }
348 else
349 {
350 pVirtMem->Pagefile[Index].bUsed = FALSE;
351 }
352 }
353 }
354 }
355
356
357 static BOOL
358 OnSelChange(PVIRTMEM pVirtMem)
359 {
360 INT Index;
361
362 Index = (INT)SendDlgItemMessage(pVirtMem->hSelf,
363 IDC_PAGEFILELIST,
364 LB_GETCURSEL,
365 0,
366 0);
367
368 if (Index < pVirtMem->Count)
369 {
370
371 if (pVirtMem->Pagefile[Index].InitialValue != 0 &&
372 pVirtMem->Pagefile[Index].MaxValue != 0)
373 {
374 /* enable and fill the custom values */
375 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE);
376 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE);
377
378 SetDlgItemInt(pVirtMem->hSelf,
379 IDC_INITIALSIZE,
380 pVirtMem->Pagefile[Index].InitialValue,
381 FALSE);
382
383 SetDlgItemInt(pVirtMem->hSelf,
384 IDC_MAXSIZE,
385 pVirtMem->Pagefile[Index].MaxValue,
386 FALSE);
387
388 CheckDlgButton(pVirtMem->hSelf,
389 IDC_CUSTOM,
390 BST_CHECKED);
391 }
392 else
393 {
394 /* It's not a custom value */
395 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
396 EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
397
398 /* is it system managed */
399 if (pVirtMem->Pagefile[Index].bUsed)
400 {
401 CheckDlgButton(pVirtMem->hSelf,
402 IDC_SYSMANSIZE,
403 BST_CHECKED);
404 }
405 else
406 {
407 CheckDlgButton(pVirtMem->hSelf,
408 IDC_NOPAGEFILE,
409 BST_CHECKED);
410 }
411 }
412 }
413
414 return TRUE;
415 }
416
417
418 static VOID
419 OnOk(PVIRTMEM pVirtMem)
420 {
421 if (pVirtMem->bSave == TRUE)
422 {
423 WritePageFileSettings(pVirtMem);
424 }
425
426 if (pVirtMem->szPagingFiles)
427 HeapFree(GetProcessHeap(),
428 0,
429 pVirtMem->szPagingFiles);
430
431 HeapFree(GetProcessHeap(),
432 0,
433 pVirtMem);
434 }
435
436
437 static VOID
438 OnCancel(PVIRTMEM pVirtMem)
439 {
440 if (pVirtMem->szPagingFiles)
441 HeapFree(GetProcessHeap(),
442 0,
443 pVirtMem->szPagingFiles);
444
445 HeapFree(GetProcessHeap(),
446 0,
447 pVirtMem);
448 }
449
450
451 static PVIRTMEM
452 OnInitDialog(HWND hwnd)
453 {
454 PVIRTMEM pVirtMem = (PVIRTMEM)HeapAlloc(GetProcessHeap(),
455 HEAP_ZERO_MEMORY,
456 sizeof(VIRTMEM));
457 if (pVirtMem == NULL)
458 {
459 EndDialog(hwnd, 0);
460 }
461
462 pVirtMem->hSelf = hwnd;
463 pVirtMem->hListBox = GetDlgItem(hwnd, IDC_PAGEFILELIST);
464 pVirtMem->bSave = FALSE;
465
466 SetListBoxColumns(pVirtMem->hListBox);
467
468 /* Load the pagefile systems from the reg */
469 if (ReadPageFileSettings(pVirtMem))
470 {
471 /* Parse our settings and set up dialog */
472 ParseMemSettings(pVirtMem);
473 }
474
475 return pVirtMem;
476 }
477
478
479 INT_PTR CALLBACK
480 VirtMemDlgProc(HWND hwndDlg,
481 UINT uMsg,
482 WPARAM wParam,
483 LPARAM lParam)
484 {
485 /* there can only be one instance of this dialog */
486 static PVIRTMEM pVirtMem = NULL;
487
488 UNREFERENCED_PARAMETER(lParam);
489
490 switch (uMsg)
491 {
492 case WM_INITDIALOG:
493 pVirtMem = OnInitDialog(hwndDlg);
494 break;
495
496 case WM_COMMAND:
497 switch (LOWORD(wParam))
498 {
499 case IDCANCEL:
500 OnCancel(pVirtMem);
501 EndDialog(hwndDlg, 0);
502 return TRUE;
503
504 case IDOK:
505 OnOk(pVirtMem);
506 EndDialog(hwndDlg, 0);
507 return TRUE;
508
509 case IDC_NOPAGEFILE:
510 OnNoPagingFile(pVirtMem);
511 return TRUE;
512
513 case IDC_SYSMANSIZE:
514 OnSysManSize(pVirtMem);
515 return TRUE;
516
517 case IDC_CUSTOM:
518 OnCustom(pVirtMem);
519 return TRUE;
520
521 case IDC_SET:
522 OnSet(pVirtMem);
523 return TRUE;
524
525 case IDC_PAGEFILELIST:
526 switch HIWORD(wParam)
527 {
528 case LBN_SELCHANGE:
529 OnSelChange(pVirtMem);
530 return TRUE;
531 }
532 break;
533 }
534 break;
535 }
536
537 return FALSE;
538 }