source: trunk/dll/systemf.c@ 441

Last change on this file since 441 was 441, checked in by root, 19 years ago

More error popups

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