source: trunk/dll/systemf.c@ 1439

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

Changes to allow high mem loading of dll; Refactor .LONGNAME and .SUBJECT EA fetch to FetchCommonEAs. Add szFSType to FillInRecordFromFSA use to bypass EA scan and size formatting for tree container; Fix labels/FS type to work on scan on NOPRESCAN Drives; Fixed dbl directory names on restore of dir cnrs; (Tickets 47, 339, 363, 368, 369, 370)

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