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=";
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 from the application's path */
80 GetModuleFileNameW(NULL
, ConfigFile
, MAX_PATH
);
81 Length
= wcsrchr(ConfigFile
, '\\') - ConfigFile
;
82 wcscpy(&ConfigFile
[Length
], L
"\\rosautotest.ini");
84 /* Check if it exists */
85 if(GetFileAttributesW(ConfigFile
) == INVALID_FILE_ATTRIBUTES
)
87 StringOut("Missing \"rosautotest.ini\" configuration file!\n");
91 /* Get the required length of the authentication request string */
92 DataLength
= sizeof(UserNameProp
) - 1;
93 Length
= IntGetINIValueA(L
"Login", L
"UserName", ConfigFile
, &UserName
);
97 StringOut("UserName is missing in the configuration file\n");
101 /* Some characters might need to be escaped and an escaped character takes 3 bytes */
102 DataLength
+= 3 * Length
;
104 DataLength
+= sizeof(PasswordProp
) - 1;
105 Length
= IntGetINIValueA(L
"Login", L
"Password", ConfigFile
, &Password
);
109 StringOut("Password is missing in the configuration file\n");
113 DataLength
+= 3 * Length
;
115 /* Build the string */
116 AuthenticationRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
118 strcpy(AuthenticationRequestString
, UserNameProp
);
119 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], UserName
);
121 strcat(AuthenticationRequestString
, PasswordProp
);
122 EscapeString(&AuthenticationRequestString
[strlen(AuthenticationRequestString
)], Password
);
128 * Determines on which platform we're running on.
129 * Prepares the appropriate request strings needed if we want to submit test results to the web service.
132 IntGetBuildAndPlatform()
134 const CHAR PlatformProp
[] = "&platform=";
135 const CHAR RevisionProp
[] = "&revision=";
137 CHAR BuildNo
[BUILDNO_LENGTH
];
138 CHAR Platform
[PLATFORM_LENGTH
];
139 CHAR PlatformArchitecture
[3];
142 GETSYSINFO GetSysInfo
;
146 WCHAR WindowsDirectory
[MAX_PATH
];
148 /* Get the build from the define */
149 _ultoa(KERNEL_VERSION_BUILD_HEX
, BuildNo
, 10);
151 /* Check if we are running under ReactOS from the SystemRoot directory */
152 GetWindowsDirectoryW(WindowsDirectory
, MAX_PATH
);
154 if(!_wcsnicmp(&WindowsDirectory
[3], L
"reactos", 7))
156 /* Yes, we are most-probably under ReactOS */
157 strcpy(Platform
, "reactos");
161 /* No, then use the info from GetVersionExW */
162 os
.dwOSVersionInfoSize
= sizeof(os
);
164 if(!GetVersionExW((LPOSVERSIONINFOW
)&os
))
166 StringOut("GetVersionExW failed\n");
170 if(os
.dwMajorVersion
< 5)
172 StringOut("Application requires at least Windows 2000!\n");
176 if(os
.wProductType
== VER_NT_WORKSTATION
)
181 /* Print all necessary identification information into the Platform string */
182 sprintf(Platform
, "%lu.%lu.%lu.%u.%u.%c", os
.dwMajorVersion
, os
.dwMinorVersion
, os
.dwBuildNumber
, os
.wServicePackMajor
, os
.wServicePackMinor
, ProductType
);
185 /* We also need to know about the processor architecture.
186 To retrieve this information accurately, check whether "GetNativeSystemInfo" is exported and use it then, otherwise fall back to "GetSystemInfo". */
187 hKernel32
= GetModuleHandleW(L
"KERNEL32.DLL");
188 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetNativeSystemInfo");
191 GetSysInfo
= (GETSYSINFO
)GetProcAddress(hKernel32
, "GetSystemInfo");
195 PlatformArchitecture
[0] = '.';
196 _ultoa(si
.wProcessorArchitecture
, &PlatformArchitecture
[1], 10);
197 PlatformArchitecture
[2] = 0;
198 strcat(Platform
, PlatformArchitecture
);
200 /* Get the required length of the system info request string */
201 DataLength
= sizeof(RevisionProp
) - 1;
202 DataLength
+= strlen(BuildNo
);
203 DataLength
+= sizeof(PlatformProp
) - 1;
204 DataLength
+= strlen(Platform
);
206 /* Now build the string */
207 SystemInfoRequestString
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
208 strcpy(SystemInfoRequestString
, RevisionProp
);
209 strcat(SystemInfoRequestString
, BuildNo
);
210 strcat(SystemInfoRequestString
, PlatformProp
);
211 strcat(SystemInfoRequestString
, Platform
);
217 * Prints the application usage.
222 printf("rosautotest - ReactOS Automatic Testing Utility\n");
223 printf("Usage: rosautotest [options] [module] [test]\n");
224 printf(" options:\n");
225 printf(" /? - Shows this help\n");
226 printf(" /s - Shut down the system after finishing the tests\n");
227 printf(" /w - Submit the results to the webservice\n");
228 printf(" Requires a \"rosautotest.ini\" with valid login data.\n");
230 printf(" module:\n");
231 printf(" The module to be tested (i.e. \"advapi32\")\n");
232 printf(" If this parameter is specified without any test parameter,\n");
233 printf(" all tests of the specified module are run.\n");
236 printf(" The test to be run. Needs to be a test of the specified module.\n");
243 wmain(int argc
, wchar_t* argv
[])
248 hProcessHeap
= GetProcessHeap();
250 /* Parse the command line arguments */
251 for(i
= 1; i
< (UINT
)argc
; i
++)
253 if(argv
[i
][0] == '-' || argv
[i
][0] == '/')
258 AppOptions
.Shutdown
= TRUE
;
262 AppOptions
.Submit
= TRUE
;
278 /* Which parameter is this? */
279 if(!AppOptions
.Module
)
281 /* Copy the parameter */
282 Length
= (wcslen(argv
[i
]) + 1) * sizeof(WCHAR
);
283 AppOptions
.Module
= HeapAlloc(hProcessHeap
, 0, Length
);
284 memcpy(AppOptions
.Module
, argv
[i
], Length
);
286 else if(!AppOptions
.Test
)
288 /* Copy the parameter converted to ASCII */
289 Length
= WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, NULL
, 0, NULL
, NULL
);
290 AppOptions
.Test
= HeapAlloc(hProcessHeap
, 0, Length
);
291 WideCharToMultiByte(CP_ACP
, 0, argv
[i
], -1, AppOptions
.Test
, Length
, NULL
, NULL
);
302 if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests())
309 OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
313 if(AppOptions
.Module
)
314 HeapFree(hProcessHeap
, 0, AppOptions
.Module
);
317 HeapFree(hProcessHeap
, 0, AppOptions
.Test
);
319 if(AuthenticationRequestString
)
320 HeapFree(hProcessHeap
, 0, AuthenticationRequestString
);
322 if(SystemInfoRequestString
)
323 HeapFree(hProcessHeap
, 0, SystemInfoRequestString
);
325 /* Shut down the system if requested */
326 if(AppOptions
.Shutdown
&& !ShutdownSystem())