source: trunk/dll/systemf.c@ 630

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

Improved fix of utility app path problem

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