From 29474c309bfa89858804d011792cfe95ad00d55e Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Tue, 18 Nov 2008 18:57:27 +0000 Subject: [PATCH] Rough code to start Winetests processes from the GUI, but with the console's stdout redirected to a pipe controlled by the GUI. We can now read the console text from the winetest processes in the GUI (although it's just usage info at the moment) svn path=/trunk/; revision=37447 --- rostests/winetests/GUI/browsewnd.c | 22 +++-- rostests/winetests/GUI/mainwnd.c | 150 ++++++++++++++++++++++++++--- rostests/winetests/GUI/precomp.h | 10 +- 3 files changed, 155 insertions(+), 27 deletions(-) diff --git a/rostests/winetests/GUI/browsewnd.c b/rostests/winetests/GUI/browsewnd.c index 613fc79dbb5..808a592eaba 100644 --- a/rostests/winetests/GUI/browsewnd.c +++ b/rostests/winetests/GUI/browsewnd.c @@ -53,7 +53,7 @@ GetListOfTestExes(PMAIN_WND_INFO pInfo) INT numFiles = 0; INT len; - len = GetCurrentDirectory(MAX_PATH, szExePath); + len = GetCurrentDirectoryW(MAX_PATH, szExePath); if (!len) return 0; wcsncat(szExePath, EXE_SEARCH_DIR, MAX_PATH - (len + 1)); @@ -205,8 +205,8 @@ InsertIntoTreeView(HWND hTreeView, } static PTEST_ITEM -BuildTestItemData(LPWSTR lpExe, - LPWSTR lpRun) +BuildTestItemData(LPWSTR lpName, + LPWSTR lpRunCmd) { PTEST_ITEM pItem; @@ -215,10 +215,14 @@ BuildTestItemData(LPWSTR lpExe, sizeof(TEST_ITEM)); if (pItem) { - if (lpExe) - wcsncpy(pItem->szSelectedExe, lpExe, MAX_PATH); - if (lpRun) - wcsncpy(pItem->szRunString, lpRun, MAX_RUN_CMD); + if (lpName) + { + wcsncpy(pItem->szName, lpName, MAX_PATH); + } + if (lpRunCmd) + { + wcsncpy(pItem->szRunCmd, lpRunCmd, MAX_RUN_CMD); + } } return pItem; @@ -248,7 +252,7 @@ PopulateTreeView(PMAIN_WND_INFO pInfo) hImgList, TVSIL_NORMAL); - pTestItem = BuildTestItemData(L"", L"Full"); + pTestItem = BuildTestItemData(L"Full", L"runall"); /* insert the root item into the tree */ hRoot = InsertIntoTreeView(pInfo->hBrowseTV, @@ -275,7 +279,7 @@ PopulateTreeView(PMAIN_WND_INFO pInfo) { //FIXME: Query the test name from the exe directly - pTestItem = BuildTestItemData(lpExePath, lpTestName); + pTestItem = BuildTestItemData(lpTestName, lpExePath); hParent = InsertIntoTreeView(pInfo->hBrowseTV, hRoot, diff --git a/rostests/winetests/GUI/mainwnd.c b/rostests/winetests/GUI/mainwnd.c index 1fb27dd9ea7..a2b3d38f7de 100644 --- a/rostests/winetests/GUI/mainwnd.c +++ b/rostests/winetests/GUI/mainwnd.c @@ -18,12 +18,125 @@ WCHAR szPipeName[] = L"\\\\.\\pipe\\winetest_pipe"; typedef int (_cdecl *RUNTEST)(char **); - -VOID -CreateClientProcess(PMAIN_WND_INFO pInfo, - LPWSTR lpExePath) +DWORD WINAPI +PipeReadThread(LPVOID lpParam) { + PMAIN_WND_INFO pInfo; + HWND hList, hEdit; + DWORD dwRead; + CHAR chBuf[BUFSIZE]; + BOOL bSuccess = FALSE; + LVITEMA item; + INT count; + pInfo = (PMAIN_WND_INFO)lpParam; + + hList = GetDlgItem(pInfo->hMainWnd, IDC_LIST); + hEdit = GetDlgItem(pInfo->hMainWnd, IDC_OUTPUT); + + ZeroMemory(&item, sizeof(LVITEMA)); + item.mask = LVIF_TEXT; + + while (TRUE) + { + dwRead = 0; + bSuccess = ReadFile(pInfo->hStdOutRd, + chBuf, + BUFSIZE, + &dwRead, + NULL); + if(!bSuccess || dwRead == 0) + break; + + chBuf[dwRead] = 0; + + count = GetWindowTextLengthA(hEdit); + SendMessageA(hEdit, EM_SETSEL, (WPARAM)count, (LPARAM)count); + SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)chBuf); + + //item.iItem = ListView_GetItemCount(hList); + //item.pszText = chBuf; + //SendMessage(hEdit, LVM_INSERTITEMA, 0, (LPARAM)&item); + } + + return 0; +} + + +DWORD WINAPI +CreateClientProcess(PMAIN_WND_INFO pInfo) +{ + SECURITY_ATTRIBUTES sa; + STARTUPINFO si; + PROCESS_INFORMATION pi; + BOOL bSuccess = FALSE; + + // + // Set up the security attributes + // + sa.nLength= sizeof(SECURITY_ATTRIBUTES); + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + // + // Create a pipe for the child process's STDOUT + // + if (!CreatePipe(&pInfo->hStdOutRd, + &pInfo->hStdOutWr, + &sa, + 0)) + { + return FALSE; + } + + // + // Ensure the read handle to the pipe for STDOUT is not inherited + // + if (!SetHandleInformation(pInfo->hStdOutRd, + HANDLE_FLAG_INHERIT, + 0)) + { + return FALSE; + } + + ZeroMemory(&si, sizeof(STARTUPINFO)); + si.cb = sizeof(STARTUPINFO); + si.hStdError = pInfo->hStdOutWr; + si.hStdOutput = pInfo->hStdOutWr; + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.dwFlags |= STARTF_USESTDHANDLES; + + ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)); + + bSuccess = CreateProcessW(pInfo->lpCmdLine, + NULL, + NULL, + NULL, + TRUE, + 0,//CREATE_SUSPENDED, + NULL, + NULL, + &si, + &pi); + if (bSuccess) + { + // + // Create thread to handle pipe input from child processes + // + pInfo->hPipeThread = CreateThread(NULL, + 0, + PipeReadThread, + pInfo, + 0, + NULL); + + WaitForSingleObject(pi.hProcess, INFINITE); + + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + + return bSuccess; } @@ -78,7 +191,6 @@ RunSelectedTest(PMAIN_WND_INFO pInfo) { HWND hRunCmd; WCHAR szTextCmd[MAX_RUN_CMD]; - LPWSTR lpExePath; INT sel; hRunCmd = GetDlgItem(pInfo->hMainWnd, IDC_TESTSELECTION); @@ -94,13 +206,22 @@ RunSelectedTest(PMAIN_WND_INFO pInfo) sel, (LPARAM)szTextCmd) != CB_ERR) { - lpExePath = (LPWSTR)SendMessage(hRunCmd, - CB_GETITEMDATA, - 0, - 0); - if (lpExePath) + pInfo->lpCmdLine = (LPWSTR)SendMessage(hRunCmd, + CB_GETITEMDATA, + 0, + 0); + if (pInfo->lpCmdLine) { - CreateClientProcess(pInfo, lpExePath); + // + // Create a new thread to create the client process + // and recieve any ouput via stdout + // + CreateThread(NULL, + 0, + CreateClientProcess, + pInfo, + 0, + NULL); } } } @@ -119,14 +240,14 @@ AddTestToCombo(PMAIN_WND_INFO pInfo) SendMessageW(hRunCmd, CB_INSERTSTRING, 0, - (LPARAM)pInfo->SelectedTest.szRunString); + (LPARAM)pInfo->SelectedTest.szName); - len = (wcslen(pInfo->SelectedTest.szSelectedExe) + 1) * sizeof(WCHAR); + len = (wcslen(pInfo->SelectedTest.szRunCmd) + 1) * sizeof(WCHAR); lpExePath = HeapAlloc(GetProcessHeap(), 0, len); if (lpExePath) { wcsncpy(lpExePath, - pInfo->SelectedTest.szSelectedExe, + pInfo->SelectedTest.szRunCmd, len / sizeof(WCHAR)); } @@ -261,7 +382,6 @@ wWinMain(HINSTANCE hInst, { INITCOMMONCONTROLSEX iccx; PMAIN_WND_INFO pInfo; - HANDLE hThread; INT Ret = -1; UNREFERENCED_PARAMETER(hPrev); diff --git a/rostests/winetests/GUI/precomp.h b/rostests/winetests/GUI/precomp.h index c601f5b1907..5164e5663a4 100644 --- a/rostests/winetests/GUI/precomp.h +++ b/rostests/winetests/GUI/precomp.h @@ -9,12 +9,13 @@ extern HINSTANCE hInstance; +#define MAX_NAME 32 #define MAX_RUN_CMD 256 typedef struct _TEST_ITEM { - WCHAR szSelectedExe[MAX_PATH]; - WCHAR szRunString[MAX_RUN_CMD]; + WCHAR szName[MAX_NAME]; + WCHAR szRunCmd[MAX_RUN_CMD]; } TEST_ITEM, *PTEST_ITEM; @@ -24,7 +25,10 @@ typedef struct _MAIN_WND_INFO HWND hBrowseDlg; HWND hBrowseTV; HWND hStatus; - HANDLE hPipe; + HANDLE hPipeThread; + HANDLE hStdOutRd; + HANDLE hStdOutWr; + LPWSTR lpCmdLine; int nCmdShow; HICON hSmIcon;