Make ReactOS report the Git revision as output by "git describe".
[reactos.git] / modules / rostests / rosautotest / CConfiguration.cpp
1 /*
2 * PROJECT: ReactOS Automatic Testing Utility
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Class for managing all the configuration parameters
5 * COPYRIGHT: Copyright 2009-2011 Colin Finck (colin@reactos.org)
6 */
7
8 #include "precomp.h"
9
10 #define CONFIGURATION_FILENAMEA "rosautotest.ini"
11 #define CONFIGURATION_FILENAMEW L"rosautotest.ini"
12
13 typedef void (WINAPI *GETSYSINFO)(LPSYSTEM_INFO);
14
15 /**
16 * Constructs an empty CConfiguration object
17 */
18 CConfiguration::CConfiguration()
19 : m_CrashRecovery(false),
20 m_IsInteractive(false),
21 m_PrintToConsole(true),
22 m_Shutdown(false),
23 m_Submit(false)
24 {
25 WCHAR WindowsDirectory[MAX_PATH];
26 WCHAR Interactive[32];
27
28 /* Check if we are running under ReactOS from the SystemRoot directory */
29 if(!GetWindowsDirectoryW(WindowsDirectory, MAX_PATH))
30 FATAL("GetWindowsDirectoryW failed");
31
32 m_IsReactOS = !_wcsnicmp(&WindowsDirectory[3], L"reactos", 7);
33
34 if(GetEnvironmentVariableW(L"WINETEST_INTERACTIVE", Interactive, _countof(Interactive)))
35 m_IsInteractive = _wtoi(Interactive);
36 }
37
38 /**
39 * Parses the passed parameters and sets the appropriate configuration settings.
40 *
41 * @param argc
42 * The number of parameters (argc parameter of the wmain function)
43 *
44 * @param argv
45 * Pointer to a wchar_t array containing the parameters (argv parameter of the wmain function)
46 */
47 void
48 CConfiguration::ParseParameters(int argc, wchar_t* argv[])
49 {
50 /* Parse the command line arguments */
51 for(int i = 1; i < argc; i++)
52 {
53 if(argv[i][0] == '-' || argv[i][0] == '/')
54 {
55 switch(argv[i][1])
56 {
57 case 'c':
58 ++i;
59 m_Comment = UnicodeToAscii(argv[i]);
60 break;
61
62 case 'n':
63 m_PrintToConsole = false;
64 break;
65
66 case 'r':
67 m_CrashRecovery = true;
68 break;
69
70 case 's':
71 m_Shutdown = true;
72 break;
73
74 case 'w':
75 m_Submit = true;
76 break;
77
78 default:
79 throw CInvalidParameterException();
80 }
81 }
82 else
83 {
84 /* Which parameter is this? */
85 if(m_Module.empty())
86 {
87 /* Copy the parameter */
88 m_Module = argv[i];
89 }
90 else if(m_Test.empty())
91 {
92 /* Copy the parameter converted to ASCII */
93 m_Test = UnicodeToAscii(argv[i]);
94 }
95 else
96 {
97 throw CInvalidParameterException();
98 }
99 }
100 }
101
102 /* The /r and /w options shouldn't be used in conjunction */
103 if(m_CrashRecovery && m_Submit)
104 throw CInvalidParameterException();
105 }
106
107 /**
108 * Gets information about the running system and sets the appropriate configuration settings.
109 */
110 void
111 CConfiguration::GetSystemInformation()
112 {
113 char ProductType;
114 GETSYSINFO GetSysInfo;
115 HMODULE hKernel32;
116 OSVERSIONINFOEXW os;
117 stringstream ss;
118 SYSTEM_INFO si;
119
120 /* Get the build from the define */
121 ss << "&revision=";
122 ss << KERNEL_VERSION_COMMIT_HASH;
123
124 ss << "&platform=";
125
126 if(m_IsReactOS)
127 {
128 ss << "reactos";
129 }
130 else
131 {
132 /* No, then use the info from GetVersionExW */
133 os.dwOSVersionInfoSize = sizeof(os);
134
135 if(!GetVersionExW((LPOSVERSIONINFOW)&os))
136 FATAL("GetVersionExW failed\n");
137
138 if(os.dwMajorVersion < 5)
139 EXCEPTION("Application requires at least Windows 2000!\n");
140
141 if(os.wProductType == VER_NT_WORKSTATION)
142 ProductType = 'w';
143 else
144 ProductType = 's';
145
146 /* Print all necessary identification information into the Platform string */
147 ss << os.dwMajorVersion << '.'
148 << os.dwMinorVersion << '.'
149 << os.dwBuildNumber << '.'
150 << os.wServicePackMajor << '.'
151 << os.wServicePackMinor << '.'
152 << ProductType << '.';
153 }
154
155 /* We also need to know about the processor architecture.
156 To retrieve this information accurately, check whether "GetNativeSystemInfo" is exported and use it then, otherwise fall back to "GetSystemInfo". */
157 hKernel32 = GetModuleHandleW(L"KERNEL32.DLL");
158 GetSysInfo = (GETSYSINFO)GetProcAddress(hKernel32, "GetNativeSystemInfo");
159
160 if(!GetSysInfo)
161 GetSysInfo = (GETSYSINFO)GetProcAddress(hKernel32, "GetSystemInfo");
162
163 GetSysInfo(&si);
164 ss << si.wProcessorArchitecture;
165
166 m_SystemInfoRequestString = ss.str();
167 }
168
169 /**
170 * Reads additional configuration options from the INI file.
171 *
172 * ParseParameters should be called before this function to get the desired result.
173 */
174 void
175 CConfiguration::GetConfigurationFromFile()
176 {
177 DWORD Length;
178 string Value;
179 WCHAR ConfigFile[MAX_PATH];
180
181 /* Most values are only needed if we're going to submit anything */
182 if(m_Submit)
183 {
184 /* Build the path to the configuration file from the application's path */
185 GetModuleFileNameW(NULL, ConfigFile, MAX_PATH);
186 Length = wcsrchr(ConfigFile, '\\') - ConfigFile + 1;
187 wcscpy(&ConfigFile[Length], CONFIGURATION_FILENAMEW);
188
189 /* Check if it exists */
190 if(GetFileAttributesW(ConfigFile) == INVALID_FILE_ATTRIBUTES)
191 EXCEPTION("Missing \"" CONFIGURATION_FILENAMEA "\" configuration file!\n");
192
193 /* Get the user name */
194 m_AuthenticationRequestString = "&sourceid=";
195 Value = GetINIValue(L"Login", L"SourceID", ConfigFile);
196
197 if(Value.empty())
198 EXCEPTION("SourceID is missing in the configuration file\n");
199
200 m_AuthenticationRequestString += EscapeString(Value);
201
202 /* Get the password */
203 m_AuthenticationRequestString += "&password=";
204 Value = GetINIValue(L"Login", L"Password", ConfigFile);
205
206 if(Value.empty())
207 EXCEPTION("Password is missing in the configuration file\n");
208
209 m_AuthenticationRequestString += EscapeString(Value);
210
211 /* If we don't have any Comment string yet, try to find one in the INI file */
212 if(m_Comment.empty())
213 m_Comment = GetINIValue(L"Submission", L"Comment", ConfigFile);
214 }
215 }