System Information

[Previous] [Next]

Many operating system values are dependent on the host machine: page size, allocation granularity size, and so on. These values should never be hard-coded into your source code. Instead, you should always retrieve these values when your process initializes and use the retrieved values within your source code. The GetSystemInfo function retrieves the values relevant to the host machine:

 VOID GetSystemInfo(LPSYSTEM_INFO psinf); 

You must pass the address of a SYSTEM_INFO structure to this function. The function will initialize all of the structure's members and return. Here is what the SYSTEM_INFO data structure looks like:

 typedef struct _SYSTEM_INFO { union { DWORD dwOemId; // Obsolete, do not use struct { WORD wProcessorArchitecture; WORD wReserved; }; }; DWORD dwPageSize; LPVOID lpMinimumApplicationAddress; LPVOID lpMaximumApplicationAddress; DWORD_PTR dwActiveProcessorMask; DWORD dwNumberOfProcessors; DWORD dwProcessorType; DWORD dwAllocationGranularity; WORD wProcessorLevel; WORD wProcessorRevision; } SYSTEM_INFO, *LPSYSTEM_INFO; 

When the system boots, it determines what the values of these members should be. For any given system, the values will always be the same, so you will never need to call this function more than once for any given process. GetSystemInfo exists so that an application can query these values at run time. Of all the members in the structure, only four of them have anything to do with memory. These four members are explained in the following table.

Member Name Description
dwPageSize Shows the CPU's page size. On x86, this value is 4096 bytes; on Alpha CPUs, this value is 8192 bytes; and on IA-64, this value is 8192 bytes.
lpMinimumApplicationAddress Gives the minimum memory address of every process's usable address space. On Windows 98, this value is 4,194,304, or 0x00400000, because the bottom 4 MB of every process's address space is unusable. On Windows 2000, this value is 65,536, or 0x00010000, because the first 64 KB of every process's address space is always free.
lpMaximumApplicationAddress Gives the maximum memory address of every process's usable private address space. On Windows 98, this address is 2,147,483,647, or 0x7FFFFFFF, because the shared memory-mapped file region and the shared operating system code are contained in the top 2-GB partition. On Windows 2000, this address is where kernel-mode memory starts, less 64 KB.
dwAllocationGranularity Shows the granularity of a reserved region of address space. As of this writing, this value is 65,536 on all Windows platforms.

The other members of this structure are not at all related to memory management; I explain them here for completeness.

Member Name Description
dwOemId Obsolete, do not reference
wReserved Reserved for future use, do not reference
dwNumberOfProcessors Indicates the number of CPUs in the machine
dwActiveProcessorMask A bitmask indicating which CPUs are active (allowed to run threads)
dwProcessorType Used for Windows 98 only—not for Windows 2000; indicates the processor type, such as Intel 386, 486, or Pentium
wProcessorArchitecture Used only for Windows 2000—not for Windows 98; indicates the processor architecture, such as Intel, Alpha, Intel 64-bit, or Alpha 64-bit
wProcessorLevel Used only for Windows 2000—not for Windows 98; breaks down the process architecture further, such as specifying Intel Pentium Pro or Pentium II
wProcessorRevision Used only for Windows 2000—not for Windows 98; breaks down the processor level further

The System Information Sample Application

The SysInfo application ("14 SysInfo.exe")—listed in Figure 14-1 below—is a simple program that calls GetSystemInfo and displays the information returned in the SYSTEM_INFO structure. The source code and resource files for the application are in the 14-SysInfo directory on the companion CD-ROM. The following dialog boxes show the results of running the SysInfo application on several different platforms.

Windows 98 on x86

32-bit Windows 2000 on x86

32-bit Windows 2000 on Alpha

64-bit Windows on Alpha

Figure 14-1. The SysInfo Application

SysInfo.cpp

 /****************************************************************************** Module: SysInfo.cpp Notices: Copyright (c) 2000 Jeffrey Richter ******************************************************************************/ #include "..\CmnHdr.h" /* See Appendix A. */ #include <windowsx.h> #include <tchar.h> #include <stdio.h> #include "Resource.h" /////////////////////////////////////////////////////////////////////////////// // Set to TRUE if the app is running on Windows 9x. BOOL g_fWin9xIsHost = FALSE; /////////////////////////////////////////////////////////////////////////////// // This function accepts a number and converts it to a // string, inserting commas where appropriate. PTSTR BigNumToString(LONG lNum, PTSTR szBuf) { TCHAR szNum[100]; wsprintf(szNum, TEXT("%d"), lNum); NUMBERFMT nf; nf.NumDigits = 0; nf.LeadingZero = FALSE; nf.Grouping = 3; nf.lpDecimalSep = TEXT("."); nf.lpThousandSep = TEXT(","); nf.NegativeOrder = 0; GetNumberFormat(LOCALE_USER_DEFAULT, 0, szNum, &nf, szBuf, 100); return(szBuf); } /////////////////////////////////////////////////////////////////////////////// void ShowCPUInfo(HWND hwnd, WORD wProcessorArchitecture, WORD wProcessorLevel, WORD wProcessorRevision) { TCHAR szCPUArch[64] = TEXT("(unknown)"); TCHAR szCPULevel[64] = TEXT("(unknown)"); TCHAR szCPURev[64] = TEXT("(unknown)"); switch (wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_INTEL: lstrcpy(szCPUArch, TEXT("Intel")); switch (wProcessorLevel) { case 3: case 4: wsprintf(szCPULevel, TEXT("80%c86"), wProcessorLevel + '0'); if (!g_fWin9xIsHost) wsprintf(szCPURev, TEXT("%c%d"), HIBYTE(wProcessorRevision) + TEXT('A'), LOBYTE(wProcessorRevision)); break; case 5: wsprintf(szCPULevel, TEXT("Pentium")); if (!g_fWin9xIsHost) wsprintf(szCPURev, TEXT("Model %d, Stepping %d"), HIBYTE(wProcessorRevision), LOBYTE(wProcessorRevision)); break; case 6: wsprintf(szCPULevel, TEXT("Pentium Pro or Pentium II")); if (!g_fWin9xIsHost) wsprintf(szCPURev, TEXT("Model %d, Stepping %d"), HIBYTE(wProcessorRevision), LOBYTE(wProcessorRevision)); break; } break; case PROCESSOR_ARCHITECTURE_ALPHA: lstrcpy(szCPUArch, TEXT("Alpha")); wsprintf(szCPULevel, TEXT("%d"), wProcessorLevel); wsprintf(szCPURev, TEXT("Model %c, Pass %d"), HIBYTE(wProcessorRevision) + TEXT('A'), LOBYTE(wProcessorRevision)); break; case PROCESSOR_ARCHITECTURE_IA64: lstrcpy(szCPUArch, TEXT("IA-64")); wsprintf(szCPULevel, TEXT("%d"), wProcessorLevel); wsprintf(szCPURev, TEXT("Model %c, Pass %d"), HIBYTE(wProcessorRevision) + TEXT('A'), LOBYTE(wProcessorRevision)); break; case PROCESSOR_ARCHITECTURE_ALPHA64: lstrcpy(szCPUArch, TEXT("Alpha64")); wsprintf(szCPULevel, TEXT("%d"), wProcessorLevel); wsprintf(szCPURev, TEXT("Model %c, Pass %d"), HIBYTE(wProcessorRevision) + TEXT('A'), LOBYTE(wProcessorRevision)); break; case PROCESSOR_ARCHITECTURE_UNKNOWN: default: wsprintf(szCPUArch, TEXT("Unknown")); break; } SetDlgItemText(hwnd, IDC_PROCARCH, szCPUArch); SetDlgItemText(hwnd, IDC_PROCLEVEL, szCPULevel); SetDlgItemText(hwnd, IDC_PROCREV, szCPURev); } /////////////////////////////////////////////////////////////////////////////// BOOL Dlg_OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) { chSETDLGICONS(hwnd, IDI_SYSINFO); SYSTEM_INFO sinf; GetSystemInfo(&sinf); if (g_fWin9xIsHost) { sinf.wProcessorLevel = (WORD) (sinf.dwProcessorType / 100); } ShowCPUInfo(hwnd, sinf.wProcessorArchitecture, sinf.wProcessorLevel, sinf.wProcessorRevision); TCHAR szBuf[50]; SetDlgItemText(hwnd, IDC_PAGESIZE, BigNumToString(sinf.dwPageSize, szBuf)); _stprintf(szBuf, TEXT("%p"), sinf.lpMinimumApplicationAddress); SetDlgItemText(hwnd, IDC_MINAPPADDR, szBuf); _stprintf(szBuf, TEXT("%p"), sinf.lpMaximumApplicationAddress); SetDlgItemText(hwnd, IDC_MAXAPPADDR, szBuf); _stprintf(szBuf, TEXT("0x%016I64X"), (_ _int64) sinf.dwActiveProcessorMask); SetDlgItemText(hwnd, IDC_ACTIVEPROCMASK, szBuf); SetDlgItemText(hwnd, IDC_NUMOFPROCS, BigNumToString(sinf.dwNumberOfProcessors, szBuf)); SetDlgItemText(hwnd, IDC_ALLOCGRAN, BigNumToString(sinf.dwAllocationGranularity, szBuf)); return(TRUE); } /////////////////////////////////////////////////////////////////////////////// void Dlg_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) { switch (id) { case IDCANCEL: EndDialog(hwnd, id); break; } } /////////////////////////////////////////////////////////////////////////////// INT_PTR WINAPI Dlg_Proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { chHANDLE_DLGMSG(hDlg, WM_INITDIALOG, Dlg_OnInitDialog); chHANDLE_DLGMSG(hDlg, WM_COMMAND, Dlg_OnCommand); } return(FALSE); } /////////////////////////////////////////////////////////////////////////////// int WINAPI _tWinMain(HINSTANCE hinstExe, HINSTANCE, PTSTR pszCmdLine, int) { OSVERSIONINFO vi = { sizeof(vi) }; GetVersionEx(&vi); g_fWin9xIsHost = (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS); DialogBox(hinstExe, MAKEINTRESOURCE(IDD_SYSINFO), NULL, Dlg_Proc); return(0); } //////////////////////////////// End of File ////////////////////////////////// 

SysInfo.rc

 //Microsoft Developer Studio generated resource script. // #include "Resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "Resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // IDD_SYSINFO DIALOG DISCARDABLE 18, 18, 186, 97 STYLE WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "System Info" FONT 8, "MS Sans Serif" BEGIN RTEXT "Processor Architecture:",IDC_STATIC,4,4,88,8, SS_NOPREFIX RTEXT "ID_PROCARCH",IDC_PROCARCH,96,4,84,8,SS_NOPREFIX RTEXT "Processor level:",IDC_STATIC,4,14,88,8,SS_NOPREFIX RTEXT "ID_PROCLEVEL",IDC_PROCLEVEL,96,14,84,8,SS_NOPREFIX RTEXT "Processor revision:",IDC_STATIC,4,24,88,8,SS_NOPREFIX RTEXT "ID_PROCREV",IDC_PROCREV,96,24,84,8,SS_NOPREFIX RTEXT "Number of processors:",IDC_STATIC,4,34,88,8,SS_NOPREFIX RTEXT "ID_NUMOFPROCS",IDC_NUMOFPROCS,96,34,84,8,SS_NOPREFIX RTEXT "Active processor mask:",IDC_STATIC,4,44,88,8, SS_NOPREFIX RTEXT "ID_ACTIVEPROCMASK",IDC_ACTIVEPROCMASK,96,44,84,8, SS_NOPREFIX RTEXT "Allocation granularity:",IDC_STATIC,4,54,88,8, SS_NOPREFIX RTEXT "ID_ALLOCGRAN",IDC_ALLOCGRAN,96,54,84,8,SS_NOPREFIX RTEXT "Page size:",IDC_STATIC,4,64,88,8,SS_NOPREFIX RTEXT "ID_PAGESIZE",IDC_PAGESIZE,96,64,84,8,SS_NOPREFIX RTEXT "Minimum app. address:",IDC_STATIC,4,74,88,8,SS_NOPREFIX RTEXT "ID_MINAPPADDR",IDC_MINAPPADDR,96,74,84,8,SS_NOPREFIX RTEXT "Maximum app. address:",IDC_STATIC,4,84,88,8,SS_NOPREFIX RTEXT "ID_MAXAPPADDR",IDC_MAXAPPADDR,96,84,84,8,SS_NOPREFIX END ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. IDI_SYSINFO ICON DISCARDABLE "SysInfo.Ico" ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN IDD_SYSINFO, DIALOG BEGIN RIGHTMARGIN, 170 BOTTOMMARGIN, 77 END END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED 



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net