source: trunk/dll/systemf.c@ 1627

Last change on this file since 1627 was 1627, checked in by Gregg Young, 14 years ago

Add a low mem version of xDosAlloc* wrappers; move error checking into all the xDosAlloc* wrappers. Ticket 471

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