/* * PROJECT: ReactOS Automatic Testing Utility * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) * PURPOSE: Class for managing all the configuration parameters * COPYRIGHT: Copyright 2009-2011 Colin Finck (colin@reactos.org) */ #include "precomp.h" #define CONFIGURATION_FILENAMEA "rosautotest.ini" #define CONFIGURATION_FILENAMEW L"rosautotest.ini" typedef void (WINAPI *GETSYSINFO)(LPSYSTEM_INFO); /** * Constructs an empty CConfiguration object */ CConfiguration::CConfiguration() : m_CrashRecovery(false), m_IsInteractive(false), m_PrintToConsole(true), m_RepeatCount(1), m_Shutdown(false), m_Submit(false), m_ListModules(false) { WCHAR WindowsDirectory[MAX_PATH]; WCHAR Interactive[32]; /* Check if we are running under ReactOS from the SystemRoot directory */ if(!GetWindowsDirectoryW(WindowsDirectory, MAX_PATH)) FATAL("GetWindowsDirectoryW failed\n"); m_IsReactOS = !_wcsnicmp(&WindowsDirectory[3], L"reactos", 7); if(GetEnvironmentVariableW(L"WINETEST_INTERACTIVE", Interactive, _countof(Interactive))) m_IsInteractive = _wtoi(Interactive); } /** * Parses the passed parameters and sets the appropriate configuration settings. * * @param argc * The number of parameters (argc parameter of the wmain function) * * @param argv * Pointer to a wchar_t array containing the parameters (argv parameter of the wmain function) */ void CConfiguration::ParseParameters(int argc, wchar_t* argv[]) { /* Parse the command line arguments */ for(int i = 1; i < argc; i++) { if(argv[i][0] == '-' || argv[i][0] == '/') { unsigned long tmp_RepeatCount; switch(argv[i][1]) { case 'c': ++i; if (i >= argc) { throw CInvalidParameterException(); } m_Comment = UnicodeToAscii(argv[i]); break; case 'n': m_PrintToConsole = false; break; case 'r': m_CrashRecovery = true; break; case 's': m_Shutdown = true; break; case 'w': m_Submit = true; break; case 't': ++i; if (i >= argc) { throw CInvalidParameterException(); } tmp_RepeatCount = wcstoul(argv[i], NULL, 10); if (tmp_RepeatCount == 0 || tmp_RepeatCount > 10000) { throw CInvalidParameterException(); } m_RepeatCount = tmp_RepeatCount; break; case 'l': m_ListModules = true; break; default: throw CInvalidParameterException(); } } else { /* Which parameter is this? */ if(m_Module.empty()) { /* Copy the parameter */ m_Module = argv[i]; } else if(m_Test.empty()) { /* Copy the parameter converted to ASCII */ m_Test = UnicodeToAscii(argv[i]); } else { throw CInvalidParameterException(); } } } /* The /r and /w options shouldn't be used in conjunction */ if(m_CrashRecovery && m_Submit) throw CInvalidParameterException(); } /** * Gets information about the running system and sets the appropriate configuration settings. */ void CConfiguration::GetSystemInformation() { char ProductType; GETSYSINFO GetSysInfo; HMODULE hKernel32; OSVERSIONINFOEXW os; stringstream ss; SYSTEM_INFO si; /* Get the build from the define */ ss << "&revision="; ss << KERNEL_VERSION_COMMIT_HASH; ss << "&platform="; if(m_IsReactOS) { ss << "reactos"; } else { /* No, then use the info from GetVersionExW */ os.dwOSVersionInfoSize = sizeof(os); if(!GetVersionExW((LPOSVERSIONINFOW)&os)) FATAL("GetVersionExW failed\n"); if(os.dwMajorVersion < 5) EXCEPTION("Application requires at least Windows 2000!\n"); if(os.wProductType == VER_NT_WORKSTATION) ProductType = 'w'; else ProductType = 's'; /* Print all necessary identification information into the Platform string */ ss << os.dwMajorVersion << '.' << os.dwMinorVersion << '.' << os.dwBuildNumber << '.' << os.wServicePackMajor << '.' << os.wServicePackMinor << '.' << ProductType << '.'; } /* We also need to know about the processor architecture. To retrieve this information accurately, check whether "GetNativeSystemInfo" is exported and use it then, otherwise fall back to "GetSystemInfo". */ hKernel32 = GetModuleHandleW(L"KERNEL32.DLL"); GetSysInfo = (GETSYSINFO)GetProcAddress(hKernel32, "GetNativeSystemInfo"); if(!GetSysInfo) GetSysInfo = (GETSYSINFO)GetProcAddress(hKernel32, "GetSystemInfo"); GetSysInfo(&si); ss << si.wProcessorArchitecture; m_SystemInfoRequestString = ss.str(); } /** * Reads additional configuration options from the INI file. * * ParseParameters should be called before this function to get the desired result. */ void CConfiguration::GetConfigurationFromFile() { DWORD Length; string Value; WCHAR ConfigFile[MAX_PATH]; /* Most values are only needed if we're going to submit anything */ if(m_Submit) { /* Build the path to the configuration file from the application's path */ GetModuleFileNameW(NULL, ConfigFile, MAX_PATH); Length = wcsrchr(ConfigFile, '\\') - ConfigFile + 1; wcscpy(&ConfigFile[Length], CONFIGURATION_FILENAMEW); /* Check if it exists */ if(GetFileAttributesW(ConfigFile) == INVALID_FILE_ATTRIBUTES) EXCEPTION("Missing \"" CONFIGURATION_FILENAMEA "\" configuration file!\n"); /* Get the user name */ m_AuthenticationRequestString = "&sourceid="; Value = GetINIValue(L"Login", L"SourceID", ConfigFile); if(Value.empty()) EXCEPTION("SourceID is missing in the configuration file\n"); m_AuthenticationRequestString += EscapeString(Value); /* Get the password */ m_AuthenticationRequestString += "&password="; Value = GetINIValue(L"Login", L"Password", ConfigFile); if(Value.empty()) EXCEPTION("Password is missing in the configuration file\n"); m_AuthenticationRequestString += EscapeString(Value); /* If we don't have any Comment string yet, try to find one in the INI file */ if(m_Comment.empty()) m_Comment = GetINIValue(L"Submission", L"Comment", ConfigFile); } }