Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1691 lines
53 KiB

// Copyright (c) 1997-1999 Microsoft Corporation
#include "precomp.h"
#ifdef EXT_DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// Application specific
#include "sysdm.h"
#include "VirtualMemDlg.h"
#include "..\common\util.h"
#include <windowsx.h>
#include "helpid.h"
#include "shlwapi.h"
#include "common.h"
#define RET_ERROR (-1)
#define RET_NO_CHANGE 0x00
#define RET_VIRTUAL_CHANGE 0x01
#define RET_RECOVER_CHANGE 0x02
#define RET_CHANGE_NO_REBOOT 0x04
#define RET_CONTINUE 0x08
#define RET_BREAK 0x10
#define RET_VIRT_AND_RECOVER (RET_VIRTUAL_CHANGE | RET_RECOVER_CHANGE)
//==========================================================================
// Local Definitions
//==========================================================================
#define MAX_SIZE_LEN 8 // Max chars in the Swap File Size edit.
#define MAX_DRIVES 26 // Max number of drives.
#define MIN_SWAPSIZE 2 // Min swap file size (see note below).
#define MIN_FREESPACE 5 // Must have 5 meg free after swap file
#define MIN_SUGGEST 22 // Always suggest at least 22 meg
#define ONE_MEG 1048576
//New consts for Win Server 2003
#define MAX_SWAPSIZE_X86 (4 * 1024) // 4 Gb (number stored in megabytes)
#define MAX_SWAPSIZE_X86_PAE (16 * 1024 * 1024) // 16 Tb
#define MAX_SWAPSIZE_IA64 (32 * 1024 * 1024) // 32 Tb
#define MAX_SWAPSIZE_AMD64 (16 * 1024 * 1024) // 16 Tb
#define MIN_FREESPACE_STR _T("5") // equal their manifests.
#define TABSTOP_VOL 22
#define TABSTOP_SIZE 122
TCHAR gszPageFileSettings[] = _T("Win32_PageFileSetting");
TCHAR gszPageFileUsage[] = _T("Win32_PageFileUsage");
TCHAR gszLogicalFile[] = _T("CIM_LogicalFile");
TCHAR gszAllocatedBaseSize[] = _T("AllocatedBaseSize");
TCHAR gszFileSize[] = _T("FileSize");
TCHAR gszInitialSize[] = _T("InitialSize");
TCHAR gszMaximumSize[] = _T("MaximumSize");
TCHAR gszName[] = _T("Name");
TCHAR gszPFNameFormat[] = _T("%s\\\\pagefile.sys");
// My privilege 'handle' structure
typedef struct
{
HANDLE hTok;
TOKEN_PRIVILEGES tp;
} PRIVDAT, *PPRIVDAT;
DWORD aVirtualMemHelpIds[] = {
IDD_VM_VOLUMES, -1,
IDD_VM_DRIVE_HDR, (IDH_DLG_VIRTUALMEM + 0),
IDD_VM_PF_SIZE_LABEL, (IDH_DLG_VIRTUALMEM + 1),
IDD_VM_DRIVE_LABEL, (IDH_DLG_VIRTUALMEM + 2),
IDD_VM_SF_DRIVE, (IDH_DLG_VIRTUALMEM + 2),
IDD_VM_SPACE_LABEL, (IDH_DLG_VIRTUALMEM + 3),
IDD_VM_SF_SPACE, (IDH_DLG_VIRTUALMEM + 3),
IDD_VM_ST_INITSIZE, (IDH_DLG_VIRTUALMEM + 4),
IDD_VM_SF_SIZE, (IDH_DLG_VIRTUALMEM + 4),
IDD_VM_ST_MAXSIZE, (IDH_DLG_VIRTUALMEM + 5),
IDD_VM_SF_SIZEMAX, (IDH_DLG_VIRTUALMEM + 5),
IDD_VM_SF_SET, (IDH_DLG_VIRTUALMEM + 6),
IDD_VM_MIN_LABEL, (IDH_DLG_VIRTUALMEM + 7),
IDD_VM_MIN, (IDH_DLG_VIRTUALMEM + 7),
IDD_VM_RECOMMEND_LABEL, (IDH_DLG_VIRTUALMEM + 8),
IDD_VM_RECOMMEND, (IDH_DLG_VIRTUALMEM + 8),
IDD_VM_ALLOCD_LABEL, (IDH_DLG_VIRTUALMEM + 9),
IDD_VM_ALLOCD, (IDH_DLG_VIRTUALMEM + 9),
IDD_VM_CUSTOMSIZE_RADIO,(IDH_DLG_VIRTUALMEM + 12), //IDH_PERFOPT_ADVTAB_VIRTUALMEM_CUSTOM in sysdm.h
IDD_VM_RAMBASED_RADIO, (IDH_DLG_VIRTUALMEM + 13), //IDH_PERFOPT_ADVTAB_VIRTUALMEM_SYSMANAGED in sysdm.h
IDD_VM_NOPAGING_RADIO, (IDH_DLG_VIRTUALMEM + 14), //IDH_PERFOPT_ADVTAB_VIRTUALMEM_NOFILE in sysdm.h
0,0
};
//==========================================================================
// Typedefs and Structs
//==========================================================================
// registry info for a page file (but not yet formatted).
//Note: since this structure gets passed to FormatMessage, all fields must
//be 4 bytes wide.
typedef struct
{
LPTSTR pszName;
DWORD nMin;
DWORD nMax;
DWORD chNull;
} PAGEFILDESC;
//==========================================================================
// Global Data Declarations
//==========================================================================
//TCHAR m_szSysHelp[] = TEXT("sysdm.hlp");
//TCHAR g_szSysDir[ MAX_PATH ];
//UINT g_wHelpMessage;
//==========================================================================
// Local Data Declarations
//==========================================================================
// Other VM Vars
BOOL gfCoreDumpChanged;
DWORD cmTotalVM;
//==========================================================================
// Local Function Prototypes
//==========================================================================
HRESULT QueryInstanceProperties(
const TCHAR * pszClass,
const TCHAR * pszRequestedProperties,
const TCHAR * pszKeyPropertyName,
const TCHAR * pszKeyPropertyValue,
CWbemServices &Services,
IWbemClassObject ** ppcoInst);
//--------------------------------------------------------------
INT_PTR CALLBACK StaticVirtDlgProc(HWND hwndDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
// if this is the initDlg msg...
if(message == WM_INITDIALOG)
{
// transfer the 'this' ptr to the extraBytes.
SetWindowLongPtr(hwndDlg, DWLP_USER, lParam);
}
// DWL_USER is the 'this' ptr.
VirtualMemDlg *me = (VirtualMemDlg *)GetWindowLongPtr(hwndDlg, DWLP_USER);
if(me != NULL)
{
// call into the DlgProc() that has some context.
return me->DlgProc(hwndDlg, message, wParam, lParam);
}
else
{
return FALSE;
}
}
//--------------------------------------------------------------
VirtualMemDlg::VirtualMemDlg(WbemServiceThread *serviceThread)
: WBEMPageHelper(serviceThread)
{
IWbemClassObject *pInst = NULL;
// this is initialized properly in Init()
m_VMWriteAccess = FALSE;
m_pgEnumSettings = NULL;
m_pgEnumUsage = NULL;
m_cxLBExtent = 0;
if((pInst = FirstInstanceOf("Win32_LogicalMemoryConfiguration")) != NULL)
{
m_memory = pInst;
}
if((pInst = FirstInstanceOf("Win32_Registry")) != NULL)
{
m_registry = pInst;
}
if((pInst = FirstInstanceOf("Win32_OSRecoveryConfiguration")) != NULL)
{
m_recovery = pInst;
}
}
//--------------------------------------------------------------
VirtualMemDlg::~VirtualMemDlg()
{
if(m_pgEnumSettings != NULL)
{
m_pgEnumSettings->Release();
m_pgEnumSettings = NULL;
}
if(m_pgEnumUsage != NULL)
{
m_pgEnumUsage->Release();
m_pgEnumUsage = NULL;
}
}
//--------------------------------------------------------------
int VirtualMemDlg::DoModal(HWND hDlg)
{
return (int) DialogBoxParam(HINST_THISDLL,
(LPTSTR) MAKEINTRESOURCE(DLG_VIRTUALMEM),
hDlg,
StaticVirtDlgProc,
(LPARAM)this);
}
//--------------------------------------------------------------
int TranslateDlgItemInt( HWND hDlg, int id )
{
/*
* We can't just call GetDlgItemInt because the
* string we are trying to translate looks like:
* nnn (MB), and the '(MB)' would break GetDlgInt.
*/
TCHAR szBuffer[256] = {0};
int i = 0;
if (GetDlgItemText(hDlg, id, szBuffer,
sizeof(szBuffer) / sizeof(*szBuffer)))
{
_stscanf(szBuffer, _T("%d"), &i);
}
return i;
}
//----------------------------------------------------
bool VirtualMemDlg::DlgProc(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static int fEdtCtlHasFocus = 0;
m_hDlg = hDlg;
switch (message)
{
case WM_INITDIALOG:
Init(hDlg);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDD_VM_VOLUMES:
// Make edit control reflect the listbox selection.
if (HIWORD(wParam) == LBN_SELCHANGE)
SelChange(hDlg);
break;
case IDD_VM_SF_SET:
if (SetNewSize(hDlg))
{
::EnableWindow(::GetDlgItem(hDlg, IDD_VM_SF_SET), FALSE);
SetDefButton(hDlg, IDOK);
}
break;
case IDOK:
{
int iRet = UpdateWBEM();
// iRet |= PromptForReboot(hDlg);
if (iRet & RET_CHANGE_NO_REBOOT)
{
// We created a pagefile, turn off temp page file flag
DWORD dwRegData;
dwRegData = 0;
}
else
{
// reboot required, warn user & set global flag
MsgBoxParam(m_hDlg, IDS_MUST_REBOOT, IDS_SYS_CHANGE_CAPTION, MB_OK | MB_ICONINFORMATION, NULL, NULL);
g_fRebootRequired = true;
}
if (gfCoreDumpChanged)
iRet |= RET_RECOVER_CHANGE;
EndDialog(hDlg, iRet );
HourGlass(FALSE);
break;
}
case IDCANCEL:
// get rid of changes and restore original values.
EndDialog(hDlg, RET_NO_CHANGE);
HourGlass(FALSE);
break;
case IDD_HELP:
break;
case IDD_VM_SF_SIZE:
case IDD_VM_SF_SIZEMAX:
switch(HIWORD(wParam))
{
case EN_CHANGE:
if ((fEdtCtlHasFocus != 0) && m_VMWriteAccess)
{
::EnableWindow(::GetDlgItem(hDlg, IDD_VM_SF_SET), TRUE);
SetDefButton( hDlg, IDD_VM_SF_SET);
}
break;
case EN_SETFOCUS:
fEdtCtlHasFocus++;
break;
case EN_KILLFOCUS:
fEdtCtlHasFocus--;
break;
}
break;
case IDD_VM_NOPAGING_RADIO:
case IDD_VM_RAMBASED_RADIO:
if( HIWORD(wParam) == BN_CLICKED )
{
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZE ), FALSE );
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZEMAX ), FALSE );
if (m_VMWriteAccess)
{
::EnableWindow(::GetDlgItem(hDlg, IDD_VM_SF_SET), TRUE);
SetDefButton( hDlg, IDD_VM_SF_SET);
}
}
break;
case IDD_VM_CUSTOMSIZE_RADIO:
if( HIWORD(wParam) == BN_CLICKED )
{
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZE ), TRUE );
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZEMAX ), TRUE );
if (m_VMWriteAccess)
{
::EnableWindow(::GetDlgItem(hDlg, IDD_VM_SF_SET), TRUE);
SetDefButton( hDlg, IDD_VM_SF_SET);
}
}
break;
default:
break;
}
break;
case WM_DESTROY:
{
PAGING_FILE *pgVal = NULL;
HWND lbHWND = GetDlgItem(m_hDlg, IDD_VM_VOLUMES);
int last = ListBox_GetCount(lbHWND);
// zero-based loop.
for(int x = 0; x < last; x++)
{
pgVal = (PAGING_FILE *)ListBox_GetItemData(lbHWND, x);
delete pgVal;
}
}
break;
case WM_HELP: // F1
::WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
L"sysdm.hlp",
HELP_WM_HELP,
(ULONG_PTR)(LPSTR)aVirtualMemHelpIds);
break;
case WM_CONTEXTMENU: // right mouse click
WinHelp((HWND) wParam, HELP_FILE, HELP_CONTEXTMENU,
(ULONG_PTR)(LPSTR) aVirtualMemHelpIds);
break;
default:
return FALSE;
break;
}
return TRUE;
}
//---------------------------------------------------------------
TCHAR szCrashControl[] = TEXT("System\\CurrentControlSet\\Control\\CrashControl");
TCHAR szMemMan[] = TEXT("System\\CurrentControlSet\\Control\\Session Manager\\Memory Management");
TCHAR szRegSizeLim[] = TEXT("System\\CurrentControlSet\\Control");
BOOL VirtualMemDlg::Init(HWND hDlg)
{
INT i;
HWND hwndLB;
INT aTabs[2];
RECT rc;
DWORD dwTotalPhys = 0;
HourGlass(TRUE);
// g_wHelpMessage = RegisterWindowMessage( TEXT( "ShellHelp" ) );
if(m_pgEnumUsage == NULL)
{
// Error - cannot even get list of paging files from WBEM
MsgBoxParam(hDlg, SYSTEM+11, IDS_TITLE, MB_ICONEXCLAMATION);
EndDialog(hDlg, RET_NO_CHANGE);
HourGlass(FALSE);
return FALSE;
}
BOOL vcVirtRO = TRUE, vcCoreRO = TRUE;
RemoteRegWriteable(szCrashControl, vcCoreRO);
RemoteRegWriteable(szMemMan, vcVirtRO);
// EXCUSE: I wanted to preserve as much of the original logic but its
// writability was reversed from my util so I do this wierd thing to
// flip it back.
vcCoreRO = !vcCoreRO;
vcVirtRO = !vcVirtRO;
// To change Virtual Memory size or Crash control, we need access
// to both the CrashCtl key and the PagingFiles value in the MemMgr key
if(vcVirtRO || vcCoreRO)
{
// Disable some fields, because they only have Read access.
EnableWindow(GetDlgItem(hDlg, IDD_VM_CUSTOMSIZE_RADIO), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_RAMBASED_RADIO), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_NOPAGING_RADIO), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_SF_SIZE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_SF_SIZEMAX), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_ST_INITSIZE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_ST_MAXSIZE), FALSE);
EnableWindow(GetDlgItem(hDlg, IDD_VM_SF_SET), FALSE);
m_VMWriteAccess = FALSE;
}
else
m_VMWriteAccess = TRUE;
hwndLB = GetDlgItem(hDlg, IDD_VM_VOLUMES);
aTabs[0] = TABSTOP_VOL;
aTabs[1] = TABSTOP_SIZE;
SendMessage(hwndLB, LB_SETTABSTOPS, 2, (LPARAM)&aTabs);
// Since SetGenLBWidth only counts tabs as one character, we must compute
// the maximum extra space that the tab characters will expand to and
// arbitrarily tack it onto the end of the string width.
//
// cxExtra = 1st Tab width + 1 default tab width (8 chrs) - strlen("d:\t\t");
//
// (I know the docs for LB_SETTABSTOPS says that a default tab == 2 dlg
// units, but I have read the code, and it is really 8 chars)
rc.top = rc.left = 0;
rc.bottom = 8;
rc.right = TABSTOP_VOL + (4 * 8) - (4 * 4);
MapDialogRect( hDlg, &rc );
m_cxExtra = rc.right - rc.left;
// List all drives
LoadVolumeList();
SendDlgItemMessage(hDlg, IDD_VM_SF_SIZE, EM_LIMITTEXT, MAX_SIZE_LEN, 0L);
SendDlgItemMessage(hDlg, IDD_VM_SF_SIZEMAX, EM_LIMITTEXT, MAX_SIZE_LEN, 0L);
// Get the total physical memory in the machine.
dwTotalPhys = m_memory.GetLong("TotalPhysicalMemory");
SetDlgItemMB(hDlg, IDD_VM_MIN, MIN_SWAPSIZE);
// convert to KBs for the calculation.
dwTotalPhys /= 1024;
dwTotalPhys *= 3;
dwTotalPhys >>=1; // x*3/2 == 1.5*x more or less.
i = (DWORD)dwTotalPhys;
SetDlgItemMB(hDlg, IDD_VM_RECOMMEND, max(i, MIN_SUGGEST));
// Select the first drive in the listbox.
SendDlgItemMessage(hDlg, IDD_VM_VOLUMES, LB_SETCURSEL, 0, 0L);
SelChange(hDlg);
//since the data is already loaded into the listbox, we use this lightweight
// way of calculating.
SetDlgItemMB(hDlg, IDD_VM_ALLOCD, RecomputeAllocated());
// Show RegQuota
cmTotalVM = ComputeTotalMax();
HourGlass(FALSE);
return TRUE;
}
//-------------------------------------------------------------------
int VirtualMemDlg::ComputeTotalMax( void )
{
INT nTotalAllocated = 0;
INT i;
HWND VolHWND = GetDlgItem(m_hDlg, IDD_VM_VOLUMES);
int cItems = ListBox_GetCount(VolHWND);
for(i = 0; i < cItems; i++)
{
PAGING_FILE *pgVal = (PAGING_FILE *)ListBox_GetItemData(VolHWND, i);
nTotalAllocated += pgVal->nMaxFileSize;
}
return nTotalAllocated;
}
//--------------------------------------------------------
void VirtualMemDlg::BuildLBLine(LPTSTR pszBuf,
const PAGING_FILE *pgVal)
{
//
// Build a string according to the following format:
//
// C: [ Vol_label ] %d - %d
//
TCHAR szVolume[MAX_PATH] = {0};
TCHAR szTemp[MAX_PATH] = {0};
if (pgVal->name != NULL)
{
lstrcpy(pszBuf, pgVal->name);
}
else
{
*pszBuf = _T('\0');
}
lstrcat(pszBuf, _T("\t"));
if (pgVal->volume != NULL && *pgVal->volume)
{
lstrcat(pszBuf, _T("["));
lstrcat(pszBuf, pgVal->volume);
lstrcat(pszBuf, _T("]"));
}
if (!pgVal->fRamBasedPagefile && pgVal->nMinFileSize)
{
//
// Drive has a page file with specific settings.
//
wsprintf(szTemp, _T("\t%d - %d"), pgVal->nMinFileSize,
pgVal->nMaxFileSize);
lstrcat(pszBuf, szTemp);
}
else
{
//
// Either the page file size is derived from the RAM size or the
// drive doesn't have a page file.
//
// In either case, do nothing else.
//
}
}
//--------------------------------------------------------------
void VirtualMemDlg::SelChange(HWND hDlg)
{
TCHAR szTemp[MAX_PATH] = {0};
INT iSel;
INT nCrtRadioButtonId;
PAGING_FILE *iDrive;
BOOL fEditsEnabled;
// where are we pointing now.
if ((iSel = (INT)SendDlgItemMessage(hDlg, IDD_VM_VOLUMES,
LB_GETCURSEL, 0, 0)) == LB_ERR)
{
return;
}
// get its data.
iDrive = (PAGING_FILE *)SendDlgItemMessage(hDlg, IDD_VM_VOLUMES,
LB_GETITEMDATA, iSel, 0);
TCHAR volBuf[40] = {0};
if(_tcslen(iDrive->volume) != 0)
{
_tcscpy(volBuf, _T("["));
_tcscat(volBuf, iDrive->volume);
_tcscat(volBuf, _T("]"));
}
wsprintf(szTemp, _T("%s %s"),
iDrive->name,
volBuf);
//LATER: should we also put up total drive size as well as free space?
SetDlgItemText(hDlg, IDD_VM_SF_DRIVE, szTemp);
if ( iDrive->fRamBasedPagefile )
{
//
// Paging file size based on RAM size
//
nCrtRadioButtonId = IDD_VM_RAMBASED_RADIO;
fEditsEnabled = FALSE;
}
else
{
if ( iDrive->nMinFileSize )
{
//
// Custom size paging file
//
nCrtRadioButtonId = IDD_VM_CUSTOMSIZE_RADIO;
SetDlgItemInt(hDlg, IDD_VM_SF_SIZE, iDrive->nMinFileSize,
FALSE);
SetDlgItemInt(hDlg, IDD_VM_SF_SIZEMAX, iDrive->nMaxFileSize,
FALSE);
fEditsEnabled = TRUE;
}
else
{
//
// No paging file
//
nCrtRadioButtonId = IDD_VM_NOPAGING_RADIO;
SetDlgItemText(hDlg, IDD_VM_SF_SIZE, TEXT(""));
SetDlgItemText(hDlg, IDD_VM_SF_SIZEMAX, TEXT(""));
fEditsEnabled = FALSE;
//
// If the allocated size is zero, then this is a volume which
// had a page file previously but does not now. In this case,
// there is no settings/usage information in the repository.
// Since the pagefile.sys file size is considered free space
// in the free space size computation, then it needs to be
// obtained here.
//
if ( iDrive->nAllocatedFileSize == 0 )
{
//
// Fetch x:\pagefile.sys file size.
//
CWbemClassObject LogicalFile;
IWbemClassObject * pcoInst;
HRESULT hr;
wsprintf(szTemp, gszPFNameFormat, iDrive->name);
hr = QueryInstanceProperties(gszLogicalFile,
gszFileSize,
gszName,
szTemp,
m_WbemServices,
&pcoInst);
LogicalFile = pcoInst;
if (SUCCEEDED(hr))
{
iDrive->nAllocatedFileSize =
(LogicalFile.GetLong(gszFileSize) / ONE_MEG);
}
}
}
}
//
// Set 'Space Available'.
//
SetDlgItemMB(hDlg, IDD_VM_SF_SPACE,
iDrive->freeSpace + iDrive->nAllocatedFileSize);
//
// Select the appropriate radio button
//
CheckRadioButton(
hDlg,
IDD_VM_CUSTOMSIZE_RADIO,
IDD_VM_NOPAGING_RADIO,
nCrtRadioButtonId );
//
// Enable/disable the min & max size edit boxes (if user has write access !)
//
if (m_VMWriteAccess)
{
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZE ), fEditsEnabled );
EnableWindow( GetDlgItem( hDlg, IDD_VM_SF_SIZEMAX ), fEditsEnabled );
}
}
//--------------------------------------------------------------
bool VirtualMemDlg::EnsureEnumerator(const bstr_t bstrClass)
{
HRESULT hr = S_OK;
//
// This code used to retain/cache these interface ptrs and call
// CreateInstanceEnum once. But the logic was commented out for
// some reason with a comment that it was expensive to cache the
// interfaces, although the data member was set each time with no
// call to Release!).
//
if (lstrcmpi(gszPageFileSettings, bstrClass) == 0)
{
IEnumWbemClassObject * pgEnumSettings = NULL;
hr = m_WbemServices.CreateInstanceEnum(bstrClass, WBEM_FLAG_SHALLOW,
&pgEnumSettings);
if (SUCCEEDED(hr))
{
if (m_pgEnumSettings != NULL)
{
m_pgEnumSettings->Release();
}
m_pgEnumSettings = pgEnumSettings;
}
}
else if (lstrcmpi(gszPageFileUsage, bstrClass) == 0)
{
IEnumWbemClassObject * pgEnumUsage = NULL;
hr = m_WbemServices.CreateInstanceEnum(bstrClass, WBEM_FLAG_SHALLOW,
&pgEnumUsage);
if (SUCCEEDED(hr))
{
if (m_pgEnumUsage != NULL)
{
m_pgEnumUsage->Release();
}
m_pgEnumUsage = pgEnumUsage;
}
}
else
{
// Do nothing.
}
return (SUCCEEDED(hr));
}
//--------------------------------------------------------------
void VirtualMemDlg::LoadVolumeList(void)
{
IEnumWbemClassObject *diskEnum = NULL;
IWbemClassObject *pInst = NULL;
CWbemClassObject newInst;
DWORD uReturned = 0;
HRESULT hr = 0;
bstr_t sNameProp(gszName);
bstr_t sVolumeProp("VolumeName");
bstr_t sFileSystemProp("FileSystem");
bstr_t sDriveTypeProp("DriveType");
bstr_t sFreeProp("FreeSpace");
bstr_t sSizeProp("Size"), temp;
long driveType;
__int64 temp64 = 0;
variant_t pVal;
int idx;
TCHAR volumeLine[100] = {0};
PAGING_FILE *pgVar;
HWND VolHWND = GetDlgItem(m_hDlg, IDD_VM_VOLUMES);
// walk the disks.
if(hr = m_WbemServices.ExecQuery(bstr_t("Select __PATH, DriveType from Win32_LogicalDisk"),
0, &diskEnum) == S_OK)
{
TCHAR bootLtr[2] = {0};
if((pInst = FirstInstanceOf("Win32_OperatingSystem")) != NULL)
{
CWbemClassObject os = pInst;
bstr_t temp = os.GetString(L"SystemDirectory");
_tcsncpy(bootLtr, temp, 1);
m_PAEEnabled = os.GetBool(L"PAEEnabled");
}
// get the first and only instance.
while(SUCCEEDED(diskEnum->Next(-1, 1, &pInst, &uReturned)) &&
(uReturned != 0))
{
// get the DriveType.
if ((pInst->Get(sDriveTypeProp, 0L, &pVal, NULL, NULL) == S_OK))
{
// look at the DriveType to see if this drive can have a swapfile.
driveType = pVal;
if(driveType == DRIVE_FIXED)
{
// it can so get the expensive properties now.
// NOTE: This releases pInst; cuz you EXCHANGED
// it for a better one.
newInst = ExchangeInstance(&pInst);
// extract.
pgVar = new PAGING_FILE;
pgVar->name = CloneString(newInst.GetString(sNameProp));
pgVar->volume = CloneString(newInst.GetString(sVolumeProp));
pgVar->filesystem = CloneString(newInst.GetString(sFileSystemProp));
if(bootLtr[0] == pgVar->name[0])
{
pgVar->bootDrive = true;
}
temp64 = 0;
temp = newInst.GetString(sFreeProp);
_stscanf(temp, _T("%I64d"), &temp64);
pgVar->freeSpace = (ULONG)(temp64 / ONE_MEG);
temp64 = 0;
temp = newInst.GetString(sSizeProp);
_stscanf(temp, _T("%I64d"), &temp64);
pgVar->totalSize = (ULONG)(temp64 / ONE_MEG);
// match with a Win32_PageFileSettings if possible.
FindSwapfile(pgVar);
// add it to the listbox.
BuildLBLine(volumeLine, pgVar);
idx = ListBox_AddString(VolHWND, volumeLine);
int nRet = ListBox_SetItemData(VolHWND, idx, pgVar);
if(nRet == LB_ERR)
{
MessageBox(NULL,_T("Error"),_T("Error"),MB_OK);
}
m_cxLBExtent = SetLBWidthEx(VolHWND, volumeLine, m_cxLBExtent, m_cxExtra);
} //endif drive can have swapfile.
} //endif get the cheap variable.
// in case it wasn't exchanged, release it now.
if(pInst)
{
pInst->Release();
pInst = NULL;
}
} // endwhile Enum
diskEnum->Release();
} //endif CreateInstanceEnum() SUCCEEDED (one way or another :)
}
//---------------------------------------------------------------
void VirtualMemDlg::FindSwapfile(PAGING_FILE *pgVar)
{
IWbemClassObject *pInst = NULL;
CWbemClassObject PFSettings;
CWbemClassObject PFUsage;
DWORD uReturned = 0;
HRESULT hr = 0;
bstr_t sNameProp(gszName);
bstr_t sMaxProp(gszMaximumSize);
bstr_t sInitProp(gszInitialSize);
bstr_t sPathProp("__PATH");
bstr_t sAllocSize(gszAllocatedBaseSize);
variant_t pVal, pVal1, pVal2, pVal3;
bstr_t bName;
// do we have one?
if(EnsureEnumerator(gszPageFileSettings))
{
m_pgEnumSettings->Reset();
// walk through the pagefiles...
while((hr = m_pgEnumSettings->Next(-1, 1, &pInst,
&uReturned) == S_OK) &&
(uReturned != 0))
{
PFSettings = pInst;
// trying to match the drive letter.
bName = PFSettings.GetString(sNameProp);
if(_wcsnicmp((wchar_t *)bName, pgVar->name, 1) == 0)
{
// letter matched; get some details.
pgVar->nMinFileSize =
pgVar->nMinFileSizePrev = PFSettings.GetLong(sInitProp);
//
// If the page file InitialSize property is zero, it is an
// indication that the page file size is to be computed based
// on RAM size.
//
pgVar->fRamBasedPagefile = (pgVar->nMinFileSize ?
FALSE : TRUE);
pgVar->nMaxFileSize =
pgVar->nMaxFileSizePrev = PFSettings.GetLong(sMaxProp);
pgVar->objPath = CloneString(PFSettings.GetString(sPathProp));
pgVar->pszPageFile = CloneString(bName);
//
// Fetch the Win32_PageFileUsage.AllocatedBaseSize property.
//
TCHAR szTemp[sizeof(gszPFNameFormat) / sizeof(TCHAR)];
wsprintf(szTemp, gszPFNameFormat, pgVar->name);
IWbemClassObject * pcoInst;
hr = QueryInstanceProperties(gszPageFileUsage,
gszAllocatedBaseSize,
gszName,
szTemp,
m_WbemServices,
&pcoInst);
PFUsage = pcoInst;
if (SUCCEEDED(hr))
{
pgVar->nAllocatedFileSize = PFUsage.GetLong(sAllocSize);
}
else
{
pgVar->nAllocatedFileSize = 0;
}
// found the one and only-- cleanup early and bail out.
pInst->Release();
break; // while()
} //endif match the drive letter.
// in case that BREAK didn't jump over the endwhile()
pInst->Release();
} // endwhile envEnum
// NOTE: The BREAK jumps here. Duplicate any cleanup from before the
// endwhile.
} //endif CreateInstanceEnum() SUCCEEDED one way or another :)
}
//--------------------------------------------------------------
// this version calculates based on pre-existing wbem data.
bool VirtualMemDlg::ComputeAllocated(unsigned long *value)
{
bool retval = false;
IWbemClassObject *pgInst = NULL;
DWORD uReturned = 0;
bstr_t sAllocSize(gszAllocatedBaseSize);
variant_t pVal, pVal1;
// do we have one?
if(EnsureEnumerator(gszPageFileUsage))
{
m_pgEnumUsage->Reset();
// get the first and only instance.
while(SUCCEEDED(m_pgEnumUsage->Next(-1, 1, &pgInst, &uReturned)) &&
(uReturned != 0))
{
// get the variables.
if((pgInst->Get(sAllocSize, 0L, &pVal1, NULL, NULL) == S_OK) &&
(pVal1.vt == VT_I4))
{
*value += pVal1.ulVal;
} //endif get the variable.
pgInst->Release();
} // endwhile envEnum
retval = true;
} //endif CreateInstanceEnum() SUCCEEDED (one way or another :)
return retval;
}
//--------------------------------------------------------------
// this version calculates based on the listbox.
unsigned long VirtualMemDlg::RecomputeAllocated(void)
{
unsigned long nTotalAllocated = 0;
PAGING_FILE *pgVal = NULL;
HWND lbHWND = GetDlgItem(m_hDlg, IDD_VM_VOLUMES);
int last = ListBox_GetCount(lbHWND);
// zero-based loop.
for(int x = 0; x < last; x++)
{
pgVal = (PAGING_FILE *)ListBox_GetItemData(lbHWND, x);
if ( pgVal->fRamBasedPagefile || pgVal->nMinFileSize )
{
//
// Add in only pagefiles in use.
//
nTotalAllocated += pgVal->nAllocatedFileSize;
}
}
return nTotalAllocated;
}
//--------------------------------------------------------------
void VirtualMemDlg::GetRecoveryFlags(bool &bWrite, bool &bLog, bool &bSend)
{
if((bool)m_recovery)
{
bWrite = m_recovery.GetBool("WriteDebugInfo");
bLog = m_recovery.GetBool("WriteToSystemLog");
bSend = m_recovery.GetBool("SendAdminAlert");
}
else
{
bWrite = bLog = bSend = false;
}
}
//--------------------------------------------------------------
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* THIS FUNCTION IS A REPLICA OF THE FUNCTION in \\depot\shell\cpls\system\util.c */
/* OFCOURSE WITH A BIT OF MODIFICATION FOR USING WMI */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
DWORD
VirtualMemDlg::GetMaxPagefileSizeInMB(
PAGING_FILE *iDrive // drive to check on
)
{
#if defined(_AMD64_)
return MAX_SWAPSIZE_AMD64;
#elif defined(_X86_)
if (m_PAEEnabled && !(_wcsnicmp(iDrive->filesystem, L"NTFS",4)))
{
return MAX_SWAPSIZE_X86_PAE;
}
else
{
return MAX_SWAPSIZE_X86;
}
#elif defined(_IA64_)
return MAX_SWAPSIZE_IA64;
#else
return 0;
#endif
}
//--------------------------------------------------------------
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
/* THIS FUNCTION IS A REPLICA OF THE FUNCTION in \\depot\shell\cpls\system\virtual.c */
/* OFCOURSE WITH A BIT OF MODIFICATION FOR USING WMI */
/*!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
bool VirtualMemDlg::SetNewSize(HWND hDlg)
{
ULONG nSwapSize;
ULONG nSwapSizeMax;
BOOL fTranslated;
INT iSel;
PAGING_FILE *iDrive;
TCHAR szTemp[MAX_PATH] = {0};
ULONG nBootPF = 0;
bool fRamBasedPagefile = FALSE;
// get the item's data.
if ((iSel = (INT)SendDlgItemMessage(
hDlg, IDD_VM_VOLUMES, LB_GETCURSEL,0, 0)) != LB_ERR)
{
if ((LRESULT)(iDrive = (PAGING_FILE *)SendDlgItemMessage(hDlg, IDD_VM_VOLUMES,
LB_GETITEMDATA, iSel, 0)) == LB_ERR)
{
return FALSE; //failure !
}
}
// Initialize variables for crashdump.
// nBootPF == crash dump size required.
//
bool bWrite = false, bLog = false, bSend = false;
GetRecoveryFlags(bWrite, bLog, bSend);
if (bWrite)
{
nBootPF = -1;
}
else if (bLog || bSend)
{
nBootPF = MIN_SWAPSIZE;
}
if (nBootPF == -1)
{
nBootPF = ((DWORD)m_memory.GetLong("TotalPhysicalMemory") / 1024);
}
if ( IsDlgButtonChecked( hDlg, IDD_VM_NOPAGING_RADIO ) == BST_CHECKED )
{
//
// No paging file on this drive.
//
nSwapSize = 0;
nSwapSizeMax = 0;
fTranslated = TRUE;
}
else
{
if ( IsDlgButtonChecked( hDlg,
IDD_VM_RAMBASED_RADIO ) == BST_CHECKED )
{
MEMORYSTATUSEX MemoryInfo;
//
// User requested a RAM based page file. We will compute a page
// file size based on the RAM currently available so that we can
// benefit of all the verifications done below related to disk
// space available etc.
//
// The final page file specification written to the registry will
// contain zero sizes though because this is the way we signal
// that we want a RAM based page file.
//
ZeroMemory (&MemoryInfo, sizeof MemoryInfo);
MemoryInfo.dwLength = sizeof MemoryInfo;
if (GlobalMemoryStatusEx (&MemoryInfo))
{
fRamBasedPagefile = TRUE;
//
// We do not lose info because we first divide the RAM size to
// 1Mb and only after that we convert to a DWORD.
//
nSwapSize = (DWORD)(MemoryInfo.ullTotalPhys / 0x100000) + 12;
nSwapSizeMax = nSwapSize;
fTranslated = TRUE;
}
else
{
nSwapSize = 0;
nSwapSizeMax = 0;
fTranslated = TRUE;
}
}
else
{
//
// User requested a custom size page file.
//
nSwapSize = (ULONG)GetDlgItemInt(hDlg, IDD_VM_SF_SIZE,
&fTranslated, FALSE);
// was it an integer?
if (!fTranslated)
{
// need a valid integer for initial size.
MsgBoxParam(hDlg, SYSTEM+37, IDS_TITLE, MB_ICONEXCLAMATION);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZE));
return FALSE;
}
// was it in range > 2MB
if ((nSwapSize < MIN_SWAPSIZE && nSwapSize != 0))
{
// initial value out of range.
MsgBoxParam(hDlg, SYSTEM+13, IDS_TITLE, MB_ICONEXCLAMATION);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZE));
return FALSE;
}
// deleting swapfile?
if (nSwapSize == 0)
{
nSwapSizeMax = 0;
}
else // adding/changing.
{
nSwapSizeMax = (ULONG)GetDlgItemInt(hDlg, IDD_VM_SF_SIZEMAX,
&fTranslated, FALSE);
// was it an integer?
if (!fTranslated)
{
// need an integer.
MsgBoxParam(hDlg, SYSTEM+38, IDS_TITLE,
MB_ICONEXCLAMATION);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZEMAX));
return FALSE;
}
// in range?
if (nSwapSizeMax < nSwapSize || nSwapSizeMax > GetMaxPagefileSizeInMB(iDrive))
{
TCHAR strTemp[16];
MsgBoxParam(hDlg, SYSTEM+14, IDS_TITLE,
MB_ICONEXCLAMATION, _ultow(GetMaxPagefileSizeInMB(iDrive), strTemp, 10));
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZEMAX));
return FALSE;
}
}
}
}
// if we have integers and the listbox has a good focus...
if (fTranslated && iSel != LB_ERR)
{
// will it fit?
if (nSwapSizeMax > iDrive->totalSize)
{
// nope.
MsgBoxParam(hDlg, SYSTEM+16, IDS_TITLE,
MB_ICONEXCLAMATION, iDrive->name);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZEMAX));
return FALSE;
}
//Actual FreeSpace is freespace in the disk + page file size.
ULONG freeSpace = iDrive->freeSpace + iDrive->nAllocatedFileSize;
// room to spare??
if (nSwapSize > freeSpace)
{
// nope.
MsgBoxParam(hDlg, SYSTEM+15, IDS_TITLE, MB_ICONEXCLAMATION);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZE));
return FALSE;
}
// don't hog the last 5MB.
if (nSwapSize != 0 && freeSpace - nSwapSize < MIN_FREESPACE)
{
MsgBoxParam(hDlg, SYSTEM+26, IDS_TITLE, MB_ICONEXCLAMATION,
MIN_FREESPACE_STR);
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZE));
return FALSE;
}
// max too big, should I just use all the space anyway.
if (nSwapSizeMax > freeSpace)
{
if (MsgBoxParam(hDlg, SYSTEM+20, IDS_TITLE, MB_ICONINFORMATION |
MB_OKCANCEL, iDrive->name) == IDCANCEL)
{
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZEMAX));
return FALSE;
}
}
// enough room for core dumps??
if (iDrive->bootDrive && nSwapSize < nBootPF)
{
// The new boot drive page file size is less than we need for
// crash control. Inform the user.
if (MsgBoxParam(hDlg, SYSTEM+29, IDS_TITLE,
MB_ICONEXCLAMATION |MB_YESNO,
iDrive->name, _itow(nBootPF, szTemp, 10)) != IDYES)
{
SetFocus(GetDlgItem(hDlg, IDD_VM_SF_SIZE));
return FALSE;
}
}
iDrive->nMinFileSize = nSwapSize;
iDrive->nMaxFileSize = nSwapSizeMax;
iDrive->fRamBasedPagefile = fRamBasedPagefile;
BuildLBLine(szTemp, iDrive);
SendDlgItemMessage(hDlg, IDD_VM_VOLUMES, LB_DELETESTRING, iSel, 0);
SendDlgItemMessage(hDlg, IDD_VM_VOLUMES, LB_INSERTSTRING, iSel,
(LPARAM)szTemp);
SendDlgItemMessage(hDlg, IDD_VM_VOLUMES, LB_SETITEMDATA, iSel,
(LPARAM)iDrive);
SendDlgItemMessage(hDlg, IDD_VM_VOLUMES, LB_SETCURSEL, iSel, 0L);
m_cxLBExtent = SetLBWidthEx(GetDlgItem(hDlg, IDD_VM_VOLUMES),
szTemp, m_cxLBExtent, m_cxExtra);
if (!iDrive->fRamBasedPagefile && iDrive->nMinFileSize)
{
SetDlgItemInt(hDlg, IDD_VM_SF_SIZE, iDrive->nMinFileSize, FALSE);
SetDlgItemInt(hDlg, IDD_VM_SF_SIZEMAX, iDrive->nMaxFileSize, FALSE);
}
else
{
SetDlgItemText(hDlg, IDD_VM_SF_SIZE, _T(""));
SetDlgItemText(hDlg, IDD_VM_SF_SIZEMAX, _T(""));
}
SetDlgItemMB(hDlg, IDD_VM_ALLOCD, RecomputeAllocated());
SetFocus(GetDlgItem(hDlg, IDD_VM_VOLUMES));
}
return true;
}
//--------------------------------------------------------------
int VirtualMemDlg::UpdateWBEM(void)
{
int iRet = RET_NO_CHANGE;
bool bRebootRequired = false;
CWbemClassObject inst;
bstr_t sNameProp(gszName);
bstr_t sMaxProp(gszMaximumSize);
bstr_t sInitProp(gszInitialSize);
HRESULT hr = 0;
PAGING_FILE *pgVal = NULL;
HWND lbHWND = GetDlgItem(m_hDlg, IDD_VM_VOLUMES);
int last = ListBox_GetCount(lbHWND);
BOOL fNewPFInstance;
#ifdef NTONLY
BOOL fCreatePFPrivEnabled = FALSE;
#endif // NTONLY
// MAINTAINERS NOTE:
// the iRet value gets *overwritten* each time through the loop
// it looks to me like the flags should be OR'd together instead
// but it's way too scary to change it at this late date...
for(int x = 0; x < last; x++)
{
// get it's state structure.
pgVal = (PAGING_FILE *)ListBox_GetItemData(lbHWND, x);
//
// Should assert objPath != NULL && *pgVal->objPath != 0.
// Do NOT assume when objPath is non-NULL that objPath
// is a non-empty string.
//
fNewPFInstance = (pgVal->objPath == NULL || !*pgVal->objPath);
if (!fNewPFInstance)
{
//
// Instance doesn't yet exist, of course, if no object path.
//
inst = m_WbemServices.GetObject(pgVal->objPath);
}
//
// This condition evaluates pagefile previous/current state.
// Evaluate to true if:
// 1. (MINprev != MINcur or MAXprev != MAXcur) - Simple case
// where the values changed.
// 2. (RAMBasedPagefile == TRUE) - Important special case from
// custom to RAM-based AND all min/max prev/cur values
// coincidentally equal.
// 3. (MINcur == 0) - Another special case from RAM-based to no
// pagefile. In this case, min/max prev/cur values are all
// zero and the RAM-Based pagefile flag is FALSE.
//
if ((pgVal->nMinFileSizePrev != pgVal->nMinFileSize ||
pgVal->nMaxFileSizePrev != pgVal->nMaxFileSize) ||
pgVal->fRamBasedPagefile ||
pgVal->nMinFileSize == 0)
{
// reboot required if a page file has *shrunk* in size
if (pgVal->nMaxFileSizePrev > pgVal->nMaxFileSize)
bRebootRequired = true;
if (pgVal->nMinFileSize != 0 || pgVal->fRamBasedPagefile)
{
//
// Custom or RAM-based. Note, the RAM-based pagefile flag
// check seems redundant but it is important for error cases
// in the SetSize code.
//
// Create the instance if it does not exist.
//
BOOL fCreate = FALSE, fModified = FALSE;
if (inst.IsNull())
{
inst = m_WbemServices.CreateInstance(
gszPageFileSettings);
}
//
// Now write out changes. Sigh, too close to RC1 to rewrite
// this existing code.
//
if(!inst.IsNull())
{
if (fNewPFInstance) // Write name at creation time only.
{
BOOL fRet = TRUE;
#ifdef NTONLY
if (!fCreatePFPrivEnabled)
{
//
// Pagefile creation requires pagefile creation
// privilege.
//
// Aargh! No return code to check here...
//
m_WbemServices.SetPriv(SE_CREATE_PAGEFILE_NAME);
fCreatePFPrivEnabled = TRUE;
}
#endif // NTONLY
if (fRet)
{
TCHAR temp[30] = {0};
wsprintf(temp, _T("%s\\pagefile.sys"),
pgVal->name);
hr = inst.Put(sNameProp, _bstr_t(temp));
if (SUCCEEDED(hr))
{
fModified = TRUE;
}
}
}
//
// Write zeros for min/max values when the page file
// size is to be computed based on RAM size.
//
if (pgVal->nMinFileSizePrev != pgVal->nMinFileSize)
{
hr = inst.Put(sInitProp,
(pgVal->fRamBasedPagefile ? 0
: (long)pgVal->nMinFileSize));
if (SUCCEEDED(hr))
{
fModified = TRUE;
}
}
if (pgVal->nMaxFileSizePrev != pgVal->nMaxFileSize)
{
hr = inst.Put(sMaxProp,
(pgVal->fRamBasedPagefile ? 0
: (long)pgVal->nMaxFileSize));
if (SUCCEEDED(hr))
{
fModified = TRUE;
}
}
if (fModified)
{
hr = m_WbemServices.PutInstance(
inst,
WBEM_FLAG_CREATE_OR_UPDATE,
EOAC_STATIC_CLOAKING);
}
if(FAILED(hr))
{
CHString errorDescription;
CHString errorMessage;
TCHAR formatString[1024];
::LoadString(HINST_THISDLL,IDS_ERR_PAGECREATE,
formatString, 1024);
TCHAR errorHeading[20];
::LoadString(HINST_THISDLL,IDS_ERR_HEADING,
errorHeading, 20);
ErrorLookup(hr, errorDescription);
errorMessage.Format(formatString, errorDescription);
::MessageBox(m_hDlg,errorMessage,errorHeading,MB_OK);
}
else
{
if (fModified)
{
iRet = RET_VIRTUAL_CHANGE;
}
}
}
}
else
{
//
// No paging file. Delete the instance.
//
if (!inst.IsNull() && !fNewPFInstance &&
pgVal->objPath != NULL) // 3rd condition insures
// extra safety.
{
hr = m_WbemServices.DeleteInstance(pgVal->objPath);
// I'm taking it on faith that we can only get here
// if we *deleted* a page file...
if (hr != WBEM_E_NOT_FOUND)
bRebootRequired = true;
if (SUCCEEDED(hr))
{
iRet = RET_VIRTUAL_CHANGE;
}
}
}
}
} // endfor
#ifdef NTONLY
if (fCreatePFPrivEnabled)
{
m_WbemServices.ClearPriv();
}
#endif // NTONLY
if (!bRebootRequired)
iRet |= RET_CHANGE_NO_REBOOT;
return iRet;
}
//--------------------------------------------------------------
int VirtualMemDlg::PromptForReboot(HWND hDlg)
{
int iReboot = RET_NO_CHANGE;
/* int i;
int iThisDrv;
WCHAR us;
LARGE_INTEGER liMin, liMax;
NTSTATUS status;
WCHAR wszPath[MAX_PATH*2];
TCHAR szDrive[3] = {0};
PRIVDAT pdOld;
GetPageFilePrivilege( &pdOld );
for (i = 0; i < MAX_DRIVES; i++)
{
// Did something change?
if (apf[i].nMinFileSize != apf[i].nMinFileSizePrev ||
apf[i].nMaxFileSize != apf[i].nMaxFileSizePrev ||
apf[i].fCreateFile )
{
// If we are strictly creating a *new* page file, then
// we can do it on the fly, otherwise we have to reboot.
// assume we will have to reboot
iThisDrv = RET_VIRTUAL_CHANGE;
// IF we are not deleting a page file
// - AND -
// The Page file does not exist
// - OR -
// (This is a New page file AND We are allowed to erase the
// old, unused pagefile that exists there now)
if (apf[i].nMinFileSize != 0 &&
((GetFileAttributes(SZPageFileName(i)) == 0xFFFFFFFF &&
GetLastError() == ERROR_FILE_NOT_FOUND) ||
(apf[i].nMinFileSizePrev == 0 && MsgBoxParam(hDlg,
SYSTEM+25, IDS_TITLE, MB_ICONQUESTION | MB_YESNO,
SZPageFileName(i)) == IDYES)) )
{
DWORD cch;
// Create the page file on the fly so JVert and MGlass will
// stop bugging me!
HourGlass(TRUE);
// convert path drive letter to an NT device path
wsprintf(szDrive, TEXT("%c:"), (TCHAR)(i + (int)TEXT('A')));
cch = QueryDosDevice( szDrive, wszPath, sizeof(wszPath) /
sizeof(TCHAR));
if (cch != 0)
{
// Concat the filename only (skip 'd:') to the nt device
// path, and convert it to a UNICODE_STRING
lstrcat( wszPath, SZPageFileName(i) + 2 );
RtlInitUnicodeString( &us, wszPath );
liMin.QuadPart = (LONGLONG)(apf[i].nMinFileSize * ONE_MEG);
liMax.QuadPart = (LONGLONG)(apf[i].nMaxFileSize * ONE_MEG);
status = NtCreatePagingFile ( &us, &liMin, &liMax, 0L );
if (NT_SUCCESS(status)) {
// made it on the fly, no need to reboot for this drive!
iThisDrv = RET_CHANGE_NO_REBOOT;
}
}
HourGlass(FALSE);
}
iReboot |= iThisDrv;
}
}
ResetOldPrivilege( &pdOld );
// If Nothing changed, then change our IDOK to IDCANCEL so System.cpl will
// know not to reboot.
*/
return iReboot;
}
/************************************************************************
* *
* Function: QueryInstanceProperties *
* *
* Description: Returns requested object properties associated with *
* the instance matching the key property value/name. *
* *
* Arguments: pszClass -- Object class. *
* pszRequestedProperties -- Space-separated property *
* names or *. *
* pszKeyPropertyName -- Specific instance key *
* property name. *
* pszKeyPropertyValue -- Key property value. *
* Services -- Wbem services. *
* ppcoInstEnum -- Returned instance. *
* *
* Returns: HRESULT *
* *
***********************************************************************/
#define QUERY_INSTANCEPROPERTY _T("SELECT %s FROM %s WHERE %s=\"%s\"")
HRESULT QueryInstanceProperties(
const TCHAR * pszClass,
const TCHAR * pszRequestedProperties,
const TCHAR * pszKeyPropertyName,
const TCHAR * pszKeyPropertyValue,
CWbemServices &Services,
IWbemClassObject ** ppcoInst)
{
TCHAR * pszQuery;
BSTR bstrQuery;
HRESULT hr;
*ppcoInst = NULL;
// Dislike multiple allocations of bstr_t.
//
pszQuery = new TCHAR[(sizeof(QUERY_INSTANCEPROPERTY) / sizeof(TCHAR)) +
lstrlen(pszClass) +
lstrlen(pszRequestedProperties) +
lstrlen(pszKeyPropertyName) + // No +1 ala
lstrlen(pszKeyPropertyValue)]; // sizeof.
if (pszQuery == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
wsprintf(pszQuery, QUERY_INSTANCEPROPERTY, pszRequestedProperties,
pszClass, pszKeyPropertyName, pszKeyPropertyValue);
// Sigh, must create a bstr.
//
bstrQuery = SysAllocString(pszQuery);
delete pszQuery;
if (bstrQuery == NULL)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
IEnumWbemClassObject * pecoInstEnum;
hr = Services.ExecQuery(bstrQuery, 0, &pecoInstEnum);
SysFreeString(bstrQuery);
if (SUCCEEDED(hr))
{
DWORD uReturned = 0;
hr = pecoInstEnum->Next(-1, 1, ppcoInst, &uReturned);
pecoInstEnum->Release();
}
return hr;
}