source: trunk/dll/systemf.c@ 1877

Last change on this file since 1877 was 1877, checked in by Gregg Young, 10 years ago

Remove debug code

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.4 KB
Line 
1
2/***********************************************************************
3
4 $Id: systemf.c 1877 2015-10-11 21:43:27Z gyoung $
5
6 System Interfaces
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2003, 2015 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 12 Aug 15 JBS Ticket #522: Ensure no "highmem-unsafe" functions are called directly
48 Calls to unsafe Dos... functions have been changed to call the wrapped xDos... functions
49
50***********************************************************************/
51
52#include <stdlib.h>
53#include <stdarg.h>
54#include <string.h>
55#include <ctype.h>
56
57#define INCL_DOS
58#define INCL_DOSERRORS
59#define INCL_WIN
60#define INCL_LONGLONG // dircnrs.h
61
62#include "fm3dll.h"
63#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
64#include "mkdir.h" // Data declaration(s)
65#include "init.h" // Data declaration(s)
66#include "mainwnd.h" // Data declaration(s)
67#include "fm3dlg.h"
68#include "fm3str.h"
69#include "errutil.h" // Dos_Error...
70#include "strutil.h" // GetPString
71#include "notebook.h" //targetdirectory
72#include "pathutil.h"
73#include "cmdline.h" // CmdLineDlgProc
74#include "shadow.h" // RunSeamless
75#include "systemf.h"
76#include "strips.h" // convert_nl_to_nul, strip_lead_char
77#include "dirs.h" // switch_to
78#include "valid.h" // MakeFullName
79#include "misc.h" // GetCmdSpec
80#include "copyf.h" // MakeTempName
81#include "wrappers.h" // xfopen
82#include "fortify.h"
83
84static PSZ pszSrcFile = __FILE__;
85
86
87//static HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
88// PROGTYPE * progt, ULONG fl, char *formatstring, ...);
89
90/**
91 * CheckExecutibleFlags checks the dialog controls and returns the appropriate
92 * flags to be passed the runemf
93 */
94
95ULONG CheckExecutibleFlags(HWND hwnd, INT caller)
96{
97 /**
98 * caller indicates the dialog calling the function:
99 * 1 = Associations (ASS_)
100 * 2 = CmdLine (EXEC_)
101 * 3 = Commands (CMD_)
102 **/
103
104 ULONG flags = 0;
105
106 if (caller != 2 &&
107 WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_DEFAULT : ASS_DEFAULT))
108 flags = 0;
109 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_FULLSCREEN :
110 caller == 1 ? ASS_FULLSCREEN : EXEC_FULLSCREEN))
111 flags = FULLSCREEN;
112 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_MINIMIZED :
113 caller == 1 ? ASS_MINIMIZED : EXEC_MINIMIZED))
114 flags = MINIMIZED;
115 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_MAXIMIZED :
116 caller == 1 ? ASS_MAXIMIZED : EXEC_MAXIMIZED))
117 flags = MAXIMIZED;
118 else if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_INVISIBLE :
119 caller == 1 ? ASS_INVISIBLE : EXEC_INVISIBLE))
120 flags = INVISIBLE;
121 if (WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_KEEP : caller == 1 ? ASS_KEEP :
122 EXEC_KEEP))
123 flags |= caller == 2 ? SEPARATEKEEP : KEEP;
124 else if (caller == 2)
125 flags |= SEPARATE;
126 if (caller !=2 && WinQueryButtonCheckstate(hwnd, caller == 3 ? CMD_PROMPT : ASS_PROMPT))
127 flags |= PROMPT;
128 if (caller == 3 && WinQueryButtonCheckstate(hwnd, CMD_ONCE))
129 flags |= ONCE;
130 if (caller == 1 && WinQueryButtonCheckstate(hwnd, ASS_DIEAFTER))
131 flags |= DIEAFTER;
132 return flags;
133}
134
135/**
136 * Bring session foreground
137 * @return TRUE if OK, else FALSE
138 */
139
140BOOL ShowSession(HWND hwnd, PID pid)
141{
142 HSWITCH hswitch;
143 SWCNTRL swctl;
144 ULONG rc;
145
146 hswitch = WinQuerySwitchHandle(pid ? (HWND)0 : hwnd, pid);
147 if (hswitch) {
148 rc = WinQuerySwitchEntry(hswitch, &swctl);
149 if (!rc) {
150 if (swctl.idProcess == pid && swctl.uchVisibility == SWL_VISIBLE)
151 rc = WinSwitchToProgram(hswitch);
152 if (!rc)
153 return TRUE;
154 }
155 }
156 return FALSE;
157}
158
159/**
160 * Invoke runemf2 for command and file/directory list
161 * @return command return code or
162 * -1 if runtime error or
163 * -2 if user cancels command line edit dialog
164 */
165
166int ExecOnList(HWND hwnd, PSZ command, int flags, PSZ tpath, PSZ environment,
167 PSZ *list, PCSZ prompt, PCSZ pszCallingFile, UINT uiLineNumber)
168{
169 // executes the command once for all files in list
170
171 CHAR path[CCHMAXPATH], *commandline, modpath[CCHMAXPATH], listfile[CCHMAXPATH],
172 *p, *pp, drive, *file, *ext, *dot;
173 register int x;
174 BOOL spaces;
175
176 if (!command || !*command) {
177 Runtime_Error(pszSrcFile, __LINE__, NULL);
178 return -1;
179 }
180 commandline = xmalloc(MaxComLineStrg + 1, pszSrcFile, __LINE__);
181 if (!commandline)
182 return -1; //already complained
183 *listfile = 0;
184 bstrip(command);
185
186 *path = 0;
187 if (tpath && *tpath)
188 strcpy(path, tpath);
189 else if (*command != '<' || !strchr(command, '>')) {
190 strcpy(path, command + (*command == '"'));
191 if (*command == '\"')
192 p = strchr(path, '\"');
193 else
194 p = strchr(path, ' ');
195 if (p)
196 *p = 0;
197 p = strrchr(path, '\\');
198 if (!p)
199 p = strrchr(path, ':');
200 if (p) {
201 if (*p == ':') {
202 p++;
203 *p = '\\';
204 p++;
205 }
206 *p = 0;
207 }
208 else
209 *path = 0;
210 }
211 if (!*path) {
212 if (list && list[0])
213 strcpy(path, list[0]);
214 p = strrchr(path, '\\');
215 if (!p)
216 p = strrchr(path, ':');
217 if (p) {
218 if (*p == ':') {
219 p++;
220 *p = '\\';
221 p++;
222 }
223 *p = 0;
224 }
225 else
226 *path = 0;
227 }
228 *modpath = 0;
229 if (list && list[0])
230 strcpy(modpath, list[0]);
231 p = strrchr(modpath, '\\');
232 if (!p)
233 p = strrchr(modpath, ':');
234 if (p) {
235 if (*p == ':') {
236 p++;
237 *p = '\\';
238 p++;
239 }
240 *p = 0;
241 }
242 else
243 *modpath = 0;
244 if (!*modpath)
245 strcpy(modpath, path);
246 if (*path)
247 MakeFullName(path);
248 if (*modpath)
249 MakeFullName(modpath);
250 if (IsFullName(path))
251 drive = toupper(*path);
252 else
253 drive = 0;
254
255 p = command; // substitue for special % sequences
256
257 pp = commandline;
258 *commandline = 0;
259 while (*p) {
260 if (*p == '%') {
261 switch (*(p + 1)) {
262 case '!': // write list to file, add filename
263 if (list) {
264 if (!*listfile) {
265 FILE *fp;
266 CHAR *modew = "w";
267
268 if (pTmpDir && !IsValidDir(pTmpDir))
269 DosCreateDir(pTmpDir, 0);
270 strcpy(listfile, pTmpDir ? pTmpDir : pFM2SaveDirectory);
271 MakeTempName(listfile, "$FM2LI$T", 2);
272 fp = xfopen(listfile, modew,pszSrcFile,__LINE__, FALSE);
273 if (fp) {
274 for (x = 0; list[x]; x++)
275 {
276 fputs(list[x], fp);
277 if (list[x + 1])
278 fputc('\n', fp);
279 }
280 fclose(fp);
281 }
282 }
283 strcpy(pp, listfile);
284 pp += strlen(listfile);
285 }
286 p += 2;
287 break;
288
289 case 'c': // add name of command processor
290 {
291 char *env = GetCmdSpec(FALSE);
292
293 if (needs_quoting(env) && !strchr(env, '\"')) {
294 *pp = '\"';
295 pp++;
296 spaces = TRUE;
297 }
298 else
299 spaces = FALSE;
300 strcpy(pp, env);
301 p += 2;
302 pp += strlen(env);
303 if (spaces) {
304 *pp = '\"';
305 pp++;
306 }
307 }
308 break;
309
310 case 't': // add Target directory
311 if (needs_quoting(targetdir) && !strchr(targetdir, '\"')) {
312 *pp = '\"';
313 pp++;
314 spaces = TRUE;
315 }
316 else
317 spaces = FALSE;
318 strcpy(pp, targetdir);
319 p += 2;
320 pp += strlen(targetdir);
321 if (spaces) {
322 *pp = '\"';
323 pp++;
324 }
325 break;
326
327 case '$': // add drive letter
328 if (drive)
329 *pp = drive;
330 else {
331 ULONG ulDriveNum = 3, ulDriveMap;
332
333 DosQCurDisk(&ulDriveNum, &ulDriveMap);
334 *pp = (char) (ulDriveNum + '@');
335 }
336 pp++;
337 p += 2;
338 break;
339
340 case 'U': // add path of first list component
341 case 'u':
342 if (*modpath) {
343 if (needs_quoting(modpath) && !strchr(modpath, '\"')) {
344 spaces = TRUE;
345 *pp = '\"';
346 pp++;
347 }
348 else
349 spaces = FALSE;
350 if (*(p + 1) == 'u') {
351 strcpy(pp, modpath);
352 pp += strlen(modpath);
353 }
354 else {
355 strcpy(pp, modpath + 2);
356 pp += strlen(modpath + 2);
357 }
358 if (spaces) {
359 if (modpath[strlen(modpath) - 1] == '\\') {
360 *pp = '\\';
361 pp++;
362 }
363 *pp = '\"';
364 pp++;
365 }
366 }
367 else {
368 char temp[CCHMAXPATH];
369
370 strcpy(temp, pFM2SaveDirectory);
371 if (needs_quoting(temp) && !strchr(temp, '\"')) {
372 spaces = TRUE;
373 *pp = '\"';
374 pp++;
375 }
376 else
377 spaces = FALSE;
378 strcpy(pp, temp);
379 pp += strlen(temp);
380 if (spaces) {
381 if (temp[strlen(temp) - 1] == '\\') {
382 *pp = '\\';
383 pp++;
384 }
385 *pp = '\"';
386 pp++;
387 }
388 }
389 p += 2;
390 break;
391
392 case 'P': // add path of execution
393 case 'p':
394 if (*path) {
395 if (needs_quoting(path) && !strchr(path, '\"')) {
396 spaces = TRUE;
397 *pp = '\"';
398 pp++;
399 }
400 else
401 spaces = FALSE;
402 if (*(p + 1) == 'p') {
403 strcpy(pp, path);
404 pp += strlen(path);
405 }
406 else {
407 strcpy(pp, path + 2);
408 pp += strlen(path + 2);
409 }
410 if (spaces) {
411 if (path[strlen(path) - 1] == '\\') {
412 *pp = '\\';
413 pp++;
414 }
415 *pp = '\"';
416 pp++;
417 }
418 }
419 else {
420 char temp[CCHMAXPATH];
421
422 strcpy(temp, pFM2SaveDirectory);
423 if (needs_quoting(temp) && !strchr(temp, '\"')) {
424 spaces = TRUE;
425 *pp = '\"';
426 pp++;
427 }
428 else
429 spaces = FALSE;
430 strcpy(pp, temp);
431 pp += strlen(temp);
432 if (spaces) {
433 if (temp[strlen(temp) - 1] == '\\') {
434 *pp = '\\';
435 pp++;
436 }
437 *pp = '\"';
438 pp++;
439 }
440 }
441 p += 2;
442 break;
443
444 case 'D':
445 if (hwndMain) {
446 PCNRITEM pci;
447
448 pci = (PCNRITEM) WinSendMsg(WinWindowFromID(WinWindowFromID(
449 hwndTree, FID_CLIENT), TREE_CNR),
450 CM_QUERYRECORDEMPHASIS,
451 MPFROMLONG(CMA_FIRST),
452 MPFROMSHORT(CRA_CURSORED));
453 if (pci && (int) pci != -1 && *pci->pszFileName) {
454 if (needs_quoting(pci->pszFileName) &&
455 !strchr(pci->pszFileName, '\"'))
456 {
457 *pp = '\"';
458 pp++;
459 spaces = TRUE;
460 }
461 else
462 spaces = FALSE;
463 strcpy(pp, pci->pszFileName);
464 pp += strlen(pci->pszFileName);
465 if (spaces) {
466 *pp = '\"';
467 pp++;
468 }
469 }
470 }
471 p += 2;
472 break;
473
474 case 'd':
475 if (hwndMain) {
476 HENUM henum;
477 char retstr[CCHMAXPATH];
478 HWND hwndC, hwndDir;
479 USHORT id;
480 BOOL first = TRUE;
481
482 henum = WinBeginEnumWindows(hwndMain);
483 while ((hwndC = WinGetNextWindow(henum)) != NULLHANDLE) {
484 if (hwndC != hwndTree) {
485 id = WinQueryWindowUShort(hwndC, QWS_ID);
486 if (id) {
487 hwndDir = WinWindowFromID(hwndC, FID_CLIENT);
488 if (hwndDir) {
489 hwndDir = WinWindowFromID(hwndDir, DIR_CNR);
490 if (hwndDir) {
491 *retstr = 0;
492 WinSendMsg(hwndC, UM_CONTAINERDIR, MPFROMP(retstr), MPVOID);
493 if (*retstr) {
494 if (!first) {
495 *pp = ' ';
496 pp++;
497 }
498 first = FALSE;
499 if (needs_quoting(retstr) && !strchr(retstr, '\"')) {
500 *pp = '\"';
501 pp++;
502 spaces = TRUE;
503 }
504 else
505 spaces = FALSE;
506 strcpy(pp, retstr);
507 pp += strlen(retstr);
508 if (spaces) {
509 *pp = '\"';
510 pp++;
511 }
512 }
513 }
514 }
515 }
516 }
517 }
518 WinEndEnumWindows(henum);
519 }
520 p += 2;
521 break;
522
523 case '%':
524 *pp = '%';
525 pp++;
526 p += 2;
527 break;
528
529 case 'R':
530 case 'F':
531 case 'A':
532 case 'r':
533 case 'f':
534 case 'a':
535 case 'e':
536 if (list) {
537 for (x = 0; list[x]; x++)
538 {
539 file = strrchr(list[x], '\\');
540 if (!file)
541 file = strrchr(list[x], ':');
542 if (file)
543 file++;
544 else
545 file = list[x];
546 ext = strrchr(file, '.');
547 dot = ext;
548 if (ext)
549 ext++;
550 switch (*(p + 1)) {
551 case 'R':
552 case 'r':
553 if (pp + strlen(list[x]) > commandline + MaxComLineStrg)
554 goto BreakOut;
555 if (*(p + 1) == 'r') {
556 strcpy(pp, list[x]);
557 pp += strlen(list[x]);
558 }
559 else {
560 strcpy(pp, list[x] + 2);
561 pp += strlen(list[x] + 2);
562 }
563 break;
564
565 case 'F':
566 case 'f':
567 if (*(p + 1) == 'F' && dot)
568 *dot = 0;
569 if (pp + strlen(file) > commandline + MaxComLineStrg)
570 goto BreakOut;
571 if (needs_quoting(file)) {
572 spaces = TRUE;
573 *pp = '\"';
574 pp++;
575 }
576 else
577 spaces = FALSE;
578 strcpy(pp, file);
579 pp += strlen(file);
580 if (*(p + 1) == 'F' && dot)
581 *dot = '.';
582 if (spaces) {
583 if (*(pp - 1) != '\"') {
584 *pp = '\"';
585 pp++;
586 }
587 }
588 break;
589
590 case 'A':
591 case 'a':
592 if (pp + strlen(list[x]) > commandline + MaxComLineStrg)
593 goto BreakOut;
594 if (needs_quoting(list[x]) && !strchr(list[x], '\"')) {
595 spaces = TRUE;
596 *pp = '\"';
597 pp++;
598 }
599 else
600 spaces = FALSE;
601 if (*(p + 1) == 'a') {
602 strcpy(pp, list[x]);
603 pp += strlen(list[x]);
604 }
605 else {
606 strcpy(pp, list[x] + 2);
607 pp += strlen(list[x] + 2);
608 }
609 if (spaces) {
610 if (list[x][strlen(list[x]) - 1] == '\\') {
611 *pp = '\\';
612 pp++;
613 }
614 *pp = '\"';
615 pp++;
616 }
617 break;
618
619 case 'e':
620 if (ext) {
621 if (pp + strlen(ext) > commandline + MaxComLineStrg)
622 goto BreakOut;
623 if (needs_quoting(ext)) {
624 spaces = TRUE;
625 *pp = '\"';
626 pp++;
627 }
628 else
629 spaces = FALSE;
630 strcpy(pp, ext);
631 pp += strlen(ext);
632 if (spaces) {
633 if (*(pp - 1) != '\"') {
634 *pp = '\"';
635 pp++;
636 }
637 }
638 }
639 break;
640 }
641 if (list[x + 1]) {
642 *pp = ' ';
643 pp++;
644 }
645 }
646 }
647 p += 2;
648 break;
649
650 default:
651 *pp = *p;
652 p++;
653 pp++;
654 break;
655 }
656 }
657 else {
658 *pp = *p;
659 pp++;
660 p++;
661 }
662 *pp = 0;
663 }
664
665BreakOut:
666
667 {
668 EXECARGS ex;
669 int ret;
670
671 memset(&ex, 0, sizeof(EXECARGS));
672 if (!environment) {
673 ULONG size;
674
675 size = ENVIRONMENT_SIZE;
676 PrfQueryProfileData(fmprof, FM3Str, command, ex.environment, &size);
677 }
678 else
679 strcpy(ex.environment, environment);
680 if (flags & PROMPT) {
681 // allow editing command line
682 ex.flags = (flags & (~PROMPT));
683 ex.commandline = commandline;
684 strcpy(ex.path, path);
685 if (prompt)
686 strcpy(ex.title, prompt);
687 ret = WinDlgBox(HWND_DESKTOP, hwnd, CmdLineDlgProc, FM3ModHandle,
688 EXEC_FRAME, &ex);
689 if (ret != 1) {
690 free(commandline);
691 return (ret == 0) ? -1 : -2;
692 }
693 }
694 else
695 ex.flags = flags;
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 xDosGetInfoBlocks(&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 = xDosStartSession(&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.