source: trunk/dll/systemf.c@ 1480

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

Fix failure to correctly check for large file support in FindSwapperDat fall back code minor streamling. Add LVM.EXE to partition submenu. Stop using xDosQueryAppType where the file name it is passed is already a local stack variable. Correct a typo in several file header comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 32.0 KB
Line 
1
2/***********************************************************************
3
4 $Id: systemf.c 1480 2009-11-22 22:58:49Z 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 char szTermTemp[30];
691 static HQUEUE hTermQ;
692 static HEV hTermQSem;
693
694 if (pszDirectory && *pszDirectory) {
695 if (!DosQueryPathInfo(pszDirectory,
696 FIL_QUERYFULLNAME,
697 szTempdir,
698 sizeof(szTempdir)))
699 pszDirectory = szTempdir;
700 }
701
702 if (!hwnd)
703 hwnd = HWND_DESKTOP;
704
705 rc = DosAllocMem((PVOID)&pszPgm,
706 MaxComLineStrg,
707 PAG_COMMIT | PAG_READ | PAG_WRITE);
708 if (rc) {
709 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,GetPString(IDS_OUTOFMEMORY));
710 return -1;
711 }
712
713 *szSavedir = 0;
714
715 *pszPgm = 0;
716 va_start(parguments,
717 formatstring);
718 vsprintf(pszPgm,
719 formatstring,
720 parguments);
721 va_end(parguments);
722
723 if (pszEnvironment) {
724 p = &pszEnvironment[strlen(pszEnvironment)] + 1;
725 *p = 0;
726 p = pszEnvironment;
727 while ((p = convert_nl_to_nul(p)) != NULL)
728 ; // loop
729 }
730
731 if (!stricmp(pszCallingFile, "init.c"))
732 fNoErrorMsg = TRUE;
733
734 if (!*pszPgm) {
735 p = GetCmdSpec(FALSE);
736 strcpy(pszPgm, p);
737 if (!*pszPgm) {
738 Runtime_Error(pszSrcFile, __LINE__, NULL);
739 return -1;
740 }
741 }
742
743 if (*pszPgm) {
744 if (*pszPgm == '<' && strchr(pszPgm, '>')) {
745 /* is a workplace object */
746 HOBJECT hWPSObject;
747 char temp;
748
749 p = strchr(pszPgm, '>');
750 p++;
751 temp = *p;
752 if (temp) {
753 rc = DosAllocMem((PVOID)&pszArgs,
754 MaxComLineStrg * 2,
755 PAG_COMMIT | PAG_READ | PAG_WRITE);
756 if (rc)
757 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,GetPString(IDS_OUTOFMEMORY));
758 }
759 else
760 pszArgs = NULL;
761 *p = 0;
762 /* Find the handle of the WPS object */
763 hWPSObject = WinQueryObject(pszPgm);
764 *p = temp;
765 if (hWPSObject != NULLHANDLE) {
766 if (pszArgs && *p) {
767 sprintf(pszArgs,"OPEN=DEFAULT;PARAMETERS=\"%s\"",p);
768 WinSetObjectData(hWPSObject,pszArgs);
769 }
770 else
771 WinSetObjectData(hWPSObject,"OPEN=DEFAULT");
772 ret = 0;
773 }
774 goto ObjectInterrupt;
775 }
776
777 if ((type & RUNTYPE_MASK) == SYNCHRONOUS ||
778 (type & RUNTYPE_MASK) == ASYNCHRONOUS ||
779 (type & RUNTYPE_MASK) == DETACHED)
780 {
781 strip_lead_char(" \t", pszPgm);
782 p = pszPgm;
783 wasquote = FALSE;
784 while (*p &&
785 (wasquote ||
786 (*p != ' ' &&
787 *p != '\t')))
788 {
789 if (*p == '\"') {
790 if (!wasquote) {
791 wasquote = TRUE;
792 memmove(p,
793 p + 1,
794 strlen(p));
795 while (*p == ' ' ||
796 *p == '\t')
797 p++;
798 }
799 else {
800 memmove(p,
801 p + 1,
802 strlen(p));
803 break;
804 }
805 }
806 else
807 p++;
808 }
809 if (*p) {
810 *p = 0;
811 p++;
812 }
813 else
814 p = pszPgm;
815 p[strlen(p) + 1] = 0; /* double-terminate args */
816 if (*pszPgm) {
817 if (!strchr(pszPgm, '\\') &&
818 !strchr(pszPgm, ':') &&
819 pszDirectory &&
820 *pszDirectory)
821 {
822 strcpy(szSavedir, pFM2SaveDirectory);
823 switch_to(pszDirectory);
824 }
825 rc = DosQueryAppType(pszPgm,&ulAppType);
826 if (!strchr(pszPgm, '\\') &&
827 !strchr(pszPgm, ':') &&
828 pszDirectory &&
829 *pszDirectory)
830 switch_to(szSavedir);
831 if (rc) {
832 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
833 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
834 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
835 DosFreeMem(pszPgm);
836 if (pszArgs)
837 DosFreeMem(pszArgs);
838 return -1;
839 }
840 if (ulAppType) {
841 if (ulAppType & FAPPTYP_DLL || ulAppType & FAPPTYP_VIRTDRV ||
842 ulAppType & FAPPTYP_PHYSDRV || ulAppType & FAPPTYP_PROTDLL)
843 {
844 Runtime_Error(pszSrcFile, __LINE__,
845 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
846 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
847 if (pszPgm)
848 DosFreeMem(pszPgm);
849 if (pszArgs)
850 DosFreeMem(pszArgs);
851 return -1;
852 }
853 if (ulAppType & FAPPTYP_DOS || ulAppType & FAPPTYP_WINDOWSREAL ||
854 ulAppType & FAPPTYP_WINDOWSPROT || ulAppType & FAPPTYP_WINDOWSPROT31)
855 {
856 Runtime_Error(pszSrcFile, __LINE__,
857 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
858 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
859 if (pszPgm)
860 DosFreeMem(pszPgm);
861 if (pszArgs)
862 DosFreeMem(pszArgs);
863 return -1;
864 }
865 }
866 memset(&results, 0, sizeof(results));
867 if (pszDirectory && *pszDirectory) {
868 strcpy(szSavedir, pFM2SaveDirectory);
869 switch_to(pszDirectory);
870 }
871 ret = DosExecPgm(szObject, sizeof(szObject),
872 ((type & RUNTYPE_MASK) == ASYNCHRONOUS ? EXEC_ASYNC : 0) +
873 ((type & RUNTYPE_MASK) == DETACHED ? EXEC_BACKGROUND : 0),
874 pszPgm, pszEnvironment, &results, pszPgm);
875 if (pszDirectory && *pszDirectory)
876 switch_to(szSavedir);
877 if (ret && !fNoErrorMsg) {
878 Dos_Error(MB_ENTER,ret,hwnd,pszSrcFile,__LINE__,
879 GetPString(IDS_DOSEXECPGMFAILEDTEXT), pszPgm,
880 pszCallingFile, uiLineNumber); // 26 May 08 SHL
881 }
882 }
883 }
884 else {
885 if (~type & FULLSCREEN)
886 type |= WINDOWED;
887 rc = DosAllocMem((PVOID) & pszArgs, MaxComLineStrg * 2,
888 PAG_COMMIT | PAG_READ | PAG_WRITE);
889 if (rc) {
890 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,GetPString(IDS_OUTOFMEMORY));
891 DosFreeMem(pszPgm);
892 return -1;
893 }
894 *pszArgs = 0;
895 memset(&sdata, 0, sizeof(sdata));
896 strip_lead_char(" \t", pszPgm);
897 p = pszPgm;
898 wasquote = FALSE;
899 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
900 if (*p == '\"') {
901 if (!wasquote) {
902 wasquote = TRUE;
903 memmove(p, p + 1, strlen(p));
904 while (*p == ' ' || *p == '\t')
905 p++;
906 }
907 else {
908 memmove(p, p + 1, strlen(p));
909 break;
910 }
911 }
912 else
913 p++;
914 } // while
915 if (*p) {
916 *p = 0;
917 p++;
918 }
919 else
920 p = NullStr;
921 if (*p)
922 strcpy(pszArgs, p);
923
924 p = strrchr(pszPgm, '.');
925 if (p) {
926 char temp[CCHMAXPATH + 1];
927
928 if (!stricmp(p, PCSZ_DOTBAT)) {
929 if (!fProtectOnly) {
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
939 saymsg(MB_OK,
940 HWND_DESKTOP,
941 NullStr,
942 GetPString(IDS_NOTPROTECTONLYEXE),
943 pszPgm);
944 }
945 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
946 // Assume 4OS2 is BTM
947 strcpy(temp, pszPgm);
948 strcpy(pszPgm, pszArgs);
949 strcpy(pszArgs, "/C ");
950 strcat(pszArgs, temp);
951 strcat(pszArgs, " ");
952 strcat(pszArgs, pszPgm);
953 strcpy(pszPgm, GetCmdSpec(FALSE)); // OS/2
954 }
955 }
956
957 // goddamned OS/2 limit
958
959 if (strlen(pszPgm) + strlen(pszArgs) > 1024)
960 pszArgs[1024 - strlen(pszPgm)] = 0;
961
962 if (!strchr(pszPgm, '\\') &&
963 !strchr(pszPgm, ':') &&
964 pszDirectory &&
965 *pszDirectory)
966 {
967 strcpy(szSavedir, pFM2SaveDirectory);
968 switch_to(pszDirectory);
969 }
970 rc = DosQueryAppType(pszPgm,&ulAppType);
971 if (!strchr(pszPgm, '\\') &&
972 !strchr(pszPgm, ':') &&
973 pszDirectory &&
974 *pszDirectory)
975 switch_to(szSavedir);
976 if (rc) {
977 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
978 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
979 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
980 DosFreeMem(pszPgm);
981 if (pszArgs)
982 DosFreeMem(pszArgs);
983 return -1;
984 }
985
986 if (ulAppType) {
987 if (ulAppType & (FAPPTYP_DLL | FAPPTYP_VIRTDRV | FAPPTYP_PHYSDRV | FAPPTYP_PROTDLL))
988 {
989 Runtime_Error(pszSrcFile, __LINE__,
990 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
991 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
992 DosFreeMem(pszPgm);
993 if (pszArgs)
994 DosFreeMem(pszArgs);
995 return -1;
996 }
997 ulAppType &= ~FAPPTYP_BOUND;
998 if (ulAppType & (FAPPTYP_DOS | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
999 {
1000 if (ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1001 {
1002 if (~type & FULLSCREEN &&
1003 ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1004 {
1005 ret = RunSeamless(pszPgm, pszArgs, hwnd);
1006 if (pszPgm)
1007 DosFreeMem(pszPgm);
1008 if (pszArgs)
1009 DosFreeMem(pszArgs);
1010 return ret ? 0 : -1;
1011 }
1012 else {
1013 strcat(pszPgm, " ");
1014 strcat(pszPgm, pszArgs);
1015 *pszArgs = 0;
1016 if (ulAppType & (FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT31))
1017 strcat(pszArgs, "/3 ");
1018 strcat(pszArgs, pszPgm);
1019 strcpy(pszPgm, "WINOS2.COM");
1020 }
1021 }
1022 else {
1023 if (~type & FULLSCREEN) {
1024 type |= WINDOWED;
1025 ulAppType = SSF_TYPE_WINDOWEDVDM;
1026 }
1027 else {
1028 type &= ~WINDOWED;
1029 ulAppType = SSF_TYPE_VDM;
1030 }
1031 }
1032 }
1033 else if (ulAppType & FAPPTYP_32BIT) {
1034 ulAppType &= ~FAPPTYP_32BIT;
1035 if (ulAppType == FAPPTYP_WINDOWAPI)
1036 ulAppType = SSF_TYPE_PM;
1037 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1038 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1039 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1040 ulAppType = SSF_TYPE_FULLSCREEN;
1041 type &= ~WINDOWED;
1042 type |= FULLSCREEN;
1043 }
1044 else /* ? */
1045 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1046 }
1047 else if (ulAppType == FAPPTYP_WINDOWAPI)
1048 ulAppType = SSF_TYPE_PM;
1049 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1050 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1051 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1052 type &= ~WINDOWED;
1053 ulAppType = SSF_TYPE_FULLSCREEN;
1054 }
1055 else
1056 ulAppType = SSF_TYPE_DEFAULT;
1057 if ((type & FULLSCREEN || ~type & WINDOWED) &&
1058 ulAppType == SSF_TYPE_WINDOWABLEVIO)
1059 {
1060 ulAppType = SSF_TYPE_FULLSCREEN;
1061 }
1062 // fixme parens?
1063 else if (type & FULLSCREEN ||
1064 (type & WINDOWED && ulAppType == SSF_TYPE_WINDOWEDVDM))
1065 {
1066 ulAppType = SSF_TYPE_VDM;
1067 }
1068 }
1069 if (ulAppType == SSF_TYPE_WINDOWEDVDM && type & SEPARATEKEEP) {
1070 type &= ~SEPARATEKEEP;
1071 type |= SEPARATE;
1072 }
1073
1074 DosGetInfoBlocks(&ptib, &ppib);
1075
1076 if (~type & WAIT)
1077 useTermQ = FALSE;
1078 else {
1079 rc = 0;
1080 DosEnterCritSec();
1081 if (!hTermQ) {
1082 // Create term queue and event semaphore just once
1083 sprintf(szTermQName, TERMQ_BASE_NAME "_%x", ppib->pib_ulpid);
1084 rc = DosCreateQueue(&hTermQ, QUE_FIFO | QUE_CONVERT_ADDRESS, szTermQName);
1085 if (rc) {
1086 hTermQ = (HQUEUE)0; // Try to survive
1087 DosExitCritSec();
1088 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosCreateQueue");
1089 }
1090 else {
1091 rc = DosCreateEventSem(NULL,(PHEV)&hTermQSem,0,FALSE);
1092 if (rc) {
1093 hTermQSem = (HEV)0; // Try to survive
1094 DosCloseQueue(hTermQ);
1095 hTermQ = (HQUEUE)0; // Try to survive
1096 DosExitCritSec();
1097 Dos_Error(MB_ENTER,rc,HWND_DESKTOP,pszSrcFile,__LINE__, PCSZ_DOSCREATEEVENTSEM);
1098 }
1099 // if (!rc) fprintf(stderr,"%s %d qcreated ptib %x hTermQ %x\n",__FILE__, __LINE__,ptib,hTermQ);
1100 }
1101 } // if 1st time
1102 useTermQ = hTermQ && hTermQSem;
1103 if (!rc)
1104 DosExitCritSec();
1105 } // if wait
1106
1107 memset(&sdata,0,sizeof(sdata));
1108 sdata.Length = sizeof(sdata);
1109 sdata.Related = type & (WAIT | CHILD) ? SSF_RELATED_CHILD :
1110 SSF_RELATED_INDEPENDENT;
1111 sdata.FgBg = type & BACKGROUND ? SSF_FGBG_BACK : SSF_FGBG_FORE;
1112 sdata.TraceOpt = SSF_TRACEOPT_NONE;
1113 sdata.PgmName = pszPgm;
1114 if (*pszArgs)
1115 sdata.PgmInputs = (PBYTE)pszArgs;
1116 if (useTermQ) {
1117 strcpy(szTermTemp, szTermQName);
1118 sdata.TermQ = (PBYTE)szTermTemp;
1119 }
1120 sdata.Environment = (PBYTE)pszEnvironment;
1121 sdata.InheritOpt = SSF_INHERTOPT_PARENT;
1122 sdata.SessionType = ulAppType;
1123 sdata.ObjectBuffer = szObject;
1124 sdata.ObjectBuffLen = sizeof(szObject);
1125 if ((type & RUNTYPE_MASK) == SEPARATEKEEP)
1126 sdata.PgmControl |= SSF_CONTROL_NOAUTOCLOSE;
1127 if (type & MAXIMIZED)
1128 sdata.PgmControl |= SSF_CONTROL_MAXIMIZE;
1129 if (type & MINIMIZED)
1130 sdata.PgmControl |= SSF_CONTROL_MINIMIZE;
1131 if (type & INVISIBLE)
1132 sdata.PgmControl |= SSF_CONTROL_INVISIBLE;
1133
1134 if (pszDirectory && *pszDirectory) {
1135 strcpy(szSavedir, pFM2SaveDirectory);
1136 switch_to(pszDirectory);
1137 }
1138 ret = DosStartSession(&sdata, &ulSessID, &sessPID);
1139
1140
1141 if (pszDirectory && *pszDirectory)
1142 switch_to(szSavedir);
1143
1144 if (ret && ret != ERROR_SMG_START_IN_BACKGROUND) {
1145 if (!fNoErrorMsg)
1146 Dos_Error(MB_CANCEL,ret,hwnd,pszSrcFile,__LINE__,
1147 GetPString(IDS_DOSSTARTSESSIONFAILEDTEXT),pszPgm,pszArgs,
1148 pszCallingFile, uiLineNumber); // 26 May 08 SHL
1149 }
1150 else if (type & WAIT) {
1151 if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1152 ShowSession(hwnd, sessPID);
1153
1154 if (!useTermQ) {
1155 STATUSDATA sd;
1156
1157 memset(&sd, 0, sizeof(sd));
1158 sd.Length = (USHORT) sizeof(sd);
1159 sd.SelectInd = SET_SESSION_UNCHANGED;
1160 sd.BondInd = SET_SESSION_UNCHANGED;
1161 for (ctr = 0;; ctr++)
1162 {
1163 DosSleep(50);//05 Aug 07 GKY 200
1164 if (DosSetSession(ulSessID, &sd)) // Check if session gone (i.e. finished)
1165 break;
1166 if (ctr > 10) {
1167 ShowSession(hwnd, sessPID); // Show every 2 seconds
1168 ctr = 0;
1169 }
1170 }
1171 }
1172 else {
1173 for (ctr = 0;; ctr++)
1174 {
1175 if (ctr < 20) {
1176 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1177 DCWW_NOWAIT, &bPriority, hTermQSem);
1178 if (rc == ERROR_QUE_EMPTY) {
1179 DosSleep(50);//05 Aug 07 GKY 100
1180 continue;
1181 }
1182 }
1183 else {
1184 if (ctr == 20) {
1185 ShowSession(hwnd, sessPID); // Show long running session
1186 }
1187 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1188 DCWW_WAIT, &bPriority, 0);
1189 }
1190
1191 if (rc) {
1192 // Oh heck
1193 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosReadQueue");
1194 DosSleep(100);//05 Aug 07 GKY 500
1195 continue;
1196 }
1197
1198 // printf("%s %d DosReadQueue thread 0x%x sess %u sessRC %u rq.pid 0x%x rq.data 0x%x\n",
1199 // __FILE__, __LINE__,ptib->tib_ordinal,pTermInfo->usSessID,pTermInfo->usRC,rq.pid, rq.ulData); fflush(stdout);
1200
1201 if (pTermInfo->usSessID == ulSessID)
1202 break; // Our session is done
1203
1204 // Requeue session for other thread
1205 {
1206 static ULONG ulLastSessID;
1207 // printf("%s %d requeue thread 0x%x our sess %u term sess %u term rc %u\n",
1208 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID,pTermInfo->usSessID,pTermInfo->usRC); fflush(stdout);
1209 // fixme to be gone when no longer needed for debug?
1210 if (ulLastSessID) {
1211 DosSleep(100);//05 Aug 07 GKY 500
1212 ulLastSessID = pTermInfo->usSessID;
1213 }
1214 // requeue term report for other thread and do not free yet
1215 rc = DosWriteQueue(hTermQ, rq.ulData, ulLength,(PVOID)pTermInfo, bPriority);
1216 if (rc)
1217 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosWriteQueue");
1218 DosSleep(50); //05 Aug 07 GKY 100 // Let other thread see queue entry
1219 }
1220 } // for
1221
1222 ret = pTermInfo->usRC == 0; // Set 1 if rc 0 else 0
1223 // printf("%s %d thread 0x%x term for sess %u\n",
1224 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID);fflush(stdout);
1225 DosFreeMem(pTermInfo);
1226 }
1227 } // if wait
1228 else if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1229 ShowSession(hwnd, sessPID);
1230 }
1231 }
1232
1233ObjectInterrupt:
1234
1235 if (pszPgm)
1236 DosFreeMem(pszPgm);
1237 if (pszArgs)
1238 DosFreeMem(pszArgs);
1239
1240 return ret;
1241}
1242
1243//== Exec() Start application with WinStartApp ==
1244#if 0 // JBS 11 Sep 08
1245HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
1246 PROGTYPE *progt, ULONG fl, char *formatstring,...)
1247{
1248 PROGDETAILS pgd;
1249 register char *p;
1250 char *parameters = NULL, *executable = NULL;
1251 HAPP happ = (HAPP)0;
1252 ULONG ulOptions = SAF_INSTALLEDCMDLINE;
1253 BOOL wasquote;
1254 va_list parguments;
1255
1256 if (child)
1257 ulOptions |= SAF_STARTCHILDAPP;
1258
1259 executable = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1260 if (executable) {
1261 va_start(parguments, formatstring);
1262 vsprintf(executable, formatstring, parguments);
1263 va_end(parguments);
1264 strip_lead_char(" \t", executable);
1265 if (*executable) {
1266 parameters = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
1267 if (parameters) {
1268 p = executable;
1269 wasquote = FALSE;
1270 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
1271 if (*p == '\"') {
1272 if (!wasquote) {
1273 wasquote = TRUE;
1274 memmove(p, p + 1, strlen(p));
1275 while (*p == ' ' || *p == '\t')
1276 p++;
1277 }
1278 else {
1279 memmove(p, p + 1, strlen(p));
1280 break;
1281 }
1282 }
1283 else
1284 p++;
1285 }
1286 if (*p) {
1287 *p = 0;
1288 p++;
1289 }
1290 else
1291 p = NullStr;
1292 if (*p)
1293 strcpy(parameters, p);
1294
1295 if (p && (!stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTCMD) ||
1296 !stricmp(p, PCSZ_DOTBTM))) {
1297 char *temp;
1298
1299 temp = xmalloc(CCHMAXPATH * 2,pszSrcFile,__LINE__);
1300 if (temp) {
1301 if (!stricmp(p, PCSZ_DOTBAT)) {
1302 if (!fProtectOnly) {
1303 strcpy(temp, executable);
1304 strcpy(executable, parameters);
1305 strcpy(parameters, "/C ");
1306 strcat(parameters, temp);
1307 strcat(parameters, " ");
1308 strcat(parameters, executable);
1309 strcpy(executable, GetCmdSpec(TRUE)); //DOS
1310 }
1311 else
1312 saymsg(MB_OK,
1313 HWND_DESKTOP,
1314 NullStr,
1315 GetPString(IDS_NOTPROTECTONLYEXE),
1316 filename);
1317 }
1318 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1319 strcpy(temp, executable);
1320 strcpy(executable, parameters);
1321 strcpy(parameters, "/C ");
1322 strcat(parameters, temp);
1323 strcat(parameters, " ");
1324 strcat(parameters, executable);
1325 strcpy(executable, GetCmdSpec(FALSE));
1326 }
1327 free(temp);
1328 }
1329 }
1330
1331 memset(&pgd, 0, sizeof(pgd));
1332 pgd.Length = sizeof(pgd);
1333 pgd.progt = *progt;
1334 pgd.swpInitial.fl = fl;
1335 pgd.pszEnvironment = env;
1336 pgd.pszStartupDir = startdir;
1337 pgd.pszParameters = *parameters ? parameters : NULL;
1338 pgd.pszExecutable = executable;
1339 pgd.swpInitial.hwndInsertBehind = HWND_TOP;
1340 happ = WinStartApp(hwndNotify, &pgd, NULL, NULL, ulOptions);
1341 free(parameters);
1342 }
1343 }
1344 free(executable);
1345 }
1346 return happ;
1347}
1348#endif
1349#pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2)
Note: See TracBrowser for help on using the repository browser.