source: trunk/dll/systemf.c@ 917

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

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

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