source: trunk/dll/systemf.c@ 918

Last change on this file since 918 was 918, checked in by Gregg Young, 18 years ago

Fix CheckApp_QuoteAddExe to return a pointer on the stack instead of a string. Use MAXCOMLINESTRG for command line length.

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