From d667517b420bcfdf643d4fe4fb4a95922e918dae Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Thu, 14 Sep 2006 16:49:11 +0000 Subject: [PATCH] start to rewrite the virtmem code to remove many bugs and make it more readable. I'm currently working on enhancements to sysdm, but it's probably better to commit this separately svn path=/trunk/; revision=24115 --- reactos/dll/cpl/sysdm/advanced.c | 6 +- reactos/dll/cpl/sysdm/computer.c | 7 +- reactos/dll/cpl/sysdm/environment.c | 8 +- reactos/dll/cpl/sysdm/general.c | 6 +- reactos/dll/cpl/sysdm/hardware.c | 6 +- reactos/dll/cpl/sysdm/{sysdm.h => precomp.h} | 89 +- reactos/dll/cpl/sysdm/sysdm.c | 8 +- reactos/dll/cpl/sysdm/sysdm.def | 2 +- reactos/dll/cpl/sysdm/userprofile.c | 6 +- reactos/dll/cpl/sysdm/virtmem.c | 1227 ++++++++---------- 10 files changed, 595 insertions(+), 770 deletions(-) rename reactos/dll/cpl/sysdm/{sysdm.h => precomp.h} (59%) diff --git a/reactos/dll/cpl/sysdm/advanced.c b/reactos/dll/cpl/sysdm/advanced.c index 20806dbce12..0ecaaebe93b 100644 --- a/reactos/dll/cpl/sysdm/advanced.c +++ b/reactos/dll/cpl/sysdm/advanced.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/computer.c b/reactos/dll/cpl/sysdm/computer.c index 220810a5333..1e17de5a5b4 100644 --- a/reactos/dll/cpl/sysdm/computer.c +++ b/reactos/dll/cpl/sysdm/computer.c @@ -25,11 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" + +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/environment.c b/reactos/dll/cpl/sysdm/environment.c index fd902c7b0cf..e7ba4a5f0f0 100644 --- a/reactos/dll/cpl/sysdm/environment.c +++ b/reactos/dll/cpl/sysdm/environment.c @@ -24,13 +24,7 @@ * PROGRAMMER: Eric Kohl */ -#include -#include -#include -#include - -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" typedef struct _VARIABLE_DATA diff --git a/reactos/dll/cpl/sysdm/general.c b/reactos/dll/cpl/sysdm/general.c index 686d0702a0a..b0dffe56510 100644 --- a/reactos/dll/cpl/sysdm/general.c +++ b/reactos/dll/cpl/sysdm/general.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" void ShowLastWin32Error(HWND hWndOwner) diff --git a/reactos/dll/cpl/sysdm/hardware.c b/reactos/dll/cpl/sysdm/hardware.c index 349afdc79c6..14a24ad5959 100644 --- a/reactos/dll/cpl/sysdm/hardware.c +++ b/reactos/dll/cpl/sysdm/hardware.c @@ -25,12 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" typedef BOOL (STDCALL *PDEVMGREXEC)(HWND hWndParent, HINSTANCE hInst, PVOID Unknown, int nCmdShow); BOOL LaunchDeviceManager(HWND hWndParent) diff --git a/reactos/dll/cpl/sysdm/sysdm.h b/reactos/dll/cpl/sysdm/precomp.h similarity index 59% rename from reactos/dll/cpl/sysdm/sysdm.h rename to reactos/dll/cpl/sysdm/precomp.h index 1bf21fcc1d4..bb4622063fa 100644 --- a/reactos/dll/cpl/sysdm/sysdm.h +++ b/reactos/dll/cpl/sysdm/precomp.h @@ -1,33 +1,56 @@ -#ifndef __CPL_SYSDM_H -#define __CPL_SYSDM_H - -typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); - -typedef struct -{ - int idIcon; - int idName; - int idDescription; - APPLET_INITPROC AppletProc; -} APPLET, *PAPPLET; - -extern HINSTANCE hApplet; - -void ShowLastWin32Error(HWND hWndOwner); - -INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -INT_PTR CALLBACK UserProfilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* environment.c */ -INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - -/* virtmem.c */ -INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); - - -#endif /* __CPL_SYSDM_H */ - -/* EOF */ +#ifndef __CPL_PRECOMP_H +#define __CPL_PRECOMP_H + +#include +#include +#include +#include +#include +#include "resource.h" + +#define NUM_APPLETS (1) + +typedef LONG (CALLBACK *APPLET_INITPROC)(VOID); + +typedef struct _APPLET +{ + int idIcon; + int idName; + int idDescription; + APPLET_INITPROC AppletProc; +} APPLET, *PAPPLET; + +extern HINSTANCE hApplet; + +void ShowLastWin32Error(HWND hWndOwner); + +INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK ComputerPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK HardwarePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK AdvancedPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK UserProfilePageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +INT_PTR CALLBACK EnvironmentDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); +INT_PTR CALLBACK VirtMemDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); + +typedef struct _PAGEFILE +{ + TCHAR szDrive[3]; + INT InitialValue; + INT MaxValue; + BOOL bUsed; +} PAGEFILE, *PPAGEFILE; + +typedef struct _VIRTMEM +{ + HWND hSelf; + HWND hListView; + LPTSTR szPagingFiles; + TCHAR szDrive[10]; + INT Count; + BOOL bSave; + PAGEFILE Pagefile[26]; +} VIRTMEM, *PVIRTMEM; + + +#endif /* __CPL_SYSDM_H */ diff --git a/reactos/dll/cpl/sysdm/sysdm.c b/reactos/dll/cpl/sysdm/sysdm.c index f17b02fd585..11c4263caf0 100644 --- a/reactos/dll/cpl/sysdm/sysdm.c +++ b/reactos/dll/cpl/sysdm/sysdm.c @@ -25,14 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include -#include -#include -#include "resource.h" -#include "sysdm.h" +#include "precomp.h" #define NUM_APPLETS (1) diff --git a/reactos/dll/cpl/sysdm/sysdm.def b/reactos/dll/cpl/sysdm/sysdm.def index f4110df42fa..1feaf5fb76f 100644 --- a/reactos/dll/cpl/sysdm/sysdm.def +++ b/reactos/dll/cpl/sysdm/sysdm.def @@ -1,6 +1,6 @@ LIBRARY sysdm.cpl EXPORTS -CPlApplet@16 +CPlApplet ; EOF diff --git a/reactos/dll/cpl/sysdm/userprofile.c b/reactos/dll/cpl/sysdm/userprofile.c index 3c2ebe9b36c..91b6d4bedde 100644 --- a/reactos/dll/cpl/sysdm/userprofile.c +++ b/reactos/dll/cpl/sysdm/userprofile.c @@ -25,10 +25,8 @@ * UPDATE HISTORY: * 03-04-2004 Created */ -#include -#include -#include "resource.h" -#include "sysdm.h" + +#include "precomp.h" /* Property page dialog callback */ INT_PTR CALLBACK diff --git a/reactos/dll/cpl/sysdm/virtmem.c b/reactos/dll/cpl/sysdm/virtmem.c index 6fd33a47663..0c1c055b112 100644 --- a/reactos/dll/cpl/sysdm/virtmem.c +++ b/reactos/dll/cpl/sysdm/virtmem.c @@ -1,735 +1,566 @@ /* -* ReactOS -* Copyright (C) 2004 ReactOS Team -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* $Id$ -* -* PROJECT: ReactOS System Control Panel -* FILE: lib/cpl/sysdm/virtmem.c -* PURPOSE: pagefile settings -* PROGRAMMER: Christian Wallukat cwallukat(at)gmx(dot)at -*/ + * PROJECT: ReactOS system properties, control panel applet + * LICENSE: GPL - See COPYING in the top level directory + * FILE: dll/cpl/sysdm/virtual.c + * PURPOSE: Virtual memory control dialog + * COPYRIGHT: Copyright 2006 Ged Murphy + * + */ -#include -#include -#include -#include -#include "resource.h" -#include "sysdm.h" -#include -#include +#include "precomp.h" +static LPCTSTR lpKey = _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"); - -// -// An array of these structs will interally manage system page files -// -typedef struct _sPagefiles +static BOOL +ReadPageFileSettings(PVIRTMEM pVirtMem) { - WCHAR szDrive[10]; - INT nMinValue; - INT nMaxValue; - INT nUsed; -} sPageFiles; + HKEY hkey = NULL; + DWORD dwType; + DWORD dwDataSize; + BOOL bRet = FALSE; + + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, + lpKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_QUERY_VALUE, + NULL, + &hkey, + NULL) == ERROR_SUCCESS) + { + if(RegQueryValueEx(hkey, + _T("PagingFiles"), + NULL, + &dwType, + NULL, + &dwDataSize) == ERROR_SUCCESS) + { + pVirtMem->szPagingFiles = (LPTSTR)HeapAlloc(GetProcessHeap(), + 0, + dwDataSize); + if (pVirtMem->szPagingFiles != NULL) + { + if(RegQueryValueEx(hkey, + _T("PagingFiles"), + NULL, + &dwType, + (PBYTE)pVirtMem->szPagingFiles, + &dwDataSize) == ERROR_SUCCESS) + { + bRet = TRUE; + } + } + + } + } + + if (!bRet) + ShowLastWin32Error(pVirtMem->hSelf); + + if (hkey != NULL) + RegCloseKey(hkey); + + return bRet; +} +static INT +GetPageFileSizes(LPTSTR lpPageFiles) +{ + while (*lpPageFiles != _T('\0')) + { + if (*lpPageFiles == _T(' ')) + { + lpPageFiles++; + return (INT)_ttoi(lpPageFiles); + } -// -// At most there can be 32 drives, so only 32 page files -// -sPageFiles g_sPagefile[32]; -// -// This is the number of drives that could have page files -// -INT g_nCount; -// -// Will save the user set action signal saving to the registry on exit -// -BOOL g_bSave; + lpPageFiles++; + } + + return -1; +} -// -// ReadRegSettings reads the page file settings from the regisrty -// -VOID ReadRegSettings(HWND hwndDlg); -// -// ParseMemSettings takes the regisrty string and create the internal page file array -// -VOID ParseMemSettings(TCHAR *szSettings, HWND hwndDlg); -// -// SaveSettings writes the paging file array to the registry -// -VOID SaveSettings(HWND hwndDlg); +static VOID +ParseMemSettings(PVIRTMEM pVirtMem) +{ + TCHAR szDrives[1024]; // all drives + LPTSTR DrivePtr = szDrives; + TCHAR szDrive[MAX_PATH]; // single drive + TCHAR szVolume[MAX_PATH]; + INT InitialSize = 0; + INT MaxSize = 0; + INT DriveLen; + INT PgCnt = 0; -// -// Callback function for messages for the windows -// -INT_PTR -CALLBACK -VirtMemDlgProc(HWND hwndDlg, - UINT uMsg, + DriveLen = GetLogicalDriveStrings(1023, + szDrives); + + while (DriveLen != 0) + { + LVITEM Item; + INT Len; + + Len = lstrlen(DrivePtr) + 1; + DriveLen -= Len; + + DrivePtr = _tcsupr(DrivePtr); + + /* copy the 'X:' portion */ + lstrcpyn(szDrive, DrivePtr, 3); + + if(GetDriveType(DrivePtr) == DRIVE_FIXED) + { + /* does drive match the one in the registry ? */ + if(!_tcsncmp(pVirtMem->szPagingFiles, szDrive, 2)) + { + /* FIXME: we only check the first available pagefile in the reg */ + InitialSize = GetPageFileSizes(pVirtMem->szPagingFiles); + MaxSize = GetPageFileSizes(pVirtMem->szPagingFiles); + + pVirtMem->Pagefile[PgCnt].InitialValue = InitialSize; + pVirtMem->Pagefile[PgCnt].MaxValue = MaxSize; + pVirtMem->Pagefile[PgCnt].bUsed = TRUE; + lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); + } + else + { + pVirtMem->Pagefile[PgCnt].InitialValue = 0; + pVirtMem->Pagefile[PgCnt].MaxValue = 0; + pVirtMem->Pagefile[PgCnt].bUsed = FALSE; + lstrcpy(pVirtMem->Pagefile[PgCnt].szDrive, szDrive); + } + + /* fill out the listview */ + ZeroMemory(&Item, sizeof(Item)); + Item.mask = LVIF_TEXT; + Item.iItem = ListView_GetItemCount(pVirtMem->hListView); + Item.pszText = szDrive; + Item.iItem = ListView_InsertItem(pVirtMem->hListView, &Item); + + /* set a volume label if there is one */ + if (GetVolumeInformation(DrivePtr, + szVolume, + 255, + NULL, + NULL, + NULL, + NULL, + 0)) + { + if (szVolume != _T('\0')) + { + TCHAR szVol[MAX_PATH + 2]; + + wsprintf(szVol, _T("[%s]"), szVolume); + + Item.iSubItem = 1; + Item.pszText = szVol; + ListView_InsertItem(pVirtMem->hListView, &Item); + } + } + + if ((InitialSize != 0) || (MaxSize != 0)) + { + TCHAR szSize[64]; + + wsprintf(szSize, _T("%i - %i"), InitialSize, MaxSize); + + Item.iSubItem = 2; + Item.pszText = szSize; + ListView_InsertItem(pVirtMem->hListView, &Item); + } + + PgCnt++; + } + + DrivePtr += Len; + } + + pVirtMem->Count = PgCnt; +} + + +static VOID +WritePageFileSettings(PVIRTMEM pVirtMem) +{ + HKEY hk = NULL; + TCHAR szPagingFiles[2048]; + INT i; + INT nPos = 0; + BOOL bErr = TRUE; + + for(i = 0; i < pVirtMem->Count; ++i) + { + if(pVirtMem->Pagefile[i].bUsed) + { + TCHAR szText[256]; + + wsprintf(szText, _T("%s\\pagefile.sys %i %i"), + pVirtMem->Pagefile[i].szDrive, + pVirtMem->Pagefile[i].InitialValue, + pVirtMem->Pagefile[i].MaxValue); + + /* Add it to our overall registry string */ + lstrcat(szPagingFiles + nPos, szText); + + /* Record the position where the next string will start */ + nPos += (INT)lstrlen(szText) + 1; + + /* add another NULL for REG_MULTI_SZ */ + szPagingFiles[nPos] = _T('\0'); + nPos++; + } + } + + if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, + lpKey, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_WRITE, + NULL, + &hk, + NULL) == ERROR_SUCCESS) + { + if (RegSetValueEx(hk, + _T("PagingFiles"), + 0, + REG_MULTI_SZ, + (LPBYTE) szPagingFiles, + (DWORD) nPos * sizeof(TCHAR))) + { + bErr = FALSE; + } + + RegCloseKey(hk); + } + + if (bErr) + ShowLastWin32Error(pVirtMem->hSelf); +} + + +static VOID +SetListViewColumns(HWND hwndListView) +{ + RECT rect; + LV_COLUMN lvc; + + GetClientRect(hwndListView, &rect); + + (void)ListView_SetExtendedListViewStyle(hwndListView, + LVS_EX_FULLROWSELECT); + + ZeroMemory(&lvc, sizeof(lvc)); + lvc.mask = LVCF_SUBITEM | LVCF_WIDTH | LVCF_FMT; + lvc.fmt = LVCFMT_LEFT; + + lvc.cx = (INT)((rect.right - rect.left) * 0.1); + lvc.iSubItem = 0; + (void)ListView_InsertColumn(hwndListView, 0, &lvc); + + lvc.cx = (INT)((rect.right - rect.left) * 0.3); + lvc.iSubItem = 1; + (void)ListView_InsertColumn(hwndListView, 1, &lvc); + + lvc.cx = (INT)((rect.right - rect.left) * 0.6); + lvc.iSubItem = 2; + (void)ListView_InsertColumn(hwndListView, 2, &lvc); +} + + +static VOID +OnNoPagingFile(PVIRTMEM pVirtMem) +{ + /* Disable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); +} + + +static VOID +OnSysManSize(PVIRTMEM pVirtMem) +{ + /* Disable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); +} + + +static VOID +OnCustom(PVIRTMEM pVirtMem) +{ + /* Enable the page file custom size boxes */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); +} + + +static VOID +OnSet(PVIRTMEM pVirtMem) +{ + INT Index; + + pVirtMem->bSave = TRUE; + + Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, + IDC_PAGEFILELIST, + LB_GETCURSEL, + 0, + 0); + + if(Index < pVirtMem->Count) + { + TCHAR szText[255]; + + /* check if custom settings are checked */ + if(SendDlgItemMessage(pVirtMem->hSelf, + IDC_CUSTOM, + BM_GETCHECK, + 0, + 0) == BST_CHECKED) + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_INITIALSIZE, + WM_GETTEXT, + 254, + (LPARAM)szText); + pVirtMem->Pagefile[Index].InitialValue = _ttoi(szText); + + SendDlgItemMessage(pVirtMem->hSelf, + IDC_MAXSIZE, + WM_GETTEXT, + 254, + (LPARAM)szText); + pVirtMem->Pagefile[Index].MaxValue = _ttoi(szText); + } + else + { + /* set sizes to 0 */ + pVirtMem->Pagefile[Index].InitialValue = pVirtMem->Pagefile[Index].MaxValue = 0; + + // check to see if this drive is used for a paging file + if (SendDlgItemMessage(pVirtMem->hSelf, + IDC_NOPAGEFILE, + BM_GETCHECK, + 0, + 0) == BST_UNCHECKED) + { + pVirtMem->Pagefile[Index].bUsed = TRUE; + } + else + { + pVirtMem->Pagefile[Index].bUsed = FALSE; + } + } + } +} + + +static BOOL +OnSelChange(PVIRTMEM pVirtMem, + LPNMLISTVIEW pnmv) +{ + TCHAR szCustVals[255]; + INT Index; + + Index = (INT)SendDlgItemMessage(pVirtMem->hSelf, + IDC_PAGEFILELIST, + LB_GETCURSEL, + 0, + 0); + + if(Index < pVirtMem->Count) + { + + if(pVirtMem->Pagefile[Index].InitialValue != 0 && + pVirtMem->Pagefile[Index].MaxValue != 0) + { + /* enable and fill the custom values */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), TRUE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), TRUE); + + _itot(pVirtMem->Pagefile[Index].InitialValue , szCustVals, 10); + SendDlgItemMessage(pVirtMem->hSelf, + IDC_INITIALSIZE, + WM_SETTEXT, + 0, + (LPARAM)szCustVals); + + _itot(pVirtMem->Pagefile[Index].MaxValue, szCustVals, 10); + SendDlgItemMessage(pVirtMem->hSelf, + IDC_MAXSIZE, + WM_SETTEXT, + 0, + (LPARAM)szCustVals); + + SendDlgItemMessage(pVirtMem->hSelf, + IDC_CUSTOM, + BM_SETCHECK, + 1, + 0); + } + else + { + /* It's not a custom value */ + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_MAXSIZE), FALSE); + EnableWindow(GetDlgItem(pVirtMem->hSelf, IDC_INITIALSIZE), FALSE); + + /* is it system managed */ + if(pVirtMem->Pagefile[Index].bUsed) + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_SYSMANSIZE, + BM_SETCHECK, + 1, + 0); + } + else + { + SendDlgItemMessage(pVirtMem->hSelf, + IDC_NOPAGEFILE, + BM_SETCHECK, + 1, + 0); + } + } + } + + return TRUE; +} + + +static VOID +OnOk(PVIRTMEM pVirtMem) +{ + if(pVirtMem->bSave == TRUE) + { + WritePageFileSettings(pVirtMem); + } + + if (pVirtMem->szPagingFiles) + HeapFree(GetProcessHeap(), + 0, + pVirtMem->szPagingFiles); + + HeapFree(GetProcessHeap(), + 0, + pVirtMem); +} + + +static VOID +OnCancel(PVIRTMEM pVirtMem) +{ + if (pVirtMem->szPagingFiles) + HeapFree(GetProcessHeap(), + 0, + pVirtMem->szPagingFiles); + + HeapFree(GetProcessHeap(), + 0, + pVirtMem); +} + + +static PVIRTMEM +OnInitDialog(HWND hwnd) +{ + PVIRTMEM pVirtMem = (PVIRTMEM)HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(VIRTMEM)); + if (pVirtMem == NULL) + { + EndDialog(hwnd, 0); + } + + pVirtMem->hSelf = hwnd; + pVirtMem->hListView = GetDlgItem(hwnd, IDC_PAGEFILELIST); + pVirtMem->bSave = FALSE; + + SetListViewColumns(pVirtMem->hListView); + + /* Load the pagefile systems from the reg */ + if (ReadPageFileSettings(pVirtMem)) + { + /* Parse our settings and set up dialog */ + ParseMemSettings(pVirtMem); + } + + return pVirtMem; +} + + +INT_PTR CALLBACK +VirtMemDlgProc(HWND hwndDlg, + UINT uMsg, WPARAM wParam, LPARAM lParam) { - SYSTEM_PROCESS_INFORMATION siSysPInfo; - TCHAR szTemp[255]; - INT nIndex = 0; + /* there can only be one instance of this dialog */ + static PVIRTMEM pVirtMem = NULL; - // - // We dont need to look at this part of the message - // UNREFERENCED_PARAMETER(lParam); switch (uMsg) { - case WM_INITDIALOG: - { - // - // We dont save the changes until set is clicked - // - g_bSave = FALSE; - // - // We start with no page files - // - g_nCount = 0; - // - // Clear out the file pagefile - // - g_sPagefile[0].nMaxValue = 0; - g_sPagefile[0].nMinValue = 0; - g_sPagefile[0].nUsed = 0; + case WM_INITDIALOG: + pVirtMem = OnInitDialog(hwndDlg); + break; - // - // Grad the system stats to get some page file into - // - NtQuerySystemInformation(SystemProcessInformation, &siSysPInfo, sizeof(SYSTEM_PROCESS_INFORMATION), NULL); - - // - // Convert the pagefile usage to a string - // - _itow(siSysPInfo.PeakPagefileUsage, szTemp, 10); - - // - // Set pagefle useage to its label - // - SendDlgItemMessage(hwndDlg, IDC_CURRENT, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Load the pagefile systems from the reg - // - ReadRegSettings(hwndDlg); - }; - break; - - case WM_COMMAND: + case WM_COMMAND: { switch (LOWORD(wParam)) { - case IDCANCEL: - { - // - // If the user hits cancel we just close and dont save - // + case IDCANCEL: + OnCancel(pVirtMem); EndDialog(hwndDlg, 0); return TRUE; - }; - break; - - case IDOK: - { - // - // Check to make sure that the user hit set and we will save the settings - // - if(g_bSave == TRUE) - { - SaveSettings(hwndDlg); - }; - - // - // Close out the window - // + case IDOK: + OnOk(pVirtMem); EndDialog(hwndDlg, 0); - }; - break; + return TRUE; + case IDC_NOPAGEFILE: + OnNoPagingFile(pVirtMem); + return TRUE; - case IDC_PAGEFILELIST: - { - switch(HIWORD(wParam)) - { - case LBN_SELCHANGE: - { - // - // Get the currently selected page file from the list box - // - nIndex = (INT)SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_GETCURSEL, (WPARAM)0, (LPARAM)0); + case IDC_SYSMANSIZE: + OnSysManSize(pVirtMem); + return TRUE; - // - // If the index is in our range then process that page file - // - if(nIndex < g_nCount) - { - // - // Convert the minvalue for the page file - // - _itow(g_sPagefile[nIndex].nMinValue, szTemp, 10); + case IDC_CUSTOM: + OnCustom(pVirtMem); + return TRUE; - // - // Set the min value to its textbox - // - SendDlgItemMessage(hwndDlg, IDC_INITIALSIZE, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Convert the max value of the page file to a string - // - _itow(g_sPagefile[nIndex].nMaxValue, szTemp, 10); - - // - // Set the max value to its textbox - // - SendDlgItemMessage(hwndDlg, IDC_MAXSIZE, WM_SETTEXT, (WPARAM)0, (LPARAM)szTemp); - - // - // Figure out what type of page file it is - // - if(g_sPagefile[nIndex].nMinValue == 0 && g_sPagefile[nIndex].nMaxValue == 0) - { - // - // There is either no page file or a system managed page file so we disable custom sizes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - // - // Check to see if that drive is used for paging - // - if(g_sPagefile[nIndex].nUsed == 1) - { - // - // This is a system managed page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - } - else - { - // - // There is no page file on this drive - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - } - } - else - { - // - // THis is a custom sized page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - // - // We need to allow the user to change the sizes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), TRUE); - } - }; - }; - break; - }; - }; - break; - - - case IDC_NOPAGEFILE: - { - // - // Set the pagefile to no page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - - // - // Disable the page file custom size boxes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - }; - break; - - case IDC_SYSMANSIZE: - { - // - // User changed this to a system managed page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - - // - // Disable the page file custom size boxes - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), FALSE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), FALSE); - }; - break; - - case IDC_CUSTOM: - { - // - // User changed this to a cutom sized page file - // - SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_SYSMANSIZE, BM_SETCHECK, (WPARAM)0, (LPARAM)0); - SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_SETCHECK, (WPARAM)1, (LPARAM)0); - - // - // The user should be able to change the size of these files - // - EnableWindow(GetDlgItem(hwndDlg, IDC_MAXSIZE), TRUE); - EnableWindow(GetDlgItem(hwndDlg, IDC_INITIALSIZE), TRUE); - }; - break; - - case IDC_SET: - { - // - // The user hit set, so we are clear to save the settings when we are done - // - g_bSave = TRUE; - - // - // Figure out which pagefile we are saving the settings too - // - nIndex = SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_GETCURSEL, (WPARAM)0, (LPARAM)0); - - // - // Make sure it isnt out of our range - // - if(nIndex < g_nCount) - { - // - // Check to see what the current user input settings are - // - if(SendDlgItemMessage(hwndDlg, IDC_CUSTOM, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) - { - // - // If custom is checked we need to get the min size - // - SendDlgItemMessage(hwndDlg, IDC_INITIALSIZE, WM_GETTEXT, (WPARAM)254, (LPARAM)szTemp); - - // - // Convert the size to an int and save it - // - g_sPagefile[nIndex].nMinValue = _wtoi(szTemp); - - // - // If custom is checked we need to get the max size - // - SendDlgItemMessage(hwndDlg, IDC_MAXSIZE, WM_GETTEXT, (WPARAM)254, (LPARAM)szTemp); - - // - // If custom is checked we need to get the max size - // - g_sPagefile[nIndex].nMaxValue = _wtoi(szTemp); - - } - else - { - // - // If it is no paging file or system then we set the sizes to zero - // - g_sPagefile[nIndex].nMinValue = g_sPagefile[nIndex].nMaxValue = 0; - } - - // - // We check to see if this drive is used for a paging file anymore - // - g_sPagefile[nIndex].nUsed = (SendDlgItemMessage(hwndDlg, IDC_NOPAGEFILE, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_UNCHECKED); - - - // - // FIXME: Rebuild the paging list - // - }; - }; - break; - }; - }; + case IDC_SET: + OnSet(pVirtMem); + return TRUE; + } + } break; - case WM_NOTIFY: + case WM_NOTIFY: { - }; + LPNMHDR pnmhdr = (LPNMHDR)lParam; + + switch (pnmhdr->code) + { + case LVN_ITEMCHANGED: + { + LPNMLISTVIEW pnmv = (LPNMLISTVIEW) lParam; + + OnSelChange(pVirtMem, pnmv); + + } + } + } break; - }; + } return FALSE; -}; - - -VOID -ReadRegSettings(HWND hwndDlg) -{ - HKEY hk = NULL; - DWORD dwType = 0x0; - DWORD dwDataSize = 0x0; - TCHAR szValue[2048]; - - - // - // Open or create this key to read our settings - // - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"), - 0x0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_WRITE | KEY_READ, - NULL, - &hk, - NULL) == ERROR_SUCCESS) - { - - // - // Get the size of the data - // - if(RegQueryValueEx(hk, _T("PagingFiles"), 0, &dwType, (PBYTE)NULL, &dwDataSize) == ERROR_SUCCESS) - { - - // - // Read paging file settings from the regisrty - // - if(RegQueryValueEx(hk, _T("PagingFiles"), 0, &dwType, (PBYTE)(LPTSTR)szValue, &dwDataSize) == ERROR_SUCCESS) - { - // - // Parse our settings and set up controls accordingly - // - ParseMemSettings(szValue, hwndDlg); - } - else - { - // - // We had a problem :( - // - OutputDebugString(_T("Err read pagefile\n")); - }; - } - else - { - // - // We had a problem :( - // - OutputDebugString(_T("Err open reg pagefile\n")); - }; - - // - // Close our key - // - RegCloseKey(hk); - }; -}; - - -VOID -ParseMemSettings(TCHAR *szSettings, HWND hwndDlg) -{ - TCHAR szVolName[256]; - TCHAR szDrive[25]; - TCHAR szDrvLst[256]; - TCHAR szTemp[256]; - TCHAR szList[256]; - INT nLastPos = 0; - INT nMinSize = 0; - INT nMaxSize = 0; - INT nTemp = 0; - BOOL bFound = FALSE; - - g_nCount = 0; - - // - // Clear out all our buffers - // - _wcsnset(szTemp, 0, sizeof(szTemp)); - _wcsnset(szVolName, 0, sizeof(szVolName)); - _wcsnset(szDrive, 0, sizeof(szDrive)); - _wcsnset(szList, 0, sizeof(szList)); - - // - // Get a list of all the drives - // - GetLogicalDriveStrings(255, szDrvLst); - - // - // Print out our drives and our reg string - // - OutputDebugString(szDrvLst); - OutputDebugString((TCHAR*)szSettings); - - // - // Loop through all the drives - // - while(TRUE) - { - // - // Copy over the drive letter - // - wsprintf(szDrive, _T("%s"), szDrvLst + nLastPos); - nLastPos += 4; - - // - // We should fixed and removeable drives, no network / cd - // - if(GetDriveType(szDrive) == DRIVE_FIXED || GetDriveType(szDrive) == DRIVE_REMOVABLE) - { - // - // Get some info about out drive - // - GetVolumeInformation(szDrive, (LPTSTR)szVolName, 255, NULL, NULL, NULL, NULL, 0); - - // - // Cut off the Drive letter : - // - szDrive[2] = 0; - - // - // Clear out our vars to prepare to walk page file setting string - // - nTemp = 0; - bFound = FALSE; - - // - // Walk through the list of page files - // - while(TRUE) - { - // - // Copy over a page file setting for a drive skipping already processed ones - // - wsprintf(szTemp, _T("%s"), szSettings + nTemp); - - - // - // Check to see if the drive for the page file setting matches our current drive - // - if(!_tcsnicmp(szTemp,szDrive,1)) - { - // - // Extract the min/max size from the string - // - nMinSize = (INT)(wcsstr(szTemp + 16, _T(" ")) - (szTemp + 16)) + 1; - nMaxSize = _wtoi(szTemp + 16 + nMinSize); - nMinSize = _wtoi(szTemp + 16); - - // - // Fill in the page file settings in the internal array - // - g_sPagefile[g_nCount].nMaxValue = nMaxSize; - g_sPagefile[g_nCount].nMinValue = nMinSize; - g_sPagefile[g_nCount].nUsed = 1; - wsprintf(g_sPagefile[g_nCount].szDrive, _T("%s"), szDrive); - - // - // Add up one more page file found - // - ++g_nCount; - - // - // Indicate that we found a pagefile for this drive - // - bFound = TRUE; - - break; - }; - - // - // Skip passed the just processed drive setting - // - nTemp += _tcslen(szSettings + nTemp) + 1; - - // - // If we are done looking through the page file settings - // or found a matching setting then break out - // - if((_tcslen(szSettings + nTemp) <= 0) || (bFound == TRUE)) - { - break; - }; - }; - - // - // If we found a page file we make a string for the list box with the size - // - if(bFound == TRUE) - { - wsprintf(szList, _T("%s [%s] %i - %i"), szDrive, szVolName, nMinSize, nMaxSize); - } - else - { - // - // Otherwise we make a blank pagefile element to show no page file - // - g_sPagefile[g_nCount].nMaxValue = 0; - g_sPagefile[g_nCount].nMinValue = 0; - g_sPagefile[g_nCount].nUsed = 0; - - // - // Copy over the drive for the blank page file element - // - wsprintf(g_sPagefile[g_nCount].szDrive, _T("%s"), szDrive); - - // - // Add up one for the blank page file - // - ++g_nCount; - - // - // We just show the name of the drive if there is no page file - // - wsprintf(szList, _T("%s [%s]"), szDrive, szVolName); - }; - - // - // Add our string to the page file list - // - SendDlgItemMessage(hwndDlg, IDC_PAGEFILELIST, LB_ADDSTRING, (WPARAM)NULL, (LPARAM)szList); - - // - // Print out the newly added string - // - OutputDebugString(szList); - }; - - // - // Once all drive have finished being processed then we break out - // - if(_tcslen(szDrvLst + nLastPos) <= 0) - { - return; - }; - }; -}; - - -void SaveSettings(HWND hwndDlg) -{ - HKEY hk = NULL; - TCHAR szValue[2048]; - TCHAR szTemp[512]; - INT nCount = 0; - INT nPos = 0; - - // - // Clear out our buffers - // - _wcsnset(szValue, 0, sizeof(szValue)); - _wcsnset(szTemp, 0, sizeof(szTemp)); - - // - // Go through all our internal pagefile records - // - for(nCount = 0; nCount < g_nCount; ++nCount) - { - // - // We only save it to the regisrty if is used - // - if(g_sPagefile[nCount].nUsed == 1) - { - // - // Clear out our temp buffer - // - _wcsnset(szTemp, 0, sizeof(szTemp)); - // - // Copy the path and sizes to our temp buffer for the page file - // - wsprintf(szTemp, _T("%s\\pagefile.sys %i %i"), g_sPagefile[nCount].szDrive, g_sPagefile[nCount].nMinValue, g_sPagefile[nCount].nMaxValue); - - // - // Add it to our overall regisrty string - // - _tcscat(szValue+nPos,szTemp); - - // - // Record the positioon where the next string will be placed in the buffer - // - nPos += _tcslen(szTemp) + 1; - // Add our null chars in to seperate the page files(REG_MULTI_SZ string) - szValue[nPos - 1] = 0; - szValue[nPos] = 0; - }; - }; - - // - // Now that we have page file setting string we open up the key to save it - // - if(RegCreateKeyEx(HKEY_LOCAL_MACHINE, - _T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory Management"), - 0x0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_ALL_ACCESS, - NULL, - &hk, - NULL) == ERROR_SUCCESS) - { - // - // We save our page file settings to the PagingFiles value - // - if (RegSetValueEx(hk, - _T("PagingFiles"), - 0, - REG_MULTI_SZ, - (LPBYTE) szValue, - (DWORD) (nPos+2)*sizeof(TCHAR))) - { - // - // We had a problem, so print out a message - // - OutputDebugString(_T("Could not save")); - - // - // Get the error for our last operation - // - _ltow(GetLastError(), szValue, 10); - - // - // Print out the error code - // - OutputDebugString(szValue); - - } - - // - // Close up the regisrty - // - RegCloseKey(hk); - } - else - { - // - // Print out an error that we couldnt open(create) the registry key. - // - OutputDebugString(_T("Could not open key")); - }; -}; - - -/* EOF */ +}