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
IntPrintUsage()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
SetNtGlobalFlags()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
wmain(int argc,wchar_t * argv[])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