#define INCL_WIN #define INCL_WINERRORS #define INCL_DOS #define INCL_DOSERRORS #include #include #include #include #include #include #include #include "fm3dll.h" #include "fm3dlg.h" #include "fm3str.h" #pragma alloc_text(SYSTEMF,ShowSession,ExecOnList,runemf2) #define MAXSTRG (4096) /* used to build command line strings */ /* quick and dirty program launcher for OS/2 2.x */ BOOL ShowSession (HWND hwnd,PID pid) { HSWITCH hswitch; SWCNTRL swctl; ULONG rc; hswitch = WinQuerySwitchHandle((pid) ? (HWND)0 : hwnd,pid); if(hswitch) { rc = WinQuerySwitchEntry(hswitch,&swctl); if(!rc) { if(swctl.idProcess == pid && swctl.uchVisibility == SWL_VISIBLE) rc = WinSwitchToProgram(hswitch); if(!rc) return TRUE; // else saymsg(MB_ENTER,HWND_DESKTOP,DEBUG_STRING,"Failed: %lu/%lx",rc,rc); } } return FALSE; } int ExecOnList (HWND hwnd, char *command, int flags, char *tpath, char **list,char *prompt) { /* executes the command once for all files in list */ char path[CCHMAXPATH],commandline[2048],modpath[CCHMAXPATH], listfile[CCHMAXPATH],*p,*pp,drive,*file,*ext,*dot; register int x; BOOL spaces; if(!command || !*command) return -1; *listfile = 0; lstrip(rstrip(command)); /* if(*command == '\"') { memmove(command,command + 1,strlen(command)); if(!*command) return -1; p = strchr(command,'\"'); if(p) memmove(p,p + 1,strlen(p)); if(!*command) return -1; } */ *path = 0; if(tpath && *tpath) strcpy(path,tpath); else if(*command != '<' || !strchr(command,'>')) { strcpy(path,command + (*command == '"')); if(*command == '\"') p = strchr(path,'\"'); else p = strchr(path,' '); if(p) *p = 0; p = strrchr(path,'\\'); if(!p) p = strrchr(path,':'); if(p) { if(*p == ':') { p++; *p = '\\'; p++; } *p = 0; } else *path = 0; } if(!*path) { if(list && list[0]) strcpy(path,list[0]); p = strrchr(path,'\\'); if(!p) p = strrchr(path,':'); if(p) { if(*p == ':') { p++; *p = '\\'; p++; } *p = 0; } else *path = 0; } *modpath = 0; if(list && list[0]) strcpy(modpath,list[0]); p = strrchr(modpath,'\\'); if(!p) p = strrchr(modpath,':'); if(p) { if(*p == ':') { p++; *p = '\\'; p++; } *p = 0; } else *modpath = 0; if(!*modpath) strcpy(modpath,path); if(*path) MakeFullName(path); if(*modpath) MakeFullName(modpath); if(IsFullName(path)) drive = toupper(*path); else drive = 0; p = command; // substitue for special % sequences pp = commandline; *commandline = 0; while(*p) { if(*p == '%') { switch(*(p + 1)) { case '!': /* write list to file, add filename */ if(list) { if(!*listfile) { FILE *fp; save_dir2(listfile); if(listfile[strlen(listfile) - 1] != '\\') strcat(listfile,"\\"); sprintf(&listfile[strlen(listfile)],"%s%03x", LISTTEMPROOT,(clock() & 4095L)); fp = fopen(listfile,"w"); if(fp) { for(x = 0;list[x];x++) { fputs(list[x],fp); if(list[x + 1]) fputc('\n',fp); } fclose(fp); } } strcpy(pp,listfile); pp += strlen(listfile); } p += 2; break; case 'c': /* add name of command processor */ { char *env = GetCmdSpec(FALSE); if(needs_quoting(env) && !strchr(env,'\"')) { *pp = '\"'; pp++; spaces = TRUE; } else spaces = FALSE; strcpy(pp,env); p += 2; pp += strlen(env); if(spaces) { *pp = '\"'; pp++; } } break; case 't': /* add Target directory */ if(needs_quoting(targetdir) && !strchr(targetdir,'\"')) { *pp = '\"'; pp++; spaces = TRUE; } else spaces = FALSE; strcpy(pp,targetdir); p += 2; pp += strlen(targetdir); if(spaces) { *pp = '\"'; pp++; } break; case '$': /* add drive letter */ if(drive) *pp = drive; else { ULONG ulDriveNum = 3L,ulDriveMap; DosQCurDisk(&ulDriveNum,&ulDriveMap); *pp = (char)(ulDriveNum + '@'); } pp++; p += 2; break; case 'U': /* add path of first list component */ case 'u': if(*modpath) { if(needs_quoting(modpath) && !strchr(modpath,'\"')) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; if(*(p + 1) == 'u') { strcpy(pp,modpath); pp += strlen(modpath); } else { strcpy(pp,modpath + 2); pp += strlen(modpath + 2); } if(spaces) { if(modpath[strlen(modpath) - 1] == '\\') { *pp = '\\'; pp++; } *pp = '\"'; pp++; } } else { char temp[CCHMAXPATH]; save_dir2(temp); if(needs_quoting(temp) && !strchr(temp,'\"')) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; strcpy(pp,temp); pp += strlen(temp); if(spaces) { if(temp[strlen(temp) - 1] == '\\') { *pp = '\\'; pp++; } *pp = '\"'; pp++; } } p += 2; break; case 'P': /* add path of execution */ case 'p': if(*path) { if(needs_quoting(path) && !strchr(path,'\"')) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; if(*(p + 1) == 'p') { strcpy(pp,path); pp += strlen(path); } else { strcpy(pp,path + 2); pp += strlen(path + 2); } if(spaces) { if(path[strlen(path) - 1] == '\\') { *pp = '\\'; pp++; } *pp = '\"'; pp++; } } else { char temp[CCHMAXPATH]; save_dir2(temp); if(needs_quoting(temp) && !strchr(temp,'\"')) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; strcpy(pp,temp); pp += strlen(temp); if(spaces) { if(temp[strlen(temp) - 1] == '\\') { *pp = '\\'; pp++; } *pp = '\"'; pp++; } } p += 2; break; case 'D': if(hwndMain) { PCNRITEM pci; pci = (PCNRITEM)WinSendMsg(WinWindowFromID(WinWindowFromID( hwndTree,FID_CLIENT),TREE_CNR), CM_QUERYRECORDEMPHASIS, MPFROMLONG(CMA_FIRST), MPFROMSHORT(CRA_CURSORED)); if(pci && (int)pci != -1 && *pci->szFileName) { if(needs_quoting(pci->szFileName) && !strchr(pci->szFileName,'\"')) { *pp = '\"'; pp++; spaces = TRUE; } else spaces = FALSE; strcpy(pp,pci->szFileName); pp += strlen(pci->szFileName); if(spaces) { *pp = '\"'; pp++; } } } p += 2; break; case 'd': if(hwndMain) { HENUM henum; char retstr[CCHMAXPATH]; HWND hwndC,hwndDir; USHORT id; BOOL first = TRUE; henum = WinBeginEnumWindows(hwndMain); while((hwndC = WinGetNextWindow(henum)) != NULLHANDLE) { if(hwndC != hwndTree) { id = WinQueryWindowUShort(hwndC,QWS_ID); if(id) { hwndDir = WinWindowFromID(hwndC,FID_CLIENT); if(hwndDir) { hwndDir = WinWindowFromID(hwndDir,DIR_CNR); if(hwndDir) { *retstr = 0; WinSendMsg(hwndC,UM_CONTAINERDIR,MPFROMP(retstr),MPVOID); if(*retstr) { if(!first) { *pp = ' '; pp++; } first = FALSE; if(needs_quoting(retstr) && !strchr(retstr,'\"')) { *pp = '\"'; pp++; spaces = TRUE; } else spaces = FALSE; strcpy(pp,retstr); pp += strlen(retstr); if(spaces) { *pp = '\"'; pp++; } } } } } } } WinEndEnumWindows(henum); } p += 2; break; case '%': *pp = '%'; pp++; p += 2; break; case 'R': case 'F': case 'A': case 'r': case 'f': case 'a': case 'e': if(list) { for(x = 0;list[x];x++) { file = strrchr(list[x],'\\'); if(!file) file = strrchr(list[x],':'); if(file) file++; else file = list[x]; ext = strrchr(file,'.'); dot = ext; if(ext) ext++; switch(*(p + 1)) { case 'R': case 'r': if(pp + strlen(list[x]) > commandline + 1250) goto BreakOut; if(*(p + 1) == 'r') { strcpy(pp,list[x]); pp += strlen(list[x]); } else { strcpy(pp,list[x] + 2); pp += strlen(list[x] + 2); } break; case 'F': case 'f': if(*(p + 1) == 'F' && dot) *dot = 0; if(pp + strlen(file) > commandline + 1250) goto BreakOut; if(needs_quoting(file)) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; strcpy(pp,file); pp += strlen(file); if(*(p + 1) == 'F' && dot) *dot = '.'; if(spaces) { if(*(pp - 1) != '\"') { *pp = '\"'; pp++; } } break; case 'A': case 'a': if(pp + strlen(list[x]) > commandline + 1250) goto BreakOut; if(needs_quoting(list[x]) && !strchr(list[x],'\"')) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; if(*(p + 1) == 'a') { strcpy(pp,list[x]); pp += strlen(list[x]); } else { strcpy(pp,list[x] + 2); pp += strlen(list[x] + 2); } if(spaces) { if(list[x][strlen(list[x]) - 1] == '\\') { *pp = '\\'; pp++; } *pp = '\"'; pp++; } break; case 'e': if(ext) { if(pp + strlen(ext) > commandline + 1250) goto BreakOut; if(needs_quoting(ext)) { spaces = TRUE; *pp = '\"'; pp++; } else spaces = FALSE; strcpy(pp,ext); pp += strlen(ext); if(spaces) { if(*(pp - 1) != '\"') { *pp = '\"'; pp++; } } } break; } if(list[x + 1]) { *pp = ' '; pp++; } } } p += 2; break; default: *pp = *p; p++; pp++; break; } } else { *pp = *p; pp++; p++; } *pp = 0; } BreakOut: { EXECARGS ex; ULONG size; int ret; memset(&ex,0,sizeof(EXECARGS)); size = sizeof(ex.environment) - 1; PrfQueryProfileData(fmprof,FM3Str,command,ex.environment,&size); if(flags & PROMPT) { /* allow editing command line */ ex.flags = (flags & (~PROMPT)); ex.commandline = commandline; strcpy(ex.path,path); if(prompt) strcpy(ex.title,prompt); ret = WinDlgBox(HWND_DESKTOP,hwnd,CmdLineDlgProc,FM3ModHandle, EXEC_FRAME,&ex); if(ret != 1) return (ret == 0) ? -1 : -2; } else ex.flags = flags; ex.flags &= (~PROMPT); return runemf2(ex.flags,hwnd,path, (*ex.environment) ? ex.environment : NULL, "%s",commandline); } } int runemf2 (int type,HWND hwnd,char *directory,char *environment, char *formatstring,...) { /* example: * * status = runemf2(SEPARATE | WINDOWED, * hwnd, * NullStr, * NULL, * "%s /C %s", * getenv("COMSPEC"), * batchfilename); * * use (HWND)0 for hwnd if window handle not handy. */ /* * type bitmapped flag -- see FM3DLL.H */ va_list parguments; int ret = -1; RESULTCODES rt; STARTDATA start; REQUESTDATA rq; ULONG sessID,apptype,ulLength,ctr = 0; PID sessPID; BOOL wasquote; char *s = NULL,*s2 = NULL,object[32] = "",*p,savedir[CCHMAXPATH]; HQUEUE hque = (HQUEUE)0; char queue_name[] = "\\QUEUES\\FM3WAIT",tempdir[CCHMAXPATH]; PUSHORT pusInfo = (PUSHORT)NULL; BYTE bPriority; APIRET rc; if(directory && *directory) { if(!DosQueryPathInfo(directory, FIL_QUERYFULLNAME, tempdir, sizeof(tempdir))) directory = tempdir; } if(!hwnd) hwnd = HWND_DESKTOP; rc = DosAllocMem((PVOID)&s, MAXSTRG, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if(rc) return -1; *savedir = 0; *s = 0; va_start(parguments, formatstring); vsprintf(s, formatstring, parguments); va_end(parguments); if(environment) { p = &environment[strlen(environment)] + 1; *p = 0; p = environment; while((p = strchr(p,'\n')) != NULL) { *p = 0; p++; } } if(!*s) { p = GetCmdSpec(FALSE); strcpy(s,p); if(!*s) return -1; } if(*s) { if(*s == '<' && strchr(s,'>')) { /* is a workplace object */ HOBJECT hWPSObject; char temp; p = strchr(s,'>'); p++; temp = *p; if(temp) rc = DosAllocMem((PVOID)&s2, MAXSTRG * 2, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); else s2 = NULL; *p = 0; /* Find the handle of the WPS object */ hWPSObject = WinQueryObject(s); *p = temp; if(hWPSObject != NULLHANDLE) { if(s2 && *p) { sprintf(s2, "OPEN=DEFAULT;PARAMETERS=\"%s\"", p); WinSetObjectData(hWPSObject, s2); } else WinSetObjectData(hWPSObject, "OPEN=DEFAULT"); ret = 0; } goto ObjectInterrupt; } if((type & 15) == SYNCHRONOUS || (type & 15) == ASYNCHRONOUS || (type & 15) == DETACHED) { strip_lead_char(" \t",s); p = s; wasquote = FALSE; while(*p && (wasquote || (*p != ' ' && *p != '\t'))) { if(*p == '\"') { if(!wasquote) { wasquote = TRUE; memmove(p, p + 1, strlen(p)); while(*p == ' ' || *p == '\t') p++; } else { memmove(p, p + 1, strlen(p)); break; } } else p++; } if(*p) { *p = 0; p++; } else p = s; p[strlen(p) + 1] = 0; /* double-terminate args */ if(*s) { if(!strchr(s,'\\') && !strchr(s,':') && directory && *directory) { save_dir2(savedir); switch_to(directory); } ret = (int)DosQAppType(s, &apptype); if(!strchr(s,'\\') && !strchr(s,':') && directory && *directory) switch_to(savedir); if(ret) { DosBeep(50,100); if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return -1; } if(apptype) { if((apptype & FAPPTYP_DLL) || (apptype & FAPPTYP_VIRTDRV) || (apptype & FAPPTYP_PHYSDRV) || (apptype & FAPPTYP_PROTDLL)) { DosBeep(250,100); if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return -1; } if((apptype & FAPPTYP_DOS) || (apptype & FAPPTYP_WINDOWSREAL) || (apptype & FAPPTYP_WINDOWSPROT) || (apptype & 0x1000)) { DosBeep(500,100); if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return -1; } } memset(&rt,0,sizeof(RESULTCODES)); if(directory && *directory) { save_dir2(savedir); switch_to(directory); } ret = (int)DosExecPgm(object,24L, (ULONG)(((type & 15) == ASYNCHRONOUS) * EXEC_ASYNC) + (((type & 15) == DETACHED) * EXEC_BACKGROUND), s,environment,&rt,s); if(directory && *directory) switch_to(savedir); if(ret) Dos_Error(MB_ENTER, ret, hwnd, __FILE__, __LINE__, GetPString(IDS_DOSEXECPGMFAILEDTEXT)); } } else { if(!(type & FULLSCREEN)) type |= WINDOWED; rc = DosAllocMem((PVOID)&s2,MAXSTRG * 2, PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE); if(rc) { DosFreeMem(s); return -1; } *s2 = 0; memset(&start,0,sizeof(STARTDATA)); strip_lead_char(" \t",s); p = s; wasquote = FALSE; while(*p && (wasquote || (*p != ' ' && *p != '\t'))) { if(*p == '\"') { if(!wasquote) { wasquote = TRUE; memmove(p,p + 1,strlen(p)); while(*p == ' ' || *p == '\t') p++; } else { memmove(p,p + 1,strlen(p)); break; } } else p++; } if(*p) { *p = 0; p++; } else p = NullStr; if(*p) strcpy(s2,p); p = strrchr(s,'.'); if(p) { char temp[CCHMAXPATH + 1]; if(!stricmp(p,".BAT")) { strcpy(temp,s); strcpy(s,s2); strcpy(s2,"/C "); strcat(s2,temp); strcat(s2," "); strcat(s2,s); strcpy(s,GetCmdSpec(TRUE)); } else if(!stricmp(p,".CMD")) { strcpy(temp,s); strcpy(s,s2); strcpy(s2,"/C "); strcat(s2,temp); strcat(s2," "); strcat(s2,s); strcpy(s,GetCmdSpec(FALSE)); } } /* goddamned OS/2 limit */ if(strlen(s) + strlen(s2) > 1024) s2[1024 - strlen(s)] = 0; if(!strchr(s,'\\') && !strchr(s,':') && directory && *directory) { save_dir2(savedir); switch_to(directory); } ret = (int)DosQAppType(s, &apptype); if(!strchr(s,'\\') && !strchr(s,':') && directory && *directory) switch_to(savedir); if(ret) { if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return -1; } if(apptype) { if((apptype & FAPPTYP_DLL) || (apptype & FAPPTYP_VIRTDRV) || (apptype & FAPPTYP_PHYSDRV) || (apptype & FAPPTYP_PROTDLL)) { if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return -1; } apptype &= (~FAPPTYP_BOUND); if((apptype & FAPPTYP_DOS) || (apptype & FAPPTYP_WINDOWSREAL) || (apptype & FAPPTYP_WINDOWSPROT) || (apptype & 0x1000)) { if((apptype & FAPPTYP_WINDOWSREAL) || (apptype & FAPPTYP_WINDOWSPROT) || (apptype & 0x1000)) { if(!(type & FULLSCREEN) && ((apptype & FAPPTYP_WINDOWSREAL) || (apptype & FAPPTYP_WINDOWSPROT) || (apptype & 0x1000))) { ret = RunSeamless(s,s2,hwnd); if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return (ret) ? 0 : -1; } else { strcat(s," "); strcat(s,s2); *s2 = 0; if((apptype & FAPPTYP_WINDOWSPROT) || (apptype & FAPPTYP_WINDOWSREAL) || (apptype & 0x1000)) strcat(s2,"/3 "); strcat(s2,s); strcpy(s,"WINOS2.COM"); } } else { if(!(type & FULLSCREEN)) { type |= WINDOWED; apptype = SSF_TYPE_WINDOWEDVDM; } else { type &= (~WINDOWED); apptype = SSF_TYPE_VDM; } } } else if(apptype & FAPPTYP_32BIT) { apptype &= (~FAPPTYP_32BIT); if(apptype == FAPPTYP_WINDOWAPI) apptype = SSF_TYPE_PM; else if(apptype == FAPPTYP_WINDOWCOMPAT) apptype = SSF_TYPE_WINDOWABLEVIO; else if(apptype == FAPPTYP_NOTWINDOWCOMPAT) { apptype = SSF_TYPE_FULLSCREEN; type &= (~WINDOWED); type |= FULLSCREEN; } else /* ? */ apptype = SSF_TYPE_WINDOWABLEVIO; } else if(apptype == FAPPTYP_WINDOWAPI) apptype = SSF_TYPE_PM; else if(apptype == FAPPTYP_WINDOWCOMPAT) apptype = SSF_TYPE_WINDOWABLEVIO; else if(apptype == FAPPTYP_NOTWINDOWCOMPAT) { type &= (~WINDOWED); apptype = SSF_TYPE_FULLSCREEN; } else apptype = SSF_TYPE_DEFAULT; if(((type & FULLSCREEN) || !(type & WINDOWED)) && apptype == SSF_TYPE_WINDOWABLEVIO) { apptype = SSF_TYPE_FULLSCREEN; } else if(((type & FULLSCREEN) || !(type & WINDOWED) && apptype == SSF_TYPE_WINDOWEDVDM)) apptype = SSF_TYPE_VDM; } if(apptype == SSF_TYPE_WINDOWEDVDM && (type & SEPARATEKEEP)) { type &= (~SEPARATEKEEP); type |= SEPARATE; } if(type & WAIT) { if(DosCreateQueue(&hque,QUE_FIFO | QUE_CONVERT_ADDRESS,queue_name)) hque = (HQUEUE)0; } else *queue_name = 0; start.Length = sizeof(start); start.Related = ((type & WAIT) != 0) ? SSF_RELATED_CHILD : ((type & CHILD) != 0) ? SSF_RELATED_CHILD : SSF_RELATED_INDEPENDENT; start.FgBg = ((type & BACKGROUND) != 0) * SSF_FGBG_BACK; start.TraceOpt = SSF_TRACEOPT_NONE; start.PgmTitle = NULL; start.PgmName = s; start.PgmInputs = (*s2) ? s2 : NULL; start.TermQ = (*queue_name) ? queue_name : NULL; start.Environment = environment; start.InheritOpt = SSF_INHERTOPT_PARENT; start.SessionType = (USHORT)apptype; start.ObjectBuffer = object; start.ObjectBuffLen = 31; start.IconFile = NULL; start.PgmHandle = 0L; start.Reserved = 0; start.PgmControl = (USHORT)((SSF_CONTROL_NOAUTOCLOSE * ((type & 15) == SEPARATEKEEP)) | (SSF_CONTROL_MAXIMIZE * ((type & MAXIMIZED) != 0)) | (SSF_CONTROL_MINIMIZE * ((type & MINIMIZED) != 0)) | (SSF_CONTROL_INVISIBLE * ((type & INVISIBLE) != 0))); if(directory && *directory) { save_dir2(savedir); switch_to(directory); } ret = (int)DosStartSession(&start,&sessID,&sessPID); if(directory && *directory) switch_to(savedir); if(ret && ret != ERROR_SMG_START_IN_BACKGROUND) Dos_Error(MB_CANCEL | MB_ICONEXCLAMATION, ret, hwnd, __FILE__, __LINE__, GetPString(IDS_DOSSTARTSESSIONFAILEDTEXT), s, s2); else if(type & WAIT) { if(!(type & (BACKGROUND | MINIMIZED | INVISIBLE))) ShowSession(hwnd,sessPID); if(!hque) { STATUSDATA sd; memset(&sd,0,sizeof(sd)); sd.Length = (USHORT)sizeof(sd); sd.SelectInd = SET_SESSION_UNCHANGED; sd.BondInd = SET_SESSION_UNCHANGED; for(ctr = 0;;ctr++) { DosSleep(200L); if(DosSetSession(sessID,&sd)) /* cheap trick */ break; if(ctr > 10) ShowSession(hwnd,sessPID); } } else { for(ctr = 0;;ctr++) { ulLength = sizeof(rq); rc = DosReadQueue(hque, &rq, &ulLength, (PPVOID)&pusInfo, 0, DCWW_NOWAIT, &bPriority, 0); if(rc == ERROR_QUE_EMPTY) { if(ctr > 20) { ShowSession(hwnd,sessPID); ulLength = sizeof(rq); DosReadQueue(hque, &rq, &ulLength, (PPVOID)&pusInfo, 0, DCWW_WAIT, &bPriority,0); break; } DosSleep(100L); } else { ulLength = sizeof(rq); if(rc) DosReadQueue(hque,&rq,&ulLength,(PPVOID)&pusInfo,0, DCWW_WAIT,&bPriority,0); break; } } if(pusInfo) { ret = (!(!pusInfo[1])); DosFreeMem(pusInfo); } DosCloseQueue(hque); } } else if(!(type & (BACKGROUND | MINIMIZED | INVISIBLE))) ShowSession(hwnd,sessPID); } } ObjectInterrupt: if(s) DosFreeMem(s); if(s2) DosFreeMem(s2); return ret; } HAPP Exec (HWND hwndNotify,BOOL child,char *startdir,char *env, PROGTYPE *progt,ULONG fl,char *formatstring,...) { PROGDETAILS pgd; register char *p; char *parameters = NULL,*executable = NULL; HAPP happ = (HAPP)0; ULONG ulOptions = SAF_INSTALLEDCMDLINE; BOOL wasquote; va_list parguments; if(child) ulOptions |= SAF_STARTCHILDAPP; executable = malloc(MAXSTRG); if(executable) { memset(executable,0,MAXSTRG); va_start(parguments,formatstring); vsprintf(executable,formatstring,parguments); va_end(parguments); strip_lead_char(" \t",executable); if(*executable) { parameters = malloc(MAXSTRG); if(parameters) { p = executable; wasquote = FALSE; while(*p && (wasquote || (*p != ' ' && *p != '\t'))) { if(*p == '\"') { if(!wasquote) { wasquote = TRUE; memmove(p,p + 1,strlen(p)); while(*p == ' ' || *p == '\t') p++; } else { memmove(p,p + 1,strlen(p)); break; } } else p++; } if(*p) { *p = 0; p++; } else p = NullStr; if(*p) strcpy(parameters,p); if(p && (!stricmp(p,".BAT") || !stricmp(p,".CMD"))) { char *temp; temp = malloc(CCHMAXPATH * 2); if(temp) { if(!stricmp(p,".BAT")) { strcpy(temp,executable); strcpy(executable,parameters); strcpy(parameters,"/C "); strcat(parameters,temp); strcat(parameters," "); strcat(parameters,executable); strcpy(executable,GetCmdSpec(TRUE)); } else if(!stricmp(p,".CMD")) { strcpy(temp,executable); strcpy(executable,parameters); strcpy(parameters,"/C "); strcat(parameters,temp); strcat(parameters," "); strcat(parameters,executable); strcpy(executable,GetCmdSpec(FALSE)); } free(temp); } } memset(&pgd,0,sizeof(pgd)); pgd.Length = sizeof(pgd); pgd.progt = *progt; pgd.swpInitial.fl = fl; pgd.pszEnvironment = env; pgd.pszStartupDir = startdir; pgd.pszParameters = (*parameters) ? parameters : NULL; pgd.pszExecutable = executable; pgd.swpInitial.hwndInsertBehind = HWND_TOP; happ = WinStartApp(hwndNotify,&pgd,NULL,NULL,ulOptions); free(parameters); } } free(executable); } return happ; }