source: trunk/dll/systemf.c@ 1544

Last change on this file since 1544 was 1544, checked in by Gregg Young, 15 years ago

Changes to fopen and _fsopen to allow FM2 to be loaded in high memory

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