home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_GEN / MSJMAR94.ZIP / WINQA.ZIP / FREEMEM2.C < prev    next >
C/C++ Source or Header  |  1994-03-01  |  6KB  |  168 lines

  1. //==================================
  2. // FREEMEM2.C - Matt Pietrek 1993
  3. //==================================
  4. #include <windows.h>
  5. #include <toolhelp.h>
  6. #include "freemem2.h"
  7.  
  8. // Reads the CMOS RAM to get the total installed memory
  9. DWORD GetInstalledRAM(void)
  10. {
  11.     __asm {
  12.         
  13.         cli                 // Disable interrupts
  14.  
  15.         // Read the base memory (in K) into BX
  16.         mov     al, 15h     // Tell the CMOS ram which byte we want to read
  17.         out     70h, al     
  18.         in      al, 71h     // read in the byte from the CMOS ram
  19.         mov     bl, al
  20.             
  21.         mov     al, 16h
  22.         out     70h, al
  23.         in      al, 71h
  24.         mov     bh, al
  25.  
  26.         // Read the extended memory (in K) into AX
  27.         mov     al, 18h
  28.         out     70h, al
  29.         in      al, 71h
  30.         mov     ah, al
  31.  
  32.         mov     al, 17h
  33.         out     70h, al
  34.         in      al, 71h
  35.  
  36.         sti                 // enable interrupts
  37.         
  38.         xor     dx, dx      // add base + extended memory and put the
  39.         add     ax, bx      // result into DX:AX
  40.         adc     dx, 0
  41.     }
  42.     
  43.     // Ignore the compiler complaint about "function must return a value"
  44. }
  45.  
  46. // Sum up the sizes of all the global heap blocks.  If a non-zero pointer
  47. // is passed as a parameter, store the size of the largest free block
  48. // into that location.
  49. DWORD GetGlobalHeapSize(DWORD *pLargestFree)
  50. {
  51.     GLOBALENTRY ge;
  52.     DWORD size = 0;
  53.     BOOL fContinue;
  54.  
  55.     if ( pLargestFree )
  56.         *pLargestFree = 0;  // Initial largest free block is 0 bytes
  57.  
  58.     // Use TOOLHELP GlobalFirst/GlobalNext to walk the global heap
  59.     ge.dwSize = sizeof(ge);
  60.     fContinue = GlobalFirst(&ge, GLOBAL_ALL);
  61.     while ( fContinue )
  62.     {
  63.         size += ge.dwBlockSize; // Add blocksize to running total
  64.  
  65.         // If the block is free, and larger than the previous largest
  66.         // free block, make it the new largest free block
  67.         if ( pLargestFree && (ge.wType == GT_FREE) )
  68.             if ( ge.dwBlockSize > *pLargestFree )
  69.                 *pLargestFree = ge.dwBlockSize;
  70.         
  71.         fContinue = GlobalNext(&ge, GLOBAL_ALL);
  72.     }
  73.     
  74.     *pLargestFree /= 1024;  // Convert bytes to K
  75.     return size / 1024;
  76. }
  77.  
  78. // Fill in the dialog text controls that never vary (installed RAM, etc...)
  79. void PaintConstantItems(HWND hWndDlg)
  80. {
  81.     MEMMANINFO mmi;
  82.     DWORD size;
  83.     char buffer[128];
  84.     
  85.     mmi.dwSize = sizeof(mmi);
  86.     MemManInfo(&mmi);
  87.     
  88.     wsprintf(buffer, "Installed RAM: %ldk", GetInstalledRAM());
  89.     SetDlgItemText(hWndDlg, IDT_INSTALLED_RAM, buffer );
  90.  
  91.     // check to see if the field is -1.  If we didn't, we'd show -4K!
  92.     size = (mmi.dwTotalPages == -1) ? -1 : mmi.dwTotalPages * 4;
  93.     wsprintf(buffer, "Total Memory: %ldk", size);
  94.     SetDlgItemText(hWndDlg, IDT_TOTAL_MEMORY, buffer );
  95.     
  96.     wsprintf(buffer, "Swap File Pages: %ldk", mmi.dwSwapFilePages * 4);
  97.     SetDlgItemText(hWndDlg, IDT_SWAP_FILE_PAGES, buffer );
  98.     
  99.     size = (mmi.dwTotalLinearSpace == -1) ? -1 : mmi.dwTotalLinearSpace * 4;
  100.     wsprintf(buffer, "Linear Space: %ldk", size);
  101.     SetDlgItemText(hWndDlg, IDT_ADDRESS_SPACE, buffer );
  102. }
  103.  
  104. // Fill in the dialog text controls that vary (largest free block, etc...)
  105. void PaintVariableItems(HWND hWndDlg)
  106. {
  107.     MEMMANINFO mmi;
  108.     DWORD largestFreeGlobalHeapBlock;
  109.     DWORD totalGlobalHeapSize;
  110.     char buffer[128];
  111.     DWORD size;
  112.     
  113.     totalGlobalHeapSize = GetGlobalHeapSize(&largestFreeGlobalHeapBlock);
  114.     mmi.dwSize = sizeof(mmi);
  115.     MemManInfo(&mmi);
  116.  
  117.     wsprintf( buffer, "Global Heap Total: %ldk", totalGlobalHeapSize);
  118.     SetDlgItemText(hWndDlg, IDT_GLOBAL_HEAP_TOTAL, buffer);
  119.  
  120.     wsprintf( buffer, "Largest Free Heap Block: %ldk",
  121.             largestFreeGlobalHeapBlock);
  122.     SetDlgItemText(hWndDlg, IDT_LARGEST_FREE_GLOBAL, buffer);
  123.  
  124.     size = (mmi.dwMaxPagesLockable == -1) ? -1 : mmi.dwMaxPagesLockable * 4;
  125.     wsprintf( buffer, "Max Lockable Pages: %ldk", size);
  126.     SetDlgItemText(hWndDlg, IDT_MAX_LOCKABLE, buffer);
  127.  
  128.     size = (mmi.dwFreePages == -1) ? -1 : mmi.dwFreePages * 4;
  129.     wsprintf( buffer, "Free Memory: %ldk", size);
  130.     SetDlgItemText(hWndDlg, IDT_TOTAL_FREE, buffer);
  131.  
  132.     wsprintf( buffer, "Largest Free Block: %ldk", mmi.dwLargestFreeBlock/1024);
  133.     SetDlgItemText(hWndDlg, IDT_LARGEST_FREE, buffer);
  134.  
  135.     size = (mmi.dwFreeLinearSpace == -1) ? -1 : mmi.dwFreeLinearSpace * 4;
  136.     wsprintf( buffer, "Free Linear Space: %ldk", size);
  137.     SetDlgItemText(hWndDlg, IDT_FREE_SPACE, buffer);
  138. }
  139.  
  140. BOOL CALLBACK _export FreeMem2DlgProc(HWND hWndDlg, UINT msg,
  141.                                       WPARAM wParam, LPARAM lParam)
  142. {
  143.     if ( msg == WM_INITDIALOG )
  144.     {
  145.         PaintConstantItems(hWndDlg);
  146.         PaintVariableItems(hWndDlg);
  147.         SetTimer( hWndDlg, 1, 5000, 0 );    // a 5 second timer
  148.     }
  149.     else if ( msg == WM_COMMAND )
  150.     {
  151.         if ( wParam == IDB_EXIT )       // Exit button pushed?
  152.             EndDialog(hWndDlg, 0);
  153.     }
  154.     else if ( msg == WM_TIMER )         // 5 seconds are up!
  155.         PaintVariableItems(hWndDlg);
  156.     else if ( msg == WM_CLOSE )
  157.         EndDialog(hWndDlg, 0);          // User hit Close on the system menu
  158.     
  159.     return FALSE;
  160. }
  161.  
  162. int PASCAL WinMain( HANDLE hInstance, HANDLE hPrevInstance,
  163.                     LPSTR lpszCmdLine, int nCmdShow )
  164. {
  165.     DialogBox(hInstance, "FreeMem2Dlg", 0, FreeMem2DlgProc);
  166.     return 0;
  167. }
  168.