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