source: trunk/dll/systemf.c@ 1859

Last change on this file since 1859 was 1859, checked in by John Small, 10 years ago

Corrected typo in previous comment.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 36.5 KB
Line 
1
2/***********************************************************************
3
4 $Id: systemf.c 1859 2015-08-21 15:59:51Z jbs $
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 //DbgMsg(pszSrcFile, __LINE__, "env %s", environment);
673 if (!environment) {
674 ULONG size;
675
676 size = ENVIRONMENT_SIZE;
677 PrfQueryProfileData(fmprof, FM3Str, command, ex.environment, &size);
678 }
679 else
680 strcpy(ex.environment, environment);
681 if (flags & PROMPT) {
682 // allow editing command line
683 ex.flags = (flags & (~PROMPT));
684 ex.commandline = commandline;
685 strcpy(ex.path, path);
686 if (prompt)
687 strcpy(ex.title, prompt);
688 ret = WinDlgBox(HWND_DESKTOP, hwnd, CmdLineDlgProc, FM3ModHandle,
689 EXEC_FRAME, &ex);
690 if (ret != 1) {
691 free(commandline);
692 return (ret == 0) ? -1 : -2;
693 }
694 }
695 else
696 ex.flags = flags;
697 //DbgMsg(pszSrcFile, __LINE__, "Inserted %s", environment);
698 ret = runemf2(ex.flags, hwnd, pszCallingFile, uiLineNumber, path,
699 *ex.environment ? ex.environment : NULL,
700 "%s", commandline);
701 free(commandline);
702 return ret;
703 }
704}
705
706/** Run requested app
707 * @return application return code or -1 if problem starting app
708 */
709
710int runemf2(int type, HWND hwnd, PCSZ pszCallingFile, UINT uiLineNumber,
711 char *pszDirectory, char *pszEnvironment,
712 char *formatstring,...)
713{
714 /** example:
715 *
716 * status = runemf2(SEPARATE | WINDOWED,
717 * hwnd, pszCallingFile, __LINE__,
718 * NullStr,
719 * NULL,
720 * "%s /C %s",
721 * getenv("COMSPEC"),
722 * batchfilename);
723 *
724 * use (HWND)0 for hwnd if window handle not handy.
725 * pszCallingFile and __LINE__ are used to determine caller for easier error tracking
726 */
727 /**
728 * type bitmapped flag -- see systemf.h
729 */
730
731 va_list parguments;
732 int ret = -1;
733 RESULTCODES results;
734 STARTDATA sdata;
735 REQUESTDATA rq;
736 ULONG ulSessID;
737 ULONG ulLength;
738 UINT ctr;
739 ULONG ulAppType;
740 PID sessPID;
741 BOOL wasquote;
742 char *p, *pszPgm, *pszArgs = NULL;
743 char szObject[32] = "";
744 char szSavedir[CCHMAXPATH];
745 BOOL useTermQ = FALSE;
746 char szTempdir[CCHMAXPATH];
747 BOOL fNoErrorMsg = FALSE;
748
749 typedef struct {
750 USHORT usSessID;
751 USHORT usRC;
752 } TERMINFO;
753
754 TERMINFO *pTermInfo;
755 BYTE bPriority;
756 APIRET rc;
757 PIB *ppib;
758 TIB *ptib;
759
760 // Shared by all threads
761# define TERMQ_BASE_NAME "\\QUEUES\\FM3WAIT"
762 static char szTermQName[30];
763 char szTermTemp[30];
764 static HQUEUE hTermQ;
765 static HEV hTermQSem;
766
767 if (pszDirectory && *pszDirectory) {
768 if (!DosQueryPathInfo(pszDirectory,
769 FIL_QUERYFULLNAME,
770 szTempdir,
771 sizeof(szTempdir)))
772 pszDirectory = szTempdir;
773 }
774
775 if (!hwnd)
776 hwnd = HWND_DESKTOP;
777
778 if (xDosAllocMemLow((PVOID)&pszPgm, MaxComLineStrg, pszSrcFile,__LINE__))
779 return -1; //already complained
780 *szSavedir = 0;
781
782 *pszPgm = 0;
783 va_start(parguments,
784 formatstring);
785 vsprintf(pszPgm,
786 formatstring,
787 parguments);
788 va_end(parguments);
789
790 if (pszEnvironment) {
791 p = &pszEnvironment[strlen(pszEnvironment)] + 1;
792 *p = 0;
793 p = pszEnvironment;
794 while ((p = convert_nl_to_nul(p)) != NULL)
795 ; // loop
796 }
797
798 if (!stricmp(pszCallingFile, "init.c"))
799 fNoErrorMsg = TRUE;
800
801 if (!*pszPgm) {
802 p = GetCmdSpec(FALSE);
803 strcpy(pszPgm, p);
804 if (!*pszPgm) {
805 Runtime_Error(pszSrcFile, __LINE__, NULL);
806 return -1;
807 }
808 }
809
810 if (*pszPgm) {
811 if (*pszPgm == '<' && strchr(pszPgm, '>')) {
812 // is a workplace object
813 HOBJECT hWPSObject;
814 char temp;
815
816 p = strchr(pszPgm, '>');
817 p++;
818 temp = *p;
819 if (temp) {
820 if (xDosAllocMemLow((PVOID)&pszArgs, MaxComLineStrg * 2, pszSrcFile, __LINE__)) {
821 DosFreeMem(pszPgm);
822 return -1; //already complained
823 }
824 }
825 else
826 pszArgs = NULL;
827 *p = 0;
828 // Find the handle of the WPS object
829 hWPSObject = WinQueryObject(pszPgm);
830 *p = temp;
831 if (hWPSObject != NULLHANDLE) {
832 if (pszArgs && *p) {
833 sprintf(pszArgs,"OPEN=DEFAULT;PARAMETERS=\"%s\"",p);
834 WinSetObjectData(hWPSObject,pszArgs);
835 }
836 else
837 WinSetObjectData(hWPSObject,"OPEN=DEFAULT");
838 ret = 0;
839 }
840 goto ObjectInterrupt;
841 }
842
843 if ((type & RUNTYPE_MASK) == SYNCHRONOUS ||
844 (type & RUNTYPE_MASK) == ASYNCHRONOUS ||
845 (type & RUNTYPE_MASK) == DETACHED)
846 {
847 strip_lead_char(" \t", pszPgm);
848 p = pszPgm;
849 wasquote = FALSE;
850 while (*p &&
851 (wasquote ||
852 (*p != ' ' &&
853 *p != '\t')))
854 {
855 if (*p == '\"') {
856 if (!wasquote) {
857 wasquote = TRUE;
858 memmove(p,
859 p + 1,
860 strlen(p));
861 while (*p == ' ' ||
862 *p == '\t')
863 p++;
864 }
865 else {
866 memmove(p,
867 p + 1,
868 strlen(p));
869 break;
870 }
871 }
872 else
873 p++;
874 }
875 if (*p) {
876 *p = 0;
877 p++;
878 }
879 else
880 p = pszPgm;
881 p[strlen(p) + 1] = 0; // double-terminate args
882 if (*pszPgm) {
883 if (!strchr(pszPgm, '\\') &&
884 !strchr(pszPgm, ':') &&
885 pszDirectory &&
886 *pszDirectory)
887 {
888 strcpy(szSavedir, pFM2SaveDirectory);
889 switch_to(pszDirectory);
890 }
891 rc = xDosQueryAppType(pszPgm, &ulAppType);
892 if (!strchr(pszPgm, '\\') &&
893 !strchr(pszPgm, ':') &&
894 pszDirectory &&
895 *pszDirectory)
896 switch_to(szSavedir);
897 if (rc) {
898 if (rc == ERROR_FILE_NOT_FOUND || rc == ERROR_PATH_NOT_FOUND ||
899 rc == ERROR_INVALID_EXE_SIGNATURE || rc == ERROR_EXE_MARKED_INVALID)
900 saymsg(MB_OK, HWND_DESKTOP, NullStr,GetPString(IDS_DOSQAPPTYPEFAILEDTEXT2),
901 pszPgm, pszCallingFile,uiLineNumber);
902 else if (rc == ERROR_INVALID_DRIVE || rc == ERROR_DRIVE_LOCKED)
903 saymsg(MB_OK, HWND_DESKTOP, NullStr,
904 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT3), pszPgm);
905 else
906 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
907 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
908 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
909 DosFreeMem(pszPgm);
910 if (pszArgs)
911 DosFreeMem(pszArgs);
912 return -1;
913 }
914 if (ulAppType) {
915 if (ulAppType & FAPPTYP_DLL || ulAppType & FAPPTYP_VIRTDRV ||
916 ulAppType & FAPPTYP_PHYSDRV || ulAppType & FAPPTYP_PROTDLL)
917 {
918 Runtime_Error(pszSrcFile, __LINE__,
919 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
920 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
921 if (pszPgm)
922 DosFreeMem(pszPgm);
923 if (pszArgs)
924 DosFreeMem(pszArgs);
925 return -1;
926 }
927 if (ulAppType & FAPPTYP_DOS || ulAppType & FAPPTYP_WINDOWSREAL ||
928 ulAppType & FAPPTYP_WINDOWSPROT || ulAppType & FAPPTYP_WINDOWSPROT31)
929 {
930 Runtime_Error(pszSrcFile, __LINE__,
931 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
932 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
933 if (pszPgm)
934 DosFreeMem(pszPgm);
935 if (pszArgs)
936 DosFreeMem(pszArgs);
937 return -1;
938 }
939 }
940 memset(&results, 0, sizeof(results));
941 if (pszDirectory && *pszDirectory) {
942 strcpy(szSavedir, pFM2SaveDirectory);
943 switch_to(pszDirectory);
944 }
945 ret = DosExecPgm(szObject, sizeof(szObject),
946 ((type & RUNTYPE_MASK) == ASYNCHRONOUS ? EXEC_ASYNC : 0) +
947 ((type & RUNTYPE_MASK) == DETACHED ? EXEC_BACKGROUND : 0),
948 pszPgm, pszEnvironment, &results, pszPgm);
949 if (pszDirectory && *pszDirectory)
950 switch_to(szSavedir);
951 if (ret && !fNoErrorMsg) {
952 Dos_Error(MB_ENTER,ret,hwnd,pszSrcFile,__LINE__,
953 GetPString(IDS_DOSEXECPGMFAILEDTEXT), pszPgm,
954 pszCallingFile, uiLineNumber); // 26 May 08 SHL
955 }
956 }
957 }
958 else {
959 if (~type & FULLSCREEN)
960 type |= WINDOWED;
961 if (xDosAllocMemLow((PVOID) &pszArgs, MaxComLineStrg * 2, pszSrcFile, __LINE__)) {
962 DosFreeMem(pszPgm);
963 return -1; //already complained
964 }
965 *pszArgs = 0;
966 memset(&sdata, 0, sizeof(sdata));
967 strip_lead_char(" \t", pszPgm);
968 p = pszPgm;
969 wasquote = FALSE;
970 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
971 if (*p == '\"') {
972 if (!wasquote) {
973 wasquote = TRUE;
974 memmove(p, p + 1, strlen(p));
975 while (*p == ' ' || *p == '\t')
976 p++;
977 }
978 else {
979 memmove(p, p + 1, strlen(p));
980 break;
981 }
982 }
983 else
984 p++;
985 } // while
986 if (*p) {
987 *p = 0;
988 p++;
989 }
990 else
991 p = NullStr;
992 if (*p)
993 strcpy(pszArgs, p);
994
995 p = strrchr(pszPgm, '.');
996 if (p) {
997 char temp[CCHMAXPATH + 1];
998
999 if (!stricmp(p, PCSZ_DOTBAT)) {
1000 if (!fProtectOnly) {
1001 strcpy(temp, pszPgm);
1002 strcpy(pszPgm, pszArgs);
1003 strcpy(pszArgs, "/C ");
1004 strcat(pszArgs, temp);
1005 strcat(pszArgs, " ");
1006 strcat(pszArgs, pszPgm);
1007 strcpy(pszPgm, GetCmdSpec(TRUE)); // DOS
1008 }
1009 else
1010 saymsg(MB_OK,
1011 HWND_DESKTOP,
1012 NullStr,
1013 GetPString(IDS_NOTPROTECTONLYEXE),
1014 pszPgm);
1015 }
1016 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1017 // Assume 4OS2 is BTM
1018 strcpy(temp, pszPgm);
1019 strcpy(pszPgm, pszArgs);
1020 strcpy(pszArgs, "/C ");
1021 strcat(pszArgs, temp);
1022 strcat(pszArgs, " ");
1023 strcat(pszArgs, pszPgm);
1024 strcpy(pszPgm, GetCmdSpec(FALSE)); // OS/2
1025 }
1026 }
1027
1028 // goddamned OS/2 limit
1029
1030 if (strlen(pszPgm) + strlen(pszArgs) > 1024)
1031 pszArgs[1024 - strlen(pszPgm)] = 0;
1032
1033 if (!strchr(pszPgm, '\\') &&
1034 !strchr(pszPgm, ':') &&
1035 pszDirectory &&
1036 *pszDirectory)
1037 {
1038 strcpy(szSavedir, pFM2SaveDirectory);
1039 switch_to(pszDirectory);
1040 }
1041 rc = xDosQueryAppType(pszPgm, &ulAppType);
1042 if (!strchr(pszPgm, '\\') &&
1043 !strchr(pszPgm, ':') &&
1044 pszDirectory &&
1045 *pszDirectory)
1046 switch_to(szSavedir);
1047 if (rc) {
1048 if (rc == ERROR_FILE_NOT_FOUND || rc == ERROR_PATH_NOT_FOUND ||
1049 rc == ERROR_INVALID_EXE_SIGNATURE || rc == ERROR_EXE_MARKED_INVALID)
1050 saymsg(MB_OK, HWND_DESKTOP, NullStr, GetPString(IDS_DOSQAPPTYPEFAILEDTEXT2),
1051 pszPgm, pszCallingFile,uiLineNumber);
1052 else if (rc == ERROR_INVALID_DRIVE || rc == ERROR_DRIVE_LOCKED)
1053 saymsg(MB_OK, HWND_DESKTOP, NullStr,
1054 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT3), pszPgm);
1055 else
1056 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
1057 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
1058 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
1059 DosFreeMem(pszPgm);
1060 if (pszArgs)
1061 DosFreeMem(pszArgs);
1062 return -1;
1063 }
1064
1065 if (ulAppType) {
1066 if (ulAppType & (FAPPTYP_DLL | FAPPTYP_VIRTDRV | FAPPTYP_PHYSDRV | FAPPTYP_PROTDLL))
1067 {
1068 Runtime_Error(pszSrcFile, __LINE__,
1069 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
1070 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
1071 DosFreeMem(pszPgm);
1072 if (pszArgs)
1073 DosFreeMem(pszArgs);
1074 return -1;
1075 }
1076 ulAppType &= ~FAPPTYP_BOUND;
1077 if (ulAppType & (FAPPTYP_DOS | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1078 {
1079 if (ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1080 {
1081 if (~type & FULLSCREEN &&
1082 ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1083 {
1084 ret = RunSeamless(pszPgm, pszArgs, hwnd);
1085 if (pszPgm)
1086 DosFreeMem(pszPgm);
1087 if (pszArgs)
1088 DosFreeMem(pszArgs);
1089 return ret ? 0 : -1;
1090 }
1091 else {
1092 strcat(pszPgm, " ");
1093 strcat(pszPgm, pszArgs);
1094 *pszArgs = 0;
1095 if (ulAppType & (FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT31))
1096 strcat(pszArgs, "/3 ");
1097 strcat(pszArgs, pszPgm);
1098 strcpy(pszPgm, "WINOS2.COM");
1099 }
1100 }
1101 else {
1102 if (~type & FULLSCREEN) {
1103 type |= WINDOWED;
1104 ulAppType = SSF_TYPE_WINDOWEDVDM;
1105 }
1106 else {
1107 type &= ~WINDOWED;
1108 ulAppType = SSF_TYPE_VDM;
1109 }
1110 }
1111 }
1112 else if (ulAppType & FAPPTYP_32BIT) {
1113 ulAppType &= ~FAPPTYP_32BIT;
1114 if (ulAppType == FAPPTYP_WINDOWAPI)
1115 ulAppType = SSF_TYPE_PM;
1116 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1117 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1118 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1119 ulAppType = SSF_TYPE_FULLSCREEN;
1120 type &= ~WINDOWED;
1121 type |= FULLSCREEN;
1122 }
1123 else // ?
1124 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1125 }
1126 else if (ulAppType == FAPPTYP_WINDOWAPI)
1127 ulAppType = SSF_TYPE_PM;
1128 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1129 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1130 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1131 type &= ~WINDOWED;
1132 ulAppType = SSF_TYPE_FULLSCREEN;
1133 }
1134 else
1135 ulAppType = SSF_TYPE_DEFAULT;
1136 if ((type & FULLSCREEN || ~type & WINDOWED) &&
1137 ulAppType == SSF_TYPE_WINDOWABLEVIO)
1138 {
1139 ulAppType = SSF_TYPE_FULLSCREEN;
1140 }
1141 // fixme parens?
1142 else if (type & FULLSCREEN ||
1143 (type & WINDOWED && ulAppType == SSF_TYPE_WINDOWEDVDM))
1144 {
1145 ulAppType = SSF_TYPE_VDM;
1146 }
1147 }
1148 if (ulAppType == SSF_TYPE_WINDOWEDVDM && type & SEPARATEKEEP) {
1149 type &= ~SEPARATEKEEP;
1150 type |= SEPARATE;
1151 }
1152
1153 xDosGetInfoBlocks(&ptib, &ppib);
1154
1155 if (~type & WAIT)
1156 useTermQ = FALSE;
1157 else {
1158 rc = 0;
1159 DosEnterCritSec();
1160 if (!hTermQ) {
1161 // Create term queue and event semaphore just once
1162 sprintf(szTermQName, TERMQ_BASE_NAME "_%x", ppib->pib_ulpid);
1163 rc = DosCreateQueue(&hTermQ, QUE_FIFO | QUE_CONVERT_ADDRESS, szTermQName);
1164 if (rc) {
1165 hTermQ = (HQUEUE)0; // Try to survive
1166 DosExitCritSec();
1167 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosCreateQueue");
1168 }
1169 else {
1170 rc = DosCreateEventSem(NULL,(PHEV)&hTermQSem,0,FALSE);
1171 if (rc) {
1172 hTermQSem = (HEV)0; // Try to survive
1173 DosCloseQueue(hTermQ);
1174 hTermQ = (HQUEUE)0; // Try to survive
1175 DosExitCritSec();
1176 Dos_Error(MB_ENTER,rc,HWND_DESKTOP,pszSrcFile,__LINE__, PCSZ_DOSCREATEEVENTSEM);
1177 }
1178 // if (!rc) fprintf(stderr,"%s %d qcreated ptib %x hTermQ %x\n",__FILE__, __LINE__,ptib,hTermQ);
1179 }
1180 } // if 1st time
1181 useTermQ = hTermQ && hTermQSem;
1182 if (!rc)
1183 DosExitCritSec();
1184 } // if wait
1185
1186 memset(&sdata,0,sizeof(sdata));
1187 sdata.Length = sizeof(sdata);
1188 sdata.Related = type & (WAIT | CHILD) ? SSF_RELATED_CHILD :
1189 SSF_RELATED_INDEPENDENT;
1190 sdata.FgBg = type & BACKGROUND ? SSF_FGBG_BACK : SSF_FGBG_FORE;
1191 sdata.TraceOpt = SSF_TRACEOPT_NONE;
1192 sdata.PgmName = pszPgm;
1193 if (*pszArgs)
1194 sdata.PgmInputs = (PBYTE)pszArgs;
1195 if (useTermQ) {
1196 strcpy(szTermTemp, szTermQName);
1197 sdata.TermQ = (PBYTE)szTermTemp;
1198 }
1199 sdata.Environment = (PBYTE)pszEnvironment;
1200 if (fUseShellEnv && (!strcmp(GetCmdSpec(TRUE), pszPgm) ||
1201 !strcmp(GetCmdSpec(FALSE), pszPgm)))
1202 sdata.InheritOpt = SSF_INHERTOPT_SHELL;
1203 else
1204 sdata.InheritOpt = SSF_INHERTOPT_PARENT;
1205 sdata.SessionType = (USHORT) ulAppType;
1206 sdata.ObjectBuffer = szObject;
1207 sdata.ObjectBuffLen = sizeof(szObject);
1208 if ((type & RUNTYPE_MASK) == SEPARATEKEEP)
1209 sdata.PgmControl |= SSF_CONTROL_NOAUTOCLOSE;
1210 if (type & MAXIMIZED)
1211 sdata.PgmControl |= SSF_CONTROL_MAXIMIZE;
1212 if (type & MINIMIZED)
1213 sdata.PgmControl |= SSF_CONTROL_MINIMIZE;
1214 if (type & INVISIBLE)
1215 sdata.PgmControl |= SSF_CONTROL_INVISIBLE;
1216
1217 if (pszDirectory && *pszDirectory) {
1218 strcpy(szSavedir, pFM2SaveDirectory);
1219 switch_to(pszDirectory);
1220 }
1221 ret = xDosStartSession(&sdata, &ulSessID, &sessPID);
1222
1223
1224 if (pszDirectory && *pszDirectory)
1225 switch_to(szSavedir);
1226
1227 if (ret && ret != ERROR_SMG_START_IN_BACKGROUND) {
1228 if (!fNoErrorMsg)
1229 Dos_Error(MB_CANCEL,ret,hwnd,pszSrcFile,__LINE__,
1230 GetPString(IDS_DOSSTARTSESSIONFAILEDTEXT),pszPgm,pszArgs,
1231 pszCallingFile, uiLineNumber); // 26 May 08 SHL
1232 }
1233 else if (type & WAIT) {
1234 if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1235 ShowSession(hwnd, sessPID);
1236
1237 if (!useTermQ) {
1238 STATUSDATA sd;
1239
1240 memset(&sd, 0, sizeof(sd));
1241 sd.Length = (USHORT) sizeof(sd);
1242 sd.SelectInd = SET_SESSION_UNCHANGED;
1243 sd.BondInd = SET_SESSION_UNCHANGED;
1244 for (ctr = 0;; ctr++)
1245 {
1246 DosSleep(50);//05 Aug 07 GKY 200
1247 if (DosSetSession(ulSessID, &sd)) // Check if session gone (i.e. finished)
1248 break;
1249 if (ctr > 10) {
1250 ShowSession(hwnd, sessPID); // Show every 2 seconds
1251 ctr = 0;
1252 }
1253 }
1254 }
1255 else {
1256 for (ctr = 0;; ctr++)
1257 {
1258 if (ctr < 20) {
1259 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1260 DCWW_NOWAIT, &bPriority, hTermQSem);
1261 if (rc == ERROR_QUE_EMPTY) {
1262 DosSleep(50);//05 Aug 07 GKY 100
1263 continue;
1264 }
1265 }
1266 else {
1267 if (ctr == 20) {
1268 ShowSession(hwnd, sessPID); // Show long running session
1269 }
1270 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1271 DCWW_WAIT, &bPriority, 0);
1272 }
1273
1274 if (rc) {
1275 // Oh heck
1276 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosReadQueue");
1277 DosSleep(100);//05 Aug 07 GKY 500
1278 continue;
1279 }
1280
1281 // printf("%s %d DosReadQueue thread 0x%x sess %u sessRC %u rq.pid 0x%x rq.data 0x%x\n",
1282 // __FILE__, __LINE__,ptib->tib_ordinal,pTermInfo->usSessID,pTermInfo->usRC,rq.pid, rq.ulData); fflush(stdout);
1283
1284 if (pTermInfo->usSessID == ulSessID)
1285 break; // Our session is done
1286
1287 // Requeue session for other thread
1288 {
1289 static ULONG ulLastSessID;
1290 // printf("%s %d requeue thread 0x%x our sess %u term sess %u term rc %u\n",
1291 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID,pTermInfo->usSessID,pTermInfo->usRC); fflush(stdout);
1292 // fixme to be gone when no longer needed for debug?
1293 if (ulLastSessID) {
1294 DosSleep(100);//05 Aug 07 GKY 500
1295 ulLastSessID = pTermInfo->usSessID;
1296 }
1297 // requeue term report for other thread and do not free yet
1298 rc = DosWriteQueue(hTermQ, rq.ulData, ulLength,(PVOID)pTermInfo, bPriority);
1299 if (rc)
1300 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosWriteQueue");
1301 DosSleep(50); //05 Aug 07 GKY 100 // Let other thread see queue entry
1302 }
1303 } // for
1304
1305 ret = pTermInfo->usRC == 0; // Set 1 if rc 0 else 0
1306 // printf("%s %d thread 0x%x term for sess %u\n",
1307 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID);fflush(stdout);
1308 DosFreeMem(pTermInfo);
1309 }
1310 } // if wait
1311 else if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1312 ShowSession(hwnd, sessPID);
1313 }
1314 }
1315
1316ObjectInterrupt:
1317
1318 if (pszPgm)
1319 DosFreeMem(pszPgm);
1320 if (pszArgs)
1321 DosFreeMem(pszArgs);
1322
1323 return ret;
1324}
1325
1326//== Exec() Start application with WinStartApp ==
1327#if 0 // JBS 11 Sep 08
1328HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
1329 PROGTYPE *progt, ULONG fl, char *formatstring,...)
1330{
1331 PROGDETAILS pgd;
1332 register char *p;
1333 char *parameters = NULL, *executable = NULL;
1334 HAPP happ = (HAPP)0;
1335 ULONG ulOptions = SAF_INSTALLEDCMDLINE;
1336 BOOL wasquote;
1337 va_list parguments;
1338
1339 if (child)
1340 ulOptions |= SAF_STARTCHILDAPP;
1341
1342 executable = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1343 if (executable) {
1344 va_start(parguments, formatstring);
1345 vsprintf(executable, formatstring, parguments);
1346 va_end(parguments);
1347 strip_lead_char(" \t", executable);
1348 if (*executable) {
1349 parameters = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
1350 if (parameters) {
1351 p = executable;
1352 wasquote = FALSE;
1353 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
1354 if (*p == '\"') {
1355 if (!wasquote) {
1356 wasquote = TRUE;
1357 memmove(p, p + 1, strlen(p));
1358 while (*p == ' ' || *p == '\t')
1359 p++;
1360 }
1361 else {
1362 memmove(p, p + 1, strlen(p));
1363 break;
1364 }
1365 }
1366 else
1367 p++;
1368 }
1369 if (*p) {
1370 *p = 0;
1371 p++;
1372 }
1373 else
1374 p = NullStr;
1375 if (*p)
1376 strcpy(parameters, p);
1377
1378 if (p && (!stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTCMD) ||
1379 !stricmp(p, PCSZ_DOTBTM))) {
1380 char *temp;
1381
1382 temp = xmalloc(CCHMAXPATH * 2,pszSrcFile,__LINE__);
1383 if (temp) {
1384 if (!stricmp(p, PCSZ_DOTBAT)) {
1385 if (!fProtectOnly) {
1386 strcpy(temp, executable);
1387 strcpy(executable, parameters);
1388 strcpy(parameters, "/C ");
1389 strcat(parameters, temp);
1390 strcat(parameters, " ");
1391 strcat(parameters, executable);
1392 strcpy(executable, GetCmdSpec(TRUE)); //DOS
1393 }
1394 else
1395 saymsg(MB_OK,
1396 HWND_DESKTOP,
1397 NullStr,
1398 GetPString(IDS_NOTPROTECTONLYEXE),
1399 filename);
1400 }
1401 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1402 strcpy(temp, executable);
1403 strcpy(executable, parameters);
1404 strcpy(parameters, "/C ");
1405 strcat(parameters, temp);
1406 strcat(parameters, " ");
1407 strcat(parameters, executable);
1408 strcpy(executable, GetCmdSpec(FALSE));
1409 }
1410 free(temp);
1411 }
1412 }
1413
1414 memset(&pgd, 0, sizeof(pgd));
1415 pgd.Length = sizeof(pgd);
1416 pgd.progt = *progt;
1417 pgd.swpInitial.fl = fl;
1418 pgd.pszEnvironment = env;
1419 pgd.pszStartupDir = startdir;
1420 pgd.pszParameters = *parameters ? parameters : NULL;
1421 pgd.pszExecutable = executable;
1422 pgd.swpInitial.hwndInsertBehind = HWND_TOP;
1423 happ = WinStartApp(hwndNotify, &pgd, NULL, NULL, ulOptions);
1424 free(parameters);
1425 }
1426 }
1427 free(executable);
1428 }
1429 return happ;
1430}
1431#endif
1432#pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2)
Note: See TracBrowser for help on using the repository browser.