/*++ 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 #include #include #include #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 #include // // 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 ); }