source: trunk/dll/systemf.c@ 907

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

Avoid out of memory traps in Compare Directories
Rework Compare Directories progress display for 2 second update rate
Start refactoring to reduce dependence on fm3dll.h
Add timer services (IsITimerExpired etc.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.8 KB
RevLine 
[78]1
2/***********************************************************************
3
4 $Id: systemf.c 907 2008-01-06 07:26:17Z stevenhl $
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{
1311 char szTempPgm[CCHMAXPATH], tempcom[CCHMAXPATH], temparg[CCHMAXPATH];
1312 char *offset, *offsetexe, *offsetcom, *offsetcmd, *offsetbtm, *offsetbat;
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");
1330 if (offsetbat){
1331 if (strstr(strlwr(pszPgm), "command ") < offsetbat)
1332 offset = pszPgm;
1333 else
1334 offset = offsetbat;
1335 }
1336 else if (offsetbtm){
1337 if (strstr(strlwr(pszPgm), "4os2 ") < offsetbtm)
1338 offset = pszPgm;
1339 else
1340 offset = offsetbtm;
1341 }
1342 else if (offsetcmd){
1343 if (strstr(strlwr(pszPgm), "cmd ") < offsetcmd ||
1344 strstr(strlwr(pszPgm), "4os2 ") < offsetcmd)
1345 offset = pszPgm;
1346 else
1347 offset = offsetcmd;
1348 }
1349 else if (offsetcom)
1350 offset = offsetcom;
1351 else if (offsetexe)
1352 offset = offsetexe;
1353 else {
1354 offset = pszPgm;
1355 }
1356 if (offset - pszPgm != 0){
1357 tempcom[offset + 4 - pszPgm] = '\0';
1358 strcpy(temparg, &pszPgm[offset + 4 - pszPgm]);
1359 /*if ((offsetexe && !offsetcom && !offsetcmd && !offsetbtm && !offsetbat) ||
1360 (offsetcom && !offsetexe && !offsetcmd && !offsetbtm && !offsetbat) ||
1361 (offsetcmd && !offsetexe && !offsetcom && !offsetbtm && !offsetbat) ||
1362 (offsetbtm && !offsetexe && !offsetcom && !offsetcmd && !offsetbat) ||
1363 (offsetbat && !offsetexe && !offsetcom && !offsetcmd && !offsetbtm))*/
1364 remove_first_occurence_of_character("\"", tempcom);
1365 if (strchr(tempcom, '\"') != strrchr(tempcom, '\"'))
1366 saymsg(MB_OK, HWND_DESKTOP,
1367 NullStr,
1368 GetPString(IDS_QUOTESINARGSTEXT),
1369 pszPgm);
1370 else
1371 remove_first_occurence_of_character("\"", tempcom);
1372 if ((temparg[0] == '\"' && temparg[1] == ' ') ||
1373 !strstr(pszPgm, "\\:")||
1374 strchr(temparg, '\"') == strrchr(temparg, '\"'))
1375 remove_first_occurence_of_character("\"", temparg);
1376 if (strchr(temparg, '\"') != strrchr(temparg, '\"'))
1377 saymsg(MB_OK, HWND_DESKTOP,
1378 NullStr,
1379 GetPString(IDS_QUOTESINARGSTEXT),
1380 pszPgm);
1381 if (!strstr(strlwr(tempcom), ".exe")) {
1382 ret = DosFindFirst(tempcom, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
1383 ulResultBufLen, &ulFindCount, FIL_STANDARD);
1384 BldQuotedFileName(szTempPgm, tempcom);
1385 }
1386 else{
1387 BldQuotedFileName(szTempPgm, tempcom);
1388 ret = DosQueryAppType(tempcom, &ulAppType);
1389 }
1390 //printf("%d A", ret); fflush(stdout);
1391 if (ret) {
1392 ret = saymsg(MB_YESNO,
1393 HWND_DESKTOP,
1394 NullStr,
1395 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
1396 pszPgm);
1397 if (ret == MBID_YES){
1398 if (temparg[0] != ' ')
1399 strcat(szTempPgm, " ");
1400 strcat(szTempPgm, temparg);
1401 pszQuotedCompletePgm = szTempPgm;
1402 }
1403 else{
1404 fCancelAction = TRUE;
1405 pszQuotedCompletePgm = pszPgm;
1406 }
1407 }
1408 else{
1409 if (temparg[0] != ' ')
1410 strcat(szTempPgm, " ");
1411 strcat(szTempPgm, temparg);
1412 pszQuotedCompletePgm = szTempPgm;
1413 }
1414
1415 }
1416 else if (tempcom && (!strchr(tempcom, '.') ||
1417 strrchr(tempcom, '.' ) < strrchr(tempcom, '\\'))){
1418 if (!strchr(tempcom, ' ')){
1419 while (strchr(tempcom, '\"'))
1420 remove_first_occurence_of_character("\"", tempcom);
1421 strcat(tempcom, ".exe");
1422 ret = DosFindFirst(tempcom, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
1423 ulResultBufLen, &ulFindCount, FIL_STANDARD);
1424 //printf("%d", ret); fflush(stdout);
1425 }
1426 else{
1427 pszChar = tempcom;
1428 while (pszChar){
1429 while (strchr(tempcom, '\"'))
1430 remove_first_occurence_of_character("\"", tempcom);
1431 if (*pszChar == ' '){
1432 *pszChar = '\0';
1433 strcat(tempcom, ".exe");
1434 ret = DosQueryAppType(tempcom, &ulAppType);
1435 //printf("%d %s\n", ret, tempcom); fflush(stdout);
1436 if (!ret){
1437 break;
1438 }
1439 }
1440 strcpy(tempcom, pszPgm);
1441 pszChar++;
1442 }
1443 }
1444 if (!ret){
1445 BldQuotedFileName(szTempPgm, tempcom);
1446 strcpy(temparg, pszPgm + strlen(tempcom) - 3);
1447 if ((temparg[0] == '\"' && temparg[1] == ' ') ||
1448 !strstr(pszPgm, "\\:" ) ||
1449 strchr(temparg, '\"') == strrchr(temparg, '\"'))
1450 remove_first_occurence_of_character("\"", temparg);
1451 if (strchr(temparg, '\"') != strrchr(temparg, '\"'))
1452 saymsg(MB_OK, HWND_DESKTOP,
1453 NullStr,
1454 GetPString(IDS_QUOTESINARGSTEXT),
1455 pszPgm);
1456 if (temparg[0] != ' ')
1457 strcat(szTempPgm, " ");
1458 strcat(szTempPgm, temparg);
1459 pszQuotedCompletePgm = szTempPgm;
1460 }
1461 else {
1462 ret = saymsg(MB_OK,
1463 HWND_DESKTOP,
1464 NullStr,
1465 GetPString(IDS_PROGRAMNOTEXE2TEXT),
1466 pszPgm);
1467 fCancelAction = TRUE;
1468 pszQuotedCompletePgm = pszPgm;
1469 }
1470 }
1471 else {
1472 pszChar = strrchr(tempcom, '.');
1473 while (pszChar && *pszChar !=' '){
1474 pszChar++;
1475 }
1476 *pszChar = '\0';
1477 strcpy (temparg, pszPgm + strlen(tempcom));
1478 while (strchr(tempcom, '\"'))
1479 remove_first_occurence_of_character("\"", tempcom);
1480 if ((temparg[0] == '\"' && temparg[1] == ' ') ||
1481 !strstr(pszPgm, "\\:")||
1482 strchr(temparg, '\"') == strrchr(temparg, '\"'))
1483 remove_first_occurence_of_character("\"", temparg);
1484 if (strchr(temparg, '\"') != strrchr(temparg, '\"'))
1485 saymsg(MB_OK, HWND_DESKTOP,
1486 NullStr,
1487 GetPString(IDS_QUOTESINARGSTEXT),
1488 pszPgm);
1489 ret = DosFindFirst(tempcom, &hdirFindHandle, FILE_NORMAL, &FindBuffer,
1490 ulResultBufLen, &ulFindCount, FIL_STANDARD);
1491
1492 BldQuotedFileName(szTempPgm, tempcom);
1493 //printf("%d %s ", ret, tempcom); fflush(stdout);
1494 if (ret) {
1495 ret = saymsg(MB_YESNO,
1496 HWND_DESKTOP,
1497 NullStr,
1498 GetPString(IDS_PROGRAMNOTFOUNDTEXT),
1499 pszPgm);
1500 if (ret == MBID_YES){
1501 if (temparg[0] != ' ')
1502 strcat(szTempPgm, " ");
1503 strcat(szTempPgm, temparg);
1504 pszQuotedCompletePgm = szTempPgm;
1505 }
1506 else{
1507 fCancelAction = TRUE;
1508 pszQuotedCompletePgm = pszPgm;
1509 }
1510 }
1511 ret = saymsg(MB_YESNO,
1512 HWND_DESKTOP,
1513 NullStr,
1514 GetPString(IDS_PROGRAMNOTEXE3TEXT),
1515 pszPgm);
1516 if (ret == MBID_YES){
1517 if (temparg[0] != ' ')
1518 strcat(szTempPgm, " ");
1519 strcat(szTempPgm, temparg);
1520 pszQuotedCompletePgm = szTempPgm;
1521 }
1522 else{
1523 fCancelAction = TRUE;
1524 pszQuotedCompletePgm = pszPgm;
1525 }
1526 }
1527 return pszQuotedCompletePgm;
1528 }
1529 return pszPgm;
1530}
1531
[793]1532#pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2)
Note: See TracBrowser for help on using the repository browser.