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