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