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 hash 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 * PasswordHash=1234567890abcdef1234567890abcdef
64 IntGetConfigurationValues()
66 const CHAR PasswordHashProp
[] = "&passwordhash=";
67 const CHAR UserNameProp
[] = "&username=";
73 WCHAR ConfigFile
[MAX_PATH
];
75 /* We only need this if the results are going to be submitted */
76 if(!AppOptions
.Submit
)
79 /* Build the path to the configuration file */
80 Length
= GetWindowsDirectoryW(ConfigFile
, MAX_PATH
);
81 wcscpy(&ConfigFile
[Length
], L
"\\rosautotest.ini");
83 /* Check if it exists */
84 if(GetFileAttributesW(ConfigFile
) == INVALID_FILE_ATTRIBUTES
)
87 /* Get the required length of the authentication request string */
88 DataLength
= sizeof(UserNameProp
) - 1;
89 Length
= IntGetINIValueA(L
"Login", L
"UserName", ConfigFile
, &UserName
);
93 StringOut("UserName is missing in the configuration file\n");
97 /* Some characters might need to be escaped and an escaped character takes 3 bytes */
98 DataLength
+= 3 * Length
;
100 DataLength
+= sizeof(PasswordHashProp
) - 1;
101 Length
= IntGetINIValueA(L
"Login", L
"PasswordHash", ConfigFile
, &PasswordHash
);
105 StringOut("PasswordHash is missing in the configuration file\n");
109 DataLength
+= 3 * Length
;
111 /* Build the string */
112 AuthenticationRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
114 strcpy(AuthenticationRequestString
, UserNameProp
);
115 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], UserName
);
117 strcat(AuthenticationRequestString
, PasswordHashProp
);
118 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], PasswordHash
);
124 * Determines on which platform we're running on.
125 * Prepares the appropriate request strings needed if we want to submit test results to the web service.
128 IntGetBuildAndPlatform()
130 const CHAR PlatformProp
[] = "&platform=";
131 const CHAR RevisionProp
[] = "&revision=";
133 CHAR BuildNo
[BUILDNO_LENGTH
];
134 CHAR Platform
[PLATFORM_LENGTH
];
135 CHAR PlatformArchitecture
[3];
138 GETSYSINFO GetSysInfo
;
142 WCHAR WindowsDirectory
[MAX_PATH
];
144 /* Get the build from the define */
145 _ultoa(KERNEL_VERSION_BUILD_HEX
, BuildNo
, 10);
147 /* Check if we are running under ReactOS from the SystemRoot directory */
148 GetWindowsDirectoryW(WindowsDirectory
, MAX_PATH
);
150 if(!_wcsnicmp(&WindowsDirectory
[3], L
"reactos", 7))
152 /* Yes, we are most-probably under ReactOS */
153 strcpy(Platform
, "reactos");
157 /* No, then use the info from GetVersionExW */
158 os
.dwOSVersionInfoSize
= sizeof(os
);
160 if(!GetVersionExW((LPOSVERSIONINFOW
)&os
))
162 StringOut("GetVersionExW failed\n");
166 if(os
.dwMajorVersion
< 5)
168 StringOut("Application requires at least Windows 2000!\n");
172 if(os
.wProductType
== VER_NT_WORKSTATION
)
177 /* Print all necessary identification information into the Platform string */
178 sprintf(Platform
, "%lu.%lu.%lu.%u.%u.%c", os
.dwMajorVersion
, os
.dwMinorVersion
, os
.dwBuildNumber
, os
.wServicePackMajor
, os
.wServicePackMinor
, ProductType
);
181 /* We also need to know about the processor architecture.
182 To retrieve this information accurately, check whether "GetNativeSystemInfo" is exported and use it then, otherwise fall back to "GetSystemInfo". */
183 hKernel32
= GetModuleHandleW(L
"KERNEL32.DLL");
184 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetNativeSystemInfo");
187 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetSystemInfo");
191 PlatformArchitecture
[0] = '.';
192 _ultoa(si
.wProcessorArchitecture
, &PlatformArchitecture
[1], 10);
193 PlatformArchitecture
[2] = 0;
194 strcat(Platform
, PlatformArchitecture
);
196 /* Get the required length of the system info request string */
197 DataLength
= sizeof(RevisionProp
) - 1;
198 DataLength
+= strlen(BuildNo
);
199 DataLength
+= sizeof(PlatformProp
) - 1;
200 DataLength
+= strlen(Platform
);
202 /* Now build the string */
203 SystemInfoRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
204 strcpy(SystemInfoRequestString
, RevisionProp
);
205 strcat(SystemInfoRequestString
, BuildNo
);
206 strcat(SystemInfoRequestString
, PlatformProp
);
207 strcat(SystemInfoRequestString
, Platform
);
213 * Prints the application usage.
218 printf("rosautotest - ReactOS Automatic Testing Utility\n");
219 printf("Usage: rosautotest [options] [module] [test]\n");
220 printf(" options:\n");
221 printf(" /? - Shows this help\n");
222 printf(" /s - Shut down the system after finishing the tests\n");
223 printf(" /w - Submit the results to the webservice\n");
224 printf(" Requires a \"rosautotest.ini\" with valid login data.\n");
226 printf(" module:\n");
227 printf(" The module to be tested (i.e. \"advapi32\")\n");
228 printf(" If this parameter is specified without any test parameter,\n");
229 printf(" all tests of the specified module are run.\n");
232 printf(" The test to be run. Needs to be a test of the specified module.\n");
239 wmain(int argc
, wchar_t* argv
[])
244 hProcessHeap
= GetProcessHeap();
246 /* Parse the command line arguments */
247 for(i
= 1; i
< (UINT
)argc
; i
++)
249 if(argv
[i
][0] == '-' || argv
[i
][0] == '/')
254 AppOptions
.Shutdown
= TRUE
;
258 AppOptions
.Submit
= TRUE
;
274 /* Which parameter is this? */
275 if(!AppOptions
.Module
)
277 /* Copy the parameter */
278 Length
= (wcslen(argv
[i
]) + 1) * sizeof(WCHAR
);
279 AppOptions
.Module
= HeapAlloc(hProcessHeap
, 0, Length
);
280 memcpy(AppOptions
.Module
, argv
[i
], Length
);
282 else if(!AppOptions
.Test
)
284 /* Copy the parameter converted to ASCII */
285 Length
= WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, NULL
, 0, NULL
, NULL
);
286 AppOptions
.Test
= HeapAlloc(hProcessHeap
, 0, Length
);
287 WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, AppOptions
.Test
, Length
, NULL
, NULL
);
298 if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests())
305 OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
309 if(AppOptions
.Module
)
310 HeapFree(hProcessHeap
, 0, AppOptions
.Module
);
313 HeapFree(hProcessHeap
, 0, AppOptions
.Test
);
315 if(AuthenticationRequestString
)
316 HeapFree(hProcessHeap
, 0, AuthenticationRequestString
);
318 if(SystemInfoRequestString
)
319 HeapFree(hProcessHeap
, 0, SystemInfoRequestString
);
321 /* Shut down the system if requested */
322 if(AppOptions
.Shutdown
&& !ShutdownSystem())