xref: /reactos/dll/cpl/sysdm/virtmem.c (revision 9393fc32)
1 /*
2  * PROJECT:     ReactOS system properties, control panel applet
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:        dll/cpl/sysdm/virtmem.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 #define NDEBUG
13 #include <debug.h>
14 
15 static BOOL OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem);
16 static LPCTSTR lpKey = _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
17 
18 static BOOL
19 ReadPageFileSettings(PVIRTMEM pVirtMem)
20 {
21     HKEY hkey = NULL;
22     DWORD dwType;
23     DWORD dwDataSize;
24     BOOL bRet = FALSE;
25 
26     if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
27                        lpKey,
28                        0,
29                        NULL,
30                        REG_OPTION_NON_VOLATILE,
31                        KEY_QUERY_VALUE,
32                        NULL,
33                        &hkey,
34                        NULL) == ERROR_SUCCESS)
35     {
36         if (RegQueryValueEx(hkey,
37                             _T("PagingFiles"),
38                             NULL,
39                             &dwType,
40                             NULL,
41                             &dwDataSize) == ERROR_SUCCESS)
42         {
43             pVirtMem->szPagingFiles = (LPTSTR)HeapAlloc(GetProcessHeap(),
44                                                         0,
45                                                         dwDataSize);
46             if (pVirtMem->szPagingFiles != NULL)
47             {
48                 ZeroMemory(pVirtMem->szPagingFiles,
49                            dwDataSize);
50                 if (RegQueryValueEx(hkey,
51                                     _T("PagingFiles"),
52                                     NULL,
53                                     &dwType,
54                                     (PBYTE)pVirtMem->szPagingFiles,
55                                     &dwDataSize) == ERROR_SUCCESS)
56                 {
57                     bRet = TRUE;
58                 }
59             }
60         }
61     }
62 
63     if (!bRet)
64         ShowLastWin32Error(pVirtMem->hSelf);
65 
66     if (hkey != NULL)
67         RegCloseKey(hkey);
68 
69     return bRet;
70 }
71 
72 
73 static VOID
74 GetPageFileSizes(LPTSTR lpPageFiles,
75                  LPINT lpInitialSize,
76                  LPINT lpMaximumSize)
77 {
78     INT i = 0;
79 
80     *lpInitialSize = -1;
81     *lpMaximumSize = -1;
82 
83     while (*lpPageFiles != _T('\0'))
84     {
85         if (*lpPageFiles == _T(' '))
86         {
87             lpPageFiles++;
88 
89             switch (i)
90             {
91                 case 0:
92                     *lpInitialSize = (INT)_ttoi(lpPageFiles);
93                     i = 1;
94                     break;
95 
96                 case 1:
97                     *lpMaximumSize = (INT)_ttoi(lpPageFiles);
98                     return;
99             }
100         }
101 
102         lpPageFiles++;
103     }
104 }
105 
106 
107 static VOID
108 ParseMemSettings(PVIRTMEM pVirtMem)
109 {
110     TCHAR szDrives[1024];    // All drives
111     LPTSTR DrivePtr = szDrives;
112     TCHAR szDrive[3];        // Single drive
113     TCHAR szVolume[MAX_PATH + 1];
114     INT MinSize;
115     INT MaxSize;
116     INT DriveLen;
117     INT PgCnt = 0;
118     INT Len;
119 
120     DriveLen = GetLogicalDriveStrings(1023,
121                                       szDrives);
122 
123     while (DriveLen != 0)
124     {
125         Len = lstrlen(DrivePtr) + 1;
126         DriveLen -= Len;
127 
128         DrivePtr = _tcsupr(DrivePtr);
129 
130         /* Copy the 'X:' portion */
131         lstrcpyn(szDrive, DrivePtr, sizeof(szDrive) / sizeof(TCHAR));
132 
133         if (GetDriveType(DrivePtr) == DRIVE_FIXED)
134         {
135             MinSize = -1;
136             MaxSize = -1;
137 
138             /* Does drive match the one in the registry ? */
139             if (!_tcsncmp(pVirtMem->szPagingFiles, szDrive, 2))
140             {
141                 GetPageFileSizes(pVirtMem->szPagingFiles,
142                                  &MinSize,
143                                  &MaxSize);
144             }
145 
146             pVirtMem->Pagefile[PgCnt].OldMinSize = MinSize;
147             pVirtMem->Pagefile[PgCnt].OldMaxSize = MaxSize;
148             pVirtMem->Pagefile[PgCnt].NewMinSize = MinSize;
149             pVirtMem->Pagefile[PgCnt].NewMaxSize = MaxSize;
150             pVirtMem->Pagefile[PgCnt].bUsed = TRUE;
151             lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive);
152 
153 
154             /* Get the volume label if there is one */
155             if (GetVolumeInformation(DrivePtr,
156                                      szVolume,
157                                      MAX_PATH + 1,
158                                      NULL,
159                                      NULL,
160                                      NULL,
161                                      NULL,
162                                      0))
163             {
164                 pVirtMem->Pagefile[PgCnt].pszVolume = HeapAlloc(GetProcessHeap(),
165                                                                 0,
166                                                                 (_tcslen(szVolume) + 1) * sizeof(TCHAR));
167                 if (pVirtMem->Pagefile[PgCnt].pszVolume != NULL)
168                     _tcscpy(pVirtMem->Pagefile[PgCnt].pszVolume, szVolume);
169             }
170 
171             PgCnt++;
172         }
173 
174         DrivePtr += Len;
175     }
176 
177     pVirtMem->Count = PgCnt;
178 }
179 
180 
181 static VOID
182 WritePageFileSettings(PVIRTMEM pVirtMem)
183 {
184     HKEY hk = NULL;
185     TCHAR szPagingFiles[2048];
186     TCHAR szText[256];
187     INT i, nPos = 0;
188     BOOL bErr = TRUE;
189 
190     for (i = 0; i < pVirtMem->Count; ++i)
191     {
192         if (pVirtMem->Pagefile[i].bUsed &&
193             pVirtMem->Pagefile[i].NewMinSize != -1 &&
194             pVirtMem->Pagefile[i].NewMaxSize != -1)
195         {
196             _stprintf(szText,
197                       _T("%s\\pagefile.sys %i %i"),
198                       pVirtMem->Pagefile[i].szDrive,
199                       pVirtMem->Pagefile[i].NewMinSize,
200                       pVirtMem->Pagefile[i].NewMaxSize);
201 
202             /* Add it to our overall registry string */
203             lstrcpy(szPagingFiles + nPos, szText);
204 
205             /* Record the position where the next string will start */
206             nPos += (INT)lstrlen(szText) + 1;
207 
208             /* Add another NULL for REG_MULTI_SZ */
209             szPagingFiles[nPos] = _T('\0');
210             nPos++;
211         }
212     }
213 
214     if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
215                        lpKey,
216                        0,
217                        NULL,
218                        REG_OPTION_NON_VOLATILE,
219                        KEY_WRITE,
220                        NULL,
221                        &hk,
222                        NULL) == ERROR_SUCCESS)
223     {
224         if (RegSetValueEx(hk,
225                           _T("PagingFiles"),
226                           0,
227                           REG_MULTI_SZ,
228                           (LPBYTE) szPagingFiles,
229                           (DWORD) nPos * sizeof(TCHAR)) == ERROR_SUCCESS)
230         {
231             bErr = FALSE;
232         }
233 
234         RegCloseKey(hk);
235     }
236 
237     if (bErr == FALSE)
238     {
239         /* Delete obsolete paging files on the next boot */
240         for (i = 0; i < 26; i++)
241         {
242             if (pVirtMem->Pagefile[i].OldMinSize != -1 &&
243                 pVirtMem->Pagefile[i].NewMinSize == -1)
244             {
245                 _stprintf(szText,
246                           _T("%s\\pagefile.sys"),
247                           pVirtMem->Pagefile[i].szDrive);
248 
249                 MoveFileEx(szText, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
250             }
251         }
252     }
253 
254     if (bErr)
255         ShowLastWin32Error(pVirtMem->hSelf);
256 
257 }
258 
259 
260 static VOID
261 SetListBoxColumns(HWND hwndListBox)
262 {
263     RECT rect = {0, 0, 103, 0};
264     MapDialogRect(hwndListBox, &rect);
265 
266     SendMessage(hwndListBox, LB_SETTABSTOPS, (WPARAM)1, (LPARAM)&rect.right);
267 }
268 
269 
270 static VOID
271 OnNoPagingFile(PVIRTMEM pVirtMem)
272 {
273     /* Disable the page file custom size boxes */
274     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
275     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
276 }
277 
278 
279 static VOID
280 OnSysManSize(PVIRTMEM pVirtMem)
281 {
282     /* Disable the page file custom size boxes */
283     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
284     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
285 }
286 
287 
288 static VOID
289 OnCustom(PVIRTMEM pVirtMem)
290 {
291     /* Enable the page file custom size boxes */
292     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE);
293     EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE);
294 }
295 
296 
297 static VOID
298 InitPagefileList(PVIRTMEM pVirtMem)
299 {
300     TCHAR szDisplayString[256];
301     TCHAR szSize[64];
302     INT Index;
303     INT i;
304 
305     for (i = 0; i < 26; i++)
306     {
307         if (pVirtMem->Pagefile[i].bUsed)
308         {
309             if ((pVirtMem->Pagefile[i].NewMinSize == -1) &&
310                 (pVirtMem->Pagefile[i].NewMaxSize == -1))
311             {
312                 LoadString(hApplet,
313                            IDS_PAGEFILE_NONE,
314                            szSize,
315                            sizeof(szSize) / sizeof(szSize[0]));
316             }
317             else if ((pVirtMem->Pagefile[i].NewMinSize == 0) &&
318                      (pVirtMem->Pagefile[i].NewMaxSize == 0))
319             {
320                 LoadString(hApplet,
321                            IDS_PAGEFILE_SYSTEM,
322                            szSize,
323                            sizeof(szSize) / sizeof(szSize[0]));
324             }
325             else
326             {
327                 _stprintf(szSize, _T("%d - %d"),
328                           pVirtMem->Pagefile[i].NewMinSize,
329                           pVirtMem->Pagefile[i].NewMaxSize);
330             }
331 
332             _stprintf(szDisplayString,
333                       _T("%s  [%s]\t%s"),
334                       pVirtMem->Pagefile[i].szDrive,
335                       pVirtMem->Pagefile[i].pszVolume ? pVirtMem->Pagefile[i].pszVolume : _T(""),
336                       szSize);
337 
338             Index = SendMessage(pVirtMem->hListBox, LB_ADDSTRING, (WPARAM)0, (LPARAM)szDisplayString);
339             SendMessage(pVirtMem->hListBox, LB_SETITEMDATA, Index, i);
340         }
341     }
342 
343     SendMessage(pVirtMem->hListBox, LB_SETCURSEL, (WPARAM)0, (LPARAM)0);
344 
345     OnSelChange(pVirtMem->hSelf, pVirtMem);
346 }
347 
348 
349 static VOID
350 UpdatePagefileEntry(PVIRTMEM pVirtMem,
351                     INT ListIndex,
352                     INT DriveIndex)
353 {
354     TCHAR szDisplayString[256];
355     TCHAR szSize[64];
356 
357     if ((pVirtMem->Pagefile[DriveIndex].NewMinSize == -1) &&
358         (pVirtMem->Pagefile[DriveIndex].NewMaxSize == -1))
359     {
360         LoadString(hApplet,
361                    IDS_PAGEFILE_NONE,
362                    szSize,
363                    sizeof(szSize) / sizeof(szSize[0]));
364     }
365     else if ((pVirtMem->Pagefile[DriveIndex].NewMinSize == 0) &&
366              (pVirtMem->Pagefile[DriveIndex].NewMaxSize == 0))
367     {
368         LoadString(hApplet,
369                    IDS_PAGEFILE_SYSTEM,
370                    szSize,
371                    sizeof(szSize) / sizeof(szSize[0]));
372     }
373     else
374     {
375         _stprintf(szSize,
376                   _T("%d - %d"),
377                   pVirtMem->Pagefile[DriveIndex].NewMinSize,
378                   pVirtMem->Pagefile[DriveIndex].NewMaxSize);
379     }
380 
381     _stprintf(szDisplayString,
382               _T("%s  [%s]\t%s"),
383               pVirtMem->Pagefile[DriveIndex].szDrive,
384               pVirtMem->Pagefile[DriveIndex].pszVolume ? pVirtMem->Pagefile[DriveIndex].pszVolume : L"",
385               szSize);
386 
387     SendMessage(pVirtMem->hListBox, LB_DELETESTRING, (WPARAM)ListIndex, 0);
388     SendMessage(pVirtMem->hListBox, LB_INSERTSTRING, (WPARAM)ListIndex, (LPARAM)szDisplayString);
389     SendMessage(pVirtMem->hListBox, LB_SETCURSEL, (WPARAM)ListIndex, 0);
390 }
391 
392 
393 static VOID
394 OnSet(PVIRTMEM pVirtMem)
395 {
396     INT Index;
397     UINT MinSize = -1;
398     UINT MaxSize = -1;
399     BOOL bTranslated;
400     INT DriveIndex = 0;
401 
402     Index  = (INT)SendDlgItemMessage(pVirtMem->hSelf,
403                                      IDC_PAGEFILELIST,
404                                      LB_GETCURSEL,
405                                      0,
406                                      0);
407     if (Index >= 0 && Index < pVirtMem->Count)
408     {
409         DriveIndex = SendDlgItemMessage(pVirtMem->hSelf,
410                                         IDC_PAGEFILELIST,
411                                         LB_GETITEMDATA,
412                                         (WPARAM)Index,
413                                         0);
414 
415         /* Check if custom settings are checked */
416         if (IsDlgButtonChecked(pVirtMem->hSelf,
417                                IDC_CUSTOM) == BST_CHECKED)
418         {
419             MinSize = GetDlgItemInt(pVirtMem->hSelf,
420                                     IDC_INITIALSIZE,
421                                     &bTranslated,
422                                     FALSE);
423             if (!bTranslated)
424             {
425                 ResourceMessageBox(hApplet,
426                                    NULL,
427                                    MB_ICONWARNING | MB_OK,
428                                    IDS_MESSAGEBOXTITLE,
429                                    IDS_WARNINITIALSIZE);
430                 return;
431             }
432 
433             MaxSize = GetDlgItemInt(pVirtMem->hSelf,
434                                     IDC_MAXSIZE,
435                                     &bTranslated,
436                                     FALSE);
437             if (!bTranslated)
438             {
439                 ResourceMessageBox(hApplet,
440                                    NULL,
441                                    MB_ICONWARNING | MB_OK,
442                                    IDS_MESSAGEBOXTITLE,
443                                    IDS_WARNMAXIMUMSIZE);
444                 return;
445             }
446 
447             /* Check the valid range of the minimum size */
448             if (MinSize < 2 ||
449                 MinSize > pVirtMem->Pagefile[DriveIndex].FreeSize ||
450                 MinSize > 4096)
451             {
452                 ResourceMessageBox(hApplet,
453                                    NULL,
454                                    MB_ICONWARNING | MB_OK,
455                                    IDS_MESSAGEBOXTITLE,
456                                    IDS_WARNINITIALRANGE);
457                 return;
458             }
459 
460             /* Check the valid range of the maximum size */
461             if (MaxSize < MinSize ||
462                 MaxSize > pVirtMem->Pagefile[DriveIndex].FreeSize ||
463                 MaxSize > 4096)
464             {
465                 ResourceMessageBox(hApplet,
466                                    NULL,
467                                    MB_ICONWARNING | MB_OK,
468                                    IDS_MESSAGEBOXTITLE,
469                                    IDS_WARNMAXIMUMRANGE);
470                 return;
471             }
472 
473             pVirtMem->Pagefile[DriveIndex].NewMinSize = MinSize;
474             pVirtMem->Pagefile[DriveIndex].NewMaxSize = MaxSize;
475             pVirtMem->Pagefile[DriveIndex].bUsed = TRUE;
476         }
477         else if (IsDlgButtonChecked(pVirtMem->hSelf,
478                                     IDC_NOPAGEFILE) == BST_CHECKED)
479         {
480             /* No pagefile */
481             pVirtMem->Pagefile[DriveIndex].NewMinSize = -1;
482             pVirtMem->Pagefile[DriveIndex].NewMaxSize = -1;
483             pVirtMem->Pagefile[DriveIndex].bUsed = TRUE;
484         }
485         else
486         {
487             /* System managed size*/
488             pVirtMem->Pagefile[DriveIndex].NewMinSize = 0;
489             pVirtMem->Pagefile[DriveIndex].NewMaxSize = 0;
490             pVirtMem->Pagefile[DriveIndex].bUsed = TRUE;
491         }
492 
493         /* Set the modified flag if min or max size has changed */
494         if ((pVirtMem->Pagefile[DriveIndex].OldMinSize != pVirtMem->Pagefile[DriveIndex].NewMinSize) ||
495             (pVirtMem->Pagefile[DriveIndex].OldMaxSize != pVirtMem->Pagefile[DriveIndex].NewMaxSize))
496             pVirtMem->bModified = TRUE;
497 
498         UpdatePagefileEntry(pVirtMem, Index, DriveIndex);
499     }
500 }
501 
502 
503 static BOOL
504 OnSelChange(HWND hwndDlg, PVIRTMEM pVirtMem)
505 {
506     TCHAR szBuffer[64];
507     MEMORYSTATUSEX MemoryStatus;
508     ULARGE_INTEGER FreeDiskSpace;
509     UINT i, FreeMemMb, RecoMemMb, PageFileSizeMb;
510     INT Index;
511     TCHAR szText[MAX_PATH], szMegabytes[8];
512     WIN32_FIND_DATAW fdata = {0};
513     HANDLE hFind;
514     ULARGE_INTEGER pfSize;
515 
516     Index = (INT)SendDlgItemMessage(hwndDlg,
517                                     IDC_PAGEFILELIST,
518                                     LB_GETCURSEL,
519                                     0,
520                                     0);
521     if (Index >= 0 && Index < pVirtMem->Count)
522     {
523         LoadString(hApplet,
524                    IDS_PAGEFILE_MB,
525                    szMegabytes,
526                    ARRAYSIZE(szMegabytes));
527 
528         /* Set drive letter */
529         SetDlgItemText(hwndDlg, IDC_DRIVE,
530                        pVirtMem->Pagefile[Index].szDrive);
531 
532         /* Set available disk space */
533         if (GetDiskFreeSpaceEx(pVirtMem->Pagefile[Index].szDrive,
534                                NULL, NULL, &FreeDiskSpace))
535         {
536             pVirtMem->Pagefile[Index].FreeSize = (UINT)(FreeDiskSpace.QuadPart / (1024 * 1024));
537             _stprintf(szBuffer, szMegabytes, pVirtMem->Pagefile[Index].FreeSize);
538             SetDlgItemText(hwndDlg, IDC_SPACEAVAIL, szBuffer);
539         }
540 
541         if (pVirtMem->Pagefile[Index].NewMinSize == -1 &&
542             pVirtMem->Pagefile[Index].NewMaxSize == -1)
543         {
544             /* No pagefile */
545 
546             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
547             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
548 
549             CheckDlgButton(pVirtMem->hSelf, IDC_NOPAGEFILE, BST_CHECKED);
550         }
551         else if (pVirtMem->Pagefile[Index].NewMinSize == 0 &&
552                  pVirtMem->Pagefile[Index].NewMaxSize == 0)
553         {
554             /* System managed size*/
555 
556             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
557             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
558 
559             CheckDlgButton(pVirtMem->hSelf, IDC_SYSMANSIZE, BST_CHECKED);
560         }
561         else
562         {
563             /* Custom size */
564 
565             /* Enable and fill the custom values */
566             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE);
567             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE);
568 
569             SetDlgItemInt(pVirtMem->hSelf,
570                           IDC_INITIALSIZE,
571                           pVirtMem->Pagefile[Index].NewMinSize,
572                           FALSE);
573 
574             SetDlgItemInt(pVirtMem->hSelf,
575                           IDC_MAXSIZE,
576                           pVirtMem->Pagefile[Index].NewMaxSize,
577                           FALSE);
578 
579             CheckDlgButton(pVirtMem->hSelf,
580                            IDC_CUSTOM,
581                            BST_CHECKED);
582         }
583 
584         /* Set minimum pagefile size (2 MB) */
585         _stprintf(szBuffer, szMegabytes, 2);
586         SetDlgItemText(hwndDlg, IDC_MINIMUM, szBuffer);
587 
588         /* Set recommended pagefile size */
589         MemoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
590         if (GlobalMemoryStatusEx(&MemoryStatus))
591         {
592             FreeMemMb = (UINT)(MemoryStatus.ullTotalPhys / (1024 * 1024));
593             RecoMemMb = FreeMemMb + (FreeMemMb / 2); /* The recommended VM size is 150% of free memory. */
594             if (RecoMemMb > 4096)
595                 RecoMemMb = 4096;
596             _stprintf(szBuffer, szMegabytes, RecoMemMb);
597             SetDlgItemText(hwndDlg, IDC_RECOMMENDED, szBuffer);
598         }
599 
600         /* Set current pagefile size */
601         PageFileSizeMb = 0;
602 
603         for (i = 0; i < pVirtMem->Count; i++)
604         {
605             _stprintf(szText,
606                       _T("%c:\\pagefile.sys"),
607                       pVirtMem->Pagefile[i].szDrive[0]);
608 
609             hFind = FindFirstFileW(szText, &fdata);
610             if (hFind == INVALID_HANDLE_VALUE)
611             {
612                 DPRINT1("Unable to read PageFile size : %ls due to error %d\n", szText,GetLastError());
613             }
614             else
615             {
616                 pfSize.LowPart = fdata.nFileSizeLow;
617                 pfSize.HighPart = fdata.nFileSizeHigh;
618                 PageFileSizeMb += pfSize.QuadPart / (1024*1024);
619                 FindClose(hFind);
620             }
621         }
622 
623         _stprintf(szBuffer, szMegabytes, PageFileSizeMb);
624         SetDlgItemText(hwndDlg, IDC_CURRENT, szBuffer);
625     }
626 
627     return TRUE;
628 }
629 
630 
631 static VOID
632 OnVirtMemDialogOk(PVIRTMEM pVirtMem)
633 {
634     if (pVirtMem->bModified != FALSE)
635     {
636         ResourceMessageBox(hApplet,
637                            NULL,
638                            MB_ICONINFORMATION | MB_OK,
639                            IDS_MESSAGEBOXTITLE,
640                            IDS_INFOREBOOT);
641 
642         WritePageFileSettings(pVirtMem);
643     }
644 }
645 
646 
647 static VOID
648 OnInitVirtMemDialog(HWND hwnd, PVIRTMEM pVirtMem)
649 {
650     INT i;
651 
652     pVirtMem->hSelf = hwnd;
653     pVirtMem->hListBox = GetDlgItem(hwnd, IDC_PAGEFILELIST);
654     pVirtMem->bModified = FALSE;
655 
656     SetListBoxColumns(pVirtMem->hListBox);
657 
658     for (i = 0; i < 26; i++)
659     {
660         pVirtMem->Pagefile[i].bUsed = FALSE;
661         pVirtMem->Pagefile[i].OldMinSize = -1;
662         pVirtMem->Pagefile[i].OldMaxSize = -1;
663         pVirtMem->Pagefile[i].NewMinSize = -1;
664         pVirtMem->Pagefile[i].NewMaxSize = -1;
665     }
666 
667     /* Load the pagefile systems from the reg */
668     ReadPageFileSettings(pVirtMem);
669 
670     /* Parse our settings and set up dialog */
671     ParseMemSettings(pVirtMem);
672 
673     InitPagefileList(pVirtMem);
674 }
675 
676 
677 static VOID
678 OnDestroy(PVIRTMEM pVirtMem)
679 {
680     INT i;
681 
682     for (i = 0; i < 26; i++)
683     {
684         if (pVirtMem->Pagefile[i].pszVolume != NULL)
685             HeapFree(GetProcessHeap(), 0, pVirtMem->Pagefile[i].pszVolume);
686     }
687 
688     if (pVirtMem->szPagingFiles)
689         HeapFree(GetProcessHeap(), 0, pVirtMem->szPagingFiles);
690 
691     HeapFree(GetProcessHeap(), 0, pVirtMem);
692 }
693 
694 
695 INT_PTR CALLBACK
696 VirtMemDlgProc(HWND hwndDlg,
697                UINT uMsg,
698                WPARAM wParam,
699                LPARAM lParam)
700 {
701     PVIRTMEM pVirtMem;
702 
703     UNREFERENCED_PARAMETER(lParam);
704 
705     pVirtMem = (PVIRTMEM)GetWindowLongPtr(hwndDlg, DWLP_USER);
706 
707     switch (uMsg)
708     {
709         case WM_INITDIALOG:
710             pVirtMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VIRTMEM));
711             if (pVirtMem == NULL)
712             {
713                 EndDialog(hwndDlg, 0);
714                 return FALSE;
715             }
716 
717             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pVirtMem);
718 
719             OnInitVirtMemDialog(hwndDlg, pVirtMem);
720             break;
721 
722         case WM_DESTROY:
723             OnDestroy(pVirtMem);
724             break;
725 
726         case WM_COMMAND:
727             switch (LOWORD(wParam))
728             {
729                 case IDCANCEL:
730                     EndDialog(hwndDlg, 0);
731                     return TRUE;
732 
733                 case IDOK:
734                     OnVirtMemDialogOk(pVirtMem);
735                     EndDialog(hwndDlg, pVirtMem->bModified);
736                     return TRUE;
737 
738                 case IDC_NOPAGEFILE:
739                     OnNoPagingFile(pVirtMem);
740                     return TRUE;
741 
742                 case IDC_SYSMANSIZE:
743                     OnSysManSize(pVirtMem);
744                     return TRUE;
745 
746                 case IDC_CUSTOM:
747                     OnCustom(pVirtMem);
748                     return TRUE;
749 
750                 case IDC_SET:
751                     OnSet(pVirtMem);
752                     return TRUE;
753 
754                 case IDC_PAGEFILELIST:
755                     switch (HIWORD(wParam))
756                     {
757                         case LBN_SELCHANGE:
758                             OnSelChange(hwndDlg, pVirtMem);
759                             return TRUE;
760                     }
761                     break;
762             }
763             break;
764     }
765 
766     return FALSE;
767 }
768