source: trunk/dll/systemf.c@ 920

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

Cleanup of NormalizeCmdLine moved to pathutil.c

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