source: trunk/dll/systemf.c@ 1742

Last change on this file since 1742 was 1742, checked in by Gregg Young, 11 years ago

Undated one of the error messages in runemf2 to provide the calling line and file. Ticket [521]

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