root/trunk/Executor.cpp

Revision 5, 9.5 kB (checked in by qbert, 6 years ago)

Initial ( and last :( ) commit

Line 
1 #include "stdafx.h"
2 #include "executor.h"
3
4 #define dim(x) (sizeof(x) / sizeof((x)[0]))
5
6 #define MAX_LINE_LENGTH 1024
7
8 unsigned long Executor::Run()
9 {
10     hreadFromChild = NULL;
11     HANDLE hwriteToParent = NULL;
12     HANDLE hwriteToParent2 = NULL;
13
14     SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; // inheritable handle
15
16     if ( lib != "" ) {
17         _putenv( string("LIB=" + lib ).c_str() ); // set the lib path!
18        
19     }
20
21     LPTSTR cmd = command.GetBuffer(command.GetLength() + 1);
22
23
24     if(!::CreatePipe(&hreadFromChild, &hwriteToParent, &sa, 0))
25     { /* pipe failed */
26         // ::GetLastError() will reveal the cause
27 //      delete this;
28         return FALSE;
29     } /* pipe failed */
30
31     if(!::DuplicateHandle(GetCurrentProcess(),     // duplicate from this process
32                   hwriteToParent,       // this handle
33                   GetCurrentProcess(),     // into this process
34                   &hwriteToParent2,        // as this handle
35                   0,                // no access flags (subsumed by DUPLICATE_SAME_ACCESS)
36                   TRUE,             // create inheritable
37                   DUPLICATE_SAME_ACCESS))  // create duplicate access
38     { /* duplicate failed */
39         DWORD err = ::GetLastError();
40         ::CloseHandle(hreadFromChild);
41         ::CloseHandle(hwriteToParent);
42         ::SetLastError(err);
43 //      delete this;
44         return FALSE;
45     } /* duplicate failed */
46
47     STARTUPINFO startup;
48     PROCESS_INFORMATION procinfo;
49
50     ::ZeroMemory(&startup, sizeof(startup));
51
52     startup.cb = sizeof(startup);
53     startup.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
54     startup.wShowWindow = SW_HIDE; // hidden console window
55     startup.hStdInput = NULL; // not used
56     startup.hStdOutput = hwriteToParent;
57     startup.hStdError = hwriteToParent2;
58
59     // We want a non-inherited read handle. DuplicateHandle with a
60     // NULL target fixes the read side to be non-inheritable
61     ::DuplicateHandle(::GetCurrentProcess(),    // in this process
62               hreadFromChild,           // child read handle
63               ::GetCurrentProcess(),    // to this process
64               NULL,                     // modify existing handle
65               0,                        // flags
66               FALSE,                    // not inheritable
67               DUPLICATE_SAME_ACCESS);   // same handle access
68
69     // We need a writeable buffer for the command (silly Windows restriction)
70
71
72     BOOL started = ::CreateProcess(NULL,        // command is part of input string
73                        cmd,         // (writeable) command string
74                        NULL,        // process security
75                        NULL,        // thread security
76                        TRUE,        // inherit handles flag
77                        0,           // flags
78                        NULL,        // inherit environment
79                        NULL,        // inherit directory
80                        &startup,    // STARTUPINFO
81                        &procinfo);  // PROCESS_INFORMATION
82     command.ReleaseBuffer();
83
84     if(!started)
85     { /* failed to start */
86         DWORD err = ::GetLastError(); // preserve across CloseHandle calls
87         ::CloseHandle(hreadFromChild);
88         ::CloseHandle(hwriteToParent);
89         ::CloseHandle(hwriteToParent2);
90         ::SetLastError(err);
91 //   target->PostMessage(UPM_FINISHED, (WPARAM)err, (LPARAM)pid);
92 //      delete this;
93         return FALSE;
94     } /* failed to start */
95
96 //     target->PostMessage(UPM_PROCESS_HANDLE, (WPARAM)procinfo.hProcess, (LPARAM)pid);
97      
98 // Now close the output pipes so we get true EOF/broken pipe
99     ::CloseHandle(hwriteToParent);
100     ::CloseHandle(hwriteToParent2);
101      
102     // We have to create a listener thread. We create a worker
103     // thread that handles this
104
105     if ( waitToComplete ) {
106
107
108         TCHAR buffer[MAX_LINE_LENGTH + 1];
109
110         CString * line;
111         line = new CString;
112
113         DWORD bytesRead;
114      
115         while(::ReadFile(hreadFromChild, buffer, sizeof(buffer) - sizeof(TCHAR), &bytesRead, NULL))
116         { /* got data */
117             if(bytesRead == 0)
118                 break; // EOF condition
119      
120             buffer[bytesRead] = _T('\0');
121             // Convert to lines
122             LPTSTR b = buffer;
123             while(TRUE)
124             { /* convert and send */
125                 LPTSTR p = _tcschr(b, _T('\n'));
126                 if(p == NULL)
127                 { /* incomplete line */
128                     *line += b;
129                     break; // leave assembly loop
130                 } /* incomplete line */
131                 else
132                 { /* complete line */
133                     int offset = 0;
134                     if(p - b > 0)
135                     { /* get rid of \r */
136                         if(p[-1] == _T('\r'))
137                             offset = 1;
138                     } /* get rid of \r */
139                     *line += CString(b, (p - b) - offset);
140                     output += line->GetBuffer(0) ;
141                     output += '\r\n';
142
143                     b = p + 1;
144                     line = new CString;
145                 } /* complete line */
146             } /* convert and send */
147         } /* got data */
148
149         DWORD err = ::GetLastError();
150
151         ::CloseHandle(hreadFromChild);
152
153
154         if(line->GetLength() > 0) {
155             output += line->GetBuffer(0) ;
156             output += '\r\n';
157         }
158
159         else
160             delete line;
161      
162         DWORD status = 0;
163         if(err != ERROR_BROKEN_PIPE)
164             status = err;
165
166 //      ::CloseHandle(hreadFromChild);
167 //      ::CloseHandle(hwriteToParent);
168 //      ::CloseHandle(hwriteToParent2);
169
170     }
171     else {
172
173         CWinThread * thread = AfxBeginThread(Listener, (LPVOID)this);
174         if(thread == NULL)
175         { /* failed */
176             DWORD err = ::GetLastError();
177             ::CloseHandle(hreadFromChild);
178             ::CloseHandle(hwriteToParent);
179             ::CloseHandle(hwriteToParent2);
180 //          delete this;
181             return FALSE;
182         }
183         return 0;
184
185     }
186    
187     unsigned long exitCode;
188     WaitForSingleObject(procinfo.hProcess,1000 );
189     GetExitCodeProcess(procinfo.hProcess, &exitCode);
190     return exitCode;
191 }
192
193 UINT Executor::Listener(LPVOID me)
194 {
195     ((Executor *)me)->Listener();
196     return 0;
197 } // Executor::listener
198
199
200 void Executor::Listener()
201 {
202     TCHAR buffer[MAX_LINE_LENGTH + 1];
203
204     CString * line;
205     line = new CString;
206
207     DWORD bytesRead;
208      
209     while(::ReadFile(hreadFromChild, buffer, sizeof(buffer) - sizeof(TCHAR), &bytesRead, NULL))
210     { /* got data */
211         if(bytesRead == 0)
212             break; // EOF condition
213      
214         buffer[bytesRead] = _T('\0');
215         // Convert to lines
216         LPTSTR b = buffer;
217         while(TRUE)
218         { /* convert and send */
219             LPTSTR p = _tcschr(b, _T('\n'));
220             if(p == NULL)
221             { /* incomplete line */
222                 *line += b;
223                 break; // leave assembly loop
224             } /* incomplete line */
225             else
226             { /* complete line */
227                 int offset = 0;
228                 if(p - b > 0)
229                 { /* get rid of \r */
230                     if(p[-1] == _T('\r'))
231                         offset = 1;
232                 } /* get rid of \r */
233                 *line += CString(b, (p - b) - offset);
234                 output += line->GetBuffer(0) ;
235                 if ( onLine ) onLine(line->GetBuffer(0) );
236                 b = p + 1;
237                 line = new CString;
238             } /* complete line */
239         } /* convert and send */
240     } /* got data */
241
242     DWORD err = ::GetLastError();
243
244     ::CloseHandle(hreadFromChild);
245
246
247     if(line->GetLength() > 0) {
248         output += line->GetBuffer(0) ;
249         if ( onLine ) onLine(line->GetBuffer(0) );
250     }
251
252     else
253         delete line;
254      
255     DWORD status = 0;
256     if(err != ERROR_BROKEN_PIPE)
257         status = err;
258      
259 //  target->PostMessage(UPM_FINISHED, status, (LPARAM)pid);
260     if ( onFinished ) onFinished(output);
261 //  delete this;
262 } // Executor::listener
263
264
265 DWORD RunSilent(char* strFunct, char* strstrParams, const string& outputFile )
266 {
267    
268     STARTUPINFO StartupInfo;
269     PROCESS_INFORMATION ProcessInfo;
270     char Args[4096];
271     char *pEnvCMD = NULL;
272     char *pDefaultCMD = "CMD.EXE";
273     ULONG rc;
274    
275     memset(&StartupInfo, 0, sizeof(StartupInfo));
276     StartupInfo.cb = sizeof(STARTUPINFO);
277     StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
278     StartupInfo.wShowWindow = SW_HIDE;
279    
280     Args[0] = 0;
281    
282     pEnvCMD = getenv("COMSPEC");
283    
284     if(pEnvCMD){
285        
286         strcpy(Args, pEnvCMD);
287     }
288     else{
289         strcpy(Args, pDefaultCMD);
290     }
291    
292     // "/c" option - Do the command then terminate the command window
293     strcat(Args, " /c ");
294     //the application you would like to run from the command window
295     strcat(Args, strFunct); 
296     strcat(Args, " ");
297     //the parameters passed to the application being run from the command window.
298     strcat(Args, strstrParams);
299    
300     if (outputFile != "none") {
301        
302         strcat(Args," > ");
303         //      AfxMessageBox(outputFile.c);
304         strcat(Args,outputFile.c_str());
305     }
306    
307     //      ofstream out("C:\\args.txt");
308     //      out << Args;
309     //  out.close();
310     //      AfxMessageBox(Args);
311    
312    
313    
314     if (!CreateProcess( NULL, Args, NULL, NULL, FALSE,
315         CREATE_NEW_CONSOLE,
316         NULL,
317         NULL,
318         &StartupInfo,
319         &ProcessInfo))
320     {
321         return GetLastError();     
322     }
323    
324     WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
325    
326    
327    
328    
329    
330    
331     if(!GetExitCodeProcess(ProcessInfo.hProcess, &rc))
332         rc = 0;
333    
334     /*  CloseHandle(ProcessInfo.hThread); */
335     /*  CloseHandle(ProcessInfo.hProcess); */
336    
337     return rc;
338    
339 }
340
341 DWORD RunLoud(char* strFunct, char* strParams) {
342    
343
344     STARTUPINFO StartupInfo;
345     PROCESS_INFORMATION ProcessInfo;
346     char Args[4096];
347     char *pEnvCMD = NULL;
348     char *pDefaultCMD = "CMD.EXE";
349     ULONG rc;
350    
351     memset(&StartupInfo, 0, sizeof(StartupInfo));
352     StartupInfo.cb = sizeof(STARTUPINFO);
353     StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
354     StartupInfo.wShowWindow = SW_HIDE;
355    
356     Args[0] = 0;
357    
358     pEnvCMD = getenv("COMSPEC");
359    
360     if(pEnvCMD){
361        
362         strcpy(Args, pEnvCMD);
363     }
364     else{
365         strcpy(Args, pDefaultCMD);
366     }
367    
368     // "/c" option - Do the command then terminate the command window
369     strcat(Args, " /k ");
370     //the application you would like to run from the command window
371     strcat(Args, strFunct); 
372     strcat(Args, " ");
373     //the parameters passed to the application being run from the command window.
374     strcat(Args, strParams);
375    
376    
377    
378     if (!CreateProcess( NULL, Args, NULL, NULL, FALSE,
379         CREATE_NEW_CONSOLE,
380         NULL,
381         NULL,
382         &StartupInfo,
383         &ProcessInfo))
384     {
385         return GetLastError();     
386     }
387    
388    
389    
390    
391    
392    
393     if(!GetExitCodeProcess(ProcessInfo.hProcess, &rc))
394         rc = 0;
395    
396     /*  CloseHandle(ProcessInfo.hThread); */
397     /*  CloseHandle(ProcessInfo.hProcess); */
398    
399     return rc;
400 }
Note: See TracBrowser for help on using the browser.