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