1 /* 2 * PROJECT: ReactOS Automatic Testing Utility 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Main implementation file 5 * COPYRIGHT: Copyright 2008-2009 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 #include <cstdio> 10 #include <ndk/setypes.h> 11 #include <ndk/exfuncs.h> 12 13 CConfiguration Configuration; 14 15 /** 16 * Prints the application usage. 17 */ 18 static void 19 IntPrintUsage() 20 { 21 cout << "rosautotest - ReactOS Automatic Testing Utility" << endl 22 << "Usage: rosautotest [options] [module] [test]" << endl 23 << " options:" << endl 24 << " /? - Shows this help." << endl 25 << " /c <comment> - Specifies the comment to be submitted to the Web Service." << endl 26 << " Skips the comment set in the configuration file (if any)." << endl 27 << " Only has an effect when /w is also used." << endl 28 << " /n - Do not print test output to console" << endl 29 << " /r - Maintain information to resume from ReactOS crashes" << endl 30 << " Can only be run under ReactOS and relies on sysreg2," << endl 31 << " so incompatible with /w" << endl 32 << " /s - Shut down the system after finishing the tests." << endl 33 << " /t <num> - Repeat the test <num> times (1-10000)" << endl 34 << " /w - Submit the results to the webservice." << endl 35 << " Requires a \"rosautotest.ini\" with valid login data." << endl 36 << " Incompatible with the /r option." << endl 37 << " /l - List all modules that would run." << endl 38 << endl 39 << " module:" << endl 40 << " The module to be tested (i.e. \"advapi32\")" << endl 41 << " If this parameter is specified without any test parameter," << endl 42 << " all tests of the specified module are run." << endl 43 << endl 44 << " test:" << endl 45 << " The test to be run. Needs to be a test of the specified module." << endl; 46 } 47 48 static 49 VOID 50 SetNtGlobalFlags() 51 { 52 ULONG NtGlobalFlags = 0; 53 BOOLEAN PrivilegeEnabled; 54 NTSTATUS Status; 55 56 /* Enable SeDebugPrivilege */ 57 Status = RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &PrivilegeEnabled); 58 if (!NT_SUCCESS(Status)) 59 { 60 DbgPrint("Failed to enable SeDebugPrivilege: 0x%08lx\n", Status); 61 return; 62 } 63 64 /* Get current NtGlobalFlags */ 65 Status = NtQuerySystemInformation(SystemFlagsInformation, &NtGlobalFlags, sizeof(NtGlobalFlags), NULL); 66 if (!NT_SUCCESS(Status)) 67 { 68 DbgPrint("Failed to get NtGlobalFlags: 0x%08lx\n", Status); 69 return; 70 } 71 72 /* Disable debug prompts */ 73 NtGlobalFlags |= FLG_DISABLE_DEBUG_PROMPTS; 74 75 /* Set new NtGlobalFlags */ 76 Status = NtSetSystemInformation(SystemFlagsInformation, &NtGlobalFlags, sizeof(NtGlobalFlags)); 77 if (!NT_SUCCESS(Status)) 78 { 79 DbgPrint("Failed to set NtGlobalFlags: 0x%08lx\n", Status); 80 } 81 } 82 83 /** 84 * Main entry point 85 */ 86 extern "C" int 87 wmain(int argc, wchar_t* argv[]) 88 { 89 int ReturnValue = 1; 90 91 SetNtGlobalFlags(); 92 93 try 94 { 95 stringstream ss; 96 97 /* Set up the configuration */ 98 Configuration.ParseParameters(argc, argv); 99 Configuration.GetSystemInformation(); 100 Configuration.GetConfigurationFromFile(); 101 102 ss << endl 103 << endl 104 << "[ROSAUTOTEST] System uptime " << setprecision(2) << fixed; 105 ss << ((float)GetTickCount()/1000) << " seconds" << endl; 106 StringOut(ss.str()); 107 108 /* Report tests startup */ 109 InitLogs(); 110 ReportEventW(hLog, 111 EVENTLOG_INFORMATION_TYPE, 112 0, 113 MSG_TESTS_STARTED, 114 NULL, 115 0, 116 0, 117 NULL, 118 NULL); 119 120 if (Configuration.GetRepeatCount() > 1) 121 { 122 stringstream ss1; 123 124 ss1 << "[ROSAUTOTEST] The test will be repeated " << Configuration.GetRepeatCount() << " times" << endl; 125 StringOut(ss1.str()); 126 } 127 128 /* Run the tests */ 129 for (unsigned long i = 0; i < Configuration.GetRepeatCount(); i++) 130 { 131 CWineTest WineTest; 132 133 if (Configuration.GetRepeatCount() > 1) 134 { 135 stringstream ss; 136 ss << "[ROSAUTOTEST] Running attempt #" << i+1 << endl; 137 StringOut(ss.str()); 138 } 139 WineTest.Run(); 140 } 141 142 /* For sysreg2 */ 143 DbgPrint("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n"); 144 145 ReturnValue = 0; 146 } 147 catch(CInvalidParameterException) 148 { 149 IntPrintUsage(); 150 } 151 catch(CSimpleException& e) 152 { 153 stringstream ss; 154 155 // e.GetMessage() must include ending '\n'. 156 ss << "[ROSAUTOTEST] " << e.GetMessage(); 157 StringOut(ss.str()); 158 } 159 catch(CFatalException& e) 160 { 161 stringstream ss; 162 163 // e.GetMessage() must include ending '\n'. 164 ss << "An exception occured in rosautotest." << endl 165 << "Message: " << e.GetMessage() 166 << "File: " << e.GetFile() << endl 167 << "Line: " << e.GetLine() << endl 168 << "Last Win32 Error: " << GetLastError() << endl; 169 StringOut(ss.str()); 170 } 171 172 /* For sysreg2 to notice if rosautotest itself failed */ 173 if(ReturnValue == 1) 174 DbgPrint("SYSREG_ROSAUTOTEST_FAILURE\n"); 175 176 /* Report successful end of tests */ 177 ReportEventW(hLog, 178 EVENTLOG_SUCCESS, 179 0, 180 MSG_TESTS_SUCCESSFUL, 181 NULL, 182 0, 183 0, 184 NULL, 185 NULL); 186 FreeLogs(); 187 188 /* Shut down the system if requested, also in case of an exception above */ 189 if(Configuration.DoShutdown() && !ShutdownSystem()) 190 ReturnValue = 1; 191 192 return ReturnValue; 193 } 194