source: trunk/dll/systemf.c@ 1421

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

Remove variable aurgs from docopy & unlinkf (not used); Move more strings to PCSZs and string table; Move PCSZs to compile time initialization; Fix hang on startup caused by a drive scan and a dircnr scan trying to update a drive in the tree at the same time (related to the "treeswitch options); Code cleanup mainly removal of old printfs, SayMsgs, DbgMsg and unneeded %s.

  • 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 1402 2009-03-14 17:17:59Z gyoung $
5
6 System Interfaces
7
8 Copyright (c) 1993-98 M. Kimes
9 Copyright (c) 2003, 2009 Steven H.Levine
10
11 21 Nov 03 SHL Comments
12 31 Jul 04 SHL Indent -i2
13 01 Aug 04 SHL Rework lstrip/rstrip usage
14 17 Jul 06 SHL Use Runtime_Error
15 26 Jul 06 SHL Use convert_nl_to_nul
16 15 Aug 06 SHL More error popups
17 01 Nov 06 SHL runemf2: temp fix for hung windows caused by termq errors
18 03 Nov 06 SHL runemf2: rework termination queue logic to work for multiple threads
19 07 Jan 07 GKY Move error strings etc. to string file
20 06 Aug 07 GKY Reduce DosSleep times (ticket 148)
21 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
22 29 Feb 08 GKY Changes to enable user settable command line length
23 29 Feb 08 GKY Refactor global command line variables to notebook.h
24 26 May 08 SHL Use uiLineNumber correctly
25 19 Jul 08 GKY Replace save_dir2(dir) with pFM2SaveDirectory or pTmpDir and use MakeTempName
26 03 Jan 09 GKY Check for system that is protectonly to gray out Dos/Win command lines and prevent
27 Dos/Win programs from being inserted into the execute dialog with message why.
28
29***********************************************************************/
30
31#include <stdlib.h>
32#include <stdarg.h>
33#include <string.h>
34#include <ctype.h>
35
36#define INCL_DOS
37#define INCL_DOSERRORS
38#define INCL_WIN
39#define INCL_LONGLONG // dircnrs.h
40
41#include "fm3dll.h"
42#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
43#include "mkdir.h" // Data declaration(s)
44#include "init.h" // Data declaration(s)
45#include "mainwnd.h" // Data declaration(s)
46#include "fm3dlg.h"
47#include "fm3str.h"
48#include "errutil.h" // Dos_Error...
49#include "strutil.h" // GetPString
50#include "notebook.h" //targetdirectory
51#include "pathutil.h"
52#include "cmdline.h" // CmdLineDlgProc
53#include "shadow.h" // RunSeamless
54#include "systemf.h"
55#include "strips.h" // convert_nl_to_nul, strip_lead_char
56#include "dirs.h" // switch_to
57#include "valid.h" // MakeFullName
58#include "misc.h" // GetCmdSpec
59#include "copyf.h" // MakeTempName
60#include "wrappers.h" // xfopen
61#include "fortify.h"
62
63static PSZ pszSrcFile = __FILE__;
64
65//static HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
66// PROGTYPE * progt, ULONG fl, char *formatstring, ...);
67
68/**
69 * Bring session foreground
70 * @return TRUE if OK, else FALSE
71 */
72
73BOOL ShowSession(HWND hwnd, PID pid)
74{
75 HSWITCH hswitch;
76 SWCNTRL swctl;
77 ULONG rc;
78
79 hswitch = WinQuerySwitchHandle(pid ? (HWND)0 : hwnd, pid);
80 if (hswitch) {
81 rc = WinQuerySwitchEntry(hswitch, &swctl);
82 if (!rc) {
83 if (swctl.idProcess == pid && swctl.uchVisibility == SWL_VISIBLE)
84 rc = WinSwitchToProgram(hswitch);
85 if (!rc)
86 return TRUE;
87 }
88 }
89 return FALSE;
90}
91
92/**
93 * Invoke runemf2 for command and file/directory list
94 * @return command return code or
95 * -1 if runtime error or
96 * -2 if user cancels command line edit dialog
97 */
98
99int ExecOnList(HWND hwnd, char *command, int flags, char *tpath,
100 PSZ *list, PCSZ prompt, PCSZ pszCallingFile, UINT uiLineNumber)
101{
102 /* executes the command once for all files in list */
103
104 CHAR path[CCHMAXPATH], *commandline, modpath[CCHMAXPATH], listfile[CCHMAXPATH],
105 *p, *pp, drive, *file, *ext, *dot;
106 register int x;
107 BOOL spaces;
108
109 if (!command || !*command) {
110 Runtime_Error(pszSrcFile, __LINE__, NULL);
111 return -1;
112 }
113 commandline = xmalloc(MaxComLineStrg + 1, pszSrcFile, __LINE__);
114 if (!commandline)
115 return -1; //already complained
116 *listfile = 0;
117 bstrip(command);
118
119 *path = 0;
120 if (tpath && *tpath)
121 strcpy(path, tpath);
122 else if (*command != '<' || !strchr(command, '>')) {
123 strcpy(path, command + (*command == '"'));
124 if (*command == '\"')
125 p = strchr(path, '\"');
126 else
127 p = strchr(path, ' ');
128 if (p)
129 *p = 0;
130 p = strrchr(path, '\\');
131 if (!p)
132 p = strrchr(path, ':');
133 if (p) {
134 if (*p == ':') {
135 p++;
136 *p = '\\';
137 p++;
138 }
139 *p = 0;
140 }
141 else
142 *path = 0;
143 }
144 if (!*path) {
145 if (list && list[0])
146 strcpy(path, list[0]);
147 p = strrchr(path, '\\');
148 if (!p)
149 p = strrchr(path, ':');
150 if (p) {
151 if (*p == ':') {
152 p++;
153 *p = '\\';
154 p++;
155 }
156 *p = 0;
157 }
158 else
159 *path = 0;
160 }
161 *modpath = 0;
162 if (list && list[0])
163 strcpy(modpath, list[0]);
164 p = strrchr(modpath, '\\');
165 if (!p)
166 p = strrchr(modpath, ':');
167 if (p) {
168 if (*p == ':') {
169 p++;
170 *p = '\\';
171 p++;
172 }
173 *p = 0;
174 }
175 else
176 *modpath = 0;
177 if (!*modpath)
178 strcpy(modpath, path);
179 if (*path)
180 MakeFullName(path);
181 if (*modpath)
182 MakeFullName(modpath);
183 if (IsFullName(path))
184 drive = toupper(*path);
185 else
186 drive = 0;
187
188 p = command; // substitue for special % sequences
189
190 pp = commandline;
191 *commandline = 0;
192 while (*p) {
193 if (*p == '%') {
194 switch (*(p + 1)) {
195 case '!': /* write list to file, add filename */
196 if (list) {
197 if (!*listfile) {
198 FILE *fp;
199
200
201 strcpy(listfile, pTmpDir ? pTmpDir : pFM2SaveDirectory);
202 MakeTempName(listfile, "$FM2LI$T", 2);
203 /*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_Error(pszSrcFile, __LINE__, NULL);
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, PCSZ_DOTBAT)) {
930 if (!fProtectOnly) {
931 strcpy(temp, pszPgm);
932 strcpy(pszPgm, pszArgs);
933 strcpy(pszArgs, "/C ");
934 strcat(pszArgs, temp);
935 strcat(pszArgs, " ");
936 strcat(pszArgs, pszPgm);
937 strcpy(pszPgm, GetCmdSpec(TRUE)); // DOS
938 }
939 else
940 saymsg(MB_OK,
941 HWND_DESKTOP,
942 NullStr,
943 GetPString(IDS_NOTPROTECTONLYEXE),
944 pszPgm);
945 }
946 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
947 // Assume 4OS2 is BTM
948 strcpy(temp, pszPgm);
949 strcpy(pszPgm, pszArgs);
950 strcpy(pszArgs, "/C ");
951 strcat(pszArgs, temp);
952 strcat(pszArgs, " ");
953 strcat(pszArgs, pszPgm);
954 strcpy(pszPgm, GetCmdSpec(FALSE)); // OS/2
955 }
956 }
957
958 // goddamned OS/2 limit
959
960 if (strlen(pszPgm) + strlen(pszArgs) > 1024)
961 pszArgs[1024 - strlen(pszPgm)] = 0;
962
963 if (!strchr(pszPgm, '\\') &&
964 !strchr(pszPgm, ':') &&
965 pszDirectory &&
966 *pszDirectory)
967 {
968 strcpy(szSavedir, pFM2SaveDirectory);
969 switch_to(pszDirectory);
970 }
971 rc = DosQueryAppType(pszPgm,&ulAppType);
972 if (!strchr(pszPgm, '\\') &&
973 !strchr(pszPgm, ':') &&
974 pszDirectory &&
975 *pszDirectory)
976 switch_to(szSavedir);
977 if (rc) {
978 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,
979 GetPString(IDS_DOSQAPPTYPEFAILEDTEXT),
980 pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
981 DosFreeMem(pszPgm);
982 if (pszArgs)
983 DosFreeMem(pszArgs);
984 return -1;
985 }
986
987 if (ulAppType) {
988 if (ulAppType & (FAPPTYP_DLL | FAPPTYP_VIRTDRV | FAPPTYP_PHYSDRV | FAPPTYP_PROTDLL))
989 {
990 Runtime_Error(pszSrcFile, __LINE__,
991 GetPString(IDS_APPTYPEUNEXPECTEDTEXT),
992 ulAppType, pszPgm, pszCallingFile, uiLineNumber); // 26 May 08 SHL
993 DosFreeMem(pszPgm);
994 if (pszArgs)
995 DosFreeMem(pszArgs);
996 return -1;
997 }
998 ulAppType &= ~FAPPTYP_BOUND;
999 if (ulAppType & (FAPPTYP_DOS | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1000 {
1001 if (ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1002 {
1003 if (~type & FULLSCREEN &&
1004 ulAppType & (FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSPROT31))
1005 {
1006 ret = RunSeamless(pszPgm, pszArgs, hwnd);
1007 if (pszPgm)
1008 DosFreeMem(pszPgm);
1009 if (pszArgs)
1010 DosFreeMem(pszArgs);
1011 return ret ? 0 : -1;
1012 }
1013 else {
1014 strcat(pszPgm, " ");
1015 strcat(pszPgm, pszArgs);
1016 *pszArgs = 0;
1017 if (ulAppType & (FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL | FAPPTYP_WINDOWSPROT31))
1018 strcat(pszArgs, "/3 ");
1019 strcat(pszArgs, pszPgm);
1020 strcpy(pszPgm, "WINOS2.COM");
1021 }
1022 }
1023 else {
1024 if (~type & FULLSCREEN) {
1025 type |= WINDOWED;
1026 ulAppType = SSF_TYPE_WINDOWEDVDM;
1027 }
1028 else {
1029 type &= ~WINDOWED;
1030 ulAppType = SSF_TYPE_VDM;
1031 }
1032 }
1033 }
1034 else if (ulAppType & FAPPTYP_32BIT) {
1035 ulAppType &= ~FAPPTYP_32BIT;
1036 if (ulAppType == FAPPTYP_WINDOWAPI)
1037 ulAppType = SSF_TYPE_PM;
1038 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1039 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1040 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1041 ulAppType = SSF_TYPE_FULLSCREEN;
1042 type &= ~WINDOWED;
1043 type |= FULLSCREEN;
1044 }
1045 else /* ? */
1046 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1047 }
1048 else if (ulAppType == FAPPTYP_WINDOWAPI)
1049 ulAppType = SSF_TYPE_PM;
1050 else if (ulAppType == FAPPTYP_WINDOWCOMPAT)
1051 ulAppType = SSF_TYPE_WINDOWABLEVIO;
1052 else if (ulAppType == FAPPTYP_NOTWINDOWCOMPAT) {
1053 type &= ~WINDOWED;
1054 ulAppType = SSF_TYPE_FULLSCREEN;
1055 }
1056 else
1057 ulAppType = SSF_TYPE_DEFAULT;
1058 if ((type & FULLSCREEN || ~type & WINDOWED) &&
1059 ulAppType == SSF_TYPE_WINDOWABLEVIO)
1060 {
1061 ulAppType = SSF_TYPE_FULLSCREEN;
1062 }
1063 // fixme parens?
1064 else if (type & FULLSCREEN ||
1065 (type & WINDOWED && ulAppType == SSF_TYPE_WINDOWEDVDM))
1066 {
1067 ulAppType = SSF_TYPE_VDM;
1068 }
1069 }
1070 if (ulAppType == SSF_TYPE_WINDOWEDVDM && type & SEPARATEKEEP) {
1071 type &= ~SEPARATEKEEP;
1072 type |= SEPARATE;
1073 }
1074
1075 DosGetInfoBlocks(&ptib, &ppib);
1076
1077 if (~type & WAIT)
1078 useTermQ = FALSE;
1079 else {
1080 rc = 0;
1081 DosEnterCritSec();
1082 if (!hTermQ) {
1083 // Create term queue and event semaphore just once
1084 sprintf(szTermQName, TERMQ_BASE_NAME "_%x", ppib->pib_ulpid);
1085 rc = DosCreateQueue(&hTermQ, QUE_FIFO | QUE_CONVERT_ADDRESS, szTermQName);
1086 if (rc) {
1087 hTermQ = (HQUEUE)0; // Try to survive
1088 DosExitCritSec();
1089 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosCreateQueue");
1090 }
1091 else {
1092 rc = DosCreateEventSem(NULL,(PHEV)&hTermQSem,0,FALSE);
1093 if (rc) {
1094 hTermQSem = (HEV)0; // Try to survive
1095 DosCloseQueue(hTermQ);
1096 hTermQ = (HQUEUE)0; // Try to survive
1097 DosExitCritSec();
1098 Dos_Error(MB_ENTER,rc,HWND_DESKTOP,pszSrcFile,__LINE__,"DoCreateEventSem");
1099 }
1100 // if (!rc) fprintf(stderr,"%s %d qcreated ptib %x hTermQ %x\n",__FILE__, __LINE__,ptib,hTermQ);
1101 }
1102 } // if 1st time
1103 useTermQ = hTermQ && hTermQSem;
1104 if (!rc)
1105 DosExitCritSec();
1106 } // if wait
1107
1108 memset(&sdata,0,sizeof(sdata));
1109 sdata.Length = sizeof(sdata);
1110 sdata.Related = type & (WAIT | CHILD) ? SSF_RELATED_CHILD :
1111 SSF_RELATED_INDEPENDENT;
1112 sdata.FgBg = type & BACKGROUND ? SSF_FGBG_BACK : SSF_FGBG_FORE;
1113 sdata.TraceOpt = SSF_TRACEOPT_NONE;
1114 sdata.PgmName = pszPgm;
1115 if (*pszArgs)
1116 sdata.PgmInputs = (PBYTE)pszArgs;
1117 if (useTermQ)
1118 sdata.TermQ = (PBYTE)szTermQName;
1119 sdata.Environment = (PBYTE)pszEnvironment;
1120 sdata.InheritOpt = SSF_INHERTOPT_PARENT;
1121 sdata.SessionType = ulAppType;
1122 sdata.ObjectBuffer = szObject;
1123 sdata.ObjectBuffLen = sizeof(szObject);
1124 if ((type & RUNTYPE_MASK) == SEPARATEKEEP)
1125 sdata.PgmControl |= SSF_CONTROL_NOAUTOCLOSE;
1126 if (type & MAXIMIZED)
1127 sdata.PgmControl |= SSF_CONTROL_MAXIMIZE;
1128 if (type & MINIMIZED)
1129 sdata.PgmControl |= SSF_CONTROL_MINIMIZE;
1130 if (type & INVISIBLE)
1131 sdata.PgmControl |= SSF_CONTROL_INVISIBLE;
1132
1133 if (pszDirectory && *pszDirectory) {
1134 strcpy(szSavedir, pFM2SaveDirectory);
1135 switch_to(pszDirectory);
1136 }
1137 ret = DosStartSession(&sdata, &ulSessID, &sessPID);
1138
1139
1140 if (pszDirectory && *pszDirectory)
1141 switch_to(szSavedir);
1142
1143 if (ret && ret != ERROR_SMG_START_IN_BACKGROUND) {
1144 if (!fNoErrorMsg)
1145 Dos_Error(MB_CANCEL,ret,hwnd,pszSrcFile,__LINE__,
1146 GetPString(IDS_DOSSTARTSESSIONFAILEDTEXT),pszPgm,pszArgs,
1147 pszCallingFile, uiLineNumber); // 26 May 08 SHL
1148 }
1149 else if (type & WAIT) {
1150 if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1151 ShowSession(hwnd, sessPID);
1152
1153 if (!useTermQ) {
1154 STATUSDATA sd;
1155
1156 memset(&sd, 0, sizeof(sd));
1157 sd.Length = (USHORT) sizeof(sd);
1158 sd.SelectInd = SET_SESSION_UNCHANGED;
1159 sd.BondInd = SET_SESSION_UNCHANGED;
1160 for (ctr = 0;; ctr++)
1161 {
1162 DosSleep(100);//05 Aug 07 GKY 200
1163 if (DosSetSession(ulSessID, &sd)) // Check if session gone (i.e. finished)
1164 break;
1165 if (ctr > 10) {
1166 ShowSession(hwnd, sessPID); // Show every 2 seconds
1167 ctr = 0;
1168 }
1169 }
1170 }
1171 else {
1172 for (ctr = 0;; ctr++)
1173 {
1174 if (ctr < 20) {
1175 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1176 DCWW_NOWAIT, &bPriority, hTermQSem);
1177 if (rc == ERROR_QUE_EMPTY) {
1178 DosSleep(50);//05 Aug 07 GKY 100
1179 continue;
1180 }
1181 }
1182 else {
1183 if (ctr == 20) {
1184 ShowSession(hwnd, sessPID); // Show long running session
1185 }
1186 rc = DosReadQueue(hTermQ, &rq, &ulLength, (PPVOID)&pTermInfo, 0,
1187 DCWW_WAIT, &bPriority, 0);
1188 }
1189
1190 if (rc) {
1191 // Oh heck
1192 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosReadQueue");
1193 DosSleep(100);//05 Aug 07 GKY 500
1194 continue;
1195 }
1196
1197 // printf("%s %d DosReadQueue thread 0x%x sess %u sessRC %u rq.pid 0x%x rq.data 0x%x\n",
1198 // __FILE__, __LINE__,ptib->tib_ordinal,pTermInfo->usSessID,pTermInfo->usRC,rq.pid, rq.ulData); fflush(stdout);
1199
1200 if (pTermInfo->usSessID == ulSessID)
1201 break; // Our session is done
1202
1203 // Requeue session for other thread
1204 {
1205 static ULONG ulLastSessID;
1206 // printf("%s %d requeue thread 0x%x our sess %u term sess %u term rc %u\n",
1207 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID,pTermInfo->usSessID,pTermInfo->usRC); fflush(stdout);
1208 // fixme to be gone when no longer needed for debug?
1209 if (ulLastSessID) {
1210 DosSleep(100);//05 Aug 07 GKY 500
1211 ulLastSessID = pTermInfo->usSessID;
1212 }
1213 // requeue term report for other thread and do not free yet
1214 rc = DosWriteQueue(hTermQ, rq.ulData, ulLength,(PVOID)pTermInfo, bPriority);
1215 if (rc)
1216 Dos_Error(MB_CANCEL,rc,hwnd,pszSrcFile,__LINE__,"DosWriteQueue");
1217 DosSleep(50); //05 Aug 07 GKY 100 // Let other thread see queue entry
1218 }
1219 } // for
1220
1221 ret = pTermInfo->usRC == 0; // Set 1 if rc 0 else 0
1222 // printf("%s %d thread 0x%x term for sess %u\n",
1223 // __FILE__, __LINE__,ptib->tib_ordinal,ulSessID);fflush(stdout);
1224 DosFreeMem(pTermInfo);
1225 }
1226 } // if wait
1227 else if (!(type & (BACKGROUND | MINIMIZED | INVISIBLE)))
1228 ShowSession(hwnd, sessPID);
1229 }
1230 }
1231
1232ObjectInterrupt:
1233
1234 if (pszPgm)
1235 DosFreeMem(pszPgm);
1236 if (pszArgs)
1237 DosFreeMem(pszArgs);
1238
1239 return ret;
1240}
1241
1242//== Exec() Start application with WinStartApp ==
1243#if 0 // JBS 11 Sep 08
1244HAPP Exec(HWND hwndNotify, BOOL child, char *startdir, char *env,
1245 PROGTYPE *progt, ULONG fl, char *formatstring,...)
1246{
1247 PROGDETAILS pgd;
1248 register char *p;
1249 char *parameters = NULL, *executable = NULL;
1250 HAPP happ = (HAPP)0;
1251 ULONG ulOptions = SAF_INSTALLEDCMDLINE;
1252 BOOL wasquote;
1253 va_list parguments;
1254
1255 if (child)
1256 ulOptions |= SAF_STARTCHILDAPP;
1257
1258 executable = xmallocz(MaxComLineStrg, pszSrcFile, __LINE__);
1259 if (executable) {
1260 va_start(parguments, formatstring);
1261 vsprintf(executable, formatstring, parguments);
1262 va_end(parguments);
1263 strip_lead_char(" \t", executable);
1264 if (*executable) {
1265 parameters = xmalloc(MaxComLineStrg, pszSrcFile, __LINE__);
1266 if (parameters) {
1267 p = executable;
1268 wasquote = FALSE;
1269 while (*p && (wasquote || (*p != ' ' && *p != '\t'))) {
1270 if (*p == '\"') {
1271 if (!wasquote) {
1272 wasquote = TRUE;
1273 memmove(p, p + 1, strlen(p));
1274 while (*p == ' ' || *p == '\t')
1275 p++;
1276 }
1277 else {
1278 memmove(p, p + 1, strlen(p));
1279 break;
1280 }
1281 }
1282 else
1283 p++;
1284 }
1285 if (*p) {
1286 *p = 0;
1287 p++;
1288 }
1289 else
1290 p = NullStr;
1291 if (*p)
1292 strcpy(parameters, p);
1293
1294 if (p && (!stricmp(p, PCSZ_DOTBAT) || !stricmp(p, PCSZ_DOTCMD) ||
1295 !stricmp(p, PCSZ_DOTBTM))) {
1296 char *temp;
1297
1298 temp = xmalloc(CCHMAXPATH * 2,pszSrcFile,__LINE__);
1299 if (temp) {
1300 if (!stricmp(p, PCSZ_DOTBAT)) {
1301 if (!fProtectOnly) {
1302 strcpy(temp, executable);
1303 strcpy(executable, parameters);
1304 strcpy(parameters, "/C ");
1305 strcat(parameters, temp);
1306 strcat(parameters, " ");
1307 strcat(parameters, executable);
1308 strcpy(executable, GetCmdSpec(TRUE));
1309 }
1310 else
1311 saymsg(MB_OK,
1312 HWND_DESKTOP,
1313 NullStr,
1314 GetPString(IDS_NOTPROTECTONLYEXE),
1315 filename);
1316 }
1317 else if (!stricmp(p, PCSZ_DOTCMD) || !stricmp(p, PCSZ_DOTBTM)) {
1318 strcpy(temp, executable);
1319 strcpy(executable, parameters);
1320 strcpy(parameters, "/C ");
1321 strcat(parameters, temp);
1322 strcat(parameters, " ");
1323 strcat(parameters, executable);
1324 strcpy(executable, GetCmdSpec(FALSE));
1325 }
1326 free(temp);
1327 }
1328 }
1329
1330 memset(&pgd, 0, sizeof(pgd));
1331 pgd.Length = sizeof(pgd);
1332 pgd.progt = *progt;
1333 pgd.swpInitial.fl = fl;
1334 pgd.pszEnvironment = env;
1335 pgd.pszStartupDir = startdir;
1336 pgd.pszParameters = *parameters ? parameters : NULL;
1337 pgd.pszExecutable = executable;
1338 pgd.swpInitial.hwndInsertBehind = HWND_TOP;
1339 happ = WinStartApp(hwndNotify, &pgd, NULL, NULL, ulOptions);
1340 free(parameters);
1341 }
1342 }
1343 free(executable);
1344 }
1345 return happ;
1346}
1347#endif
1348#pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2)
Note: See TracBrowser for help on using the repository browser.