- 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 PasswordProp[] = "&password=";
const CHAR UserNameProp[] = "&username="; const CHAR UserNameProp[] = "&username=";
BOOL ReturnValue = FALSE;
DWORD DataLength; DWORD DataLength;
DWORD Length; DWORD Length;
PCHAR Password; PCHAR Password = NULL;
PCHAR UserName; PCHAR UserName = NULL;
WCHAR ConfigFile[MAX_PATH]; WCHAR ConfigFile[MAX_PATH];
/* We only need this if the results are going to be submitted */ /* We only need this if the results are going to be submitted */
if(!AppOptions.Submit) if(!AppOptions.Submit)
return TRUE; {
ReturnValue = TRUE;
goto Cleanup;
}
/* Build the path to the configuration file from the application's path */ /* Build the path to the configuration file from the application's path */
GetModuleFileNameW(NULL, ConfigFile, MAX_PATH); GetModuleFileNameW(NULL, ConfigFile, MAX_PATH);
@ -85,7 +89,7 @@ IntGetConfigurationValues()
if(GetFileAttributesW(ConfigFile) == INVALID_FILE_ATTRIBUTES) if(GetFileAttributesW(ConfigFile) == INVALID_FILE_ATTRIBUTES)
{ {
StringOut("Missing \"rosautotest.ini\" configuration file!\n"); StringOut("Missing \"rosautotest.ini\" configuration file!\n");
return FALSE; goto Cleanup;
} }
/* Get the required length of the authentication request string */ /* Get the required length of the authentication request string */
@ -95,7 +99,7 @@ IntGetConfigurationValues()
if(!Length) if(!Length)
{ {
StringOut("UserName is missing in the configuration file\n"); 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 */ /* Some characters might need to be escaped and an escaped character takes 3 bytes */
@ -107,7 +111,7 @@ IntGetConfigurationValues()
if(!Length) if(!Length)
{ {
StringOut("Password is missing in the configuration file\n"); StringOut("Password is missing in the configuration file\n");
return FALSE; goto Cleanup;
} }
DataLength += 3 * Length; DataLength += 3 * Length;
@ -121,7 +125,16 @@ IntGetConfigurationValues()
strcat(AuthenticationRequestString, PasswordProp); strcat(AuthenticationRequestString, PasswordProp);
EscapeString(&AuthenticationRequestString[strlen(AuthenticationRequestString)], Password); 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 int
wmain(int argc, wchar_t* argv[]) wmain(int argc, wchar_t* argv[])
{ {
int Result = 0; int ReturnValue = 0;
UINT i; UINT i;
hProcessHeap = GetProcessHeap(); hProcessHeap = GetProcessHeap();
@ -263,12 +276,12 @@ wmain(int argc, wchar_t* argv[])
break; break;
default: default:
Result = 1; ReturnValue = 1;
/* Fall through */ /* Fall through */
case '?': case '?':
IntPrintUsage(); IntPrintUsage();
goto End; goto Cleanup;
} }
} }
else else
@ -292,24 +305,23 @@ wmain(int argc, wchar_t* argv[])
} }
else else
{ {
Result = 1; ReturnValue = 1;
IntPrintUsage(); IntPrintUsage();
goto End; goto Cleanup;
} }
} }
} }
if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests()) if(!IntGetConfigurationValues() || !IntGetBuildAndPlatform() || !RunWineTests())
{ {
Result = 1; ReturnValue = 1;
goto End; goto Cleanup;
} }
/* For sysreg */ /* For sysreg */
OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n"); OutputDebugStringA("SYSREG_CHECKPOINT:THIRDBOOT_COMPLETE\n");
End: Cleanup:
/* Cleanup */
if(AppOptions.Module) if(AppOptions.Module)
HeapFree(hProcessHeap, 0, AppOptions.Module); HeapFree(hProcessHeap, 0, AppOptions.Module);
@ -324,7 +336,7 @@ End:
/* Shut down the system if requested */ /* Shut down the system if requested */
if(AppOptions.Shutdown && !ShutdownSystem()) 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"; const WCHAR Headers[] = L"Content-Type: application/x-www-form-urlencoded";
HINTERNET hHTTP; BOOL ReturnValue = FALSE;
HINTERNET hHTTPRequest; HINTERNET hHTTP = NULL;
HINTERNET hInet; HINTERNET hHTTPRequest = NULL;
HINTERNET hInet = NULL;
/* Establish an internet connection to the "testman" server */ /* Establish an internet connection to the "testman" server */
hInet = InternetOpenW(L"rosautotest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); hInet = InternetOpenW(L"rosautotest", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
@ -43,7 +44,7 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!hInet) if(!hInet)
{ {
StringOut("InternetOpenW failed\n"); StringOut("InternetOpenW failed\n");
return FALSE; goto Cleanup;
} }
hHTTP = InternetConnectW(hInet, SERVER_HOSTNAME, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); 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) if(!hHTTP)
{ {
StringOut("InternetConnectW failed\n"); StringOut("InternetConnectW failed\n");
return FALSE; goto Cleanup;
} }
/* Post our test results to the web service */ /* Post our test results to the web service */
@ -60,22 +61,23 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!hHTTPRequest) if(!hHTTPRequest)
{ {
StringOut("HttpOpenRequestW failed\n"); StringOut("HttpOpenRequestW failed\n");
return FALSE; goto Cleanup;
} }
if(!HttpSendRequestW(hHTTPRequest, Headers, wcslen(Headers), *Data, *DataLength)) if(!HttpSendRequestW(hHTTPRequest, Headers, wcslen(Headers), *Data, *DataLength))
{ {
StringOut("HttpSendRequestW failed\n"); StringOut("HttpSendRequestW failed\n");
return FALSE; goto Cleanup;
} }
HeapFree(hProcessHeap, 0, *Data); HeapFree(hProcessHeap, 0, *Data);
*Data = NULL;
/* Get the response */ /* Get the response */
if(!InternetQueryDataAvailable(hHTTPRequest, DataLength, 0, 0)) if(!InternetQueryDataAvailable(hHTTPRequest, DataLength, 0, 0))
{ {
StringOut("InternetQueryDataAvailable failed\n"); StringOut("InternetQueryDataAvailable failed\n");
return FALSE; goto Cleanup;
} }
*Data = HeapAlloc(hProcessHeap, 0, *DataLength + 1); *Data = HeapAlloc(hProcessHeap, 0, *DataLength + 1);
@ -83,16 +85,23 @@ IntDoRequest(char** Data, PDWORD DataLength)
if(!InternetReadFile(hHTTPRequest, *Data, *DataLength, DataLength)) if(!InternetReadFile(hHTTPRequest, *Data, *DataLength, DataLength))
{ {
StringOut("InternetReadFile failed\n"); StringOut("InternetReadFile failed\n");
return FALSE; goto Cleanup;
} }
(*Data)[*DataLength] = 0; (*Data)[*DataLength] = 0;
ReturnValue = TRUE;
InternetCloseHandle(hHTTPRequest); Cleanup:
InternetCloseHandle(hHTTP); if(hHTTPRequest)
InternetCloseHandle(hInet); InternetCloseHandle(hHTTPRequest);
return TRUE; if(hHTTP)
InternetCloseHandle(hHTTP);
if(hInet)
InternetCloseHandle(hInet);
return ReturnValue;
} }
/** /**
@ -127,6 +136,7 @@ IsNumber(PCHAR Input)
* *
* @return * @return
* Returns the Test ID as a CHAR array if successful or NULL otherwise. * 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 PCHAR
GetTestID(TESTTYPES TestType) GetTestID(TESTTYPES TestType)
@ -135,6 +145,7 @@ GetTestID(TESTTYPES TestType)
DWORD DataLength; DWORD DataLength;
PCHAR Data; PCHAR Data;
PCHAR ReturnValue = NULL;
/* Build the full request string */ /* Build the full request string */
DataLength = sizeof(ActionProp) - 1 + sizeof(GetTestIDAction) - 1; DataLength = sizeof(ActionProp) - 1 + sizeof(GetTestIDAction) - 1;
@ -163,7 +174,7 @@ GetTestID(TESTTYPES TestType)
} }
if(!IntDoRequest(&Data, &DataLength)) if(!IntDoRequest(&Data, &DataLength))
return NULL; goto Cleanup;
/* Verify that this is really a number */ /* Verify that this is really a number */
if(!IsNumber(Data)) if(!IsNumber(Data))
@ -171,11 +182,16 @@ GetTestID(TESTTYPES TestType)
StringOut("Expected Test ID, but received:\n"); StringOut("Expected Test ID, but received:\n");
StringOut(Data); StringOut(Data);
StringOut("\n"); StringOut("\n");
HeapFree(hProcessHeap, 0, Data); goto Cleanup;
return NULL;
} }
return Data; ReturnValue = Data;
Cleanup:
if(Data && ReturnValue != Data)
HeapFree(hProcessHeap, 0, Data);
return ReturnValue;
} }
/** /**
@ -190,6 +206,7 @@ GetTestID(TESTTYPES TestType)
* *
* @return * @return
* Returns the Suite ID as a CHAR array if successful or NULL otherwise. * 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 PCHAR
GetSuiteID(TESTTYPES TestType, const PVOID TestData) GetSuiteID(TESTTYPES TestType, const PVOID TestData)
@ -200,6 +217,7 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
DWORD DataLength; DWORD DataLength;
PCHAR Data; PCHAR Data;
PCHAR ReturnValue = NULL;
PWINE_GETSUITEID_DATA WineData; PWINE_GETSUITEID_DATA WineData;
DataLength = sizeof(ActionProp) - 1 + sizeof(GetSuiteIDAction) - 1; DataLength = sizeof(ActionProp) - 1 + sizeof(GetSuiteIDAction) - 1;
@ -242,7 +260,7 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
} }
if(!IntDoRequest(&Data, &DataLength)) if(!IntDoRequest(&Data, &DataLength))
return NULL; goto Cleanup;
/* Verify that this is really a number */ /* Verify that this is really a number */
if(!IsNumber(Data)) if(!IsNumber(Data))
@ -250,11 +268,16 @@ GetSuiteID(TESTTYPES TestType, const PVOID TestData)
StringOut("Expected Suite ID, but received:\n"); StringOut("Expected Suite ID, but received:\n");
StringOut(Data); StringOut(Data);
StringOut("\n"); StringOut("\n");
HeapFree(hProcessHeap, 0, Data); goto Cleanup;
return NULL;
} }
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 SuiteIDProp[] = "&suiteid=";
const CHAR LogProp[] = "&log="; const CHAR LogProp[] = "&log=";
BOOL ReturnValue = FALSE;
DWORD DataLength; DWORD DataLength;
PCHAR Data; PCHAR Data;
PCHAR pData; PCHAR pData;
@ -342,7 +366,7 @@ Submit(TESTTYPES TestType, const PVOID TestData)
/* Send all the stuff */ /* Send all the stuff */
if(!IntDoRequest(&Data, &DataLength)) if(!IntDoRequest(&Data, &DataLength))
return FALSE; goto Cleanup;
/* Output the response */ /* Output the response */
StringOut("The server responded:\n"); StringOut("The server responded:\n");
@ -350,9 +374,13 @@ Submit(TESTTYPES TestType, const PVOID TestData)
StringOut("\n"); StringOut("\n");
if(!strcmp(Data, "OK")) 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"; const CHAR FinishAction[] = "finish";
BOOL ReturnValue = FALSE;
DWORD DataLength; DWORD DataLength;
PCHAR Data; PCHAR Data;
PGENERAL_FINISH_DATA GeneralData; PGENERAL_FINISH_DATA GeneralData;
@ -410,10 +439,14 @@ Finish(TESTTYPES TestType, const PVOID TestData)
} }
if(!IntDoRequest(&Data, &DataLength)) if(!IntDoRequest(&Data, &DataLength))
return FALSE; goto Cleanup;
if(!strcmp(Data, "OK")) 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) IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWINE_GETSUITEID_DATA GetSuiteIDData, PWINE_SUBMIT_DATA SubmitData)
{ {
BOOL BreakLoop = FALSE; BOOL BreakLoop = FALSE;
BOOL ReturnValue = FALSE;
DWORD BytesAvailable; DWORD BytesAvailable;
DWORD LogAvailable = 0; DWORD LogAvailable = 0;
DWORD LogLength = 0; DWORD LogLength = 0;
DWORD LogPosition = 0; DWORD LogPosition = 0;
DWORD Temp; DWORD Temp;
PCHAR Buffer; PCHAR Buffer = NULL;
PROCESS_INFORMATION ProcessInfo; PROCESS_INFORMATION ProcessInfo = {0};
if(AppOptions.Submit) 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); sprintf(Buffer, "Running Wine Test, Module: %s, Test: %s\n", GetSuiteIDData->Module, GetSuiteIDData->Test);
StringOut(Buffer); StringOut(Buffer);
HeapFree(hProcessHeap, 0, Buffer); HeapFree(hProcessHeap, 0, Buffer);
Buffer = NULL;
/* Execute the test */ /* Execute the test */
if(!CreateProcessW(NULL, CommandLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &ProcessInfo)) if(!CreateProcessW(NULL, CommandLine, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &ProcessInfo))
{ {
StringOut("CreateProcessW for running the test failed\n"); StringOut("CreateProcessW for running the test failed\n");
return FALSE; goto Cleanup;
} }
/* Receive all the data from the pipe */ /* 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)) if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL))
{ {
StringOut("PeekNamedPipe failed for the test run\n"); StringOut("PeekNamedPipe failed for the test run\n");
return FALSE; goto Cleanup;
} }
if(BytesAvailable) if(BytesAvailable)
@ -89,7 +91,7 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL)) if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL))
{ {
StringOut("ReadFile failed for the test run\n"); 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 */ /* 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); HeapFree(hProcessHeap, 0, Buffer);
Buffer = NULL;
} }
} }
while(!BreakLoop); while(!BreakLoop);
/* Close the process handles */
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
if(AppOptions.Submit) if(AppOptions.Submit)
{ {
SubmitData->Log[LogLength - LogAvailable] = 0; SubmitData->Log[LogLength - LogAvailable] = 0;
@ -137,29 +136,47 @@ IntRunTest(PWSTR CommandLine, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWIN
SubmitData->General.TestID = GetTestID(WineTest); SubmitData->General.TestID = GetTestID(WineTest);
if(!SubmitData->General.TestID) if(!SubmitData->General.TestID)
return FALSE; goto Cleanup;
} }
/* Get a Suite ID for this combination */ /* Get a Suite ID for this combination */
SubmitData->General.SuiteID = GetSuiteID(WineTest, GetSuiteIDData); SubmitData->General.SuiteID = GetSuiteID(WineTest, GetSuiteIDData);
if(!SubmitData->General.SuiteID) if(!SubmitData->General.SuiteID)
return FALSE; goto Cleanup;
/* Submit the stuff */ /* Submit the stuff */
Submit(WineTest, SubmitData); Submit(WineTest, SubmitData);
/* Cleanup */
HeapFree(hProcessHeap, 0, SubmitData->General.SuiteID);
} }
/* Cleanup */
HeapFree(hProcessHeap, 0, SubmitData->Log);
} }
StringOut("\n\n"); 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 static BOOL
IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWINE_SUBMIT_DATA SubmitData) IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW StartupInfo, PWINE_SUBMIT_DATA SubmitData)
{ {
BOOL ReturnValue = FALSE;
DWORD BytesAvailable; DWORD BytesAvailable;
DWORD Length; DWORD Length;
DWORD Temp; DWORD Temp;
PCHAR Buffer; PCHAR Buffer = NULL;
PCHAR pStart; PCHAR pStart;
PCHAR pEnd; PCHAR pEnd;
PROCESS_INFORMATION ProcessInfo; PROCESS_INFORMATION ProcessInfo = {0};
PWSTR pUnderscore;
size_t FilePosition; size_t FilePosition;
WINE_GETSUITEID_DATA GetSuiteIDData; WINE_GETSUITEID_DATA GetSuiteIDData = {0};
/* Build the full command line */ /* Build the full command line */
FilePosition = wcslen(FilePath); FilePosition = wcslen(FilePath);
@ -202,8 +221,25 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
FilePath[FilePosition] = 0; FilePath[FilePosition] = 0;
wcscat(FilePath, L"--list"); 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 */ /* Store the tested module name */
Length = wcschr(File, L'_') - File; Length = pUnderscore - File;
GetSuiteIDData.Module = HeapAlloc(hProcessHeap, 0, Length + 1); GetSuiteIDData.Module = HeapAlloc(hProcessHeap, 0, Length + 1);
WideCharToMultiByte(CP_ACP, 0, File, Length, GetSuiteIDData.Module, Length, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, File, Length, GetSuiteIDData.Module, Length, NULL, NULL);
GetSuiteIDData.Module[Length] = 0; 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)) if(!CreateProcessW(NULL, FilePath, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, StartupInfo, &ProcessInfo))
{ {
StringOut("CreateProcessW for getting the available tests failed\n"); StringOut("CreateProcessW for getting the available tests failed\n");
return FALSE; goto Cleanup;
} }
/* Wait till this process ended */ /* Wait till this process ended */
if(WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_FAILED) if(WaitForSingleObject(ProcessInfo.hProcess, INFINITE) == WAIT_FAILED)
{ {
StringOut("WaitForSingleObject failed for the test list\n"); 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 */ /* Read the output data into a buffer */
if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL)) if(!PeekNamedPipe(hReadPipe, NULL, 0, NULL, &BytesAvailable, NULL))
{ {
StringOut("PeekNamedPipe failed for the test list\n"); 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); Buffer = HeapAlloc(hProcessHeap, 0, BytesAvailable);
if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL)) if(!ReadFile(hReadPipe, Buffer, BytesAvailable, &Temp, NULL))
{ {
StringOut("ReadFile failed\n"); StringOut("ReadFile failed\n");
return FALSE; goto Cleanup;
} }
/* Jump to the first available test */ /* Jump to the first available test */
@ -267,21 +315,36 @@ IntRunModuleTests(PWSTR File, PWSTR FilePath, HANDLE hReadPipe, LPSTARTUPINFOW S
FilePath[FilePosition + Length] = 0; FilePath[FilePosition + Length] = 0;
if(!IntRunTest(FilePath, hReadPipe, StartupInfo, &GetSuiteIDData, SubmitData)) if(!IntRunTest(FilePath, hReadPipe, StartupInfo, &GetSuiteIDData, SubmitData))
return FALSE; goto Cleanup;
} }
/* Cleanup */ /* Cleanup */
HeapFree(hProcessHeap, 0, GetSuiteIDData.Test); HeapFree(hProcessHeap, 0, GetSuiteIDData.Test);
GetSuiteIDData.Test = NULL;
/* Move to the next test */ /* Move to the next test */
pStart = pEnd + 6; pStart = pEnd + 6;
} }
/* Cleanup */ ReturnValue = TRUE;
HeapFree(hProcessHeap, 0, GetSuiteIDData.Module);
HeapFree(hProcessHeap, 0, Buffer);
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 BOOL
RunWineTests() RunWineTests()
{ {
BOOL ReturnValue = FALSE;
GENERAL_FINISH_DATA FinishData; GENERAL_FINISH_DATA FinishData;
HANDLE hFind; HANDLE hFind = NULL;
HANDLE hReadPipe; HANDLE hReadPipe = NULL;
HANDLE hWritePipe; HANDLE hWritePipe = NULL;
SECURITY_ATTRIBUTES SecurityAttributes; SECURITY_ATTRIBUTES SecurityAttributes;
STARTUPINFOW StartupInfo = {0}; STARTUPINFOW StartupInfo = {0};
size_t PathPosition; size_t PathPosition;
@ -312,7 +376,7 @@ RunWineTests()
if(!CreatePipe(&hReadPipe, &hWritePipe, &SecurityAttributes, 0)) if(!CreatePipe(&hReadPipe, &hWritePipe, &SecurityAttributes, 0))
{ {
StringOut("CreatePipe failed\n"); StringOut("CreatePipe failed\n");
return FALSE; goto Cleanup;
} }
StartupInfo.cb = sizeof(StartupInfo); StartupInfo.cb = sizeof(StartupInfo);
@ -323,7 +387,7 @@ RunWineTests()
if(GetWindowsDirectoryW(FilePath, MAX_PATH) > MAX_PATH - 60) if(GetWindowsDirectoryW(FilePath, MAX_PATH) > MAX_PATH - 60)
{ {
StringOut("Windows directory path is too long\n"); StringOut("Windows directory path is too long\n");
return FALSE; goto Cleanup;
} }
wcscat(FilePath, L"\\bin\\"); wcscat(FilePath, L"\\bin\\");
@ -346,7 +410,7 @@ RunWineTests()
if(hFind == INVALID_HANDLE_VALUE) if(hFind == INVALID_HANDLE_VALUE)
{ {
StringOut("FindFirstFileW failed\n"); StringOut("FindFirstFileW failed\n");
return FALSE; goto Cleanup;
} }
/* Run the tests */ /* Run the tests */
@ -357,27 +421,33 @@ RunWineTests()
/* Run it */ /* Run it */
if(!IntRunModuleTests(fd.cFileName, FilePath, hReadPipe, &StartupInfo, &SubmitData)) if(!IntRunModuleTests(fd.cFileName, FilePath, hReadPipe, &StartupInfo, &SubmitData))
return FALSE; goto Cleanup;
} }
while(FindNextFileW(hFind, &fd)); while(FindNextFileW(hFind, &fd));
/* Cleanup */ /* Close this test run if necessary */
FindClose(hFind); if(SubmitData.General.TestID)
if(AppOptions.Submit && SubmitData.General.TestID)
{ {
/* We're done with the tests, so close this test run */
FinishData.TestID = SubmitData.General.TestID; FinishData.TestID = SubmitData.General.TestID;
if(!Finish(WineTest, &FinishData)) if(!Finish(WineTest, &FinishData))
return FALSE; goto Cleanup;
/* Cleanup */
HeapFree(hProcessHeap, 0, FinishData.TestID);
} }
CloseHandle(hReadPipe); ReturnValue = TRUE;
CloseHandle(hWritePipe);
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;
} }