xref: /reactos/dll/cpl/sysdm/virtmem.c (revision 032b5aac)
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];
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         /* Set drive letter */
524         SetDlgItemText(hwndDlg, IDC_DRIVE,
525                        pVirtMem->Pagefile[Index].szDrive);
526 
527         /* Set available disk space */
528         if (GetDiskFreeSpaceEx(pVirtMem->Pagefile[Index].szDrive,
529                                NULL, NULL, &FreeDiskSpace))
530         {
531             pVirtMem->Pagefile[Index].FreeSize = (UINT)(FreeDiskSpace.QuadPart / (1024 * 1024));
532             _stprintf(szBuffer, _T("%u MB"), pVirtMem->Pagefile[Index].FreeSize);
533             SetDlgItemText(hwndDlg, IDC_SPACEAVAIL, szBuffer);
534         }
535 
536         if (pVirtMem->Pagefile[Index].NewMinSize == -1 &&
537             pVirtMem->Pagefile[Index].NewMaxSize == -1)
538         {
539             /* No pagefile */
540 
541             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
542             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
543 
544             CheckDlgButton(pVirtMem->hSelf, IDC_NOPAGEFILE, BST_CHECKED);
545         }
546         else if (pVirtMem->Pagefile[Index].NewMinSize == 0 &&
547                  pVirtMem->Pagefile[Index].NewMaxSize == 0)
548         {
549             /* System managed size*/
550 
551             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE);
552             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE);
553 
554             CheckDlgButton(pVirtMem->hSelf, IDC_SYSMANSIZE, BST_CHECKED);
555         }
556         else
557         {
558             /* Custom size */
559 
560             /* Enable and fill the custom values */
561             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE);
562             EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE);
563 
564             SetDlgItemInt(pVirtMem->hSelf,
565                           IDC_INITIALSIZE,
566                           pVirtMem->Pagefile[Index].NewMinSize,
567                           FALSE);
568 
569             SetDlgItemInt(pVirtMem->hSelf,
570                           IDC_MAXSIZE,
571                           pVirtMem->Pagefile[Index].NewMaxSize,
572                           FALSE);
573 
574             CheckDlgButton(pVirtMem->hSelf,
575                            IDC_CUSTOM,
576                            BST_CHECKED);
577         }
578 
579         /* Set minimum pagefile size */
580         SetDlgItemText(hwndDlg, IDC_MINIMUM, _T("2 MB"));
581 
582         /* Set recommended pagefile size */
583         MemoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
584         if (GlobalMemoryStatusEx(&MemoryStatus))
585         {
586             FreeMemMb = (UINT)(MemoryStatus.ullTotalPhys / (1024 * 1024));
587             RecoMemMb = FreeMemMb + (FreeMemMb / 2); /* The recommended VM size is 150% of free memory. */
588             if (RecoMemMb > 4096)
589                 RecoMemMb = 4096;
590             _stprintf(szBuffer, _T("%u MB"), RecoMemMb);
591             SetDlgItemText(hwndDlg, IDC_RECOMMENDED, szBuffer);
592         }
593 
594         /* Set current pagefile size */
595         PageFileSizeMb = 0;
596 
597         for (i = 0; i < pVirtMem->Count; i++)
598         {
599             _stprintf(szText,
600                       _T("%c:\\pagefile.sys"),
601                       pVirtMem->Pagefile[i].szDrive[0]);
602 
603             hFind = FindFirstFileW(szText, &fdata);
604             if (hFind == INVALID_HANDLE_VALUE)
605             {
606                 DPRINT1("Unable to read PageFile size : %ls due to error %d\n", szText,GetLastError());
607             }
608             else
609             {
610                 pfSize.LowPart = fdata.nFileSizeLow;
611                 pfSize.HighPart = fdata.nFileSizeHigh;
612                 PageFileSizeMb += pfSize.QuadPart / (1024*1024);
613                 FindClose(hFind);
614             }
615         }
616 
617         _stprintf(szBuffer, _T("%u MB"), PageFileSizeMb);
618         SetDlgItemText(hwndDlg, IDC_CURRENT, szBuffer);
619     }
620 
621     return TRUE;
622 }
623 
624 
625 static VOID
626 OnVirtMemDialogOk(PVIRTMEM pVirtMem)
627 {
628     if (pVirtMem->bModified != FALSE)
629     {
630         ResourceMessageBox(hApplet,
631                            NULL,
632                            MB_ICONINFORMATION | MB_OK,
633                            IDS_MESSAGEBOXTITLE,
634                            IDS_INFOREBOOT);
635 
636         WritePageFileSettings(pVirtMem);
637     }
638 }
639 
640 
641 static VOID
642 OnInitVirtMemDialog(HWND hwnd, PVIRTMEM pVirtMem)
643 {
644     INT i;
645 
646     pVirtMem->hSelf = hwnd;
647     pVirtMem->hListBox = GetDlgItem(hwnd, IDC_PAGEFILELIST);
648     pVirtMem->bModified = FALSE;
649 
650     SetListBoxColumns(pVirtMem->hListBox);
651 
652     for (i = 0; i < 26; i++)
653     {
654         pVirtMem->Pagefile[i].bUsed = FALSE;
655         pVirtMem->Pagefile[i].OldMinSize = -1;
656         pVirtMem->Pagefile[i].OldMaxSize = -1;
657         pVirtMem->Pagefile[i].NewMinSize = -1;
658         pVirtMem->Pagefile[i].NewMaxSize = -1;
659     }
660 
661     /* Load the pagefile systems from the reg */
662     ReadPageFileSettings(pVirtMem);
663 
664     /* Parse our settings and set up dialog */
665     ParseMemSettings(pVirtMem);
666 
667     InitPagefileList(pVirtMem);
668 }
669 
670 
671 static VOID
672 OnDestroy(PVIRTMEM pVirtMem)
673 {
674     INT i;
675 
676     for (i = 0; i < 26; i++)
677     {
678         if (pVirtMem->Pagefile[i].pszVolume != NULL)
679             HeapFree(GetProcessHeap(), 0, pVirtMem->Pagefile[i].pszVolume);
680     }
681 
682     if (pVirtMem->szPagingFiles)
683         HeapFree(GetProcessHeap(), 0, pVirtMem->szPagingFiles);
684 
685     HeapFree(GetProcessHeap(), 0, pVirtMem);
686 }
687 
688 
689 INT_PTR CALLBACK
690 VirtMemDlgProc(HWND hwndDlg,
691                UINT uMsg,
692                WPARAM wParam,
693                LPARAM lParam)
694 {
695     PVIRTMEM pVirtMem;
696 
697     UNREFERENCED_PARAMETER(lParam);
698 
699     pVirtMem = (PVIRTMEM)GetWindowLongPtr(hwndDlg, DWLP_USER);
700 
701     switch (uMsg)
702     {
703         case WM_INITDIALOG:
704             pVirtMem = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(VIRTMEM));
705             if (pVirtMem == NULL)
706             {
707                 EndDialog(hwndDlg, 0);
708                 return FALSE;
709             }
710 
711             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pVirtMem);
712 
713             OnInitVirtMemDialog(hwndDlg, pVirtMem);
714             break;
715 
716         case WM_DESTROY:
717             OnDestroy(pVirtMem);
718             break;
719 
720         case WM_COMMAND:
721             switch (LOWORD(wParam))
722             {
723                 case IDCANCEL:
724                     EndDialog(hwndDlg, 0);
725                     return TRUE;
726 
727                 case IDOK:
728                     OnVirtMemDialogOk(pVirtMem);
729                     EndDialog(hwndDlg, pVirtMem->bModified);
730                     return TRUE;
731 
732                 case IDC_NOPAGEFILE:
733                     OnNoPagingFile(pVirtMem);
734                     return TRUE;
735 
736                 case IDC_SYSMANSIZE:
737                     OnSysManSize(pVirtMem);
738                     return TRUE;
739 
740                 case IDC_CUSTOM:
741                     OnCustom(pVirtMem);
742                     return TRUE;
743 
744                 case IDC_SET:
745                     OnSet(pVirtMem);
746                     return TRUE;
747 
748                 case IDC_PAGEFILELIST:
749                     switch (HIWORD(wParam))
750                     {
751                         case LBN_SELCHANGE:
752                             OnSelChange(hwndDlg, pVirtMem);
753                             return TRUE;
754                     }
755                     break;
756             }
757             break;
758     }
759 
760     return FALSE;
761 }
762