source: trunk/dll/systemf.c@ 917

Last change on this file since 917 was 917, checked in by Steven Levine, 18 years ago

Correct/enhance settings notebook navigation, ticket #188 (Steven)
Reopen settings notebook to last selected page unless overridden, ticket #188 (Steven)
More Compare Directory overflow tweaks (Steven)

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