2 * PROJECT: ReactOS Automatic Testing Utility
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
4 * PURPOSE: Main implementation file
5 * COPYRIGHT: Copyright 2008-2009 Colin Finck <colin@reactos.org>
10 typedef void (WINAPI
*GETSYSINFO
)(LPSYSTEM_INFO
);
12 APP_OPTIONS AppOptions
= {0};
14 PCHAR AuthenticationRequestString
= NULL
;
15 PCHAR SystemInfoRequestString
= NULL
;
18 * Gets a value from a specified INI file and returns it converted to ASCII.
21 * The INI section to look in (lpAppName parameter passed to GetPrivateProfileStringW)
24 * The key to look for in the specified section (lpKeyName parameter passed to GetPrivateProfileStringW)
27 * The path to the INI file
29 * @param ReturnedValue
30 * Pointer to a CHAR pointer, which will receive the read and converted value.
31 * The caller needs to HeapFree that value manually.
34 * Returns the string length of the read value (in characters) or zero if we didn't get any value.
37 IntGetINIValueA(PCWCH AppName
, PCWCH KeyName
, PCWCH FileName
, char** ReturnedValue
)
42 /* Load the value into a temporary Unicode buffer */
43 Length
= GetPrivateProfileStringW(AppName
, KeyName
, NULL
, Buffer
, sizeof(Buffer
) / sizeof(WCHAR
), FileName
);
48 /* Convert the string to ANSI charset */
49 *ReturnedValue
= HeapAlloc(hProcessHeap
, 0, Length
+ 1);
50 WideCharToMultiByte(CP_ACP
, 0, Buffer
, Length
+ 1, *ReturnedValue
, Length
+ 1, NULL
, NULL
);
56 * Gets the username and password from the "rosautotest.ini" file if the user enabled submitting the results to the web service.
57 * The "rosautotest.ini" file should look like this:
61 * Password=TestPassword
64 IntGetConfigurationValues()
66 const CHAR PasswordProp
[] = "&password=";
67 const CHAR UserNameProp
[] = "&username=";
69 BOOL ReturnValue
= FALSE
;
72 PCHAR Password
= NULL
;
73 PCHAR UserName
= NULL
;
74 WCHAR ConfigFile
[MAX_PATH
];
76 /* We only need this if the results are going to be submitted */
77 if(!AppOptions
.Submit
)
83 /* Build the path to the configuration file from the application's path */
84 GetModuleFileNameW(NULL
, ConfigFile
, MAX_PATH
);
85 Length
= wcsrchr(ConfigFile
, '\\') - ConfigFile
;
86 wcscpy(&ConfigFile
[Length
], L
"\\rosautotest.ini");
88 /* Check if it exists */
89 if(GetFileAttributesW(ConfigFile
) == INVALID_FILE_ATTRIBUTES
)
91 StringOut("Missing \"rosautotest.ini\" configuration file!\n");
95 /* Get the required length of the authentication request string */
96 DataLength
= sizeof(UserNameProp
) - 1;
97 Length
= IntGetINIValueA(L
"Login", L
"UserName", ConfigFile
, &UserName
);
101 StringOut("UserName is missing in the configuration file\n");
105 /* Some characters might need to be escaped and an escaped character takes 3 bytes */
106 DataLength
+= 3 * Length
;
108 DataLength
+= sizeof(PasswordProp
) - 1;
109 Length
= IntGetINIValueA(L
"Login", L
"Password", ConfigFile
, &Password
);
113 StringOut("Password is missing in the configuration file\n");
117 DataLength
+= 3 * Length
;
119 /* Build the string */
120 AuthenticationRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
122 strcpy(AuthenticationRequestString
, UserNameProp
);
123 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], UserName
);
125 strcat(AuthenticationRequestString
, PasswordProp
);
126 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], Password
);
132 HeapFree(hProcessHeap
, 0, UserName
);
135 HeapFree(hProcessHeap
, 0, Password
);
141 * Determines on which platform we're running on.
142 * Prepares the appropriate request strings needed if we want to submit test results to the web service.
145 IntGetBuildAndPlatform()
147 const CHAR PlatformProp
[] = "&platform=";
148 const CHAR RevisionProp
[] = "&revision=";
150 CHAR BuildNo
[BUILDNO_LENGTH
];
151 CHAR Platform
[PLATFORM_LENGTH
];
152 CHAR PlatformArchitecture
[3];
155 GETSYSINFO GetSysInfo
;
159 WCHAR WindowsDirectory
[MAX_PATH
];
161 /* Get the build from the define */
162 _ultoa(KERNEL_VERSION_BUILD_HEX
, BuildNo
, 10);
164 /* Check if we are running under ReactOS from the SystemRoot directory */
165 GetWindowsDirectoryW(WindowsDirectory
, MAX_PATH
);
167 if(!_wcsnicmp(&WindowsDirectory
[3], L
"reactos", 7))
169 /* Yes, we are most-probably under ReactOS */
170 strcpy(Platform
, "reactos");
174 /* No, then use the info from GetVersionExW */
175 os
.dwOSVersionInfoSize
= sizeof(os
);
177 if(!GetVersionExW((LPOSVERSIONINFOW
)&os
))
179 StringOut("GetVersionExW failed\n");
183 if(os
.dwMajorVersion
< 5)
185 StringOut("Application requires at least Windows 2000!\n");
189 if(os
.wProductType
== VER_NT_WORKSTATION
)
194 /* Print all necessary identification information into the Platform string */
195 sprintf(Platform
, "%lu.%lu.%lu.%u.%u.%c", os
.dwMajorVersion
, os
.dwMinorVersion
, os
.dwBuildNumber
, os
.wServicePackMajor
, os
.wServicePackMinor
, ProductType
);
198 /* We also need to know about the processor architecture.
199 To retrieve this information accurately, check whether "GetNativeSystemInfo" is exported and use it then, otherwise fall back to "GetSystemInfo". */
200 hKernel32
= GetModuleHandleW(L
"KERNEL32.DLL");
201 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetNativeSystemInfo");
204 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetSystemInfo");
208 PlatformArchitecture
[0] = '.';
209 _ultoa(si
.wProcessorArchitecture
, &PlatformArchitecture
[1], 10);
210 PlatformArchitecture
[2] = 0;
211 strcat(Platform
, PlatformArchitecture
);
213 /* Get the required length of the system info request string */
214 DataLength
= sizeof(RevisionProp
) - 1;
215 DataLength
+= strlen(BuildNo
);
216 DataLength
+= sizeof(PlatformProp
) - 1;
217 DataLength
+= strlen(Platform
);
219 /* Now build the string */
220 SystemInfoRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
221 strcpy(SystemInfoRequestString
, RevisionProp
);
222 strcat(SystemInfoRequestString
, BuildNo
);
223 strcat(SystemInfoRequestString
, PlatformProp
);
224 strcat(SystemInfoRequestString
, Platform
);
230 * Prints the application usage.
235 printf("rosautotest - ReactOS Automatic Testing Utility\n");
236 printf("Usage: rosautotest [options] [module] [test]\n");
237 printf(" options:\n");
238 printf(" /? - Shows this help\n");
239 printf(" /s - Shut down the system after finishing the tests\n");
240 printf(" /w - Submit the results to the webservice\n");
241 printf(" Requires a \"rosautotest.ini\" with valid login data.\n");
243 printf(" module:\n");
244 printf(" The module to be tested (i.e. \"advapi32\")\n");
245 printf(" If this parameter is specified without any test parameter,\n");
246 printf(" all tests of the specified module are run.\n");
249 printf(" The test to be run. Needs to be a test of the specified module.\n");
256 wmain(int argc
, wchar_t* argv
[])
261 hProcessHeap
= GetProcessHeap();
263 /* Parse the command line arguments */
264 for(i
= 1; i
< (UINT
)argc
; i
++)
266 if(argv
[i
][0] == '-' || argv
[i
][0] == '/')
271 AppOptions
.Shutdown
= TRUE
;
275 AppOptions
.Submit
= TRUE
;
291 /* Which parameter is this? */
292 if(!AppOptions
.Module
)
294 /* Copy the parameter */
295 Length
= (wcslen(argv
[i
]) + 1) * sizeof(WCHAR
);
296 AppOptions
.Module
= HeapAlloc(hProcessHeap
, 0, Length
);
297 memcpy(AppOptions
.Module
, argv
[i
], Length
);
299 else if(!AppOptions
.Test
)
301 /* Copy the parameter converted to ASCII */
302 Length
= WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, NULL
, 0, NULL
, NULL
);
303 AppOptions
.Test
= HeapAlloc(hProcessHeap
, 0, Length
);
304 WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, AppOptions
.Test
, Length
, NULL
, NULL
);
315 if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests())
322 OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
325 if(AppOptions
.Module
)
326 HeapFree(hProcessHeap
, 0, AppOptions
.Module
);
329 HeapFree(hProcessHeap
, 0, AppOptions
.Test
);
331 if(AuthenticationRequestString
)
332 HeapFree(hProcessHeap
, 0, AuthenticationRequestString
);
334 if(SystemInfoRequestString
)
335 HeapFree(hProcessHeap
, 0, SystemInfoRequestString
);
337 /* Shut down the system if requested */
338 if(AppOptions
.Shutdown
&& !ShutdownSystem())