source: trunk/dll/systemf.c@ 1554

Last change on this file since 1554 was 1554, checked in by Gregg Young, 15 years ago

Check that pTmpDir IsValid and recreate if not found; Fixes hangs caused by temp file creation failures. (Ticket 440)

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