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