|
|
//---------------------------------------------------------------------------
// UxBud.cpp - quick cmdline test for uxtheme.dll
//---------------------------------------------------------------------------
#include "stdafx.h"
#include "uxbud.h"
//---------------------------------------------------------------------------
BOOL fQuiet = FALSE; HANDLE hFileOutput = NULL;
TESTINFO *pTestInfo; int iTestCount; //---------------------------------------------------------------------------
void Output(LPCSTR pszFormat, ...) { //---- writes to both "uxbud.log" and console ----
va_list args; va_start(args, pszFormat);
//---- format caller's string ----
CHAR szBigBuff[256]; StringCchVPrintfA(szBigBuff, ARRAYSIZE(szBigBuff), pszFormat, args);
if (hFileOutput != INVALID_HANDLE_VALUE) { //---- expand all LF to CR/LF ----
CHAR szBuff2[512]; CHAR *s = szBigBuff; CHAR *p = szBuff2;
while (*s) { if (*s == '\n') { *p++ = '\r'; }
*p++ = *s++; }
*p = 0; // zero terminate szBuff2
//---- write expanded buff to log file ----
DWORD dw; WriteFile(hFileOutput, szBuff2, strlen(szBuff2), &dw, NULL); } if (! fQuiet) printf(szBigBuff);
va_end(args); } //-----------------------------------------------------------------
BOOL ReportResults(BOOL fPassed, HRESULT hr, LPCWSTR pszTestName) { Output("%S ", pszTestName);
if (fPassed) { Output("PASSED\n\n"); } else { if (hr == S_OK) hr = GetLastError();
WCHAR szBuff[2*MAX_PATH];
if (THEME_PARSING_ERROR(hr)) { PARSE_ERROR_INFO Info = {sizeof(Info)};
HRESULT hr2 = GetThemeParseErrorInfo(&Info); if (SUCCEEDED(hr2)) { StringCchCopyW(szBuff, ARRAYSIZE(szBuff), Info.szMsg); } else { StringCchPrintfW(szBuff, ARRAYSIZE(szBuff), L"Unknown parsing error"); } } else { // normal win32 error
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, 0, szBuff, ARRAYSIZE(szBuff), NULL); }
Output("FAILED [%S]\n\n", pszTestName, szBuff); }
return fPassed; } //---------------------------------------------------------------------------
BOOL RunCmd(LPCWSTR pszExeName, LPCWSTR pszParams, BOOL fHide, BOOL fDisplayParams, BOOL fWait) { HANDLE hInst; BOOL fRanOk = FALSE;
STARTUPINFO si; memset(&si, 0, sizeof(si)); si.cb = sizeof(STARTUPINFO); si.dwFlags = STARTF_FORCEOFFFEEDBACK; // don't mess with our cursor
if (fHide) { si.dwFlags |= STARTF_USESHOWWINDOW; // hide window
si.wShowWindow = SW_HIDE; }
PROCESS_INFORMATION pi; TCHAR szBuff[2*_MAX_PATH];
if (pszParams) StringCchPrintfW(szBuff, ARRAYSIZE(szBuff), _T("%s %s"), pszExeName, pszParams); else { StringCchCopyW(szBuff, ARRAYSIZE(szBuff), pszExeName); }
BOOL bSuccess = CreateProcess(NULL, szBuff, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if (! bSuccess) goto exit;
hInst = pi.hProcess; if (! hInst) goto exit;
if (fWait) { //---- wait for process to terminate ----
DWORD dwVal; dwVal = WaitForSingleObject(hInst, INFINITE);
if (dwVal != WAIT_OBJECT_0) goto exit;
DWORD dwExitCode; if (! GetExitCodeProcess(hInst, &dwExitCode)) goto exit;
if (dwExitCode) goto exit; }
fRanOk = TRUE;
exit:
if (fWait) // being used for the test...
{ if (fDisplayParams) Output(" RunCmd: %S (ranok=%d)\n", szBuff, fRanOk); else Output(" RunCmd: %S <params> (ranok=%d)\n", pszExeName, fRanOk); }
CloseHandle(hInst); return fRanOk; } //---------------------------------------------------------------------------
BOOL TestAll() { DWORD dwStartTicks = GetTickCount();
for (int i=0; i < iTestCount; i++) { pTestInfo[i].pfnTest(); }
DWORD dwTicks = GetTickCount() - dwStartTicks;
if (! fQuiet) printf("Total test time: %d secs\n", dwTicks/1000);
return TRUE; } //---------------------------------------------------------------------------
void PrintTests() { printf("available tests: \n");
for (int i=0; i < iTestCount; i++) { printf(" %s \t(%s)\n", pTestInfo[i].pszName, pTestInfo[i].pszDesc); } printf("\n"); } //---------------------------------------------------------------------------
void PrintHelp() { printf("\nusage\n"); printf(" uxbud [ <options> ] \n\n");
printf("UxBud will run a set of quick tests to verify basic \"uxtheme.dll\"\n"); printf("functionality. If no options are specified, one pass over the normal\n"); printf("set of tests will be run and the \"uxbud.log\" file created will be \n"); printf("compared against the known good \"uxbud.ok\" log file. This will result\n"); printf("in an overall PASS or FAIL msg at the end of the uxbud run.\n\n");
printf("<options>:\n\n");
printf(" -r <number> (to specify a repeat factor)\n"); printf(" -q (to run in quiet mode\n"); printf(" -? (to print this usage msg\n"); printf(" <test> (to run a specific test\n\n");
PrintTests(); } //---------------------------------------------------------------------------
BOOL HandleOptions(LPTSTR pszCmdLine, TESTPROC *ppfnTest, int *piRepeat, BOOL *pfQuiet, int *piRetVal) { BOOL fContinue = TRUE; USES_CONVERSION;
*piRetVal = 0;
if ((! pszCmdLine) || (! *pszCmdLine)) // no options
return TRUE;
LPCSTR p = W2A(pszCmdLine); while ((p) && (*p)) { while (isspace(*p)) p++;
//---- process switches ----
if ((*p == '/') || (*p == '-')) { p++;
if ((*p == 'r') || (*p == 'R')) // repeat factor
{ p++; while (isspace(*p)) p++;
sscanf(p, "%d", piRepeat);
//---- skip over the scanned number ----
while (isdigit(*p)) p++; } else if ((*p == 'q') || (*p == 'Q')) // quiet mode
{ p++; *pfQuiet = TRUE; } else if (*p == '?') // cmdline help
{ p++; PrintHelp(); fContinue = FALSE; break; }
} else // test name specified
{ for (int i=0; i < iTestCount; i++) { if (lstrcmpiA(p, pTestInfo[i].pszName)==0) { *ppfnTest = pTestInfo[i].pfnTest; break; } }
if (i == iTestCount) // not found
{ printf("\nError - unrecognized test: %s\n\n", p); PrintTests();
*piRetVal = 1; fContinue = FALSE; }
break; } }
return fContinue; } //---------------------------------------------------------------------------
BOOL FileCompare(LPCWSTR pszName1, LPCWSTR pszName2) { BOOL fSame = FALSE; HANDLE hFile1 = NULL; HANDLE hFile2 = NULL; CHAR *pszBuff1 = NULL; CHAR *pszBuff2= NULL; DWORD dw1, dw2;
//---- open files ----
hFile1 = CreateFile(pszName1, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile1 == INVALID_HANDLE_VALUE) goto exit;
hFile2 = CreateFile(pszName2, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile2 == INVALID_HANDLE_VALUE) goto exit;
DWORD dwSize1, dwSize2; dwSize1 = GetFileSize(hFile1, NULL); dwSize2 = GetFileSize(hFile1, NULL);
if ((! dwSize1) || (dwSize1 != dwSize2)) goto exit;
pszBuff1 = new CHAR[dwSize1]; if (! pszBuff1) goto exit;
pszBuff2 = new CHAR[dwSize1]; if (! pszBuff2) goto exit;
ReadFile(hFile1, pszBuff1, dwSize1, &dw1, NULL); ReadFile(hFile2, pszBuff2, dwSize1, &dw2, NULL);
if ((dw1 != dwSize1) || (dw2 != dwSize1)) goto exit; if (memcmp(pszBuff1, pszBuff2, dwSize1)!=0) goto exit; fSame = TRUE; exit: delete [] pszBuff1; delete [] pszBuff2;
CloseHandle(hFile1); CloseHandle(hFile2);
return fSame; } //---------------------------------------------------------------------------
extern "C" WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE previnst, LPTSTR pszCmdLine, int nShowCmd) { //---- default run params ----
int iRepeat = 1; int iRetVal = 0; TESTPROC pfnTest = TestAll;
GetTestInfo(&pTestInfo, &iTestCount);
if (! HandleOptions(pszCmdLine, &pfnTest, &iRepeat, &fQuiet, &iRetVal)) return iRetVal;
//---- create the log file ----
hFileOutput = CreateFile(L"uxbud.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); if (hFileOutput == INVALID_HANDLE_VALUE) { printf("\nError - could not open uxbud.log output file\n"); return 1; }
printf("\nUxBud - quick (under 3 mins) test for uxtheme.dll (version 1.0)\n\n"); if (iRepeat > 1) Output("REPEAT FACTOR=%d\n\n", iRepeat);
//---- run the needed test ----
for (int i=0; i < iRepeat; i++) { if (iRepeat > 1) Output("TEST PASS: %d\n\n", i);
pfnTest(); }
//---- close the log file ----
if (hFileOutput) CloseHandle(hFileOutput);
if ((iRepeat == 1) && (pfnTest == TestAll)) // standard run
{ if (FileCompare(L"uxbud.log", L"uxbud.ok")) { printf("*** UxBud PASSED ****\n"); } else { printf("\nFailure detected - running: windiff uxbud.ok uxbud.log...)\n\n"); printf("*** UxBud FAILED ****\n");
RunCmd(L"windiff", L"uxbud.ok uxbud.log", TRUE, FALSE, FALSE); } }
return 0; } //---------------------------------------------------------------------------
|