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 */ 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 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 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 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