source: trunk/dll/systemf.c@ 1498

Last change on this file since 1498 was 1498, checked in by Gregg Young, 16 years ago

Changes to get FM2 to compile with the latest watcom 1.9 beta (mostly type casts of CHAR CONSTANT * to CHAR *). Changes to get the environment settings working everywhere again (broken by the change that moved commands to the INI); Added an environment size variable (set to 2048 which was the largest I found hard coded). Still need to find everywhere the environment size is set and use this variable.

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