source: trunk/dll/systemf.c@ 1401

Last change on this file since 1401 was 1398, checked in by Gregg Young, 17 years ago

Move embeded strings to PCSZ variables or string table; Eliminate Error2 functions Runtime_Error with NULL format string returns "No data" error. Change declares from PSZ to PCSZ in functions where the variable isn't changed. Added btm as an executable file type in several additional places. Use fProtectOnly to prevent attempt to execute Dos and Win programs on "Protect only" installs in several additional places.

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