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