source: trunk/dll/systemf.c@ 1369

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

Add check for p-rotectonly system to gray out dos/win commandline choices etc. Ticket 325 It also fixes problem with some drives not being scanned on startup.

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