source: trunk/dll/systemf.c@ 1880

Last change on this file since 1880 was 1880, checked in by Gregg Young, 10 years ago

Remove dead code and comments from remaining c files. #if 0 and #if NEVER were not addressed

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