eef86e3d3e8fde45343dfa120832751767ab6d67
[reactos.git] / base / applications / drwtsn32 / sysinfo.cpp
1 /*
2 * PROJECT: Dr. Watson crash reporter
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Output system info
5 * COPYRIGHT: Copyright 2017 Mark Jansen (mark.jansen@reactos.org)
6 */
7
8 #include "precomp.h"
9 #include <udmihelp.h>
10 #include <winreg.h>
11 #include <reactos/buildno.h>
12 #include <reactos/stubs.h>
13
14 static const char* Exception2Str(DWORD code)
15 {
16 switch (code)
17 {
18 case EXCEPTION_ACCESS_VIOLATION: return "EXCEPTION_ACCESS_VIOLATION";
19 case EXCEPTION_DATATYPE_MISALIGNMENT: return "EXCEPTION_DATATYPE_MISALIGNMENT";
20 case EXCEPTION_BREAKPOINT: return "EXCEPTION_BREAKPOINT";
21 case EXCEPTION_SINGLE_STEP: return "EXCEPTION_SINGLE_STEP";
22 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: return "EXCEPTION_ARRAY_BOUNDS_EXCEEDED";
23 case EXCEPTION_FLT_DENORMAL_OPERAND: return "EXCEPTION_FLT_DENORMAL_OPERAND";
24 case EXCEPTION_FLT_DIVIDE_BY_ZERO: return "EXCEPTION_FLT_DIVIDE_BY_ZERO";
25 case EXCEPTION_FLT_INEXACT_RESULT: return "EXCEPTION_FLT_INEXACT_RESULT";
26 case EXCEPTION_FLT_INVALID_OPERATION: return "EXCEPTION_FLT_INVALID_OPERATION";
27 case EXCEPTION_FLT_OVERFLOW: return "EXCEPTION_FLT_OVERFLOW";
28 case EXCEPTION_FLT_STACK_CHECK: return "EXCEPTION_FLT_STACK_CHECK";
29 case EXCEPTION_FLT_UNDERFLOW: return "EXCEPTION_FLT_UNDERFLOW";
30 case EXCEPTION_INT_DIVIDE_BY_ZERO: return "EXCEPTION_INT_DIVIDE_BY_ZERO";
31 case EXCEPTION_INT_OVERFLOW: return "EXCEPTION_INT_OVERFLOW";
32 case EXCEPTION_PRIV_INSTRUCTION: return "EXCEPTION_PRIV_INSTRUCTION";
33 case EXCEPTION_IN_PAGE_ERROR: return "EXCEPTION_IN_PAGE_ERROR";
34 case EXCEPTION_ILLEGAL_INSTRUCTION: return "EXCEPTION_ILLEGAL_INSTRUCTION";
35 case EXCEPTION_NONCONTINUABLE_EXCEPTION: return "EXCEPTION_NONCONTINUABLE_EXCEPTION";
36 case EXCEPTION_STACK_OVERFLOW: return "EXCEPTION_STACK_OVERFLOW";
37 case EXCEPTION_INVALID_DISPOSITION: return "EXCEPTION_INVALID_DISPOSITION";
38 case EXCEPTION_GUARD_PAGE: return "EXCEPTION_GUARD_PAGE";
39 case EXCEPTION_INVALID_HANDLE: return "EXCEPTION_INVALID_HANDLE";
40 case EXCEPTION_WINE_STUB: return "EXCEPTION_WINE_STUB";
41 case STATUS_ASSERTION_FAILURE: return "STATUS_ASSERTION_FAILURE";
42 }
43
44 return "--";
45 }
46
47 static void ReadKey(HKEY hKey, const char* ValueName, char* Buffer, DWORD size)
48 {
49 DWORD dwType;
50 LSTATUS ret = RegQueryValueExA(hKey, ValueName, NULL, &dwType, (LPBYTE)Buffer, &size);
51 if (ret != ERROR_SUCCESS || dwType != REG_SZ)
52 Buffer[0] = '\0';
53 }
54
55 void PrintSystemInfo(FILE* output, DumpData& data)
56 {
57 SYSTEMTIME LocalTime;
58 GetLocalTime(&LocalTime);
59 xfprintf(output, NEWLINE "ReactOS " KERNEL_VERSION_STR " DrWtsn32" NEWLINE NEWLINE);
60 xfprintf(output, "Application exception occurred:" NEWLINE);
61 xfprintf(output, " App: %ls (pid=%d, tid=0x%x)" NEWLINE, data.ProcessName.c_str(), data.ProcessID, data.ThreadID);
62 xfprintf(output, " When: %d/%d/%d @ %02d:%02d:%02d.%d" NEWLINE,
63 LocalTime.wDay, LocalTime.wMonth, LocalTime.wYear,
64 LocalTime.wHour, LocalTime.wMinute, LocalTime.wSecond, LocalTime.wMilliseconds);
65
66 xfprintf(output, " First chance: %u" NEWLINE, data.ExceptionInfo.dwFirstChance);
67 EXCEPTION_RECORD& Record = data.ExceptionInfo.ExceptionRecord;
68 xfprintf(output, " Exception number: 0x%08x (%s)" NEWLINE, Record.ExceptionCode, Exception2Str(Record.ExceptionCode));
69 xfprintf(output, " Exception flags: 0x%08x" NEWLINE, Record.ExceptionFlags);
70 xfprintf(output, " Exception address: %p" NEWLINE, Record.ExceptionAddress);
71 if (Record.NumberParameters)
72 {
73 xfprintf(output, " Exception parameters: %u" NEWLINE, Record.NumberParameters);
74 for (DWORD n = 0; n < std::min<DWORD>(EXCEPTION_MAXIMUM_PARAMETERS, Record.NumberParameters); ++n)
75 {
76 xfprintf(output, " Parameter %u: 0x%p" NEWLINE, n, Record.ExceptionInformation[n]);
77 }
78 }
79
80 char Buffer[MAX_PATH];
81 DWORD count = sizeof(Buffer);
82 xfprintf(output, NEWLINE "*----> System Information <----*" NEWLINE NEWLINE);
83 if (GetComputerNameA(Buffer, &count))
84 xfprintf(output, " Computer Name: %s" NEWLINE, Buffer);
85 count = sizeof(Buffer);
86 if (GetUserNameA(Buffer, &count))
87 xfprintf(output, " User Name: %s" NEWLINE, Buffer);
88
89
90 PVOID SMBiosBuf;
91 PCHAR DmiStrings[ID_STRINGS_MAX] = { 0 };
92 SMBiosBuf = LoadSMBiosData(DmiStrings);
93 if (SMBiosBuf)
94 {
95 if (DmiStrings[BIOS_VENDOR])
96 xfprintf(output, " BIOS Vendor: %s" NEWLINE, DmiStrings[BIOS_VENDOR]);
97 if (DmiStrings[BIOS_VERSION])
98 xfprintf(output, " BIOS Version: %s" NEWLINE, DmiStrings[BIOS_VERSION]);
99 if (DmiStrings[BIOS_DATE])
100 xfprintf(output, " BIOS Date: %s" NEWLINE, DmiStrings[BIOS_DATE]);
101 if (DmiStrings[SYS_VENDOR])
102 xfprintf(output, " System Manufacturer: %s" NEWLINE, DmiStrings[SYS_VENDOR]);
103 if (DmiStrings[SYS_FAMILY])
104 xfprintf(output, " System Family: %s" NEWLINE, DmiStrings[SYS_FAMILY]);
105 if (DmiStrings[SYS_PRODUCT])
106 xfprintf(output, " System Model: %s" NEWLINE, DmiStrings[SYS_PRODUCT]);
107 if (DmiStrings[SYS_VERSION])
108 xfprintf(output, " System Version: %s" NEWLINE, DmiStrings[SYS_VERSION]);
109 if (DmiStrings[SYS_SKU])
110 xfprintf(output, " System SKU: %s" NEWLINE, DmiStrings[SYS_SKU]);
111 if (DmiStrings[BOARD_VENDOR])
112 xfprintf(output, " Baseboard Manufacturer: %s" NEWLINE, DmiStrings[BOARD_VENDOR]);
113 if (DmiStrings[BOARD_NAME])
114 xfprintf(output, " Baseboard Model: %s" NEWLINE, DmiStrings[BOARD_NAME]);
115 if (DmiStrings[BOARD_VERSION])
116 xfprintf(output, " Baseboard Version: %s" NEWLINE, DmiStrings[BOARD_VERSION]);
117 FreeSMBiosData(SMBiosBuf);
118 }
119
120 SYSTEM_INFO info;
121 GetSystemInfo(&info);
122 xfprintf(output, " Number of Processors: %d" NEWLINE, info.dwNumberOfProcessors);
123
124 HKEY hKey;
125 LONG ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
126 0, KEY_READ, &hKey);
127 if (ret == ERROR_SUCCESS)
128 {
129 DWORD dwType;
130 count = sizeof(Buffer);
131 ret = RegQueryValueExA(hKey, "Identifier", NULL, &dwType, (LPBYTE)Buffer, &count);
132 if (ret == ERROR_SUCCESS && dwType == REG_SZ)
133 {
134 Buffer[count] = '\0';
135 xfprintf(output, " Processor Type: %s" NEWLINE, Buffer);
136 }
137 RegCloseKey(hKey);
138 }
139
140 ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_READ, &hKey);
141 if (ret == ERROR_SUCCESS)
142 {
143 char Version[50];
144 ReadKey(hKey, "ProductName", Buffer, sizeof(Buffer));
145 ReadKey(hKey, "CurrentVersion", Version, sizeof(Version));
146 xfprintf(output, " %s Version: %s" NEWLINE, Buffer, Version);
147 ReadKey(hKey, "BuildLab", Buffer, sizeof(Buffer));
148 xfprintf(output, " BuildLab: %s" NEWLINE, Buffer);
149 ReadKey(hKey, "CSDVersion", Buffer, sizeof(Buffer));
150 if (Buffer[0])
151 xfprintf(output, " Service Pack: %s" NEWLINE, Buffer);
152 ReadKey(hKey, "CurrentType", Buffer, sizeof(Buffer));
153 xfprintf(output, " Current Type: %s" NEWLINE, Buffer);
154 ReadKey(hKey, "RegisteredOrganization", Buffer, sizeof(Buffer));
155 xfprintf(output, " Registered Organization: %s" NEWLINE, Buffer);
156 ReadKey(hKey, "RegisteredOwner", Buffer, sizeof(Buffer));
157 xfprintf(output, " Registered Owner: %s" NEWLINE, Buffer);
158
159 RegCloseKey(hKey);
160 }
161 }