1: // osInfo.cpp : 定義主控台應用程式的進入點。
2: //
3:
4: #include "stdafx.h"
5: #include <windows.h>
6: #include <tchar.h>
7: #include <stdio.h>
8: #include <strsafe.h>
9:
10: #pragma comment(lib, "User32.lib")
11:
12: #define BUFSIZE 256
13:
14: typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
15: typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
16:
17: BOOL GetOSDisplayString( LPTSTR pszOS)
18: { 19: // 宣告變數
20: OSVERSIONINFOEX osvi; // 呼叫GetVersionEx需要此結構,內存Windows版本相關資訊
21: SYSTEM_INFO si; // 呼叫GetNativeSystemInfo需要此結構,內存系統資訊
22: PGNSI pGNSI;
23: PGPI pGPI;
24: BOOL bOsVersionInfoEx;
25: DWORD dwType;
26:
27: ZeroMemory(&si, sizeof(SYSTEM_INFO));
28: ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
29:
30: osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
31:
32: // GetVersionEx 呼叫成功會傳回非0值
33: //
34: if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
35: // GetVersionEx 呼叫失敗,結束函式
36: return 1;
37:
38: // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise
39: // 呼叫 GetNativeSystemInfo 或 GetSystemInfo
40: pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo"); 41: if(NULL != pGNSI)
42: pGNSI(&si);
43: else GetSystemInfo(&si); // 呼叫 GetNativeSystemInfo 失敗,改呼叫 GetSystemInfo
44:
45: // NT 平台且主版本序號大於 4 者,會符合以下條件式
46: // 這支程式僅支援 NT 平台且主版本序號大於 4 的 Windows
47: if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && osvi.dwMajorVersion > 4 )
48: { 49: // 隨著以下的檢查,會一一將查到的資訊複製到 pszOS 字串
50: StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft ")); 51:
52: // Test for the specific product.
53: // 先從主版本序號為 6 的產品開始檢
54: // 也就是 Vista / Windows Server 2008、Windows 7 / Windows Server 2008 R2
55: if ( osvi.dwMajorVersion == 6 )
56: { 57: // 如果次版本序號是 0,就是 Vista / Windows Server 2008
58: if( osvi.dwMinorVersion == 0 )
59: { 60: // VER_NT_WORKSTATION 表示用戶端版
61: if( osvi.wProductType == VER_NT_WORKSTATION )
62: StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista (Ver 6.0) ")); 63: // 不然就是伺服器版
64: else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 (Ver 6.0) " )); 65: }
66:
67: // 如果次版本序號是 1,就是 Windows 7 / Windows Server 2008 R2
68: if ( osvi.dwMinorVersion == 1 )
69: { 70: if( osvi.wProductType == VER_NT_WORKSTATION )
71: StringCchCat(pszOS, BUFSIZE, TEXT("Windows 7 (Ver 6.1) ")); 72: else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 R2 (Ver 6.1) " )); 73: }
74:
75: // 呼叫 GetProductInfo,取得產品類型
76: pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo"); 77:
78: pGPI( osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
79:
80: // 根據 dwType 取得 SKU
81: // 實際上可取得的 SKU 不止以下所列,
82: // 完整資訊可參考 SDK 文件 GetProductInfo 的說明
83: switch( dwType )
84: { 85: case PRODUCT_ULTIMATE:
86: StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" )); 87: break;
88: case PRODUCT_HOME_PREMIUM:
89: StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" )); 90: break;
91: case PRODUCT_HOME_BASIC:
92: StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" )); 93: break;
94: case PRODUCT_ENTERPRISE:
95: StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" )); 96: break;
97: case PRODUCT_BUSINESS:
98: StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" )); 99: break;
100: case PRODUCT_STARTER:
101: StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" )); 102: break;
103: case PRODUCT_CLUSTER_SERVER:
104: StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" )); 105: break;
106: case PRODUCT_DATACENTER_SERVER:
107: StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" )); 108: break;
109: case PRODUCT_DATACENTER_SERVER_CORE:
110: StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" )); 111: break;
112: case PRODUCT_ENTERPRISE_SERVER:
113: StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" )); 114: break;
115: case PRODUCT_ENTERPRISE_SERVER_CORE:
116: StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" )); 117: break;
118: case PRODUCT_ENTERPRISE_SERVER_IA64:
119: StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" )); 120: break;
121: case PRODUCT_SMALLBUSINESS_SERVER:
122: StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" )); 123: break;
124: case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
125: StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" )); 126: break;
127: case PRODUCT_STANDARD_SERVER:
128: StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" )); 129: break;
130: case PRODUCT_STANDARD_SERVER_CORE:
131: StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" )); 132: break;
133: case PRODUCT_WEB_SERVER:
134: StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" )); 135: break;
136: }
137: }
138:
139: // 以下檢查主版本序號為 5 且次版本序號為 2 的產品
140: // 也就是 Windows Server 2003 或 Windows Server 2003 R2
141: if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
142: { 143: if( GetSystemMetrics(SM_SERVERR2) )
144: StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2 (Ver 5.2), "));
145: else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
146: StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003 (Ver 5.2) "));
147: else if ( osvi.wSuiteMask==VER_SUITE_WH_SERVER )
148: StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Home Server (Ver 5.2) "));
149: else if( osvi.wProductType == VER_NT_WORKSTATION &&
150: si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
151: { 152: // Windows XP Professional x64 與 Windows Server 2003 是相同 codebase
153: // 但 wProductType 是 VER_NT_WORKSTATION,
154: // 且 wProcessorArchitecture 是 PROCESSOR_ARCHITECTURE_AMD64
155: StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition (Ver 5.2) "));
156: }
157: // 以上皆非則為 Windows Server 2003
158: else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, ")); 159:
160: // Test for the server type.
161: // 檢查其他的伺服器版
162: if ( osvi.wProductType != VER_NT_WORKSTATION )
163: { 164: if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
165: { 166: if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
167: StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));
168: else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
169: StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));
170: }
171:
172: else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
173: { 174: if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
175: StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));
176: else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
177: StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));
178: else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));
179: }
180: else
181: { 182: if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
183: StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));
184: else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
185: StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));
186: else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
187: StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));
188: else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
189: StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));
190: else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));
191: }
192: }
193: }
194:
195: // 以下檢查主版本序號為 5 且次版本序號為 1 的產品
196: // 也就是 Windows XP
197: if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
198: { 199: StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP (Ver 5.1) ")); 200: if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
201: StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));
202: else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
203: }
204:
205: // 以下檢查主版本序號為 5 且次版本序號為 0 的產品
206: // 也就是 Windows 2000
207: if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
208: { 209: StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 (Ver 5.0) ")); 210:
211: if ( osvi.wProductType == VER_NT_WORKSTATION )
212: { 213: // 用戶端版本
214: StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
215: }
216: else
217: { 218: // 伺服器版本
219: if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
220: StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));
221: else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
222: StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));
223: else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));
224: }
225: }
226:
227: // Include service pack (if any) and build number.
228: // 取得 Service Pack 版本及組建編號
229: if( _tcslen(osvi.szCSDVersion) > 0 )
230: { 231: StringCchCat(pszOS, BUFSIZE, TEXT(" ") ); 232: StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
233: }
234:
235: TCHAR buf[80];
236:
237: StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber); 238: StringCchCat(pszOS, BUFSIZE, buf);
239:
240: // 主版本序號 6 及 6 以上,再檢查是 x64 還是 x86
241: if ( osvi.dwMajorVersion >= 6 )
242: { 243: if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
244: StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
245: else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
246: StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit")); 247: }
248:
249: // 完成檢查,傳回 True
250: return TRUE;
251: }
252:
253: else
254: { 255: // 這支程式僅支援 NT 平台且主版本序號大於 4 的 Windows
256: printf( "This sample does not support this version of Windows.\n");
257: return FALSE;
258: }
259: }
260:
261: // 主控台程式的進入點
262: int __cdecl _tmain()
263: { 264: TCHAR szOS[BUFSIZE];
265:
266: // 呼叫 GetOSDisplayString
267: if( GetOSDisplayString( szOS ) )
268: // 呼叫成功即列出相關版本資訊
269: _tprintf( TEXT("\n%s\n"), szOS ); 270: }