source: trunk/dll/systemf.c@ 1720

Last change on this file since 1720 was 1720, checked in by Gregg Young, 12 years ago

Add "#" command line switch to workaround problem with blank command shell started from fm2 after fm2 has been started with stdout and stderr redirected to a file. Fixes it by using the system environment instead of fm2's when starting command shells.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: systemf.c 1720 2014-02-16 19:47:30Z gyoung $
5
6 System Interfaces
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2003, 2010 Steven H.Levine
10
11 21 Nov 03 SHL Comments
12 31 Jul 04 SHL Indent -i2
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 17 Jul 06 SHL Use Runtime_Error
15 26 Jul 06 SHL Use convert_nl_to_nul
16 15 Aug 06 SHL More error popups
17 01 Nov 06 SHL runemf2: temp fix for hung windows caused by termq errors
18 03 Nov 06 SHL runemf2: rework termination queue logic to work for multiple threads
19 07 Jan 07 GKY Move error strings etc. to string file
20 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
21 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
22 29 Feb 08 GKY Changes to enable user settable command line length
23 29 Feb 08 GKY Refactor global command line variables to notebook.h
24 26 May 08 SHL Use uiLineNumber correctly
25 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory or pTmpDir and use MakeTempName
26 03 Jan 09 GKY Check for system that is protectonly to gray out Dos/Win command lines and prevent
27 Dos/Win programs from being inserted into the execute dialog with message why.
28 12 Jul 09 GKY Allow FM/2 to load in high memory
29 21 Dec 09 GKY Added CheckExecutibleFlags to streamline code in command.c assoc.c & cmdline.c
30 27 Dec 09 GKY Provide human readable error message when DosQueryAppType fails because it
31 couldn't find the exe (such as missing archivers).
32 17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
33 17 JAN 10 GKY Changes to environment handling in ExecuteOnList to facilitate move of commands to INI and allow
34 the same commandline to have different environments (multiple different command titles).
35 17 JAN 10 GKY Add ENVIRONMENT_SIZE vaiable to replace multiple (often different hard coded sizes) set to 2048
36 (the largest value I found).
37 20 Nov 10 GKY Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused
38 by temp file creation failures.
39 26 Aug 11 GKY Add a low mem version of xDosAlloc* wrappers; move error checking into all the
40 xDosAlloc* wrappers.
41 16 Feb 14 GKY Add "#" command line switch to workaround problem with blank command shell
42 started from fm2 after fm2 has been started with stdout and stderr
43 redirected to a file.
44
45***********************************************************************/
46
47#include <stdlib.h>
48#include <stdarg.h>
49#include <string.h>
50#include <ctype.h>
51
52#define INCL_DOS
53#define INCL_DOSERRORS
54#define INCL_WIN
55#define INCL_LONGLONG // dircnrs.h
56
57#include "fm3dll.h"
58#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
59#include "mkdir.h" // Data declaration(s)
60#include "init.h" // Data declaration(s)
61#include "mainwnd.h" // Data declaration(s)
62#include "fm3dlg.h"
63#include "fm3str.h"
64#include "errutil.h" // Dos_Error...
65#include "strutil.h" // GetPString
66#include "notebook.h" //targetdirectory
67#include "pathutil.h"
68#include "cmdline.h" // CmdLineDlgProc
69#include "shadow.h" // RunSeamless
70#include "systemf.h"
71#include "strips.h" // convert_nl_to_nul, strip_lead_char
72#include "dirs.h" // switch_to
73#include "valid.h" // MakeFullName
74#include "misc.h" // GetCmdSpec
75#include "copyf.h" // MakeTempName
76#include "wrappers.h" // xfopen
77#include "fortify.h"
78
79static PSZ pszSrcFile = __FILE__;
80
81
82//static HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
83// PROGTYPE * progt, ULONG fl, char *formatstring, ...);
84
85/**
86 * CheckExecutibleFlags checks the dialog controls and returns the appropriate
87 * flags to be passed the runemf
88 */
89
90ULONG CheckExecutibleFlags(HWND hwnd, INT caller)
91{
92 /**
93 * caller indicates the dialog calling the function:
94 * 1 = Associations (ASS_)
95 * 2 = CmdLine (EXEC_)
96 * 3 = Commands (CMD_)
97 **/
98
99 ULONG flags = 0;
100
101 if (caller != 2 &&
102 WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_DEFAULT : ASS_DEFAULT))
103 flags = 0;
104 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_FULLSCREEN :
105 caller == 1 ? ASS_FULLSCREEN : EXEC_FULLSCREEN))
106 flags = FULLSCREEN;
107 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_MINIMIZED :
108 caller == 1 ? ASS_MINIMIZED : EXEC_MINIMIZED))
109 flags = MINIMIZED;
110 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_MAXIMIZED :
111 caller == 1 ? ASS_MAXIMIZED : EXEC_MAXIMIZED))
112 flags = MAXIMIZED;
113 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_INVISIBLE :
114 caller == 1 ? ASS_INVISIBLE : EXEC_INVISIBLE))
115 flags = INVISIBLE;
116 if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_KEEP : caller == 1 ? ASS_KEEP :
117 EXEC_KEEP))
118 flags |= caller == 2 ? SEPARATEKEEP : KEEP;
119 else if (caller == 2)
120 flags |= SEPARATE;
121 if (caller !=2 && WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_PROMPT : ASS_PROMPT))
122 flags |= PROMPT;
123 if (caller == 3 && WinQueryButtonCheckstate(hwnd, CMD_ONCE))
124 flags |= ONCE;
125 if (caller == 1 && WinQueryButtonCheckstate(hwnd, ASS_DIEAFTER))
126 flags |= DIEAFTER;
127 return flags;
128}
129
130/**
131 * Bring session foreground
132 * @return TRUE if OK, else FALSE
133 */
134
135BOOL ShowSession(HWND hwnd, PID pid)
136{
137 HSWITCH hswitch;
138 SWCNTRL swctl;
139 ULONG rc;
140
141 hswitch = WinQuerySwitchHandle(pid ? (HWND)0 : hwnd, pid);
142 if (hswitch) {
143 rc = WinQuerySwitchEntry(hswitch, &swctl);
144 if (!rc) {
145 if (swctl.idProcess == pid && swctl.uchVisibility == SWL_VISIBLE)
146 rc = WinSwitchToProgram(hswitch);
147 if (!rc)
148 return TRUE;
149 }
150 }
151 return FALSE;
152}
153
154/**
155 * Invoke runemf2 for command and file/directory list
156 * @return command return code or
157 * -1 if runtime error or
158 * -2 if user cancels command line edit dialog
159 */
160
161int ExecOnList(HWND hwnd, PSZ command, int flags, PSZ tpath, PSZ environment,
162 PSZ *list, PCSZ prompt, PCSZ pszCallingFile, UINT uiLineNumber)
163{
164 // executes the command once for all files in list
165
166 CHAR path[CCHMAXPATH], *commandline, modpath[CCHMAXPATH], listfile[CCHMAXPATH],
167 *p, *pp, drive, *file, *ext, *dot;
168 register int x;
169 BOOL spaces;
170
171 if (!command || !*command) {
172 Runtime_Error(pszSrcFile, __LINE__, NULL);
173 return -1;
174 }
175 commandline = xmalloc(MaxComLineStrg + 1, pszSrcFile, __LINE__);
176 if (!commandline)
177 return -1; //already complained
178 *listfile = 0;
179 bstrip(command);
180
181 *path = 0;
182 if (tpath && *tpath)
183 strcpy(path, tpath);
184 else if (*command != '<' || !strchr(command, '>')) {
185 strcpy(path, command + (*command == '"'));
186 if (*command == '\"')
187 p = strchr(path, '\"');
188 else
189 p = strchr(path, ' ');
190 if (p)
191 *p = 0;
192 p = strrchr(path, '\\');
193 if (!p)
194 p = strrchr(path, ':');
195 if (p) {
196 if (*p == ':') {
197 p++;
198 *p = '\\';
199 p++;
200 }
201 *p = 0;
202 }
203 else
204 *path = 0;
205 }
206 if (!*path) {
207 if (list && list[0])
208 strcpy(path, list[0]);
209 p = strrchr(path, '\\');
210 if (!p)
211 p = strrchr(path, ':');
212 if (p) {
213 if (*p == ':') {
214 p++;
215 *p = '\\';
216 p++;
217 }
218 *p = 0;
219 }
220 else
221 *path = 0;
222 }
223 *modpath = 0;
224 if (list && list[0])
225 strcpy(modpath, list[0]);
226 p = strrchr(modpath, '\\');
227 if (!p)
228 p = strrchr(modpath, ':');
229 if (p) {
230 if (*p == ':') {
231 p++;
232 *p = '\\';
233 p++;
234 }
235 *p = 0;
236 }
237 else
238 *modpath = 0;
239 if (!*modpath)
240 strcpy(modpath, path);
241 if (*path)
242 MakeFullName(path);
243 if (*modpath)
244 MakeFullName(modpath);
245 if (IsFullName(path))
246 drive = toupper(*path);
247 else
248 drive = 0;
249
250 p = command; // substitue for special % sequences
251
252 pp = commandline;
253 *commandline = 0;
254 while (*p) {
255 if (*p == '%') {
256 switch (*(p + 1)) {
257 case '!': // write list to file, add filename
258 if (list) {
259 if (!*listfile) {
260 FILE *fp;
261 CHAR *modew = "w";
262
263 if (pTmpDir && !IsValidDir(pTmpDir))
264 DosCreateDir(pTmpDir, 0);
265 strcpy(listfile, pTmpDir ? pTmpDir : pFM2SaveDirectory);
266 MakeTempName(listfile, "$FM2LI$T", 2);
267 fp = xfopen(listfile, modew,pszSrcFile,__LINE__, FALSE);
268 if (fp) {
269 for (x = 0; list[x]; x++)
270 {
271 fputs(list[x], fp);
272 if (list[x + 1])
273 fputc('\n', fp);
274 }
275 fclose(fp);
276 }
277 }
278 strcpy(pp, listfile);
279 pp += strlen(listfile);
280 }
281 p += 2;
282 break;
283
284 case 'c': // add name of command processor
285 {
286 char *env = GetCmdSpec(FALSE);
287
288 if (needs_quoting(env) && !strchr(env, '\"')) {
289 *pp = '\"';
290 pp++;
291 spaces = TRUE;
292 }
293 else
294 spaces = FALSE;
295 strcpy(pp, env);
296 p += 2;
297 pp += strlen(env);
298 if (spaces) {
299 *pp = '\"';
300 pp++;
301 }
302 }
303 break;
304
305 case 't': // add Target directory
306 if (needs_quoting(targetdir) && !strchr(targetdir, '\"')) {
307 *pp = '\"';
308 pp++;
309 spaces = TRUE;
310 }
311 else
312 spaces = FALSE;
313 strcpy(pp, targetdir);
314 p += 2;
315 pp += strlen(targetdir);
316 if (spaces) {
317 *pp = '\"';
318 pp++;
319 }
320 break;
321
322 case '$': // add drive letter
323 if (drive)
324 *pp = drive;
325 else {
326 ULONG ulDriveNum = 3, ulDriveMap;
327
328 DosQCurDisk(&ulDriveNum, &ulDriveMap);
329 *pp = (char) (ulDriveNum + '@');
330 }
331 pp++;
332 p += 2;
333 break;
334
335 case 'U': // add path of first list component
336 case 'u':
337 if (*modpath) {
338 if (needs_quoting(modpath) && !strchr(modpath, '\"')) {
339 spaces = TRUE;
340 *pp = '\"';
341 pp++;
342 }
343 else
344 spaces = FALSE;
345 if (*(p + 1) == 'u') {
346 strcpy(pp, modpath);
347 pp += strlen(modpath);
348 }
349 else {
350 strcpy(pp, modpath + 2);
351 pp += strlen(modpath + 2);
352 }
353 if (spaces) {
354 if (modpath[strlen(modpath) - 1] == '\\') {
355 *pp = '\\';
356 pp++;
357 }
358 *pp = '\"';
359 pp++;
360 }
361 }
362 else {
363 char temp[CCHMAXPATH];
364
365 strcpy(temp, pFM2SaveDirectory);
366 if (needs_quoting(temp) && !strchr(temp, '\"')) {
367 spaces = TRUE;
368 *pp = '\"';
369 pp++;
370 }
371 else
372 spaces = FALSE;
373 strcpy(pp, temp);
374 pp += strlen(temp);
375 if (spaces) {
376 if (temp[strlen(temp) - 1] == '\\') {
377 *pp = '\\';
378 pp++;
379 }
380 *pp = '\"';
381 pp++;
382 }
383 }
384 p += 2;
385 break;
386
387 case 'P': // add path of execution
388 case 'p':
389 if (*path) {
390 if (needs_quoting(path) && !strchr(path, '\"')) {
391 spaces = TRUE;
392 *pp = '\"';
393 pp++;
394 }
395 else
396 spaces = FALSE;
397 if (*(p + 1) == 'p') {
398 strcpy(pp, path);
399 pp += strlen(path);
400 }
401 else {
402 strcpy(pp, path + 2);
403 pp += strlen(path + 2);
404 }
405 if (spaces) {
406 if (path[strlen(path) - 1] == '\\') {
407 *pp = '\\';
408 pp++;
409 }
410 *pp = '\"';
411 pp++;
412 }
413 }
414 else {
415 char temp[CCHMAXPATH];
416
417 strcpy(temp, pFM2SaveDirectory);
418 if (needs_quoting(temp) && !strchr(temp, '\"')) {
419 spaces = TRUE;
420 *pp = '\"';
421 pp++;
422 }
423 else
424 spaces = FALSE;
425 strcpy(pp, temp);
426 pp += strlen(temp);
427 if (spaces) {
428 if (temp[strlen(temp) - 1] == '\\') {
429 *pp = '\\';
430 pp++;
431 }
432 *pp = '\"';
433 pp++;
434 }
435 }
436 p += 2;
437 break;
438
439 case 'D':
440 if (hwndMain) {
441 PCNRITEM pci;
442
443 pci = (PCNRITEM) WinSendMsg(WinWindowFromID(WinWindowFromID(
444 hwndTree, FID_CLIENT), TREE_CNR),
445 CM_QUERYRECORDEMPHASIS,
446 MPFROMLONG(CMA_FIRST),
447 MPFROMSHORT(CRA_CURSORED));
448 if (pci && (int) pci != -1 && *pci->pszFileName) {
449 if (needs_quoting(pci->pszFileName) &&
450 !strchr(pci->pszFileName, '\"'))
451 {
452 *pp = '\"';
453 pp++;
454 spaces = TRUE;
455 }
456 else
457 spaces = FALSE;
458 strcpy(pp, pci->pszFileName);
459 pp += strlen(pci->pszFileName);
460 if (spaces) {
461 *pp = '\"';
462 pp++;
463 }
464 }
465 }
466 p += 2;
467 break;
468
469 case 'd':
470 if (hwndMain) {
471 HENUM henum;
472 char retstr[CCHMAXPATH];
473 HWND hwndC, hwndDir;
474 USHORT id;
475 BOOL first = TRUE;
476
477 henum = WinBeginEnumWindows(hwndMain);
478 while ((hwndC = WinGetNextWindow(henum)) != NULLHANDLE) {
479 if (hwndC != hwndTree) {
480 id = WinQueryWindowUShort(hwndC, QWS_ID);
481 if (id) {
482 hwndDir = WinWindowFromID(hwndC, FID_CLIENT);
483 if (hwndDir) {
484 hwndDir = WinWindowFromID(hwndDir, DIR_CNR);
485 if (hwndDir) {
486 *retstr = 0;
487 WinSendMsg(hwndC, UM_CONTAINERDIR, MPFROMP(retstr), MPVOID);
488 if (*retstr) {
489 if (!first) {
490 *pp = ' ';
491 pp++;
492 }
493 first = FALSE;
494 if (needs_quoting(retstr) && !strchr(retstr, '\"')) {
495 *pp = '\"';
496 pp++;
497 spaces = TRUE;
498 }
499 else
500 spaces = FALSE;
501 strcpy(pp, retstr);
502 pp += strlen(retstr);
503 if (spaces) {
504 *pp = '\"';
505 pp++;
506 }
507 }
508 }
509 }
510 }
511 }
512 }
513 WinEndEnumWindows(henum);
514 }
515 p += 2;
516 break;
517
518 case '%':
519 *pp = '%';
520 pp++;
521 p += 2;
522 break;
523
524 case 'R':
525 case 'F':
526 case 'A':
527 case 'r':
528 case 'f':
529 case 'a':
530 case 'e':
531 if (list) {
532 for (x = 0; list[x]; x++)
533 {
534 file = strrchr(list[x], '\\');
535 if (!file)
536 file = strrchr(list[x], ':');
537 if (file)
538 file++;
539 else
540 file = list[x];
541 ext = strrchr(file, '.');
542 dot = ext;
543 if (ext)
544 ext++;
545 switch (*(p + 1)) {
546 case 'R':
547 case 'r':
548 if (pp + strlen(list[x]) > commandline + MaxComLineStrg)
549 goto BreakOut;
550 if (*(p + 1) == 'r') {
551 strcpy(pp, list[x]);
552 pp += strlen(list[x]);
553 }
554 else {
555 strcpy(pp, list[x] + 2);
556 pp += strlen(list[x] + 2);
557 }
558 break;
559
560 case 'F':
561 case 'f':
562 if (*(p + 1) == 'F' && dot)
563 *dot = 0;
564 if (pp + strlen(file) > commandline + MaxComLineStrg)
565 goto BreakOut;
566 if (needs_quoting(file)) {
567 spaces = TRUE;
568 *pp = '\"';
569 pp++;
570 }
571 else
572 spaces = FALSE;
573 strcpy(pp, file);
574 pp += strlen(file);
575 if (*(p + 1) == 'F' && dot)
576 *dot = '.';
577 if (spaces) {
578 if (*(pp - 1) != '\"') {
579 *pp = '\"';
580 pp++;
581 }
582 }
583 break;
584
585 case 'A':
586 case 'a':
587 if (pp + strlen(list[x]) > commandline + MaxComLineStrg)
588 goto BreakOut;
589 if (needs_quoting(list[x]) && !strchr(list[x], '\"')) {
590 spaces = TRUE;
591 *pp = '\"';
592 pp++;
593 }
594 else
595 spaces = FALSE;
596 if (*(p + 1) == 'a') {
597 strcpy(pp, list[x]);
598 pp += strlen(list[x]);
599 }
600 else {
601 strcpy(pp, list[x] + 2);
602 pp += strlen(list[x] + 2);
603 }
604 if (spaces) {
605 if (list[x][strlen(list[x]) - 1] == '\\') {
606 *pp = '\\';
607 pp++;
608 }
609 *pp = '\"';
610 pp++;
611 }
612 break;
613
614 case 'e':
615 if (ext) {
616 if (pp + strlen(ext) > commandline + MaxComLineStrg)
617 goto BreakOut;
618 if (needs_quoting(ext)) {
619 spaces = TRUE;
620 *pp = '\"';
621 pp++;
622 }
623 else
624 spaces = FALSE;
625 strcpy(pp, ext);
626 pp += strlen(ext);
627 if (spaces) {
628 if (*(pp - 1) != '\"') {
629 *pp = '\"';
630 pp++;
631 }
632 }
633 }
634 break;
635 }
636 if (list[x + 1]) {
637 *pp = ' ';
638 pp++;
639 }
640 }
641 }
642 p += 2;
643 break;
644
645 default:
646 *pp = *p;
647 p++;
648 pp++;
649 break;
650 }
651 }
652 else {
653 *pp = *p;
654 pp++;
655 p++;
656 }
657 *pp = 0;
658 }
659
660BreakOut:
661
662 {
663 EXECARGS ex;
664 int ret;
665
666 memset(&ex, 0, sizeof(EXECARGS));
667 //DbgMsg(pszSrcFile, __LINE__, "env %s", environment);
668 if (!environment) {
669 ULONG size;
670
671 size = ENVIRONMENT_SIZE;
672 PrfQueryProfileData(fmprof, FM3Str, command, ex.environment, &size);
673 }
674 else
675 strcpy(ex.environment, environment);
676 if (flags & PROMPT) {
677 // allow editing command line
678 ex.flags = (flags & (~PROMPT));
679 ex.commandline = commandline;
680 strcpy(ex.path, path);
681 if (prompt)
682 strcpy(ex.title, prompt);
683 ret = WinDlgBox(HWND_DESKTOP, hwnd, CmdLineDlgProc, FM3ModHandle,
684 EXEC_FRAME, &ex);
685 if (ret != 1) {
686 free(commandline);
687 return (ret == 0) ? -1 : -2;
688 }
689 }
690 else
691 ex.flags = flags;
692 //DbgMsg(pszSrcFile, __LINE__, "Inserted %s", environment);
693 ret = runemf2(ex.flags, hwnd, pszCallingFile, uiLineNumber, path,
694 *ex.environment ? ex.environment : NULL,
695 "%s", commandline);
696 free(commandline);
697 return ret;
698 }
699}
700
701/** Run requested app
702 * @return application return code or -1 if problem starting app
703 */
704
705int runemf2(int type, HWND hwnd, PCSZ pszCallingFile, UINT uiLineNumber,
706 char *pszDirectory, char *pszEnvironment,
707 char *formatstring,...)
708{
709 /** example:
710 *
711 * status = runemf2(SEPARATE | WINDOWED,
712 * hwnd, pszCallingFile, __LINE__,
713 * NullStr,
714 * NULL,
715 * "%s /C %s",
716 * getenv("COMSPEC"),
717 * batchfilename);
718 *
719 * use (HWND)0 for hwnd if window handle not handy.
720 * pszCallingFile and __LINE__ are used to determine caller for easier error tracking
721 */
722 /**
723 * type bitmapped flag -- see systemf.h
724 */
725
726 va_list parguments;
727 int ret = -1;
728 RESULTCODES results;
729 STARTDATA sdata;
730 REQUESTDATA rq;
731 ULONG ulSessID;
732 ULONG ulLength;
733 UINT ctr;
734 ULONG ulAppType;
735 PID sessPID;
736 BOOL wasquote;
737 char *p, *pszPgm, *pszArgs = NULL;
738 char szObject[32] = "";
739 char szSavedir[CCHMAXPATH];
740 BOOL useTermQ = FALSE;
741 char szTempdir[CCHMAXPATH];
742 BOOL fNoErrorMsg = FALSE;
743
744 typedef struct {
745 USHORT usSessID;
746 USHORT usRC;
747 } TERMINFO;
748
749 TERMINFO *pTermInfo;
750 BYTE bPriority;
751 APIRET rc;
752 PIB *ppib;
753 TIB *ptib;
754
755 // Shared by all threads
756# define TERMQ_BASE_NAME "\\QUEUES\\FM3WAIT"
757 static char szTermQName[30];
758 char szTermTemp[30];
759 static HQUEUE hTermQ;
760 static HEV hTermQSem;
761
762 if (pszDirectory && *pszDirectory) {
763 if (!DosQueryPathInfo(pszDirectory,
764 FIL_QUERYFULLNAME,
765 szTempdir,
766 sizeof(szTempdir)))
767 pszDirectory = szTempdir;
768 }
769
770 if (!hwnd)
771 hwnd = HWND_DESKTOP;
772
773 if (xDosAllocMemLow((PVOID)&pszPgm, MaxComLineStrg, pszSrcFile,__LINE__))
774 return -1; //already complained
775 *szSavedir = 0;
776
777 *pszPgm = 0;
778 va_start(parguments,
779 formatstring);
780 vsprintf(pszPgm,
781 formatstring,
782 parguments);
783 va_end(parguments);
784
785 if (pszEnvironment) {
786 p = &pszEnvironment[strlen(pszEnvironment)] + 1;
787 *p = 0;
788 p = pszEnvironment;
789 while ((p = convert_nl_to_nul(p)) != NULL)
790 ; // loop
791 }
792
793 if (!stricmp(pszCallingFile, "init.c"))
794 fNoErrorMsg = TRUE;
795
796 if (!*pszPgm) {
797 p = GetCmdSpec(FALSE);
798 strcpy(pszPgm, p);
799 if (!*pszPgm) {
800 Runtime_Error(pszSrcFile, __LINE__, NULL);
801 return -1;
802 }
803 }
804
805 if (*pszPgm) {
806 if (*pszPgm == '<' && strchr(pszPgm, '>')) {
807 // is a workplace object
808 HOBJECT hWPSObject;
809 char temp;
810
811 p = strchr(pszPgm, '>');
812 p++;
813 temp = *p;
814 if (temp) {
815 if (xDosAllocMemLow((PVOID)&pszArgs, MaxComLineStrg * 2, pszSrcFile, __LINE__)) {
816 DosFreeMem(pszPgm);
817 return -1; //already complained
818 }
819 }
820 else
821 pszArgs = NULL;
822 *p = 0;
823 // Find the handle of the WPS object
824 hWPSObject = WinQueryObject(pszPgm);
825 *p = temp;
826 if (hWPSObject != NULLHANDLE) {
827 if (pszArgs && *p) {
828 sprintf(pszArgs,"OPEN=DEFAULT;PARAMETERS=\"%s\"",p);
829 WinSetObjectData(hWPSObject,pszArgs);
830 }
831 else
832 WinSetObjectData(hWPSObject,"OPEN=DEFAULT");
833 ret = 0;
834 }
835 goto ObjectInterrupt;
836 }
837
838 if ((type & RUNTYPE_MASK) == SYNCHRONOUS ||
839 (type & RUNTYPE_MASK) == ASYNCHRONOUS ||
840 (type & RUNTYPE_MASK) == DETACHED)
841 {
842 strip_lead_char(" \t", pszPgm);
843 p = pszPgm;
844 wasquote = FALSE;
845 while (*p &&
846 (wasquote ||
847 (*p != ' ' &&
848 *p != '\t')))
849 {
850 if (*p == '\"') {
851 if (!wasquote) {
852 wasquote = TRUE;
853 memmove(p,
854 p + 1,
855 strlen(p));
856 while (*p == ' ' ||
857 *p == '\t')
858 p++;
859 }
860 else {
861 memmove(p,
862 p + 1,
863 strlen(p));
864 break;
865 }
866 }
867 else
868 p++;
869 }
870 if (*p) {
871 *p = 0;
872 p++;
873 }
874 else
875 p = pszPgm;
876 p[strlen(p) + 1] = 0; // double-terminate args
877 if (*pszPgm) {
878 if (!strchr(pszPgm, '\\') &&
879 !strchr(pszPgm, ':') &&
880 pszDirectory &&
881 *pszDirectory)
882 {
883 strcpy(szSavedir, pFM2SaveDirectory);
884 switch_to(pszDirectory);
885 }
886 rc = DosQueryAppType(pszPgm,&ulAppType);
887 if (!strchr(pszPgm, '\\') &&
888 !strchr(pszPgm, ':') &&
889 pszDirectory &&
890 *pszDirectory)
891 switch_to(szSavedir);
892 if (rc) {
893 if (rc == ERROR_FILE_NOT_FOUND || rc == ERROR_PATH_NOT_FOUND ||
894 rc == ERROR_INVALID_EXE_SIGNATURE || rc == ERROR_EXE_MARKED_INVALID)
895 saymsg(MB_OK, HWND_DESKTOP, NullStr,
896 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT2), pszPgm);
897 else if (rc == ERROR_INVALID_DRIVE || rc == ERROR_DRIVE_LOCKED)
898 saymsg(MB_OK, HWND_DESKTOP, NullStr,
899 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT3), pszPgm);
900 else
901 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
902 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
903 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
904 DosFreeMem(pszPgm);
905 if (pszArgs)
906 DosFreeMem(pszArgs);
907 return -1;
908 }
909 if (ulAppType) {
910 if (ulAppType & FAPPTYP_DLL || ulAppType & FAPPTYP_VIRTDRV ||
911 ulAppType & FAPPTYP_PHYSDRV || ulAppType & FAPPTYP_PROTDLL)
912 {
913 Runtime_Error(pszSrcFile, __LINE__,
914 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
915 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
916 if (pszPgm)
917 DosFreeMem(pszPgm);
918 if (pszArgs)
919 DosFreeMem(pszArgs);
920 return -1;
921 }
922 if (ulAppType & FAPPTYP_DOS || ulAppType & FAPPTYP_WINDOWSREAL ||
923 ulAppType & FAPPTYP_WINDOWSPROT || ulAppType & FAPPTYP_WINDOWSPROT31)
924 {
925 Runtime_Error(pszSrcFile, __LINE__,
926 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
927 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
928 if (pszPgm)
929 DosFreeMem(pszPgm);
930 if (pszArgs)
931 DosFreeMem(pszArgs);
932 return -1;
933 }
934 }
935 memset(&results, 0, sizeof(results));
936 if (pszDirectory && *pszDirectory) {
937 strcpy(szSavedir, pFM2SaveDirectory);
938 switch_to(pszDirectory);
939 }
940 ret = DosExecPgm(szObject, sizeof(szObject),
941 ((type & RUNTYPE_MASK) == ASYNCHRONOUS ? EXEC_ASYNC : 0) +
942 ((type & RUNTYPE_MASK) == DETACHED ? EXEC_BACKGROUND : 0),
943 pszPgm, pszEnvironment, &results, pszPgm);
944 if (pszDirectory && *pszDirectory)
945 switch_to(szSavedir);
946 if (ret && !fNoErrorMsg) {
947 Dos_Error(MB_ENTER,ret,hwnd,pszSrcFile,__LINE__,
948 GetPString(IDS_DOSEXECPGMFAILEDTEXT), pszPgm,
949 pszCallingFile, uiLineNumber); // 26 May 08 SHL
950 }
951 }
952 }
953 else {
954 if (~type & FULLSCREEN)
955 type |= WINDOWED;
956 if (xDosAllocMemLow((PVOID) &pszArgs, MaxComLineStrg * 2, pszSrcFile, __LINE__)) {
957 DosFreeMem(pszPgm);
958 return -1; //already complained
959 }
960 *pszArgs = 0;
961 memset(&sdata, 0, sizeof(sdata));
962 strip_lead_char(" \t", pszPgm);
963 p = pszPgm;
964 wasquote = FALSE;
965 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
966 if (*p == '\"') {
967 if (!wasquote) {
968 wasquote = TRUE;
969 memmove(p, p + 1, strlen(p));
970 while (*p == ' ' || *p == '\t')
971 p++;
972 }
973 else {
974 memmove(p, p + 1, strlen(p));
975 break;
976 }
977 }
978 else
979 p++;
980 } // while
981 if (*p) {
982 *p = 0;
983 p++;
984 }
985 else
986 p = NullStr;
987 if (*p)
988 strcpy(pszArgs, p);
989
990 p = strrchr(pszPgm, '.');
991 if (p) {
992 char temp[CCHMAXPATH + 1];
993
994 if (!stricmp(p, PCSZ_DOTBAT)) {
995 if (!fProtectOnly) {
996 strcpy(temp, pszPgm);
997 strcpy(pszPgm, pszArgs);
998 strcpy(pszArgs, "/C ");
999 strcat(pszArgs, temp);
1000 strcat(pszArgs, " ");
1001 strcat(pszArgs, pszPgm);
1002 strcpy(pszPgm, GetCmdSpec(TRUE)); // DOS
1003 }
1004 else
1005 saymsg(MB_OK,
1006 HWND_DESKTOP,
1007 NullStr,
1008 GetPString(IDS_NOTPROTECTONLYEXE),
1009 pszPgm);
1010 }
1011 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1012 // Assume 4OS2 is BTM
1013 strcpy(temp, pszPgm);
1014 strcpy(pszPgm, pszArgs);
1015 strcpy(pszArgs, "/C ");
1016 strcat(pszArgs, temp);
1017 strcat(pszArgs, " ");
1018 strcat(pszArgs, pszPgm);
1019 strcpy(pszPgm, GetCmdSpec(FALSE)); // OS/2
1020 }
1021 }
1022
1023 // goddamned OS/2 limit
1024
1025 if (strlen(pszPgm) + strlen(pszArgs) > 1024)
1026 pszArgs[1024 - strlen(pszPgm)] = 0;
1027
1028 if (!strchr(pszPgm, '\\') &&
1029 !strchr(pszPgm, ':') &&
1030 pszDirectory &&
1031 *pszDirectory)
1032 {
1033 strcpy(szSavedir, pFM2SaveDirectory);
1034 switch_to(pszDirectory);
1035 }
1036 rc = DosQueryAppType(pszPgm,&ulAppType);
1037 if (!strchr(pszPgm, '\\') &&
1038 !strchr(pszPgm, ':') &&
1039 pszDirectory &&
1040 *pszDirectory)
1041 switch_to(szSavedir);
1042 if (rc) {
1043 if (rc == ERROR_FILE_NOT_FOUND || rc == ERROR_PATH_NOT_FOUND ||
1044 rc == ERROR_INVALID_EXE_SIGNATURE || rc == ERROR_EXE_MARKED_INVALID)
1045 saymsg(MB_OK, HWND_DESKTOP, NullStr,
1046 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT2), pszPgm);
1047 else if (rc == ERROR_INVALID_DRIVE || rc == ERROR_DRIVE_LOCKED)
1048 saymsg(MB_OK, HWND_DESKTOP, NullStr,
1049 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT3), pszPgm);
1050 else
1051 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
1052 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
1053 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
1054 DosFreeMem(pszPgm);
1055 if (pszArgs)
1056 DosFreeMem(pszArgs);
1057 return -1;
1058 }
1059
1060 if (ulAppType) {
1061 if (ulAppType & (FAPPTYP_DLL | FAPPTYP_VIRTDRV | FAPPTYP_PHYSDRV | FAPPTYP_PROTDLL))
1062 {
1063 Runtime_Error(pszSrcFile, __LINE__,
1064 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
1065 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
1066 DosFreeMem(pszPgm);
1067 if (pszArgs)
1068 DosFreeMem(pszArgs);
1069 return -1;
1070 }
1071 ulAppType &= ~FAPPTYP_BOUND;
1072 if (ulAppType & (FAPPTYP_DOS | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1073 {
1074 if (ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1075 {
1076 if (~type & FULLSCREEN &&
1077 ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1078 {
1079 ret = RunSeamless(pszPgm, pszArgs, hwnd);
1080 if (pszPgm)
1081 DosFreeMem(pszPgm);
1082 if (pszArgs)
1083 DosFreeMem(pszArgs);
1084 return ret ? 0 : -1;
1085 }
1086 else {
1087 strcat(pszPgm, " ");
1088 strcat(pszPgm, pszArgs);
1089 *pszArgs = 0;
1090 if (ulAppType & (FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT31))
1091 strcat(pszArgs, "/3 ");
1092 strcat(pszArgs, pszPgm);
1093 strcpy(pszPgm, "WINOS2.COM");
1094 }
1095 }
1096 else {
1097 if (~type & FULLSCREEN) {
1098 type |= WINDOWED;
1099 ulAppType = SSF_TYPE_WINDOWEDVDM;
1100 }
1101 else {
1102 type &= ~WINDOWED;
1103 ulAppType = SSF_TYPE_VDM;
1104 }
1105 }
1106 }
1107 else if (ulAppType & FAPPTYP_32BIT) {
1108 ulAppType &= ~FAPPTYP_32BIT;
1109 if (ulAppType == FAPPTYP_WINDOWAPI)
1110 ulAppType = SSF_TYPE_PM;
1111 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1112 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1113 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1114 ulAppType = SSF_TYPE_FULLSCREEN;
1115 type &= ~WINDOWED;
1116 type |= FULLSCREEN;
1117 }
1118 else // ?
1119 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1120 }
1121 else if (ulAppType == FAPPTYP_WINDOWAPI)
1122 ulAppType = SSF_TYPE_PM;
1123 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1124 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1125 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1126 type &= ~WINDOWED;
1127 ulAppType = SSF_TYPE_FULLSCREEN;
1128 }
1129 else
1130 ulAppType = SSF_TYPE_DEFAULT;
1131 if ((type & FULLSCREEN || ~type & WINDOWED) &&
1132 ulAppType == SSF_TYPE_WINDOWABLEVIO)
1133 {
1134 ulAppType = SSF_TYPE_FULLSCREEN;
1135 }
1136 // fixme parens?
1137 else if (type & FULLSCREEN ||
1138 (type & WINDOWED && ulAppType == SSF_TYPE_WINDOWEDVDM))
1139 {
1140 ulAppType = SSF_TYPE_VDM;
1141 }
1142 }
1143 if (ulAppType == SSF_TYPE_WINDOWEDVDM && type & SEPARATEKEEP) {
1144 type &= ~SEPARATEKEEP;
1145 type |= SEPARATE;
1146 }
1147
1148 DosGetInfoBlocks(&ptib, &ppib);
1149
1150 if (~type & WAIT)
1151 useTermQ = FALSE;
1152 else {
1153 rc = 0;
1154 DosEnterCritSec();
1155 if (!hTermQ) {
1156 // Create term queue and event semaphore just once
1157 sprintf(szTermQName, TERMQ_BASE_NAME "_%x", ppib->pib_ulpid);
1158 rc = DosCreateQueue(&hTermQ, QUE_FIFO | QUE_CONVERT_ADDRESS, szTermQName);
1159 if (rc) {
1160 hTermQ = (HQUEUE)0; // Try to survive
1161 DosExitCritSec();
1162 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosCreateQueue");
1163 }
1164 else {
1165 rc = DosCreateEventSem(NULL,(PHEV)&hTermQSem,0,FALSE);
1166 if (rc) {
1167 hTermQSem = (HEV)0; // Try to survive
1168 DosCloseQueue(hTermQ);
1169 hTermQ = (HQUEUE)0; // Try to survive
1170 DosExitCritSec();
1171 Dos_Error(MB_ENTER,rc,HWND_DESKTOP,pszSrcFile,__LINE__, PCSZ_DOSCREATEEVENTSEM);
1172 }
1173 // if (!rc) fprintf(stderr,"%s %d qcreated ptib %x hTermQ %x\n",__FILE__, __LINE__,ptib,hTermQ);
1174 }
1175 } // if 1st time
1176 useTermQ = hTermQ && hTermQSem;
1177 if (!rc)
1178 DosExitCritSec();
1179 } // if wait
1180
1181 memset(&sdata,0,sizeof(sdata));
1182 sdata.Length = sizeof(sdata);
1183 sdata.Related = type & (WAIT | CHILD) ? SSF_RELATED_CHILD :
1184 SSF_RELATED_INDEPENDENT;
1185 sdata.FgBg = type & BACKGROUND ? SSF_FGBG_BACK : SSF_FGBG_FORE;
1186 sdata.TraceOpt = SSF_TRACEOPT_NONE;
1187 sdata.PgmName = pszPgm;
1188 if (*pszArgs)
1189 sdata.PgmInputs = (PBYTE)pszArgs;
1190 if (useTermQ) {
1191 strcpy(szTermTemp, szTermQName);
1192 sdata.TermQ = (PBYTE)szTermTemp;
1193 }
1194 sdata.Environment = (PBYTE)pszEnvironment;
1195 if (fUseShellEnv && (!strcmp(GetCmdSpec(TRUE), pszPgm) ||
1196 !strcmp(GetCmdSpec(FALSE), pszPgm)))
1197 sdata.InheritOpt = SSF_INHERTOPT_SHELL;
1198 else
1199 sdata.InheritOpt = SSF_INHERTOPT_PARENT;
1200 sdata.SessionType = (USHORT) ulAppType;
1201 sdata.ObjectBuffer = szObject;
1202 sdata.ObjectBuffLen = sizeof(szObject);
1203 if ((type & RUNTYPE_MASK) == SEPARATEKEEP)
1204 sdata.PgmControl |= SSF_CONTROL_NOAUTOCLOSE;
1205 if (type & MAXIMIZED)
1206 sdata.PgmControl |= SSF_CONTROL_MAXIMIZE;
1207 if (type & MINIMIZED)
1208 sdata.PgmControl |= SSF_CONTROL_MINIMIZE;
1209 if (type & INVISIBLE)
1210 sdata.PgmControl |= SSF_CONTROL_INVISIBLE;
1211
1212 if (pszDirectory && *pszDirectory) {
1213 strcpy(szSavedir, pFM2SaveDirectory);
1214 switch_to(pszDirectory);
1215 }
1216 ret = DosStartSession(&sdata, &ulSessID, &sessPID);
1217
1218
1219 if (pszDirectory && *pszDirectory)
1220 switch_to(szSavedir);
1221
1222 if (ret && ret != ERROR_SMG_START_IN_BACKGROUND) {
1223 if (!fNoErrorMsg)
1224 Dos_Error(MB_CANCEL,ret,hwnd,pszSrcFile,__LINE__,
1225 GetPString(IDS_DOSSTARTSESSIONFAILEDTEXT),pszPgm,pszArgs,
1226 pszCallingFile, uiLineNumber); // 26 May 08 SHL
1227 }
1228 else if (type & WAIT) {
1229 if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1230 ShowSession(hwnd, sessPID);
1231
1232 if (!useTermQ) {
1233 STATUSDATA sd;
1234
1235 memset(&sd, 0, sizeof(sd));
1236 sd.Length = (USHORT) sizeof(sd);
1237 sd.SelectInd = SET_SESSION_UNCHANGED;
1238 sd.BondInd = SET_SESSION_UNCHANGED;
1239 for (ctr = 0;; ctr++)
1240 {
1241 DosSleep(50);//05 Aug 07 GKY 200
1242 if (DosSetSession(ulSessID, &sd)) // Check if session gone (i.e. finished)
1243 break;
1244 if (ctr > 10) {
1245 ShowSession(hwnd, sessPID); // Show every 2 seconds
1246 ctr = 0;
1247 }
1248 }
1249 }
1250 else {
1251 for (ctr = 0;; ctr++)
1252 {
1253 if (ctr < 20) {
1254 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1255 DCWW_NOWAIT, &bPriority, hTermQSem);
1256 if (rc == ERROR_QUE_EMPTY) {
1257 DosSleep(50);//05 Aug 07 GKY 100
1258 continue;
1259 }
1260 }
1261 else {
1262 if (ctr == 20) {
1263 ShowSession(hwnd, sessPID); // Show long running session
1264 }
1265 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1266 DCWW_WAIT, &bPriority, 0);
1267 }
1268
1269 if (rc) {
1270 // Oh heck
1271 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosReadQueue");
1272 DosSleep(100);//05 Aug 07 GKY 500
1273 continue;
1274 }
1275
1276 // printf("%s %d DosReadQueue thread 0x%x sess %u sessRC %u rq.pid 0x%x rq.data 0x%x\n",
1277 // __FILE__, __LINE__,ptib->tib_ordinal,pTermInfo->usSessID,pTermInfo->usRC,rq.pid, rq.ulData); fflush(stdout);
1278
1279 if (pTermInfo->usSessID == ulSessID)
1280 break; // Our session is done
1281
1282 // Requeue session for other thread
1283 {
1284 static ULONG ulLastSessID;
1285 // printf("%s %d requeue thread 0x%x our sess %u term sess %u term rc %u\n",
1286 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID,pTermInfo->usSessID,pTermInfo->usRC); fflush(stdout);
1287 // fixme to be gone when no longer needed for debug?
1288 if (ulLastSessID) {
1289 DosSleep(100);//05 Aug 07 GKY 500
1290 ulLastSessID = pTermInfo->usSessID;
1291 }
1292 // requeue term report for other thread and do not free yet
1293 rc = DosWriteQueue(hTermQ, rq.ulData, ulLength,(PVOID)pTermInfo, bPriority);
1294 if (rc)
1295 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosWriteQueue");
1296 DosSleep(50); //05 Aug 07 GKY 100 // Let other thread see queue entry
1297 }
1298 } // for
1299
1300 ret = pTermInfo->usRC == 0; // Set 1 if rc 0 else 0
1301 // printf("%s %d thread 0x%x term for sess %u\n",
1302 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID);fflush(stdout);
1303 DosFreeMem(pTermInfo);
1304 }
1305 } // if wait
1306 else if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1307 ShowSession(hwnd, sessPID);
1308 }
1309 }
1310
1311ObjectInterrupt:
1312
1313 if (pszPgm)
1314 DosFreeMem(pszPgm);
1315 if (pszArgs)
1316 DosFreeMem(pszArgs);
1317
1318 return ret;
1319}
1320
1321//== Exec() Start application with WinStartApp ==
1322#if 0 // JBS 11 Sep 08
1323HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
1324 PROGTYPE *progt, ULONG fl, char *formatstring,...)
1325{
1326 PROGDETAILS pgd;
1327 register char *p;
1328 char *parameters = NULL, *executable = NULL;
1329 HAPP happ = (HAPP)0;
1330 ULONG ulOptions = SAF_INSTALLEDCMDLINE;
1331 BOOL wasquote;
1332 va_list parguments;
1333
1334 if (child)
1335 ulOptions |= SAF_STARTCHILDAPP;
1336
1337 executable = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1338 if (executable) {
1339 va_start(parguments, formatstring);
1340 vsprintf(executable, formatstring, parguments);
1341 va_end(parguments);
1342 strip_lead_char(" \t", executable);
1343 if (*executable) {
1344 parameters = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
1345 if (parameters) {
1346 p = executable;
1347 wasquote = FALSE;
1348 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
1349 if (*p == '\"') {
1350 if (!wasquote) {
1351 wasquote = TRUE;
1352 memmove(p, p + 1, strlen(p));
1353 while (*p == ' ' || *p == '\t')
1354 p++;
1355 }
1356 else {
1357 memmove(p, p + 1, strlen(p));
1358 break;
1359 }
1360 }
1361 else
1362 p++;
1363 }
1364 if (*p) {
1365 *p = 0;
1366 p++;
1367 }
1368 else
1369 p = NullStr;
1370 if (*p)
1371 strcpy(parameters, p);
1372
1373 if (p && (!stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTCMD) ||
1374 !stricmp(p, PCSZ_DOTBTM))) {
1375 char *temp;
1376
1377 temp = xmalloc(CCHMAXPATH * 2,pszSrcFile,__LINE__);
1378 if (temp) {
1379 if (!stricmp(p, PCSZ_DOTBAT)) {
1380 if (!fProtectOnly) {
1381 strcpy(temp, executable);
1382 strcpy(executable, parameters);
1383 strcpy(parameters, "/C ");
1384 strcat(parameters, temp);
1385 strcat(parameters, " ");
1386 strcat(parameters, executable);
1387 strcpy(executable, GetCmdSpec(TRUE)); //DOS
1388 }
1389 else
1390 saymsg(MB_OK,
1391 HWND_DESKTOP,
1392 NullStr,
1393 GetPString(IDS_NOTPROTECTONLYEXE),
1394 filename);
1395 }
1396 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1397 strcpy(temp, executable);
1398 strcpy(executable, parameters);
1399 strcpy(parameters, "/C ");
1400 strcat(parameters, temp);
1401 strcat(parameters, " ");
1402 strcat(parameters, executable);
1403 strcpy(executable, GetCmdSpec(FALSE));
1404 }
1405 free(temp);
1406 }
1407 }
1408
1409 memset(&pgd, 0, sizeof(pgd));
1410 pgd.Length = sizeof(pgd);
1411 pgd.progt = *progt;
1412 pgd.swpInitial.fl = fl;
1413 pgd.pszEnvironment = env;
1414 pgd.pszStartupDir = startdir;
1415 pgd.pszParameters = *parameters ? parameters : NULL;
1416 pgd.pszExecutable = executable;
1417 pgd.swpInitial.hwndInsertBehind = HWND_TOP;
1418 happ = WinStartApp(hwndNotify, &pgd, NULL, NULL, ulOptions);
1419 free(parameters);
1420 }
1421 }
1422 free(executable);
1423 }
1424 return happ;
1425}
1426#endif
1427#pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2)
Note: See TracBrowser for help on using the repository browser.