Report current bus number during IRP_MN_QUERY_RESOURCES
[reactos.git] / cis / ReactOS.Verify / Main.cs
1 using System;
2 using System.IO;
3 using System.Diagnostics;
4 using System.Configuration;
5 using System.Web.Mail;
6 using System.Collections;
7 using System.Collections.Specialized;
8
9 namespace ReactOS.Verify
10 {
11 public class MainClass
12 {
13 /// <summary>
14 /// Run the application.
15 /// </summary>
16 /// <param name="script">Script to run.</param>
17 /// <param name="args">Arguments to pass to script.</param>
18 /// <param name="workingDirectory">Working directory.</param>
19 /// <param name="standardOutput">Receives standard output.</param>
20 /// <param name="standardError">Receives standard error.</param>
21 /// <returns>
22 /// Exit code.
23 /// </returns>
24 private static int RunScript(string script,
25 string args,
26 string workingDirectory,
27 StringDictionary environmentVarables,
28 out string standardOutput,
29 out string standardError)
30 {
31 ProcessStartInfo scriptProcessStartInfo = new ProcessStartInfo(script,
32 args);
33 scriptProcessStartInfo.CreateNoWindow = true;
34 /*
35 * All standard streams must be redirected.
36 * Otherwise DuplicateHandle() will fail.
37 */
38 scriptProcessStartInfo.RedirectStandardInput = true;
39 scriptProcessStartInfo.RedirectStandardError = true;
40 scriptProcessStartInfo.RedirectStandardOutput = true;
41 scriptProcessStartInfo.UseShellExecute = false;
42 scriptProcessStartInfo.WorkingDirectory = workingDirectory;
43 if (environmentVarables != null)
44 {
45 foreach (DictionaryEntry de in environmentVarables)
46 scriptProcessStartInfo.EnvironmentVariables.Add(de.Key as string, de.Value as string);
47 }
48 RedirectableProcess redirectableProcess = new RedirectableProcess(scriptProcessStartInfo);
49 standardOutput = redirectableProcess.ProcessOutput;
50 standardError = redirectableProcess.ProcessError;
51 return redirectableProcess.ExitCode;
52 }
53
54 /// <summary>
55 /// Retrieve value of configuration from configuration file.
56 /// </summary>
57 /// <param name="name">Name of configuration option.</param>
58 /// <param name="defaultValue">
59 /// Default value to be returned if the option does not exist.
60 /// </param>
61 /// <returns>
62 /// Value of configuration option or null if the option does not
63 /// exist and no default value is provided.
64 /// </returns>
65 private static string GetConfigurationOption(string name,
66 string defaultValue)
67 {
68 if (ConfigurationSettings.AppSettings[name] != null)
69 {
70 string s = ConfigurationSettings.AppSettings[name].Trim();
71 return s.Equals(String.Empty) ? defaultValue : s;
72 }
73 else
74 return defaultValue;
75 }
76
77 /// <summary>
78 /// Send an email.
79 /// </summary>
80 /// <param name="subject">Subject of the email.</param>
81 /// <param name="body">Content of the email.</param>
82 private static void SendErrorMail(string subject, string body)
83 {
84 try
85 {
86 string smtpServer = GetConfigurationOption("smtpServer", "localhost");
87 string email = GetConfigurationOption("errorEmail", null);
88 if (email == null)
89 return;
90 MailMessage mm = new MailMessage();
91 mm.Priority = MailPriority.Normal;
92 mm.From = email;
93 mm.To = email;
94 mm.Subject = subject;
95 mm.Body += body;
96 mm.Body += "<br>";
97 mm.BodyFormat = MailFormat.Html;
98 SmtpMail.SmtpServer = smtpServer;
99 SmtpMail.Send(mm);
100 }
101 catch (Exception ex)
102 {
103 Console.Error.WriteLine(ex.Message);
104 }
105 }
106
107 /// <summary>
108 /// Fail with an error message.
109 /// </summary>
110 /// <param name="text">Error message.</param>
111 private static void Fail(string text)
112 {
113 Console.WriteLine(text);
114 }
115
116 /// <summary>
117 /// Paths to fast disk for temporary files.
118 /// </summary>
119 private static string TemporaryFastDisk
120 {
121 get
122 {
123 string temporaryFastDisk = GetConfigurationOption("temporaryFastDisk", null);
124 if (temporaryFastDisk == null || temporaryFastDisk.Trim().Equals(String.Empty))
125 return null;
126 return temporaryFastDisk.Trim();
127 }
128 }
129
130 /// <summary>
131 /// Paths to fast disk for intermediate files.
132 /// </summary>
133 private static string IntermediateFastDisk
134 {
135 get
136 {
137 string intermediateFastDisk = GetConfigurationOption("intermediateFastDisk", null);
138 if (intermediateFastDisk == null || intermediateFastDisk.Trim().Equals(String.Empty))
139 return null;
140 return intermediateFastDisk.Trim();
141 }
142 }
143
144 /// <summary>
145 /// Paths to fast disk for output files.
146 /// </summary>
147 private static string OutputFastDisk
148 {
149 get
150 {
151 string outputFastDisk = GetConfigurationOption("outputFastDisk", null);
152 if (outputFastDisk == null || outputFastDisk.Trim().Equals(String.Empty))
153 return null;
154 return outputFastDisk.Trim();
155 }
156 }
157
158 /// <summary>
159 /// Return collection of environment variables.
160 /// </summary>
161 /// <returns>Collection of environment variables or null if there is none.</returns>
162 private static StringDictionary GetEnvironmentVarables()
163 {
164 StringDictionary environmentVarables = new StringDictionary();
165 if (TemporaryFastDisk != null)
166 environmentVarables.Add("ROS_TEMPORARY", TemporaryFastDisk);
167 if (IntermediateFastDisk != null)
168 environmentVarables.Add("ROS_INTERMEDIATE", IntermediateFastDisk);
169 if (OutputFastDisk != null)
170 environmentVarables.Add("ROS_OUTPUT", OutputFastDisk);
171 return environmentVarables;
172 }
173
174 /// <summary>
175 /// Run make.
176 /// </summary>
177 /// <param name="arguments">Arguments.</param>
178 /// <param name="standardOutput">Receives standard output.</param>
179 /// <param name="standardError">Receives standard error.</param>
180 /// <returns>Make exit code.</returns>
181 private static int RunMake(string arguments,
182 out string standardOutput,
183 out string standardError)
184 {
185 string make = "mingw32-make";
186 string makeParameters = GetConfigurationOption("makeParameters", "");
187 string reactosDirectory = Path.Combine(System.Environment.CurrentDirectory,
188 "reactos");
189 return RunScript(make,
190 makeParameters + " " + arguments,
191 reactosDirectory,
192 GetEnvironmentVarables(),
193 out standardOutput,
194 out standardError);
195 }
196
197 /// <summary>
198 /// Verify a revision of ReactOS by building it all.
199 /// </summary>
200 private static int VerifyFull()
201 {
202 string standardOutput;
203 string standardError;
204 int exitCode = RunMake("bootcd",
205 out standardOutput,
206 out standardError);
207 if (exitCode != 0)
208 {
209 Fail(String.Format("make bootcd failed: (error: {0}) {1}",
210 standardError,
211 standardOutput));
212 return exitCode;
213 }
214
215 string reactosDirectory = Path.Combine(System.Environment.CurrentDirectory,
216 "reactos");
217 string isoFilename = Path.Combine(reactosDirectory,
218 "ReactOS.iso");
219 if (!File.Exists(isoFilename))
220 Fail("make bootcd produced no ReactOS.iso");
221
222 return exitCode;
223 }
224
225 /// <summary>
226 /// Verify a revision of ReactOS by building parts.
227 /// </summary>
228 /// <param name="components">Comma separated list of components to build.</param>
229 private static int VerifyPartial(string components)
230 {
231 string standardOutput;
232 string standardError;
233 string componentParameters = "\"" + components.Replace(",", "\" \"") + "\"";
234 int exitCode = RunMake(componentParameters,
235 out standardOutput,
236 out standardError);
237 if (exitCode != 0)
238 Fail(String.Format("make failed for targets {0}: (error: {1}) {2}",
239 componentParameters,
240 standardError,
241 standardOutput));
242 return exitCode;
243 }
244
245 /// <summary>
246 /// Verify a revision of ReactOS.
247 /// </summary>
248 /// <param name="args">Arguments from command line.</param>
249 private static int Verify(string[] args)
250 {
251 if (args.Length > 0)
252 return VerifyPartial(args[0]);
253 else
254 return VerifyFull();
255 }
256
257 /// <summary>
258 /// Program entry point.
259 /// </summary>
260 /// <param name="args">Arguments from command line.</param>
261 /// <remarks>
262 /// If exit code is 0, then the commit was processed successfully.
263 /// If exit code is 1, then the commit was not processed successfully.
264 /// </remarks>
265 public static void Main(string[] args)
266 {
267 try
268 {
269 System.Environment.ExitCode = Verify(args);
270 }
271 catch (Exception ex)
272 {
273 string text = String.Format("Exception: {0}", ex);
274 SendErrorMail("ReactOS Verify Error", text);
275 System.Environment.ExitCode = 1;
276 }
277 }
278 }
279 }