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