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