*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
* This program is dedicated to Anna Lindh,
* Swedish Minister of Foreign Affairs.
#include "winetest.h"
#include "resource.h"
+#include <reason.h>
struct wine_test
{
char *tag = NULL;
static struct wine_test *wine_tests;
+static int nr_of_files, nr_of_tests;
static struct rev_info *rev_infos = NULL;
static const char whitespace[] = " \t\r\n";
+static const char testexe[] = "_test.exe";
+
+static char * get_file_version(char * file_name)
+{
+ static char version[32];
+ DWORD size;
+ DWORD handle;
+
+ size = GetFileVersionInfoSizeA(file_name, &handle);
+ if (size) {
+ char * data = xmalloc(size);
+ if (data) {
+ if (GetFileVersionInfoA(file_name, handle, size, data)) {
+ static char backslash[] = "\\";
+ VS_FIXEDFILEINFO *pFixedVersionInfo;
+ UINT len;
+ if (VerQueryValueA(data, backslash, (LPVOID *)&pFixedVersionInfo, &len)) {
+ sprintf(version, "%d.%d.%d.%d",
+ pFixedVersionInfo->dwFileVersionMS >> 16,
+ pFixedVersionInfo->dwFileVersionMS & 0xffff,
+ pFixedVersionInfo->dwFileVersionLS >> 16,
+ pFixedVersionInfo->dwFileVersionLS & 0xffff);
+ } else
+ sprintf(version, "version not available");
+ } else
+ sprintf(version, "unknown");
+ free(data);
+ } else
+ sprintf(version, "failed");
+ } else
+ sprintf(version, "version not available");
+
+ return version;
+}
static int running_under_wine (void)
{
{
OSVERSIONINFOEX ver;
BOOL ext;
+ int is_win2k3_r2;
+ const char *(*wine_get_build_id)(void);
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (!(ext = GetVersionEx ((OSVERSIONINFO *) &ver)))
ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber,
ver.dwPlatformId, ver.szCSDVersion);
+ wine_get_build_id = (void *)GetProcAddress(GetModuleHandleA("ntdll.dll"), "wine_get_build_id");
+ if (wine_get_build_id) xprintf( " WineBuild=%s\n", wine_get_build_id() );
+
+ is_win2k3_r2 = GetSystemMetrics(SM_SERVERR2);
+ if(is_win2k3_r2)
+ xprintf(" R2 build number=%d\n", is_win2k3_r2);
+
if (!ext) return;
xprintf (" wServicePackMajor=%d\n wServicePackMinor=%d\n"
static const char* get_test_source_file(const char* test, const char* subtest)
{
static const char* special_dirs[][2] = {
- { "gdi32", "gdi"}, { "kernel32", "kernel" },
- { "msacm32", "msacm" },
- { "user32", "user" }, { "winspool.drv", "winspool" },
- { "ws2_32", "winsock" }, { 0, 0 }
+ { 0, 0 }
};
static char buffer[MAX_PATH];
int i;
static const char* get_file_rev(const char* file)
{
const struct rev_info* rev;
-
+
for(rev = rev_infos; rev->file; rev++) {
if (strcmp(rev->file, file) == 0) return rev->rev;
}
len = LoadStringA (module, REV_INFO+i, revinfo, sizeof(revinfo));
if (len == 0) break; /* end of revision info */
- if (len >= sizeof(revinfo) - 1)
+ if (len >= sizeof(revinfo) - 1)
report (R_FATAL, "Revision info too long.");
if(!(p = strrchr(revinfo, ':')))
report (R_FATAL, "Revision info malformed (i=%d)", i);
}
}
-static void* extract_rcdata (int id, int type, DWORD* size)
+static void* extract_rcdata (LPTSTR name, int type, DWORD* size)
{
HRSRC rsrc;
HGLOBAL hdl;
LPVOID addr;
-
- if (!(rsrc = FindResource (NULL, (LPTSTR)id, MAKEINTRESOURCE(type))) ||
+
+ if (!(rsrc = FindResource (NULL, name, MAKEINTRESOURCE(type))) ||
!(*size = SizeofResource (0, rsrc)) ||
!(hdl = LoadResource (0, rsrc)) ||
!(addr = LockResource (hdl)))
/* Fills in the name and exename fields */
static void
-extract_test (struct wine_test *test, const char *dir, int id)
+extract_test (struct wine_test *test, const char *dir, LPTSTR res_name)
{
BYTE* code;
DWORD size;
FILE* fout;
- int strlen, bufflen = 128;
char *exepos;
- code = extract_rcdata (id, TESTRES, &size);
- if (!code) report (R_FATAL, "Can't find test resource %d: %d",
- id, GetLastError ());
- test->name = xmalloc (bufflen);
- while ((strlen = LoadStringA (NULL, id, test->name, bufflen))
- == bufflen - 1) {
- bufflen *= 2;
- test->name = xrealloc (test->name, bufflen);
- }
- if (!strlen) report (R_FATAL, "Can't read name of test %d.", id);
+ code = extract_rcdata (res_name, TESTRES, &size);
+ if (!code) report (R_FATAL, "Can't find test resource %s: %d",
+ res_name, GetLastError ());
+ test->name = xstrdup( res_name );
test->exename = strmake (NULL, "%s/%s", dir, test->name);
- exepos = strstr (test->name, "_test.exe");
+ exepos = strstr (test->name, testexe);
if (!exepos) report (R_FATAL, "Not an .exe file: %s", test->name);
*exepos = 0;
test->name = xrealloc (test->name, exepos - test->name + 1);
value of WaitForSingleObject.
*/
static int
-run_ex (char *cmd, const char *out, DWORD ms)
+run_ex (char *cmd, const char *out, const char *tempdir, DWORD ms)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD wait, status;
GetStartupInfo (&si);
- si.wShowWindow = SW_HIDE;
- si.dwFlags = STARTF_USESHOWWINDOW;
+ si.dwFlags = 0;
if (out) {
fd = open (out, O_WRONLY | O_CREAT, 0666);
close (fd);
}
- if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, 0,
- NULL, NULL, &si, &pi)) {
+ if (!CreateProcessA (NULL, cmd, NULL, NULL, TRUE, CREATE_DEFAULT_ERROR_MODE,
+ NULL, tempdir, &si, &pi)) {
status = -2;
} else {
CloseHandle (pi.hThread);
}
static void
-get_subtests (const char *tempdir, struct wine_test *test, int id)
+get_subtests (const char *tempdir, struct wine_test *test, LPTSTR res_name)
{
char *subname, *cmd;
FILE *subfile;
subname = tempnam (0, "sub");
if (!subname) report (R_FATAL, "Can't name subtests file.");
- extract_test (test, tempdir, id);
+ extract_test (test, tempdir, res_name);
cmd = strmake (NULL, "%s --list", test->exename);
- run_ex (cmd, subname, 5000);
+ run_ex (cmd, subname, tempdir, 5000);
free (cmd);
subfile = fopen (subname, "r");
}
static void
-run_test (struct wine_test* test, const char* subtest)
+run_test (struct wine_test* test, const char* subtest, const char *tempdir)
{
int status;
const char* file = get_test_source_file(test->name, subtest);
char *cmd = strmake (NULL, "%s %s", test->exename, subtest);
xprintf ("%s:%s start %s %s\n", test->name, subtest, file, rev);
- status = run_ex (cmd, NULL, 120000);
+ status = run_ex (cmd, NULL, tempdir, 120000);
free (cmd);
xprintf ("%s:%s done (%d)\n", test->name, subtest, status);
}
return TRUE;
}
+static BOOL CALLBACK
+extract_test_proc (HMODULE hModule, LPCTSTR lpszType,
+ LPTSTR lpszName, LONG_PTR lParam)
+{
+ const char *tempdir = (const char *)lParam;
+ char dllname[MAX_PATH];
+ HMODULE dll;
+
+ /* Check if the main dll is present on this system */
+ CharLowerA(lpszName);
+ strcpy(dllname, lpszName);
+ *strstr(dllname, testexe) = 0;
+
+ dll = LoadLibraryExA(dllname, NULL, LOAD_LIBRARY_AS_DATAFILE);
+ if (!dll) {
+ xprintf (" %s=dll is missing\n", dllname);
+ return TRUE;
+ }
+ FreeLibrary(dll);
+
+ xprintf (" %s=%s\n", dllname, get_file_version(dllname));
+
+ get_subtests( tempdir, &wine_tests[nr_of_files], lpszName );
+ nr_of_tests += wine_tests[nr_of_files].subtest_count;
+ nr_of_files++;
+ return TRUE;
+}
+
static char *
run_tests (char *logname)
{
- int nr_of_files = 0, nr_of_tests = 0, i;
+ int i;
char *tempdir, *shorttempdir;
int logfile;
char *strres, *eol, *nextline;
DWORD strsize;
+ char build[64];
SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
report (R_FATAL, "Could not create directory: %s", tempdir);
report (R_DIR, tempdir);
- xprintf ("Version 3\n");
- strres = extract_rcdata (WINE_BUILD, STRINGRES, &strsize);
+ xprintf ("Version 4\n");
+ strres = extract_rcdata (MAKEINTRESOURCE(WINE_BUILD), STRINGRES, &strsize);
xprintf ("Tests from build ");
- if (strres) xprintf ("%.*s", strsize, strres);
+ if (LoadStringA( 0, IDS_BUILD_ID, build, sizeof(build) )) xprintf( "%s\n", build );
+ else if (strres) xprintf ("%.*s", strsize, strres);
else xprintf ("-\n");
- strres = extract_rcdata (TESTS_URL, STRINGRES, &strsize);
+ strres = extract_rcdata (MAKEINTRESOURCE(TESTS_URL), STRINGRES, &strsize);
xprintf ("Archive: ");
if (strres) xprintf ("%.*s", strsize, strres);
else xprintf ("-\n");
xprintf ("Tag: %s\n", tag);
xprintf ("Build info:\n");
- strres = extract_rcdata (BUILD_INFO, STRINGRES, &strsize);
+ strres = extract_rcdata (MAKEINTRESOURCE(BUILD_INFO), STRINGRES, &strsize);
while (strres) {
eol = memchr (strres, '\n', strsize);
if (!eol) {
}
xprintf ("Operating system version:\n");
print_version ();
- xprintf ("Test output:\n" );
+ xprintf ("Dll info:\n" );
report (R_STATUS, "Counting tests");
if (!EnumResourceNames (NULL, MAKEINTRESOURCE(TESTRES),
report (R_STATUS, "Extracting tests");
report (R_PROGRESS, 0, nr_of_files);
- for (i = 0; i < nr_of_files; i++) {
- get_subtests (tempdir, wine_tests+i, i);
- nr_of_tests += wine_tests[i].subtest_count;
- }
+ nr_of_files = 0;
+ nr_of_tests = 0;
+ if (!EnumResourceNames (NULL, MAKEINTRESOURCE(TESTRES),
+ extract_test_proc, (LPARAM)tempdir))
+ report (R_FATAL, "Can't enumerate test files: %d",
+ GetLastError ());
+
+ xprintf ("Test output:\n" );
+
report (R_DELTA, 0, "Extracting: Done");
report (R_STATUS, "Running tests");
for (j = 0; j < test->subtest_count; j++) {
report (R_STEP, "Running: %s:%s", test->name,
test->subtests[j]);
- run_test (test, test->subtests[j]);
+ run_test (test, test->subtests[j], tempdir);
}
}
report (R_DELTA, 0, "Running: Done");
static void
usage (void)
{
- fprintf (stderr, "\
-Usage: winetest [OPTION]...\n\n\
- -c console mode, no GUI\n\
- -e preserve the environment\n\
- -h print this message and exit\n\
- -q quiet mode, no output at all\n\
- -o FILE put report into FILE, do not submit\n\
- -s FILE submit FILE, do not run tests\n\
- -t TAG include TAG of characters [-.0-9a-zA-Z] in the report\n");
+ fprintf (stderr,
+"Usage: winetest [OPTION]...\n\n"
+" -c console mode, no GUI\n"
+" -e preserve the environment\n"
+" -h print this message and exit\n"
+" -p shutdown when the tests are done\n"
+" -q quiet mode, no output at all\n"
+" -o FILE put report into FILE, do not submit\n"
+" -s FILE submit FILE, do not run tests\n"
+" -t TAG include TAG of characters [-.0-9a-zA-Z] in the report\n");
}
int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInst,
char *logname = NULL;
const char *cp, *submit = NULL;
int reset_env = 1;
+ int poweroff = 0;
int interactive = 1;
/* initialize the revision information first */
reset_env = 0;
break;
case 'h':
+ case '?':
usage ();
exit (0);
+ case 'p':
+ poweroff = 1;
+ break;
case 'q':
report (R_QUIET);
interactive = 0;
cmdLine = strtok (NULL, whitespace);
}
if (!submit) {
+ static CHAR platform_windows[] = "WINETEST_PLATFORM=windows",
+ platform_wine[] = "WINETEST_PLATFORM=wine",
+ debug_yes[] = "WINETEST_DEBUG=1",
+ interactive_no[] = "WINETEST_INTERACTIVE=0",
+ report_success_no[] = "WINETEST_REPORT_SUCCESS=0";
+ CHAR *platform;
+
report (R_STATUS, "Starting up");
if (!running_on_visible_desktop ())
report (R_FATAL, "Tests must be run on a visible desktop");
- if (reset_env && (putenv ("WINETEST_PLATFORM=windows") ||
- putenv ("WINETEST_DEBUG=1") ||
- putenv ("WINETEST_INTERACTIVE=0") ||
- putenv ("WINETEST_REPORT_SUCCESS=0")))
+ platform = running_under_wine () ? platform_wine : platform_windows;
+
+ if (reset_env && (putenv (platform) ||
+ putenv (debug_yes) ||
+ putenv (interactive_no) ||
+ putenv (report_success_no)))
report (R_FATAL, "Could not reset environment: %d", errno);
if (!tag) {
} else run_tests (logname);
report (R_STATUS, "Finished");
}
+ if (poweroff)
+ {
+ HANDLE hToken;
+ TOKEN_PRIVILEGES npr;
+
+ /* enable the shutdown privilege for the current process */
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
+ {
+ LookupPrivilegeValueA(0, SE_SHUTDOWN_NAME, &npr.Privileges[0].Luid);
+ npr.PrivilegeCount = 1;
+ npr.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+ AdjustTokenPrivileges(hToken, FALSE, &npr, 0, 0, 0);
+ CloseHandle(hToken);
+ }
+ ExitWindowsEx(EWX_SHUTDOWN | EWX_POWEROFF | EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_OTHER | SHTDN_REASON_MINOR_OTHER);
+ }
exit (0);
}