source: trunk/dll/systemf.c@ 1438

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

Improved drivebar changes; Added AddBackslashToPath() to remove repeatative code. replaced "
" with PCSZ variable; ANY_OBJ added the DosAlloc... (experimental)

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