mirror of https://github.com/lianthony/NT4.0
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.
940 lines
23 KiB
940 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
Mem.c
|
|
|
|
Abstract:
|
|
|
|
This module contains support for displaying the Memory dialog.
|
|
|
|
Author:
|
|
|
|
David J. Gilman (davegi) 12-Jan-1993
|
|
Gregg R. Acheson (GreggA) 7-May-1993
|
|
John Hazen (jhazen) 30-May-1996 - rewritten for 4.0
|
|
|
|
Environment:
|
|
|
|
User Mode
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntexapi.h>
|
|
|
|
#include "dialogs.h"
|
|
#include "mem.h"
|
|
#include "msg.h"
|
|
#include "registry.h"
|
|
#include "strtab.h"
|
|
#include "strresid.h"
|
|
#include "dlgprint.h"
|
|
#include "winmsd.h"
|
|
|
|
#include <string.h>
|
|
#include <tchar.h>
|
|
|
|
//
|
|
// Object used to pass information around about memory.
|
|
//
|
|
|
|
typedef
|
|
struct
|
|
_MEMORY_INFO {
|
|
|
|
DECLARE_SIGNATURE
|
|
|
|
DWORD m_cHandles;
|
|
DWORD m_cThreads;
|
|
DWORD m_cProcesses;
|
|
DWORD m_dwPhysicalMemory;
|
|
DWORD m_dwPhysAvail;
|
|
DWORD m_dwFileCache;
|
|
DWORD m_dwKernelPaged;
|
|
DWORD m_dwKernelNP;
|
|
DWORD m_dwKernelTotal;
|
|
DWORD m_dwCommitTotal;
|
|
DWORD m_dwCommitLimit;
|
|
DWORD m_dwCommitPeak;
|
|
ULONG m_uPagefileTotalSize;
|
|
ULONG m_uPagefileTotalInUse;
|
|
ULONG m_uPagefilePeakUsage;
|
|
|
|
} MEMORY_INFO, *LPMEMORY_INFO;
|
|
|
|
|
|
//
|
|
// Internal function prototypes
|
|
//
|
|
BOOL
|
|
InitializeMemoryTab(
|
|
IN HWND hWnd
|
|
);
|
|
|
|
BOOL
|
|
DisplayPagefiles(
|
|
IN HWND hListView ,
|
|
UINT fReport
|
|
);
|
|
|
|
BOOL
|
|
GetMemoryData(
|
|
IN LPMEMORY_INFO pMemoryInfo
|
|
);
|
|
|
|
BOOL
|
|
MemoryTabProc(
|
|
IN HWND hWnd,
|
|
IN UINT message,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
MemoryDlgProc supports the display of the memory dialog which displays
|
|
information about total memory, available memory and paging file location.
|
|
|
|
Arguments:
|
|
|
|
Standard DLGPROC entry.
|
|
|
|
Return Value:
|
|
|
|
BOOL - Depending on input message and processing options.
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
switch( message ) {
|
|
|
|
case WM_INITDIALOG:
|
|
{
|
|
TCHAR Buffer[64];
|
|
LV_COLUMN lvc;
|
|
RECT rect;
|
|
|
|
//
|
|
// initialize the pagefile list view
|
|
//
|
|
|
|
lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT;
|
|
lvc.cx = 100;
|
|
LoadString(_hModule, IDS_PAGEFILE, Buffer, cchSizeof(Buffer));
|
|
lvc.pszText = Buffer;
|
|
lvc.fmt = LVCFMT_LEFT;
|
|
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_PAGEFILES), 0, &lvc);
|
|
|
|
lvc.cx = 75;
|
|
LoadString(_hModule, IDS_PAGEFILE_TOTAL, Buffer, cchSizeof(Buffer));
|
|
lvc.pszText = Buffer;
|
|
lvc.fmt = LVCFMT_RIGHT;
|
|
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_PAGEFILES), 1, &lvc);
|
|
|
|
lvc.cx = 85;
|
|
LoadString(_hModule, IDS_PAGEFILE_INUSE, Buffer, cchSizeof(Buffer));
|
|
lvc.pszText = Buffer;
|
|
lvc.fmt = LVCFMT_RIGHT;
|
|
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_PAGEFILES), 2, &lvc);
|
|
|
|
lvc.cx = 95;
|
|
LoadString(_hModule, IDS_PAGEFILE_PEAKUSE, Buffer, cchSizeof(Buffer));
|
|
lvc.pszText = Buffer;
|
|
lvc.fmt = LVCFMT_RIGHT;
|
|
ListView_InsertColumn(GetDlgItem(hWnd, IDC_LV_PAGEFILES), 3, &lvc);
|
|
|
|
//adjust the column width to make it look good
|
|
GetClientRect( GetDlgItem(hWnd, IDC_LV_PAGEFILES), &rect );
|
|
ListView_SetColumnWidth( GetDlgItem(hWnd, IDC_LV_PAGEFILES), 0, rect.right - 255);
|
|
|
|
InitializeMemoryTab( hWnd );
|
|
|
|
DisplayPagefiles( GetDlgItem( hWnd, IDC_LV_PAGEFILES ), FALSE );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case WM_COMMAND:
|
|
{
|
|
|
|
if ( LOWORD( wParam ) == IDC_PUSH_REFRESH)
|
|
{
|
|
InitializeMemoryTab( hWnd );
|
|
DisplayPagefiles( GetDlgItem( hWnd, IDC_LV_PAGEFILES ), FALSE );
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
BOOL
|
|
DisplayPagefiles(
|
|
IN HWND hListView,
|
|
UINT fReport
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Displays the pagefiles in the ListView box
|
|
|
|
Arguments:
|
|
|
|
hListView - to the listview control
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if successful
|
|
|
|
--*/
|
|
{
|
|
|
|
LV_ITEM lvI;
|
|
TCHAR Buffer[MAX_PATH];
|
|
NTSTATUS Status;
|
|
SYSTEM_BASIC_INFORMATION BasicInfo;
|
|
PSYSTEM_PAGEFILE_INFORMATION pPagefile;
|
|
LPVOID pvBuffer = NULL;
|
|
DWORD cbBuffer = 4096;
|
|
ULONG cbOffset = 0;
|
|
int index = 0;
|
|
int i;
|
|
|
|
|
|
ListView_DeleteAllItems(hListView);
|
|
|
|
//
|
|
// Get basic info like page size, etc.
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(
|
|
SystemBasicInformation,
|
|
&BasicInfo,
|
|
sizeof(BasicInfo),
|
|
NULL
|
|
);
|
|
|
|
|
|
//
|
|
// Get pagefile information
|
|
//
|
|
|
|
i = TRUE;
|
|
|
|
while(i)
|
|
{
|
|
if (pvBuffer)
|
|
{
|
|
Status = NtQuerySystemInformation(SystemPageFileInformation,
|
|
pvBuffer,
|
|
cbBuffer,
|
|
NULL);
|
|
|
|
//
|
|
// If we succeeded, great, get outta here. If not, any error other
|
|
// than "buffer too small" is fatal, in which case we bail
|
|
//
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Status != STATUS_INFO_LENGTH_MISMATCH)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Buffer wasn't large enough to hold the process info table, so resize it
|
|
// to be larger, then retry.
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
cbBuffer += 4096;
|
|
|
|
pvBuffer = LocalAlloc (LPTR, cbBuffer);
|
|
|
|
if (pvBuffer == NULL)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// add the pagefiles to the list view
|
|
//
|
|
lvI.mask = LVIF_TEXT | LVIF_STATE;
|
|
lvI.state = 0;
|
|
lvI.stateMask = 0;
|
|
|
|
cbOffset = 0;
|
|
do
|
|
{
|
|
pPagefile = (PSYSTEM_PAGEFILE_INFORMATION)&((LPBYTE)pvBuffer)[cbOffset];
|
|
ASSERT( FALSE == IsBadReadPtr((LPVOID)pPagefile, sizeof(PSYSTEM_PAGEFILE_INFORMATION)));
|
|
|
|
if ( fReport )
|
|
{
|
|
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
|
|
lvI.pszText = pPagefile->PageFileName.Buffer;
|
|
|
|
//
|
|
// lvI.pszText is now in the form \DosDevices\C:PAGEFILE.SYS, or \??\C:\pagefile.sys
|
|
// skip the preface to only show C:\PAGEFILE.SYS
|
|
//
|
|
|
|
lvI.pszText = wcschr( &lvI.pszText[1], L'\\') +1;
|
|
|
|
AddLineToReport( SINGLE_INDENT, RFO_SINGLELINE, lvI.pszText, NULL );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->TotalSize * (BasicInfo.PageSize / 1024), FALSE ));
|
|
AddLineToReport( SINGLE_INDENT * 2, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->TotalInUse * (BasicInfo.PageSize / 1024), FALSE ));
|
|
AddLineToReport( SINGLE_INDENT * 2, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL_IN_USE ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->PeakUsage * (BasicInfo.PageSize / 1024), FALSE ));
|
|
AddLineToReport( SINGLE_INDENT * 2, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_PEAK ),
|
|
Buffer );
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
lvI.iItem = index;
|
|
lvI.iSubItem = 0;
|
|
|
|
lvI.pszText = pPagefile->PageFileName.Buffer;
|
|
lvI.cchTextMax = 100;
|
|
|
|
//
|
|
// lvI.pszText is now in the form \DosDevices\C:PAGEFILE.SYS, or \??\C:\pagefile.sys
|
|
// skip the preface to only show C:\PAGEFILE.SYS
|
|
//
|
|
|
|
lvI.pszText = wcschr( &lvI.pszText[1], L'\\') +1;
|
|
|
|
i = ListView_InsertItem( hListView, &lvI);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->TotalSize * (BasicInfo.PageSize / 1024), FALSE ));
|
|
ListView_SetItemText( hListView, index, 1, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->TotalInUse * (BasicInfo.PageSize / 1024), FALSE ));
|
|
ListView_SetItemText( hListView, index, 2, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( pPagefile->PeakUsage * (BasicInfo.PageSize / 1024), FALSE ));
|
|
ListView_SetItemText( hListView, index, 3, Buffer);
|
|
|
|
}
|
|
|
|
index++;
|
|
|
|
cbOffset += pPagefile->NextEntryOffset;
|
|
|
|
} while (pPagefile->NextEntryOffset);
|
|
|
|
//
|
|
// free the pagefile buffer
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
GetMemoryData(
|
|
IN LPMEMORY_INFO pMemoryInfo
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
GetMemoryData queries the registry for the data required
|
|
for the Memory Dialog.
|
|
|
|
Arguments:
|
|
|
|
IN LPMEMORY_INFO pMemoryInfo - pointer to a MEMORY_INFO object
|
|
|
|
Return Value:
|
|
|
|
BOOL - Returns TRUE if function succeeds, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL Success;
|
|
HREGKEY hRegKey;
|
|
UINT i;
|
|
LPTSTR PagingFile;
|
|
TCHAR Buffer [ MAX_PATH ];
|
|
MEMORYSTATUS MemoryStatus;
|
|
NTSTATUS Status;
|
|
SYSTEM_PERFORMANCE_INFORMATION PerfInfo;
|
|
SYSTEM_BASIC_INFORMATION BasicInfo;
|
|
PSYSTEM_PROCESS_INFORMATION pCurrent;
|
|
SYSTEM_FILECACHE_INFORMATION FileCache;
|
|
PSYSTEM_PAGEFILE_INFORMATION pPagefile;
|
|
LPVOID pvBuffer = NULL;
|
|
DWORD cbBuffer = 4096;
|
|
ULONG cbOffset = 0;
|
|
|
|
|
|
//
|
|
// Initialize buffers with empty strings.
|
|
//
|
|
|
|
ZeroMemory( pMemoryInfo, sizeof(MEMORY_INFO) );
|
|
|
|
|
|
if (_fIsRemote) {
|
|
//BUGBUG: need to disable this for remote operations
|
|
lstrcpy( Buffer, GetString( IDS_NOT_AVAILABLE_REMOTE ) );
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//
|
|
// Get basic info like page size, etc.
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(
|
|
SystemBasicInformation,
|
|
&BasicInfo,
|
|
sizeof(BasicInfo),
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pMemoryInfo->m_dwPhysicalMemory = BasicInfo.NumberOfPhysicalPages *
|
|
(BasicInfo.PageSize / 1024);
|
|
|
|
//
|
|
// Get some non-process specific info, like memory status
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(
|
|
SystemPerformanceInformation,
|
|
&PerfInfo,
|
|
sizeof(PerfInfo),
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pMemoryInfo->m_dwPhysAvail = PerfInfo.AvailablePages * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwCommitTotal = PerfInfo.CommittedPages * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwCommitLimit = PerfInfo.CommitLimit * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwCommitPeak = PerfInfo.PeakCommitment * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwKernelPaged = PerfInfo.PagedPoolPages * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwKernelNP = PerfInfo.NonPagedPoolPages * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_dwKernelTotal = pMemoryInfo->m_dwKernelNP + pMemoryInfo->m_dwKernelPaged;
|
|
|
|
//
|
|
// Get FileCache info
|
|
//
|
|
|
|
Status = NtQuerySystemInformation(
|
|
SystemFileCacheInformation,
|
|
&FileCache,
|
|
sizeof(FileCache),
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
pMemoryInfo->m_dwFileCache = FileCache.CurrentSize / 1024;
|
|
|
|
//
|
|
// Get pagefile information
|
|
//
|
|
|
|
i = TRUE;
|
|
|
|
while(i)
|
|
{
|
|
if (pvBuffer)
|
|
{
|
|
Status = NtQuerySystemInformation(SystemPageFileInformation,
|
|
pvBuffer,
|
|
cbBuffer,
|
|
NULL);
|
|
|
|
//
|
|
// If we succeeded, great, get outta here. If not, any error other
|
|
// than "buffer too small" is fatal, in which case we bail
|
|
//
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Status != STATUS_INFO_LENGTH_MISMATCH)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Buffer wasn't large enough to hold the process info table, so resize it
|
|
// to be larger, then retry.
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
cbBuffer += 4096;
|
|
|
|
pvBuffer = LocalAlloc (LPTR, cbBuffer);
|
|
|
|
if (pvBuffer == NULL)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// count the pagefile totals
|
|
//
|
|
|
|
cbOffset = 0;
|
|
do
|
|
{
|
|
pPagefile = (PSYSTEM_PAGEFILE_INFORMATION)&((LPBYTE)pvBuffer)[cbOffset];
|
|
ASSERT( FALSE == IsBadReadPtr((LPVOID)pPagefile, sizeof(PSYSTEM_PAGEFILE_INFORMATION)));
|
|
|
|
pMemoryInfo->m_uPagefileTotalSize += pPagefile->TotalSize * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_uPagefileTotalInUse += pPagefile->TotalInUse * (BasicInfo.PageSize / 1024);
|
|
pMemoryInfo->m_uPagefilePeakUsage += pPagefile->PeakUsage * (BasicInfo.PageSize / 1024);
|
|
|
|
cbOffset += pPagefile->NextEntryOffset;
|
|
|
|
|
|
} while (pPagefile->NextEntryOffset);
|
|
|
|
//
|
|
// free the pagefile buffer
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
cbBuffer = 4096;
|
|
|
|
//
|
|
// Get Process infomation
|
|
//
|
|
i = TRUE;
|
|
|
|
while(i)
|
|
{
|
|
if (pvBuffer)
|
|
{
|
|
Status = NtQuerySystemInformation(SystemProcessInformation,
|
|
pvBuffer,
|
|
cbBuffer,
|
|
NULL);
|
|
|
|
//
|
|
// If we succeeded, great, get outta here. If not, any error other
|
|
// than "buffer too small" is fatal, in which case we bail
|
|
//
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (Status != STATUS_INFO_LENGTH_MISMATCH)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Buffer wasn't large enough to hold the process info table, so resize it
|
|
// to be larger, then retry.
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
cbBuffer += 4096;
|
|
|
|
pvBuffer = LocalAlloc (LPTR, cbBuffer);
|
|
|
|
if (pvBuffer == NULL)
|
|
{
|
|
i = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// count the handles, threads, and processes
|
|
//
|
|
|
|
cbOffset = 0;
|
|
do
|
|
{
|
|
pCurrent = (PSYSTEM_PROCESS_INFORMATION)&((LPBYTE)pvBuffer)[cbOffset];
|
|
ASSERT( FALSE == IsBadReadPtr((LPVOID)pCurrent, sizeof(PSYSTEM_PROCESS_INFORMATION)));
|
|
|
|
if (pCurrent->UniqueProcessId != NULL && pCurrent->NumberOfThreads != 0)
|
|
{
|
|
|
|
pMemoryInfo->m_cHandles += pCurrent->HandleCount;
|
|
pMemoryInfo->m_cThreads += pCurrent->NumberOfThreads;
|
|
pMemoryInfo->m_cProcesses++;
|
|
|
|
}
|
|
|
|
cbOffset += pCurrent->NextEntryOffset;
|
|
|
|
} while (pCurrent->NextEntryOffset);
|
|
|
|
//
|
|
// free the process buffer
|
|
//
|
|
|
|
if (pvBuffer)
|
|
{
|
|
LocalFree(pvBuffer);
|
|
pvBuffer = NULL;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BuildMemoryReport(
|
|
IN HWND hWnd,
|
|
IN UINT iDetailLevel
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Formats and adds MemoryData to the report buffer.
|
|
|
|
Arguments:
|
|
|
|
hWnd - Main window handle
|
|
iDetailLevel - summary or complete details?
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if report is build successfully, FALSE otherwise.
|
|
|
|
--*/
|
|
{
|
|
|
|
TCHAR Buffer[64];
|
|
MEMORY_INFO MemoryInfo;
|
|
|
|
//
|
|
// Skip a line, set the title, and print a separator.
|
|
//
|
|
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_MEMORY_REPORT ), NULL );
|
|
AddLineToReport( 0, RFO_SEPARATOR, NULL, NULL );
|
|
|
|
//
|
|
// Display memory information
|
|
//
|
|
if (_fIsRemote) {
|
|
|
|
lstrcpy( Buffer, GetString( IDS_NOT_AVAILABLE_REMOTE ) );
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
if (GetMemoryData( &MemoryInfo ))
|
|
{
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cHandles, FALSE ));
|
|
AddLineToReport( 0, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_HANDLES ),
|
|
Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cThreads, FALSE ));
|
|
AddLineToReport( 0, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_THREADS ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cProcesses, FALSE ));
|
|
AddLineToReport( 0, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_PROCESSES ),
|
|
Buffer );
|
|
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_PHYSICAL_MEMORY ), NULL );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwPhysicalMemory, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwPhysAvail, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_AVAILABLE ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwFileCache, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_FILECACHE ),
|
|
Buffer );
|
|
|
|
if ( iDetailLevel == IDC_COMPLETE_REPORT )
|
|
{
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_KERNELMEMORY ), NULL );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelTotal, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelPaged, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_PAGED ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelNP, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_NONPAGED ),
|
|
Buffer );
|
|
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_COMMITCHARGE ), NULL );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitTotal, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitLimit, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_LIMIT ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitPeak, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_PEAK ),
|
|
Buffer );
|
|
|
|
AddLineToReport( 1, RFO_SKIPLINE, NULL, NULL );
|
|
AddLineToReport( 0, RFO_SINGLELINE, (LPTSTR) GetString( IDS_PAGEFILESPACE ), NULL );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefileTotalSize, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefileTotalInUse, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_TOTAL_IN_USE ),
|
|
Buffer );
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefilePeakUsage, FALSE ));
|
|
AddLineToReport( SINGLE_INDENT, RFO_RPTLINE,
|
|
(LPTSTR) GetString( IDS_PEAK ),
|
|
Buffer );
|
|
|
|
DisplayPagefiles( NULL, TRUE );
|
|
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
InitializeMemoryTab(
|
|
HWND hWnd
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Adds the appropriate controls to the memory tab control and
|
|
initializes any needed structures.
|
|
|
|
Arguments:
|
|
|
|
hWnd - to the main window
|
|
|
|
Return Value:
|
|
|
|
BOOL - TRUE if successful
|
|
|
|
--*/
|
|
{
|
|
HCURSOR hSaveCursor;
|
|
MEMORY_INFO MemoryInfo;
|
|
DLGHDR *pHdr = (DLGHDR *) GetWindowLong( GetParent(hWnd), GWL_USERDATA );
|
|
TCHAR Buffer[64];
|
|
|
|
//
|
|
// Set the pointer to an hourglass
|
|
//
|
|
|
|
hSaveCursor = SetCursor ( LoadCursor ( NULL, IDC_WAIT ) ) ;
|
|
DbgHandleAssert( hSaveCursor ) ;
|
|
|
|
//
|
|
// set state of global buttons
|
|
//
|
|
EnableControl( GetParent(hWnd),
|
|
IDC_PUSH_PROPERTIES,
|
|
FALSE);
|
|
|
|
EnableControl( GetParent(hWnd),
|
|
IDC_PUSH_REFRESH,
|
|
TRUE);
|
|
|
|
//
|
|
// Size and position the child dialog
|
|
//
|
|
SetWindowPos(hWnd, HWND_TOP,
|
|
pHdr->rcDisplay.left,
|
|
pHdr->rcDisplay.top,
|
|
pHdr->rcDisplay.right - pHdr->rcDisplay.left,
|
|
pHdr->rcDisplay.bottom - pHdr->rcDisplay.top,
|
|
SWP_SHOWWINDOW);
|
|
//
|
|
// Get Memory data and fill out fields
|
|
//
|
|
|
|
if (GetMemoryData( &MemoryInfo ))
|
|
{
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cHandles, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_TOTAL_HANDLES, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cThreads, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_TOTAL_THREADS, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_cProcesses, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_TOTAL_PROCESSES, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwPhysicalMemory, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_TOTAL_PHYSICAL, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwPhysAvail, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_AVAIL_PHYSICAL, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwFileCache, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_FILE_CACHE, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitTotal, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_COMMIT_TOTAL, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitLimit, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_COMMIT_LIMIT, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwCommitPeak, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_COMMIT_PEAK, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelPaged, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_KERNEL_PAGED, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelNP, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_KERNEL_NONPAGED, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_dwKernelTotal, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_KERNEL_TOTAL, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefileTotalSize, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_TOTAL_PAGEFILE_SPACE, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefileTotalInUse, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_PAGEFILE_INUSE, Buffer);
|
|
|
|
wsprintf( Buffer, L"%s", FormatBigInteger( MemoryInfo.m_uPagefilePeakUsage, FALSE ));
|
|
SetDlgItemText( hWnd, IDC_PAGEFILE_PEAKUSE, Buffer);
|
|
|
|
}
|
|
|
|
//
|
|
// Set the extended style to get full row selection
|
|
//
|
|
SendDlgItemMessage(hWnd, IDC_LV_PAGEFILES, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT);
|
|
|
|
|
|
SetCursor ( hSaveCursor ) ;
|
|
|
|
return( TRUE );
|
|
|
|
}
|
|
|