1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Alax.Info, 2006-2015 |
---|
3 | // http://alax.info |
---|
4 | // |
---|
5 | // A permission to use the source code is granted as long as reference to |
---|
6 | // source website http://alax.info is retained. |
---|
7 | // |
---|
8 | // Created by Roman Ryltsov roman@alax.info |
---|
9 | |
---|
10 | #pragma once |
---|
11 | |
---|
12 | #include <atlsecurity.h> |
---|
13 | #include <atlcoll.h> |
---|
14 | #include <atlcrack.h> |
---|
15 | #include <atlmisc.h> |
---|
16 | |
---|
17 | //////////////////////////////////////////////////////////// |
---|
18 | // CMainDialog |
---|
19 | |
---|
20 | class CMainDialog : |
---|
21 | public CDialogImpl<CMainDialog>, |
---|
22 | public CDialogResize<CMainDialog> |
---|
23 | { |
---|
24 | public: |
---|
25 | |
---|
26 | enum { IDD = IDD_MAIN }; |
---|
27 | |
---|
28 | BEGIN_MSG_MAP_EX(CMainDialog) |
---|
29 | CHAIN_MSG_MAP(CDialogResize<CMainDialog>) |
---|
30 | MSG_WM_INITDIALOG(OnInitDialog) |
---|
31 | COMMAND_ID_HANDLER_EX(IDOK, OnCommand) |
---|
32 | COMMAND_ID_HANDLER_EX(IDCANCEL, OnCommand) |
---|
33 | END_MSG_MAP() |
---|
34 | |
---|
35 | BEGIN_DLGRESIZE_MAP(CMainDialog) |
---|
36 | DLGRESIZE_CONTROL(IDC_TEXT, DLSZ_SIZE_X | DLSZ_SIZE_Y) |
---|
37 | DLGRESIZE_CONTROL(IDOK, DLSZ_MOVE_X | DLSZ_MOVE_Y) |
---|
38 | END_DLGRESIZE_MAP() |
---|
39 | |
---|
40 | public: |
---|
41 | |
---|
42 | //////////////////////////////////////////////////////// |
---|
43 | // VALUENAME |
---|
44 | |
---|
45 | typedef struct _VALUENAME |
---|
46 | { |
---|
47 | INT_PTR nValue; |
---|
48 | LPCTSTR pszName; |
---|
49 | } VALUENAME; |
---|
50 | |
---|
51 | private: |
---|
52 | CString m_sText; |
---|
53 | CEdit m_TextEdit; |
---|
54 | |
---|
55 | public: |
---|
56 | // CMainDialog |
---|
57 | static CString AtlFormatString(LPCTSTR pszFormat, ...) |
---|
58 | { |
---|
59 | CString sValue; |
---|
60 | va_list Arguments; |
---|
61 | va_start(Arguments, pszFormat); |
---|
62 | sValue.FormatV(pszFormat, Arguments); |
---|
63 | va_end(Arguments); |
---|
64 | return sValue; |
---|
65 | } |
---|
66 | static CString NameFromValue(INT_PTR nValue, const VALUENAME* pValueNames) |
---|
67 | { |
---|
68 | ATLASSERT(pValueNames); |
---|
69 | CString sName; |
---|
70 | for(const VALUENAME* pValueName = pValueNames; pValueName->pszName; pValueName++) |
---|
71 | if(pValueName->nValue == nValue) |
---|
72 | { |
---|
73 | sName.Format(_T("%s (0x%x)"), pValueName->pszName, nValue); |
---|
74 | break; |
---|
75 | } |
---|
76 | if(sName.IsEmpty()) |
---|
77 | sName.Format(_T("0x%x"), nValue); |
---|
78 | return sName; |
---|
79 | } |
---|
80 | VOID Initialize() |
---|
81 | { |
---|
82 | m_sText.Empty(); |
---|
83 | #pragma region System |
---|
84 | { |
---|
85 | m_sText += _T("## System") _T("\r\n") _T("\r\n"); |
---|
86 | #pragma region Version |
---|
87 | if(IsWindowsServer()) |
---|
88 | { |
---|
89 | } else |
---|
90 | { |
---|
91 | static const struct |
---|
92 | { |
---|
93 | bool (*pIsOrGreater)(); |
---|
94 | LPCTSTR pszTitle; |
---|
95 | } g_pMap[] = |
---|
96 | { |
---|
97 | { &IsWindows8Point1OrGreater, _T("Windows 8.1") }, |
---|
98 | { &IsWindows8OrGreater, _T("Windows 8") }, |
---|
99 | { &IsWindows7SP1OrGreater, _T("Windows 7 Service Pack 1") }, |
---|
100 | { &IsWindows7OrGreater, _T("Windows 7") }, |
---|
101 | { &IsWindowsVistaSP2OrGreater, _T("Windows Vista Service Pack 2") }, |
---|
102 | { &IsWindowsVistaSP1OrGreater, _T("Windows Vista Service Pack 1") }, |
---|
103 | { &IsWindowsVistaOrGreater, _T("Windows Vista") }, |
---|
104 | { &IsWindowsXPSP3OrGreater, _T("Windows XP Service Pack 3") }, |
---|
105 | { &IsWindowsXPSP2OrGreater, _T("Windows XP Service Pack 2") }, |
---|
106 | { &IsWindowsXPSP1OrGreater, _T("Windows XP Service Pack 1") }, |
---|
107 | { &IsWindowsXPOrGreater, _T("Windows XP") }, |
---|
108 | }; |
---|
109 | for(auto&& Item: g_pMap) |
---|
110 | if((Item.pIsOrGreater)()) |
---|
111 | { |
---|
112 | m_sText += AtlFormatString(_T(" * ") _T("Version: %s") _T("\r\n"), Item.pszTitle); |
---|
113 | break; |
---|
114 | } |
---|
115 | } |
---|
116 | #pragma endregion |
---|
117 | TCHAR pszComputerName[256] = { 0 }; |
---|
118 | DWORD nComputerNameLength = _countof(pszComputerName); |
---|
119 | GetComputerName(pszComputerName, &nComputerNameLength); |
---|
120 | m_sText += AtlFormatString(_T(" * ") _T("Computer Name: `%s`") _T("\r\n"), pszComputerName); |
---|
121 | TCHAR pszUserName[256] = { 0 }; |
---|
122 | DWORD nUserNameLength = _countof(pszUserName); |
---|
123 | GetUserName(pszUserName, &nUserNameLength); |
---|
124 | CString sUserName(pszUserName); |
---|
125 | BOOL bAdministrator = FALSE; |
---|
126 | bool bIsMember = FALSE; |
---|
127 | if(CAccessToken().CheckTokenMembership(Sids::Admins(), &bIsMember) && bIsMember) |
---|
128 | bAdministrator = TRUE; |
---|
129 | m_sText += AtlFormatString(_T(" * ") _T("User Name: `%s` %s") _T("\r\n"), sUserName, bAdministrator ? _T("(Administrator)") : _T("")); |
---|
130 | //SYSTEMTIME LocalTime; |
---|
131 | //GetLocalTime(&LocalTime); |
---|
132 | //m_sText += AtlFormatString(_T(" * ") _T("Local Time: `%s`") _T("\r\n"), _StringHelper::FormatDateTime(&LocalTime)); |
---|
133 | SYSTEM_INFO SystemInformation; |
---|
134 | GetSystemInfo(&SystemInformation); |
---|
135 | #pragma region Architecture |
---|
136 | CString sArchitecture; |
---|
137 | switch(SystemInformation.wProcessorArchitecture) |
---|
138 | { |
---|
139 | case PROCESSOR_ARCHITECTURE_INTEL: |
---|
140 | sArchitecture = _T("x86"); |
---|
141 | break; |
---|
142 | case PROCESSOR_ARCHITECTURE_AMD64: |
---|
143 | sArchitecture = _T("AMD/Intel x64"); |
---|
144 | break; |
---|
145 | case PROCESSOR_ARCHITECTURE_IA64: |
---|
146 | sArchitecture = _T("Intel Itanium"); |
---|
147 | break; |
---|
148 | default: |
---|
149 | sArchitecture = AtlFormatString(_T("`0x%04X`"), SystemInformation.wProcessorArchitecture); |
---|
150 | } |
---|
151 | #if defined(_WIN64) |
---|
152 | m_sText += AtlFormatString(_T(" * ") _T("Architecture: %s (x64 Application)") _T("\r\n"), sArchitecture); |
---|
153 | #else |
---|
154 | m_sText += AtlFormatString(_T(" * ") _T("Architecture: %s") _T("\r\n"), sArchitecture); |
---|
155 | #endif // defined(_WIN64) |
---|
156 | #pragma endregion |
---|
157 | m_sText += AtlFormatString(_T(" * ") _T("Processors: `%d`, Active Mask `0x%X`") _T("\r\n"), SystemInformation.dwNumberOfProcessors, SystemInformation.dwActiveProcessorMask); |
---|
158 | m_sText += AtlFormatString(_T(" * ") _T("Page Size: `0x%X`") _T("\r\n"), SystemInformation.dwPageSize); |
---|
159 | m_sText += AtlFormatString(_T(" * ") _T("Application Address Space: `0x%p`..`0x%p`") _T("\r\n"), SystemInformation.lpMinimumApplicationAddress, SystemInformation.lpMaximumApplicationAddress); |
---|
160 | #pragma region CPU Identification and Features |
---|
161 | _ATLTRY |
---|
162 | { |
---|
163 | // CRoArrayT<CString> Array; |
---|
164 | // NOTE: __cpuid, __cpuidex https://msdn.microsoft.com/en-us/library/hskdteyh.aspx |
---|
165 | // http://stackoverflow.com/questions/6121792/how-to-check-if-a-cpu-supports-the-sse3-instruction-set |
---|
166 | INT pnInformation[4] = { -1 }; |
---|
167 | __cpuid(pnInformation, 0); |
---|
168 | const INT nIdentifierCount = pnInformation[0]; |
---|
169 | CTempBuffer<INT> pnData((nIdentifierCount + 1) * _countof(pnInformation)); |
---|
170 | for(INT nIdentifierIndex = 0; nIdentifierIndex <= nIdentifierCount; nIdentifierIndex++) |
---|
171 | __cpuidex(pnData + 4 * nIdentifierIndex, nIdentifierIndex, 0); |
---|
172 | #pragma region Vendor |
---|
173 | CHAR pszVendor[0x20]; |
---|
174 | ZeroMemory(pszVendor, sizeof pszVendor); |
---|
175 | *reinterpret_cast<INT*>(pszVendor + 0) = pnData[1]; |
---|
176 | *reinterpret_cast<INT*>(pszVendor + 4) = pnData[3]; |
---|
177 | *reinterpret_cast<INT*>(pszVendor + 8) = pnData[2]; |
---|
178 | // Array.Add(AtlFormatString(_T("`%hs`"), pszVendor)); |
---|
179 | #pragma endregion |
---|
180 | /* |
---|
181 | INT n1Ecx = 0, n1Edx = 0; |
---|
182 | if(nIdentifierCount >= 1) |
---|
183 | { |
---|
184 | n1Ecx = pnData[1 * 4 + 2]; |
---|
185 | n1Edx = pnData[1 * 4 + 3]; |
---|
186 | if(n1Edx) |
---|
187 | { |
---|
188 | CRoArrayT<CString> SubArray; |
---|
189 | if(n1Edx & (1 << 23)) |
---|
190 | SubArray.Add(_T("MMX")); |
---|
191 | if(n1Edx & (1 << 25)) |
---|
192 | SubArray.Add(_T("SSE")); |
---|
193 | if(n1Edx & (1 << 26)) |
---|
194 | SubArray.Add(_T("SSE2")); |
---|
195 | Array.Add(AtlFormatString(_T("0x1 EDX `0x%08X` (%s)"), n1Edx, _StringHelper::Join(SubArray, _T(", ")))); |
---|
196 | } |
---|
197 | if(n1Ecx) |
---|
198 | { |
---|
199 | CRoArrayT<CString> SubArray; |
---|
200 | if(n1Ecx & (1 << 0)) |
---|
201 | SubArray.Add(_T("SSE3")); |
---|
202 | if(n1Ecx & (1 << 9)) |
---|
203 | SubArray.Add(_T("SSSE3")); |
---|
204 | if(n1Ecx & (1 << 19)) |
---|
205 | SubArray.Add(_T("SSE41")); |
---|
206 | if(n1Ecx & (1 << 20)) |
---|
207 | SubArray.Add(_T("SSE42")); |
---|
208 | if(n1Ecx & (1 << 28)) |
---|
209 | SubArray.Add(_T("AVX")); |
---|
210 | Array.Add(AtlFormatString(_T("0x1 ECX `0x%08X` (%s)"), n1Ecx, _StringHelper::Join(SubArray, _T(", ")))); |
---|
211 | } |
---|
212 | } |
---|
213 | INT n7Ebx = 0, n7Ecx = 0; |
---|
214 | if(nIdentifierCount >= 7) |
---|
215 | { |
---|
216 | n7Ebx = pnData[7 * 4 + 1]; |
---|
217 | n7Ecx = pnData[7 * 4 + 2]; |
---|
218 | if(n7Ebx) |
---|
219 | { |
---|
220 | CRoArrayT<CString> SubArray; |
---|
221 | if(n7Ebx & (1 << 5)) |
---|
222 | SubArray.Add(_T("AVX2")); |
---|
223 | Array.Add(AtlFormatString(_T("0x7 EBX `0x%08X` (%s)"), n7Ebx, _StringHelper::Join(SubArray, _T(", ")))); |
---|
224 | } |
---|
225 | if(n7Ecx) |
---|
226 | { |
---|
227 | //CRoArrayT<CString> SubArray; |
---|
228 | //if(n7Ecx & (1 << 5)) |
---|
229 | // SubArray.Add(_T("AVX2")); |
---|
230 | Array.Add(AtlFormatString(_T("0x7 ECX `0x%08X`"), n7Ebx)); |
---|
231 | } |
---|
232 | } |
---|
233 | */ |
---|
234 | __cpuid(pnInformation, 0x80000000); |
---|
235 | const UINT nExtendedIdentifierCount = (UINT) pnInformation[0]; |
---|
236 | CTempBuffer<INT> pnExtendedData((nExtendedIdentifierCount - 0x80000000 + 1) * _countof(pnInformation)); |
---|
237 | for(UINT nExtendedIdentifierIndex = 0x80000000; nExtendedIdentifierIndex <= nExtendedIdentifierCount; nExtendedIdentifierIndex++) |
---|
238 | __cpuidex(pnExtendedData + 4 * (nExtendedIdentifierIndex - 0x80000000), nExtendedIdentifierIndex, 0); |
---|
239 | INT nEx1Ecx = 0, nEx1Edx = 0; |
---|
240 | if(nExtendedIdentifierCount >= 0x80000001) |
---|
241 | { |
---|
242 | nEx1Ecx = pnExtendedData[1 * 4 + 2]; |
---|
243 | nEx1Edx = pnExtendedData[1 * 4 + 3]; |
---|
244 | } |
---|
245 | #pragma region Vendor |
---|
246 | CHAR pszBrand[0x40]; |
---|
247 | ZeroMemory(pszBrand, sizeof pszBrand); |
---|
248 | if(nExtendedIdentifierCount >= 0x80000004) |
---|
249 | { |
---|
250 | memcpy(pszBrand, pnExtendedData + 2 * 4, 3 * 4 * sizeof (INT)); |
---|
251 | // Array.Add(AtlFormatString(_T("Brand `%hs`"), pszBrand)); |
---|
252 | m_sText += AtlFormatString(_T(" * ") _T("CPU Brand: %hs") _T("\r\n"), pszBrand); |
---|
253 | } |
---|
254 | #pragma endregion |
---|
255 | // m_sText += AtlFormatString(_T(" * ") _T("CPU: %s") _T("\r\n"), _StringHelper::Join(Array, _T(", "))); |
---|
256 | } |
---|
257 | _ATLCATCHALL() |
---|
258 | { |
---|
259 | //_Z_EXCEPTION(); |
---|
260 | } |
---|
261 | #pragma endregion |
---|
262 | } |
---|
263 | m_sText += _T("\r\n"); |
---|
264 | #pragma endregion |
---|
265 | DWORD nSize = 0; |
---|
266 | GetLogicalProcessorInformation(NULL, &nSize); |
---|
267 | CTempBuffer<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> pLogicalProcessorInformation; |
---|
268 | ATLVERIFY(pLogicalProcessorInformation.AllocateBytes(nSize)); |
---|
269 | ATLENSURE_THROW(GetLogicalProcessorInformation(pLogicalProcessorInformation, &nSize), AtlHresultFromLastError()); |
---|
270 | static const VALUENAME g_pLogicalProcessorRelationshipNames[] = |
---|
271 | { |
---|
272 | { RelationProcessorCore, _T("RelationProcessorCore") }, |
---|
273 | { RelationNumaNode, _T("RelationNumaNode") }, |
---|
274 | { RelationCache, _T("RelationCache") }, |
---|
275 | { RelationProcessorPackage, _T("RelationProcessorPackage") }, |
---|
276 | { RelationGroup, _T("RelationGroup") }, |
---|
277 | //{ RelationAll, |
---|
278 | { 0, NULL } |
---|
279 | }; |
---|
280 | static const VALUENAME g_pProcessorCacheTypeNames[] = |
---|
281 | { |
---|
282 | { CacheUnified, _T("CacheUnified") }, |
---|
283 | { CacheInstruction, _T("CacheInstruction") }, |
---|
284 | { CacheData, _T("CacheData") }, |
---|
285 | { CacheTrace, _T("CacheTrace") }, |
---|
286 | { 0, NULL } |
---|
287 | }; |
---|
288 | m_sText.Append(_T("## Logical Processors") _T("\r\n")); |
---|
289 | m_sText.Append(_T("\r\n")); |
---|
290 | ATLTRACE2(atlTraceGeneral, 4, _T("nSize %d, sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION) %d\n"), nSize, sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)); |
---|
291 | CAtlMap<LOGICAL_PROCESSOR_RELATIONSHIP, UINT> RelationshipMap; |
---|
292 | RelationshipMap[RelationProcessorCore] = 0; |
---|
293 | RelationshipMap[RelationNumaNode] = 0; |
---|
294 | RelationshipMap[RelationCache] = 0; |
---|
295 | RelationshipMap[RelationProcessorPackage] = 0; |
---|
296 | RelationshipMap[RelationGroup] = 0; |
---|
297 | for(const SYSTEM_LOGICAL_PROCESSOR_INFORMATION* pCurrentLogicalProcessorInformation = pLogicalProcessorInformation; (const BYTE*) (pCurrentLogicalProcessorInformation + 1) <= (const BYTE*) ((const SYSTEM_LOGICAL_PROCESSOR_INFORMATION*) pLogicalProcessorInformation) + nSize; pCurrentLogicalProcessorInformation++) |
---|
298 | { |
---|
299 | ATLTRACE2(atlTraceGeneral, 4, _T("pCurrentLogicalProcessorInformation 0x%p\n"), pCurrentLogicalProcessorInformation); |
---|
300 | m_sText.AppendFormat(_T("Mask: 0x%08x\r\n"), pCurrentLogicalProcessorInformation->ProcessorMask); |
---|
301 | m_sText.AppendFormat(_T("Relationship: %s\r\n"), NameFromValue(pCurrentLogicalProcessorInformation->Relationship, g_pLogicalProcessorRelationshipNames)); |
---|
302 | if(pCurrentLogicalProcessorInformation->Relationship == RelationProcessorCore) |
---|
303 | { |
---|
304 | m_sText.AppendFormat(_T("ProcessorCore.Flags: 0x%02x\r\n"), pCurrentLogicalProcessorInformation->ProcessorCore.Flags); |
---|
305 | RelationshipMap[RelationProcessorCore]++; |
---|
306 | } |
---|
307 | if(pCurrentLogicalProcessorInformation->Relationship == RelationNumaNode) |
---|
308 | { |
---|
309 | m_sText.AppendFormat(_T("NumaNode.NodeNumber: 0x%x\r\n"), pCurrentLogicalProcessorInformation->NumaNode.NodeNumber); |
---|
310 | RelationshipMap[RelationNumaNode]++; |
---|
311 | } |
---|
312 | if(pCurrentLogicalProcessorInformation->Relationship == RelationCache) |
---|
313 | { |
---|
314 | m_sText.AppendFormat(_T("Cache.Level: %d\r\n"), pCurrentLogicalProcessorInformation->Cache.Level); |
---|
315 | m_sText.AppendFormat(_T("Cache.Associativity: %d\r\n"), pCurrentLogicalProcessorInformation->Cache.Associativity); |
---|
316 | m_sText.AppendFormat(_T("Cache.LineSize: %d (0x%x)\r\n"), pCurrentLogicalProcessorInformation->Cache.LineSize, pCurrentLogicalProcessorInformation->Cache.LineSize); |
---|
317 | m_sText.AppendFormat(_T("Cache.Size: %d (0x%x)\r\n"), pCurrentLogicalProcessorInformation->Cache.Size, pCurrentLogicalProcessorInformation->Cache.Size); |
---|
318 | m_sText.AppendFormat(_T("Cache.Type: %s\r\n"), NameFromValue(pCurrentLogicalProcessorInformation->Cache.Type, g_pProcessorCacheTypeNames)); |
---|
319 | RelationshipMap[RelationCache]++; |
---|
320 | } |
---|
321 | if(pCurrentLogicalProcessorInformation->Relationship == RelationProcessorPackage) |
---|
322 | RelationshipMap[RelationProcessorPackage]++; |
---|
323 | if(pCurrentLogicalProcessorInformation->Relationship == RelationGroup) |
---|
324 | RelationshipMap[RelationGroup]++; |
---|
325 | m_sText.Append(_T("\r\n")); |
---|
326 | } |
---|
327 | m_sText.Append(_T("### Record Count per Relationship") _T("\r\n") _T("\r\n")); |
---|
328 | m_sText.AppendFormat(_T(" * %s: `%d`\r\n"), NameFromValue(RelationProcessorCore, g_pLogicalProcessorRelationshipNames), RelationshipMap[RelationProcessorCore]); |
---|
329 | m_sText.AppendFormat(_T(" * %s: `%d`\r\n"), NameFromValue(RelationNumaNode, g_pLogicalProcessorRelationshipNames), RelationshipMap[RelationNumaNode]); |
---|
330 | m_sText.AppendFormat(_T(" * %s: `%d`\r\n"), NameFromValue(RelationCache, g_pLogicalProcessorRelationshipNames), RelationshipMap[RelationCache]); |
---|
331 | m_sText.AppendFormat(_T(" * %s: `%d`\r\n"), NameFromValue(RelationProcessorPackage, g_pLogicalProcessorRelationshipNames), RelationshipMap[RelationProcessorPackage]); |
---|
332 | m_sText.AppendFormat(_T(" * %s: `%d`\r\n"), NameFromValue(RelationGroup, g_pLogicalProcessorRelationshipNames), RelationshipMap[RelationGroup]); |
---|
333 | m_sText += _T("\r\n"); |
---|
334 | } |
---|
335 | |
---|
336 | // Window message handlers |
---|
337 | LRESULT OnInitDialog(HWND, LPARAM) |
---|
338 | { |
---|
339 | Initialize(); |
---|
340 | DlgResize_Init(FALSE); |
---|
341 | m_TextEdit = GetDlgItem(IDC_TEXT); |
---|
342 | m_TextEdit.SetWindowText(m_sText); |
---|
343 | SetIcon(AtlLoadIconImage(IDR_MAINFRAME, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR), TRUE); |
---|
344 | //SetIcon(AtlLoadIconImage(IDR_MAINFRAME, GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR), FALSE); |
---|
345 | ATLVERIFY(CenterWindow()); |
---|
346 | return TRUE; |
---|
347 | } |
---|
348 | LRESULT OnCommand(UINT, INT nIdentifier, HWND) |
---|
349 | { |
---|
350 | ATLVERIFY(EndDialog(nIdentifier)); |
---|
351 | return 0; |
---|
352 | } |
---|
353 | }; |
---|