- Add some checks to prevent crashes in unexpected situations and add useful error messages for them.

This should make debugging something like r39578 easier :-)
- Prevent some memory leaks in case of failure (well, some memory wasn't even freed in case of success :-P)

svn path=/trunk/; revision=39584
This commit is contained in:
Colin Finck 2009-02-13 17:39:58 +00:00
parent 09ad068987
commit 43659c9ace
3 changed files with 214 additions and 99 deletions

View file

@ -66,15 +66,19 @@ IntGetConfigurationValues()
const CHAR PasswordProp[] = "&password=";
const CHAR UserNameProp[] = "&username=";
BOOL ReturnValue = FALSE;
DWORD DataLength;
DWORD Length;
PCHAR Password;
PCHAR UserName;
PCHAR Password = NULL;
PCHAR UserName = NULL;
WCHAR ConfigFile[MAX_PATH];
/* We only need this if the results are going to be submitted */
if(!AppOptions.Submit)
return TRUE;
{
ReturnValue = TRUE;
goto Cleanup;
}
/* Build the path to the configuration file from the application's path */
GetModuleFileNameW(NULL, ConfigFile, MAX_PATH);
@ -85,7 +89,7 @@ IntGetConfigurationValues()
if(GetFileAttributesW(ConfigFile) == INVALID_FILE_ATTRIBUTES)
{
StringOut("Missing \"rosautotest.ini\" configuration file!\n");
return FALSE;
goto Cleanup;
}
/* Get the required length of the authentication request string */
@ -95,7 +99,7 @@ IntGetConfigurationValues()
if(!Length)
{
StringOut("UserName is missing in the configuration file\n");
return FALSE;
goto Cleanup;
}
/* Some characters might need to be escaped and an escaped character takes 3 bytes */
@ -107,7 +111,7 @@ IntGetConfigurationValues()
if(!Length)
{
StringOut("Password is missing in the configuration file\n");
return FALSE;
goto Cleanup;
}
DataLength += 3 * Length;
@ -121,7 +125,16 @@ IntGetConfigurationValues()
strcat(AuthenticationRequestString, PasswordProp);
EscapeString(&AuthenticationRequestString[strlen(AuthenticationRequestString)], Password);
return TRUE;
ReturnValue = TRUE;
Cleanup:
if(UserName)
HeapFree(hProcessHeap, 0, UserName);
if(Password)
HeapFree(hProcessHeap, 0, Password);
return ReturnValue;
}
/**
@ -242,7 +255,7 @@ IntPrintUsage()
int
wmain(int argc, wchar_t* argv[])
{
int Result = 0;
int ReturnValue = 0;
UINT i;
hProcessHeap = GetProcessHeap();
@ -263,12 +276,12 @@ wmain(int argc, wchar_t* argv[])
break;
default:
Result = 1;
ReturnValue = 1;
/* Fall through */
case '?':
IntPrintUsage();
goto End;
goto Cleanup;
}
}
else
@ -292,24 +305,23 @@ wmain(int argc, wchar_t* argv[])
}
else
{
Result = 1;
ReturnValue = 1;
IntPrintUsage();
goto End;
goto Cleanup;
}
}
}
if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests())
{
Result = 1;
goto End;
ReturnValue = 1;
goto Cleanup;
}
/* For sysreg */
OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
End:
/* Cleanup */
Cleanup:
if(AppOptions.Module)
HeapFree(hProcessHeap, 0, AppOptions.Module);
@ -324,7 +336,7 @@ End:
/* Shut down the system if requested */
if(AppOptions.Shutdown && !ShutdownSystem())
Result = 1;
ReturnValue = 1;
return Result;
return ReturnValue;
}

View file

@ -33,9 +33,10 @@ IntDoRequest(char** Data, PDWORD DataLength)
{
const WCHAR Headers[] = L"Content-Type: application/x-www-form-urlencoded";
HINTERNET hHTTP;
HINTERNET hHTTPRequest;
HINTERNET hInet;
BOOL ReturnValue = FALSE;
HINTERNET hHTTP = NULL;
HINTERNET hHTTPRequest = NULL;
HINTERNET hInet = NULL;
/* Establish an internet connection to the "testman" server */
hInet = InternetOpenW(L"rosautotest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
@ -43,7 +44,7 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!hInet)
{
StringOut("InternetOpenW failed\n");
return FALSE;
goto Cleanup;
}
hHTTP = InternetConnectW(hInet, SERVER_HOSTNAME, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0);
@ -51,7 +52,7 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!hHTTP)
{
StringOut("InternetConnectW failed\n");
return FALSE;
goto Cleanup;
}
/* Post our test results to the web service */
@ -60,22 +61,23 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!hHTTPRequest)
{
StringOut("HttpOpenRequestW failed\n");
return FALSE;
goto Cleanup;
}
if(!HttpSendRequestW(hHTTPRequest, Headers, wcslen(Headers), *Data, *DataLength))
{
StringOut("HttpSendRequestW failed\n");
return FALSE;
goto Cleanup;
}
HeapFree(hProcessHeap, 0, *Data);
*Data = NULL;
/* Get the response */
if(!InternetQueryDataAvailable(hHTTPRequest, DataLength, 0, 0))
{
StringOut("InternetQueryDataAvailable failed\n");
return FALSE;
goto Cleanup;
}
*Data = HeapAlloc(hProcessHeap, 0, *DataLength + 1);
@ -83,16 +85,23 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!InternetReadFile(hHTTPRequest, *Data, *DataLength, DataLength))
{
StringOut("InternetReadFile failed\n");
return FALSE;
goto Cleanup;
}
(*Data)[*DataLength] = 0;
ReturnValue = TRUE;
InternetCloseHandle(hHTTPRequest);
InternetCloseHandle(hHTTP);
InternetCloseHandle(hInet);
Cleanup:
if(hHTTPRequest)
InternetCloseHandle(hHTTPRequest);
return TRUE;
if(hHTTP)
InternetCloseHandle(hHTTP);
if(hInet)
InternetCloseHandle(hInet);
return ReturnValue;
}
/**
@ -127,6 +136,7 @@ IsNumber(PCHAR Input)
*
* @return
* Returns the Test ID as a CHAR array if successful or NULL otherwise.
* The caller needs to HeapFree the returned pointer in case of success.
*/
PCHAR
GetTestID(TESTTYPES TestType)
@ -135,6 +145,7 @@ GetTestID(TESTTYPES TestType)
DWORD DataLength;
PCHAR Data;
PCHAR ReturnValue = NULL;
/* Build the full request string */
DataLength = sizeof(ActionProp) - 1 + sizeof(GetTestIDAction) - 1;
@ -163,7 +174,7 @@ GetTestID(TESTTYPES TestType)
}
if(!IntDoRequest(&Data, &DataLength))
return NULL;
goto Cleanup;
/* Verify that this is really a number */
if(!IsNumber(Data))
@ -171,11 +182,16 @@ GetTestID(TESTTYPES TestType)
StringOut("Expected Test ID, but received:\n");
StringOut(Data);
StringOut("\n");
HeapFree(hProcessHeap, 0, Data);
return NULL;
goto Cleanup;
}
return Data;
ReturnValue = Data;
Cleanup:
if(Data && ReturnValue != Data)
HeapFree(hProcessHeap, 0, Data);
return ReturnValue;
}
/**
@ -190,6 +206,7 @@ GetTestID(TESTTYPES TestType)
*
* @return
* Returns the Suite ID as a CHAR array if successful or NULL otherwise.
* The caller needs to HeapFree the returned pointer in case of success.
*/
PCHAR
GetSuiteID(TESTTYPES TestType, const PVOID TestData)
@ -200,6 +217,7 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
DWORD DataLength;
PCHAR Data;
PCHAR ReturnValue = NULL;
PWINE_GETSUITEID_DATA WineData;
DataLength = sizeof(ActionProp) - 1 + sizeof(GetSuiteIDAction) - 1;
@ -242,7 +260,7 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
}
if(!IntDoRequest(&Data, &DataLength))
return NULL;
goto Cleanup;
/* Verify that this is really a number */
if(!IsNumber(Data))
@ -250,11 +268,16 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
StringOut("Expected Suite ID, but received:\n");
StringOut(Data);
StringOut("\n");
HeapFree(hProcessHeap, 0, Data);
return NULL;
goto Cleanup;
}
return Data;
ReturnValue = Data;
Cleanup:
if(Data && ReturnValue != Data)
HeapFree(hProcessHeap, 0, Data);
return ReturnValue;
}
/**
@ -277,6 +300,7 @@ Submit(TESTTYPES TestType, const PVOID TestData)
const CHAR SuiteIDProp[] = "&suiteid=";
const CHAR LogProp[] = "&log=";
BOOL ReturnValue = FALSE;
DWORD DataLength;
PCHAR Data;
PCHAR pData;
@ -342,7 +366,7 @@ Submit(TESTTYPES TestType, const PVOID TestData)
/* Send all the stuff */
if(!IntDoRequest(&Data, &DataLength))
return FALSE;
goto Cleanup;
/* Output the response */
StringOut("The server responded:\n");
@ -350,9 +374,13 @@ Submit(TESTTYPES TestType, const PVOID TestData)
StringOut("\n");
if(!strcmp(Data, "OK"))
return TRUE;
ReturnValue = TRUE;
return FALSE;
Cleanup:
if(Data)
HeapFree(hProcessHeap, 0, Data);
return ReturnValue;
}
/**
@ -373,6 +401,7 @@ Finish(TESTTYPES TestType, const PVOID TestData)
{
const CHAR FinishAction[] = "finish";
BOOL ReturnValue = FALSE;
DWORD DataLength;
PCHAR Data;
PGENERAL_FINISH_DATA GeneralData;
@ -410,10 +439,14 @@ Finish(TESTTYPES TestType, const PVOID TestData)
}
if(!IntDoRequest(&Data, &DataLength))
return FALSE;
goto Cleanup;
if(!strcmp(Data, "OK"))
return TRUE;
ReturnValue = TRUE;
return FALSE;
Cleanup:
if(Data)
HeapFree(hProcessHeap, 0, Data);
return ReturnValue;
}

View file

@ -33,13 +33,14 @@ static BOOL
IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWINE_GETSUITEID_DATA GetSuiteIDData, PWINE_SUBMIT_DATA SubmitData)
{
BOOL BreakLoop = FALSE;
BOOL ReturnValue = FALSE;
DWORD BytesAvailable;
DWORD LogAvailable = 0;
DWORD LogLength = 0;
DWORD LogPosition = 0;
DWORD Temp;
PCHAR Buffer;
PROCESS_INFORMATION ProcessInfo;
PCHAR Buffer = NULL;
PROCESS_INFORMATION ProcessInfo = {0};
if(AppOptions.Submit)
{
@ -55,12 +56,13 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
sprintf(Buffer, "Running Wine Test, Module: %s, Test: %s\n", GetSuiteIDData->Module, GetSuiteIDData->Test);
StringOut(Buffer);
HeapFree(hProcessHeap, 0, Buffer);
Buffer = NULL;
/* Execute the test */
if(!CreateProcessW(NULL, CommandLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &ProcessInfo))
{
StringOut("CreateProcessW for running the test failed\n");
return FALSE;
goto Cleanup;
}
/* Receive all the data from the pipe */
@ -78,7 +80,7 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL))
{
StringOut("PeekNamedPipe failed for the test run\n");
return FALSE;
goto Cleanup;
}
if(BytesAvailable)
@ -89,7 +91,7 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL))
{
StringOut("ReadFile failed for the test run\n");
return FALSE;
goto Cleanup;
}
/* Output all test output through StringOut, even while the test is still running */
@ -114,14 +116,11 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
}
HeapFree(hProcessHeap, 0, Buffer);
Buffer = NULL;
}
}
while(!BreakLoop);
/* Close the process handles */
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
if(AppOptions.Submit)
{
SubmitData->Log[LogLength - LogAvailable] = 0;
@ -137,29 +136,47 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
SubmitData->General.TestID = GetTestID(WineTest);
if(!SubmitData->General.TestID)
return FALSE;
goto Cleanup;
}
/* Get a Suite ID for this combination */
SubmitData->General.SuiteID = GetSuiteID(WineTest, GetSuiteIDData);
if(!SubmitData->General.SuiteID)
return FALSE;
goto Cleanup;
/* Submit the stuff */
Submit(WineTest, SubmitData);
/* Cleanup */
HeapFree(hProcessHeap, 0, SubmitData->General.SuiteID);
}
/* Cleanup */
HeapFree(hProcessHeap, 0, SubmitData->Log);
}
StringOut("\n\n");
return TRUE;
ReturnValue = TRUE;
Cleanup:
if(Buffer)
HeapFree(hProcessHeap, 0, Buffer);
if(ProcessInfo.hProcess)
HeapFree(hProcessHeap, 0, ProcessInfo.hProcess);
if(ProcessInfo.hThread)
HeapFree(hProcessHeap, 0, ProcessInfo.hThread);
if(SubmitData->General.SuiteID)
{
HeapFree(hProcessHeap, 0, SubmitData->General.SuiteID);
SubmitData->General.SuiteID = NULL;
}
if(SubmitData->Log)
{
HeapFree(hProcessHeap, 0, SubmitData->Log);
SubmitData->Log = NULL;
}
return ReturnValue;
}
/**
@ -186,15 +203,17 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
static BOOL
IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWINE_SUBMIT_DATA SubmitData)
{
BOOL ReturnValue = FALSE;
DWORD BytesAvailable;
DWORD Length;
DWORD Temp;
PCHAR Buffer;
PCHAR Buffer = NULL;
PCHAR pStart;
PCHAR pEnd;
PROCESS_INFORMATION ProcessInfo;
PROCESS_INFORMATION ProcessInfo = {0};
PWSTR pUnderscore;
size_t FilePosition;
WINE_GETSUITEID_DATA GetSuiteIDData;
WINE_GETSUITEID_DATA GetSuiteIDData = {0};
/* Build the full command line */
FilePosition = wcslen(FilePath);
@ -202,8 +221,25 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
FilePath[FilePosition] = 0;
wcscat(FilePath, L"--list");
/* Find the underscore in the file name */
pUnderscore = wcschr(File, L'_');
if(!pUnderscore)
{
StringOut("Invalid test file name: ");
Length = wcslen(File);
Buffer = HeapAlloc(hProcessHeap, 0, Length + 1);
WideCharToMultiByte(CP_ACP, 0, File, Length + 1, Buffer, Length + 1, NULL, NULL);
StringOut(Buffer);
StringOut("\n");
goto Cleanup;
}
/* Store the tested module name */
Length = wcschr(File, L'_') - File;
Length = pUnderscore - File;
GetSuiteIDData.Module = HeapAlloc(hProcessHeap, 0, Length + 1);
WideCharToMultiByte(CP_ACP, 0, File, Length, GetSuiteIDData.Module, Length, NULL, NULL);
GetSuiteIDData.Module[Length] = 0;
@ -212,33 +248,45 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
if(!CreateProcessW(NULL, FilePath, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &ProcessInfo))
{
StringOut("CreateProcessW for getting the available tests failed\n");
return FALSE;
goto Cleanup;
}
/* Wait till this process ended */
if(WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_FAILED)
{
StringOut("WaitForSingleObject failed for the test list\n");
return FALSE;
goto Cleanup;
}
/* Close the process handles */
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
/* Read the output data into a buffer */
if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL))
{
StringOut("PeekNamedPipe failed for the test list\n");
return FALSE;
goto Cleanup;
}
/* Check if we got any */
if(!BytesAvailable)
{
StringOut("The --list command did not return any data for ");
Length = wcslen(File);
Buffer = HeapAlloc(hProcessHeap, 0, Length + 1);
WideCharToMultiByte(CP_ACP, 0, File, Length + 1, Buffer, Length + 1, NULL, NULL);
StringOut(Buffer);
StringOut("\n");
goto Cleanup;
}
/* Read the data */
Buffer = HeapAlloc(hProcessHeap, 0, BytesAvailable);
if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL))
{
StringOut("ReadFile failed\n");
return FALSE;
goto Cleanup;
}
/* Jump to the first available test */
@ -267,21 +315,36 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
FilePath[FilePosition + Length] = 0;
if(!IntRunTest(FilePath, hReadPipe, StartupInfo, &GetSuiteIDData, SubmitData))
return FALSE;
goto Cleanup;
}
/* Cleanup */
HeapFree(hProcessHeap, 0, GetSuiteIDData.Test);
GetSuiteIDData.Test = NULL;
/* Move to the next test */
pStart = pEnd + 6;
}
/* Cleanup */
HeapFree(hProcessHeap, 0, GetSuiteIDData.Module);
HeapFree(hProcessHeap, 0, Buffer);
ReturnValue = TRUE;
return TRUE;
Cleanup:
if(GetSuiteIDData.Module)
HeapFree(hProcessHeap, 0, GetSuiteIDData.Module);
if(GetSuiteIDData.Test)
HeapFree(hProcessHeap, 0, GetSuiteIDData.Test);
if(Buffer)
HeapFree(hProcessHeap, 0, Buffer);
if(ProcessInfo.hProcess)
CloseHandle(ProcessInfo.hProcess);
if(ProcessInfo.hThread)
CloseHandle(ProcessInfo.hThread);
return ReturnValue;
}
/**
@ -293,10 +356,11 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
BOOL
RunWineTests()
{
BOOL ReturnValue = FALSE;
GENERAL_FINISH_DATA FinishData;
HANDLE hFind;
HANDLE hReadPipe;
HANDLE hWritePipe;
HANDLE hFind = NULL;
HANDLE hReadPipe = NULL;
HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES SecurityAttributes;
STARTUPINFOW StartupInfo = {0};
size_t PathPosition;
@ -312,7 +376,7 @@ RunWineTests()
if(!CreatePipe(&hReadPipe, &hWritePipe, &SecurityAttributes, 0))
{
StringOut("CreatePipe failed\n");
return FALSE;
goto Cleanup;
}
StartupInfo.cb = sizeof(StartupInfo);
@ -323,7 +387,7 @@ RunWineTests()
if(GetWindowsDirectoryW(FilePath, MAX_PATH) > MAX_PATH - 60)
{
StringOut("Windows directory path is too long\n");
return FALSE;
goto Cleanup;
}
wcscat(FilePath, L"\\bin\\");
@ -346,7 +410,7 @@ RunWineTests()
if(hFind == INVALID_HANDLE_VALUE)
{
StringOut("FindFirstFileW failed\n");
return FALSE;
goto Cleanup;
}
/* Run the tests */
@ -357,27 +421,33 @@ RunWineTests()
/* Run it */
if(!IntRunModuleTests(fd.cFileName, FilePath, hReadPipe, &StartupInfo, &SubmitData))
return FALSE;
goto Cleanup;
}
while(FindNextFileW(hFind, &fd));
/* Cleanup */
FindClose(hFind);
if(AppOptions.Submit && SubmitData.General.TestID)
/* Close this test run if necessary */
if(SubmitData.General.TestID)
{
/* We're done with the tests, so close this test run */
FinishData.TestID = SubmitData.General.TestID;
if(!Finish(WineTest, &FinishData))
return FALSE;
/* Cleanup */
HeapFree(hProcessHeap, 0, FinishData.TestID);
goto Cleanup;
}
CloseHandle(hReadPipe);
CloseHandle(hWritePipe);
ReturnValue = TRUE;
return TRUE;
Cleanup:
if(SubmitData.General.TestID)
HeapFree(hProcessHeap, 0, SubmitData.General.TestID);
if(hFind && hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
if(hReadPipe)
CloseHandle(hReadPipe);
if(hWritePipe)
CloseHandle(hWritePipe);
return ReturnValue;
}