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