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