source: trunk/dll/systemf.c@ 909

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

Added quoting code to commands, associations and avv; Minor clean up and fixed one problem with quoting logic; Added warning re %a for commands to work on selected files.

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