1 /*
2  * PROJECT:     ReactOS API Test GUI
3  * LICENSE:     GPL - See COPYING in the top level directory
4  * FILE:
5  * PURPOSE:     main dialog implementation
6  * COPYRIGHT:   Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
7  *
8  */
9 
10 #include <precomp.h>
11 #include <io.h>
12 
13 #define BUFSIZE 4096
14 
15 HINSTANCE hInstance;
16 
17 WCHAR szPipeName[] = L"\\\\.\\pipe\\winetest_pipe";
18 
19 typedef int (_cdecl *RUNTEST)(char **);
20 
21 DWORD WINAPI
22 PipeReadThread(LPVOID lpParam)
23 {
24     PMAIN_WND_INFO pInfo;
25     HWND hList, hEdit;
26     DWORD dwRead;
27     CHAR chBuf[BUFSIZE];
28     BOOL bSuccess = FALSE;
29     LVITEMA item;
30     INT count;
31 
32     pInfo = (PMAIN_WND_INFO)lpParam;
33 
34     hList = GetDlgItem(pInfo->hMainWnd, IDC_LIST);
35     hEdit = GetDlgItem(pInfo->hMainWnd, IDC_OUTPUT);
36 
37     ZeroMemory(&item, sizeof(LVITEMA));
38     item.mask = LVIF_TEXT;
39 
40     while (TRUE)
41     {
42         dwRead = 0;
43         bSuccess = ReadFile(pInfo->hStdOutRd,
44                             chBuf,
45                             BUFSIZE,
46                             &dwRead,
47                             NULL);
48         if(!bSuccess || dwRead == 0)
49             break;
50 
51         chBuf[dwRead] = 0;
52 
53         count = GetWindowTextLengthA(hEdit);
54         SendMessageA(hEdit, EM_SETSEL, (WPARAM)count, (LPARAM)count);
55         SendMessageA(hEdit, EM_REPLACESEL, 0, (LPARAM)chBuf);
56 
57         //item.iItem = ListView_GetItemCount(hList);
58         //item.pszText = chBuf;
59         //SendMessage(hEdit, LVM_INSERTITEMA, 0, (LPARAM)&item);
60     }
61 
62     return 0;
63 }
64 
65 
66 DWORD WINAPI
67 CreateClientProcess(PMAIN_WND_INFO pInfo)
68 {
69     SECURITY_ATTRIBUTES sa;
70     STARTUPINFO si;
71     PROCESS_INFORMATION pi;
72     BOOL bSuccess = FALSE;
73 
74     //
75     // Set up the security attributes
76     //
77     sa.nLength= sizeof(SECURITY_ATTRIBUTES);
78     sa.lpSecurityDescriptor = NULL;
79     sa.bInheritHandle = TRUE;
80 
81     //
82     // Create a pipe for the child process's STDOUT
83     //
84     if (!CreatePipe(&pInfo->hStdOutRd,
85                     &pInfo->hStdOutWr,
86                     &sa,
87                     0))
88     {
89         return FALSE;
90     }
91 
92     //
93     // Ensure the read handle to the pipe for STDOUT is not inherited
94     //
95     if (!SetHandleInformation(pInfo->hStdOutRd,
96                               HANDLE_FLAG_INHERIT,
97                               0))
98     {
99         return FALSE;
100     }
101 
102     ZeroMemory(&si, sizeof(STARTUPINFO));
103     si.cb = sizeof(STARTUPINFO);
104     si.hStdError = pInfo->hStdOutWr;
105     si.hStdOutput = pInfo->hStdOutWr;
106     si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
107     si.dwFlags |= STARTF_USESTDHANDLES;
108 
109     ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
110 
111     bSuccess = CreateProcessW(pInfo->lpCmdLine,
112                               NULL,
113                               NULL,
114                               NULL,
115                               TRUE,
116                               0,//CREATE_SUSPENDED,
117                               NULL,
118                               NULL,
119                               &si,
120                               &pi);
121     if (bSuccess)
122     {
123         //
124         // Create thread to handle pipe input from child processes
125         //
126         pInfo->hPipeThread = CreateThread(NULL,
127                                           0,
128                                           PipeReadThread,
129                                           pInfo,
130                                           0,
131                                           NULL);
132 
133         WaitForSingleObject(pi.hProcess, INFINITE);
134 
135         CloseHandle(pi.hProcess);
136         CloseHandle(pi.hThread);
137     }
138 
139     return bSuccess;
140 }
141 
142 
143 static BOOL
144 OnInitMainDialog(HWND hDlg,
145                  LPARAM lParam)
146 {
147     PMAIN_WND_INFO pInfo;
148 
149     pInfo = (PMAIN_WND_INFO)lParam;
150 
151     /* Initialize the main window context */
152     pInfo->hMainWnd = hDlg;
153 
154     SetWindowLongPtr(hDlg,
155                      GWLP_USERDATA,
156                      (LONG_PTR)pInfo);
157 
158     pInfo->hSmIcon = LoadImageW(hInstance,
159                                 MAKEINTRESOURCEW(IDI_ICON),
160                                 IMAGE_ICON,
161                                 16,
162                                 16,
163                                 0);
164     if (pInfo->hSmIcon)
165     {
166          SendMessageW(hDlg,
167                       WM_SETICON,
168                       ICON_SMALL,
169                       (LPARAM)pInfo->hSmIcon);
170     }
171 
172     pInfo->hBgIcon = LoadImageW(hInstance,
173                                 MAKEINTRESOURCEW(IDI_ICON),
174                                 IMAGE_ICON,
175                                 32,
176                                 32,
177                                 0);
178     if (pInfo->hBgIcon)
179     {
180         SendMessageW(hDlg,
181                      WM_SETICON,
182                      ICON_BIG,
183                      (LPARAM)pInfo->hBgIcon);
184     }
185 
186     return TRUE;
187 }
188 
189 static VOID
190 RunSelectedTest(PMAIN_WND_INFO pInfo)
191 {
192     HWND hRunCmd;
193     WCHAR szTextCmd[MAX_RUN_CMD];
194     INT sel;
195 
196     hRunCmd = GetDlgItem(pInfo->hMainWnd, IDC_TESTSELECTION);
197 
198     sel = SendMessageW(hRunCmd,
199                        CB_GETCURSEL,
200                        0,
201                        0);
202     if (sel != CB_ERR)
203     {
204         if (SendMessageW(hRunCmd,
205                          CB_GETLBTEXT,
206                          sel,
207                          (LPARAM)szTextCmd) != CB_ERR)
208         {
209             pInfo->lpCmdLine = (LPWSTR)SendMessage(hRunCmd,
210                                                    CB_GETITEMDATA,
211                                                    0,
212                                                    0);
213             if (pInfo->lpCmdLine)
214             {
215                 //
216                 // Create a new thread to create the client process
217                 // and receive any ouput via stdout
218                 //
219                 CreateThread(NULL,
220                              0,
221                              CreateClientProcess,
222                              pInfo,
223                              0,
224                              NULL);
225             }
226         }
227     }
228 }
229 
230 static VOID
231 AddTestToCombo(PMAIN_WND_INFO pInfo)
232 {
233     HWND hRunCmd;
234     LPWSTR lpExePath;
235     INT len;
236 
237     hRunCmd = GetDlgItem(pInfo->hMainWnd, IDC_TESTSELECTION);
238     if (hRunCmd)
239     {
240         SendMessageW(hRunCmd,
241                      CB_INSERTSTRING,
242                      0,
243                      (LPARAM)pInfo->SelectedTest.szName);
244 
245         len = (wcslen(pInfo->SelectedTest.szRunCmd) + 1) * sizeof(WCHAR);
246         lpExePath = HeapAlloc(GetProcessHeap(), 0, len);
247         if (lpExePath)
248         {
249             wcsncpy(lpExePath,
250                     pInfo->SelectedTest.szRunCmd,
251                     len / sizeof(WCHAR));
252         }
253 
254         SendMessageW(hRunCmd,
255                      CB_SETITEMDATA,
256                      0,
257                      (LPARAM)lpExePath);
258         SendMessageW(hRunCmd,
259                      CB_SETCURSEL,
260                      0,
261                      0);
262     }
263 }
264 
265 static VOID
266 FreeTestCmdStrings(PMAIN_WND_INFO pInfo)
267 {
268     HWND hRunCmd;
269     LPWSTR lpExePath;
270     INT cnt, i;
271 
272     hRunCmd = GetDlgItem(pInfo->hMainWnd, IDC_TESTSELECTION);
273 
274     cnt = SendMessageW(hRunCmd,
275                        CB_GETCOUNT,
276                        0,
277                        0);
278     if (cnt != CB_ERR)
279     {
280         for (i = 0; i < cnt; i++)
281         {
282             lpExePath = (LPWSTR)SendMessage(hRunCmd,
283                                             CB_GETITEMDATA,
284                                             i,
285                                             0);
286             if (lpExePath)
287             {
288                 HeapFree(GetProcessHeap(), 0, lpExePath);
289             }
290         }
291     }
292 }
293 
294 static BOOL CALLBACK
295 MainDlgProc(HWND hDlg,
296             UINT Message,
297             WPARAM wParam,
298             LPARAM lParam)
299 {
300     PMAIN_WND_INFO pInfo;
301 
302     /* Get the window context */
303     pInfo = (PMAIN_WND_INFO)GetWindowLongPtr(hDlg,
304                                              GWLP_USERDATA);
305     if (pInfo == NULL && Message != WM_INITDIALOG)
306     {
307         goto HandleDefaultMessage;
308     }
309 
310     switch(Message)
311     {
312         case WM_INITDIALOG:
313             return OnInitMainDialog(hDlg, lParam);
314 
315         case WM_COMMAND:
316         {
317             switch(LOWORD(wParam))
318             {
319                 case IDC_BROWSE:
320                 {
321                     INT_PTR ret;
322 
323                     ret = DialogBoxParamW(hInstance,
324                                           MAKEINTRESOURCEW(IDD_TESTBROWSER),
325                                           hDlg,
326                                           (DLGPROC)BrowseDlgProc,
327                                           (LPARAM)pInfo);
328                     if (ret == IDOK)
329                     {
330                         AddTestToCombo(pInfo);
331                     }
332 
333                     break;
334                 }
335                 case IDC_OPTIONS:
336                     DialogBoxParamW(hInstance,
337                                     MAKEINTRESOURCEW(IDD_OPTIONS),
338                                     hDlg,
339                                     (DLGPROC)OptionsDlgProc,
340                                     (LPARAM)pInfo);
341                     break;
342 
343                 case IDC_RUN:
344                     RunSelectedTest(pInfo);
345                     break;
346 
347                 case IDOK:
348                     EndDialog(hDlg, 0);
349                     break;
350             }
351         }
352         break;
353 
354         case WM_CLOSE:
355             EndDialog(hDlg, 0);
356             break;
357 
358         case WM_DESTROY:
359              if (pInfo->hSmIcon)
360                 DestroyIcon(pInfo->hSmIcon);
361             if (pInfo->hBgIcon)
362                 DestroyIcon(pInfo->hBgIcon);
363 
364             FreeTestCmdStrings(pInfo);
365 
366             break;
367 
368 HandleDefaultMessage:
369         default:
370             return FALSE;
371     }
372 
373     return FALSE;
374 }
375 
376 
377 INT WINAPI
378 wWinMain(HINSTANCE hInst,
379          HINSTANCE hPrev,
380          LPWSTR Cmd,
381          int iCmd)
382 {
383     INITCOMMONCONTROLSEX iccx;
384     PMAIN_WND_INFO pInfo;
385     INT Ret = -1;
386 
387     UNREFERENCED_PARAMETER(hPrev);
388     UNREFERENCED_PARAMETER(Cmd);
389     UNREFERENCED_PARAMETER(iCmd);
390 
391     hInstance = hInst;
392 
393     ZeroMemory(&iccx, sizeof(INITCOMMONCONTROLSEX));
394     iccx.dwSize = sizeof(INITCOMMONCONTROLSEX);
395     iccx.dwICC = ICC_TAB_CLASSES;
396     InitCommonControlsEx(&iccx);
397 
398     pInfo = HeapAlloc(GetProcessHeap(),
399                       0,
400                       sizeof(MAIN_WND_INFO));
401     if (pInfo)
402     {
403         Ret = (DialogBoxParamW(hInstance,
404                                MAKEINTRESOURCEW(IDD_WINETESTGUI),
405                                NULL,
406                                (DLGPROC)MainDlgProc,
407                                (LPARAM)pInfo) == IDOK);
408 
409         HeapFree(GetProcessHeap(),
410                  0,
411                  pInfo);
412     }
413 
414     return Ret;
415 }
416