source: trunk/dll/systemf.c@ 1749

Last change on this file since 1749 was 1749, checked in by John Small, 11 years ago

Ticket #522: Ensure use of wrapper functions where needed

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