Ignore:
Timestamp:
Apr 14, 2002, 1:42:05 AM (23 years ago)
Author:
umoeller
Message:

Lots of changes from the last three weeks.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/helpers/apps.c

    r152 r153  
    4949#include "setup.h"                      // code generation and debugging options
    5050
    51 #include "helpers\apps.h"
    5251#include "helpers\dosh.h"
    5352#include "helpers\except.h"             // exception handling
     
    5756#include "helpers\winh.h"
    5857#include "helpers\xstring.h"
     58
     59#include "helpers\apps.h"
    5960
    6061/*
     
    843844 *
    844845 *@@added V0.9.12 (2001-05-26) [umoeller]
    845  */
    846 
    847 PSZ appQueryDefaultWin31Environment(VOID)
     846 *@@changed V0.9.19 (2002-03-28) [umoeller]: now returning APIRET
     847 */
     848
     849APIRET appQueryDefaultWin31Environment(PSZ *ppsz)
    848850{
     851    APIRET arc = NO_ERROR;
    849852    PSZ pszReturn = NULL;
    850853    ULONG ulSize = 0;
    851     // get default environment (from Win-OS/2 settings object)
    852     // from OS2.INI
    853     PSZ pszDefEnv = prfhQueryProfileData(HINI_USER,
     854
     855    // get default environment (from Win-OS/2 settings object) from OS2.INI
     856    PSZ pszDefEnv;
     857    if (pszDefEnv = prfhQueryProfileData(HINI_USER,
    854858                                         "WINOS2",
    855859                                         "PM_GlobalWindows31Settings",
    856                                          &ulSize);
    857     if (pszDefEnv)
     860                                         &ulSize))
    858861    {
    859862        if (pszReturn = (PSZ)malloc(ulSize + 2))
     
    871874            // okay.... now we got an OS/2-style environment
    872875            // with 0, 0, 00 strings
    873         }
     876
     877            *ppsz = pszReturn;
     878        }
     879        else
     880            arc = ERROR_NOT_ENOUGH_MEMORY;
    874881
    875882        free(pszDefEnv);
    876883    }
    877 
    878     return (pszReturn);
     884    else
     885        arc = ERROR_BAD_ENVIRONMENT;
     886
     887    return (arc);
    879888}
    880889
     
    957966
    958967/*
    959  *@@ appFixProgDetails:
     968 *@@ appBuildProgDetails:
    960969 *      extracted code from appStartApp to fix the
    961970 *      given PROGDETAILS data to support the typical
    962  *      WPS stuff.
     971 *      WPS stuff and allocate a single block of
     972 *      shared memory containing all the data.
    963973 *
    964974 *      This is now used by XWP's progOpenProgram
     
    966976 *      session hangs.
    967977 *
    968  *      The caller is responsible for cleaning out
    969  *      the given three memory buffers.
     978 *      As input, this takes a PROGDETAILS structure,
     979 *      which is converted in various ways. In detail,
     980 *      this supports:
     981 *
     982 *      -- starting "*" executables (command prompts
     983 *         for OS/2, DOS, Win-OS/2);
     984 *
     985 *      -- starting ".CMD" and ".BAT" files as
     986 *         PROGDETAILS.pszExecutable; for those, we
     987 *         convert the executable and parameters to
     988 *         start CMD.EXE or COMMAND.COM with the "/C"
     989 *         parameter instead;
     990 *
     991 *      -- starting apps which are not fully qualified
     992 *         and therefore assumed to be on the PATH
     993 *         (for which doshSearchPath("PATH") is called).
     994 *
     995 *      Unless it is "*", PROGDETAILS.pszExecutable must
     996 *      be a proper file name. The full path may be omitted
     997 *      if it is on the PATH, but the extension (.EXE etc.)
     998 *      must be given. You can use doshFindExecutable to
     999 *      find executables if you don't know the extension.
     1000 *
     1001 *      This also handles and merges special and default
     1002 *      environments for the app to be started. The
     1003 *      following should be respected:
     1004 *
     1005 *      --  As with WinStartApp, if PROGDETAILS.pszEnvironment
     1006 *          is NULL, the new app inherits the default environment
     1007 *          from the shell.
     1008 *
     1009 *      --  However, if you specify an environment, you _must_
     1010 *          specify a complete environment. This function
     1011 *          will not merge environments. Use
     1012 *          appSetEnvironmentVar to change environment
     1013 *          variables in a complete environment set.
     1014 *
     1015 *      --  If PROGDETAILS specifies a Win-OS/2 session
     1016 *          and PROGDETAILS.pszEnvironment is empty,
     1017 *          this uses the default Win-OS/2 environment
     1018 *          from OS2.INI. See appQueryDefaultWin31Environment.
     1019 *
     1020 *      Even though this isn't clearly said in PMREF,
     1021 *      PROGDETAILS.swpInitial is important:
     1022 *
     1023 *      -- To start a session minimized, set fl to SWP_MINIMIZE.
     1024 *
     1025 *      -- To start a VIO session with auto-close disabled,
     1026 *         set the half-documented SWP_NOAUTOCLOSE flag (0x8000)
     1027 *         This flag is now in the newer toolkit headers.
     1028 *
     1029 *      In addition, this supports the following session
     1030 *      flags with ulFlags if PROG_DEFAULT is specified:
     1031 *
     1032 *      --  APP_RUN_FULLSCREEN: start a fullscreen session
     1033 *          for VIO, DOS, and Win-OS/2 programs. Otherwise
     1034 *          we start a windowed or (share) a seamless session.
     1035 *          Ignored if the program is PM.
     1036 *
     1037 *      --  APP_RUN_ENHANCED: for Win-OS/2 sessions, use
     1038 *          enhanced mode.
     1039 *          Ignored if the program is not Win-OS/2.
     1040 *
     1041 *      --  APP_RUN_STANDARD: for Win-OS/2 sessions, use
     1042 *          standard mode.
     1043 *          Ignored if the program is not Win-OS/2.
     1044 *
     1045 *      --  APP_RUN_SEPARATE: for Win-OS/2 sessions, use
     1046 *          a separate session.
     1047 *          Ignored if the program is not Win-OS/2.
     1048 *
     1049 *      If NO_ERROR is returned, *ppDetails receives a
     1050 *      new buffer of shared memory containing all the
     1051 *      data packed together.
     1052 *
     1053 *      The shared memory is allocated unnamed and
     1054 *      with OBJ_GETTABLE. It is the responsibility
     1055 *      of the caller to call DosFreeMem on that buffer.
     1056 *
     1057 *      Returns:
     1058 *
     1059 *      --  NO_ERROR
     1060 *
     1061 *      --  ERROR_INVALID_PARAMETER: pcProgDetails or
     1062 *          ppDetails is NULL; or PROGDETAILS.pszExecutable is NULL.
     1063 *
     1064 *      --  ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND:
     1065 *          PROGDETAILS.pszExecutable and/or PROGDETAILS.pszStartupDir
     1066 *          are invalid.
     1067 *          A NULL PROGDETAILS.pszStartupDir is supported though.
     1068 *
     1069 *      --  ERROR_BAD_FORMAT
     1070 *
     1071 *      --  ERROR_BAD_ENVIRONMENT: environment is larger than 60.000 bytes.
     1072 *
     1073 *      --  ERROR_NOT_ENOUGH_MEMORY
     1074 *
     1075 *      plus the error codes from doshQueryPathAttr, doshSearchPath,
     1076 *      appParseEnvironment, appSetEnvironmentVar, and appConvertEnvironment.
    9701077 *
    9711078 *@@added V0.9.18 (2002-03-27) [umoeller]
    972  */
    973 
    974 APIRET appFixProgDetails(PPROGDETAILS pDetails,             // out: fixed program spec (req.)
    975                          const PROGDETAILS *pcProgDetails,  // in: program spec (req.)
    976                          ULONG ulFlags,                     // in: APP_RUN_* flags or 0
    977                          PXSTRING pstrExecutablePatched,    // in: init'ed XSTRING, out: to be freed
    978                          PXSTRING pstrParamsPatched,        // in: init'ed XSTRING, out: to be freed
    979                          PSZ *ppszWinOS2Env)                // in: ptr to NULL, out: memory to be freed
     1079 *@@changed V0.9.19 (2002-03-28) [umoeller]: now allocating contiguous buffer
     1080 */
     1081
     1082APIRET appBuildProgDetails(PPROGDETAILS *ppDetails,           // out: shared mem with fixed program spec (req.)
     1083                           const PROGDETAILS *pcProgDetails,  // in: program spec (req.)
     1084                           ULONG ulFlags)                     // in: APP_RUN_* flags or 0
    9801085{
    9811086    APIRET          arc = NO_ERROR;
    9821087
    983     memcpy(pDetails, pcProgDetails, sizeof(PROGDETAILS));
     1088    XSTRING         strExecutablePatched,
     1089                    strParamsPatched;
     1090    PSZ             pszWinOS2Env = 0;
     1091
     1092    PROGDETAILS     Details;
     1093
     1094    *ppDetails = NULL;
     1095
     1096    if (!pcProgDetails && !ppDetails)
     1097        return (ERROR_INVALID_PARAMETER);
     1098
     1099    /*
     1100     * part 1:
     1101     *      fix up the PROGDETAILS fields
     1102     */
     1103
     1104    xstrInit(&strExecutablePatched, 0);
     1105    xstrInit(&strParamsPatched, 0);
     1106
     1107    memcpy(&Details, pcProgDetails, sizeof(PROGDETAILS));
    9841108            // pointers still point into old prog details buffer
    985     pDetails->Length = sizeof(PROGDETAILS);
    986     pDetails->progt.fbVisible = SHE_VISIBLE;
     1109    Details.Length = sizeof(PROGDETAILS);
     1110    Details.progt.fbVisible = SHE_VISIBLE;
    9871111
    9881112    // all this only makes sense if this contains something...
    9891113    // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller]
    990     if (    (!pDetails->pszExecutable)
    991          || (!(*(pDetails->pszExecutable)))
     1114    if (    (!Details.pszExecutable)
     1115         || (!Details.pszExecutable[0])
    9921116       )
    9931117        arc = ERROR_INVALID_PARAMETER;
     
    9961120        ULONG           ulIsWinApp;
    9971121
    998         // memset(&pDetails->swpInitial, 0, sizeof(SWP));
     1122        // memset(&Details.swpInitial, 0, sizeof(SWP));
    9991123        // this wasn't a good idea... WPProgram stores stuff
    10001124        // in here, such as the "minimize on startup" -> SWP_MINIMIZE
     
    10021126        // duplicate parameters...
    10031127        // we need this for string manipulations below...
    1004         if (    (pDetails->pszParameters)
    1005              && (*pDetails->pszParameters)    // V0.9.18
     1128        if (    (Details.pszParameters)
     1129             && (Details.pszParameters[0])    // V0.9.18
    10061130           )
    1007             xstrcpy(pstrParamsPatched,
    1008                     pDetails->pszParameters,
     1131            xstrcpy(&strParamsPatched,
     1132                    Details.pszParameters,
    10091133                    0);
    10101134
    10111135        #ifdef DEBUG_PROGRAMSTART
    10121136            _Pmpf((__FUNCTION__ ": old progc: 0x%lX", pcProgDetails->progt.progc));
    1013             _Pmpf(("  pszTitle: %s", (pDetails->pszTitle) ? pDetails->pszTitle : NULL));
    1014             _Pmpf(("  pszIcon: %s", (pDetails->pszIcon) ? pDetails->pszIcon : NULL));
     1137            _Pmpf(("  pszTitle: %s", (Details.pszTitle) ? Details.pszTitle : NULL));
     1138            _Pmpf(("  pszIcon: %s", (Details.pszIcon) ? Details.pszIcon : NULL));
    10151139        #endif
    10161140
    10171141        // program type fixups
    1018         switch (pDetails->progt.progc)        // that's a ULONG
     1142        switch (Details.progt.progc)        // that's a ULONG
    10191143        {
    10201144            case ((ULONG)-1):       // we get that sometimes...
     
    10231147                // V0.9.12 (2001-05-26) [umoeller]
    10241148                ULONG ulDosAppType;
    1025                 appQueryAppType(pDetails->pszExecutable,
     1149                appQueryAppType(Details.pszExecutable,
    10261150                                &ulDosAppType,
    1027                                 &pDetails->progt.progc);
     1151                                &Details.progt.progc);
    10281152            }
    10291153            break;
     
    10331157        if (ulFlags & APP_RUN_FULLSCREEN)
    10341158        {
    1035             if (pDetails->progt.progc == PROG_WINDOWABLEVIO)
    1036                 pDetails->progt.progc = PROG_FULLSCREEN;
    1037             else if (pDetails->progt.progc == PROG_WINDOWEDVDM)
    1038                 pDetails->progt.progc = PROG_VDM;
    1039         }
    1040 
    1041         if (ulIsWinApp = appIsWindowsApp(pDetails->progt.progc))
     1159            if (Details.progt.progc == PROG_WINDOWABLEVIO)
     1160                Details.progt.progc = PROG_FULLSCREEN;
     1161            else if (Details.progt.progc == PROG_WINDOWEDVDM)
     1162                Details.progt.progc = PROG_VDM;
     1163        }
     1164
     1165        if (ulIsWinApp = appIsWindowsApp(Details.progt.progc))
    10421166        {
    10431167            if (ulFlags & APP_RUN_FULLSCREEN)
    1044                 pDetails->progt.progc = (ulFlags & APP_RUN_ENHANCED)
     1168                Details.progt.progc = (ulFlags & APP_RUN_ENHANCED)
    10451169                                                ? PROG_31_ENH
    10461170                                                : PROG_31_STD;
     
    10481172            {
    10491173                if (ulFlags & APP_RUN_STANDARD)
    1050                     pDetails->progt.progc = (ulFlags & APP_RUN_SEPARATE)
     1174                    Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
    10511175                                                ? PROG_31_STDSEAMLESSVDM
    10521176                                                : PROG_31_STDSEAMLESSCOMMON;
    10531177                else if (ulFlags & APP_RUN_ENHANCED)
    1054                     pDetails->progt.progc = (ulFlags & APP_RUN_SEPARATE)
     1178                    Details.progt.progc = (ulFlags & APP_RUN_SEPARATE)
    10551179                                                ? PROG_31_ENHSEAMLESSVDM
    10561180                                                : PROG_31_ENHSEAMLESSCOMMON;
     
    10581182
    10591183            // re-run V0.9.16 (2001-10-19) [umoeller]
    1060             ulIsWinApp = appIsWindowsApp(pDetails->progt.progc);
     1184            ulIsWinApp = appIsWindowsApp(Details.progt.progc);
    10611185        }
    10621186
     
    10681192             */
    10691193
    1070             if (!strcmp(pDetails->pszExecutable, "*"))
     1194            if (!strcmp(Details.pszExecutable, "*"))
    10711195            {
    10721196                /*
     
    10791203                    // enhanced Win-OS/2 session:
    10801204                    PSZ psz = NULL;
    1081                     if (pstrParamsPatched->ulLength)
     1205                    if (strParamsPatched.ulLength)
    10821206                        // "/3 " + existing params
    1083                         psz = strdup(pstrParamsPatched->psz);
    1084 
    1085                     xstrcpy(pstrParamsPatched, "/3 ", 0);
     1207                        psz = strdup(strParamsPatched.psz);
     1208
     1209                    xstrcpy(&strParamsPatched, "/3 ", 0);
    10861210
    10871211                    if (psz)
    10881212                    {
    1089                         xstrcat(pstrParamsPatched, psz, 0);
     1213                        xstrcat(&strParamsPatched, psz, 0);
    10901214                        free(psz);
    10911215                    }
     
    10961220                    // cheat: WinStartApp doesn't support NULL
    10971221                    // for Win-OS2 sessions, so manually start winos2.com
    1098                     pDetails->pszExecutable = "WINOS2.COM";
     1222                    Details.pszExecutable = "WINOS2.COM";
    10991223                    // this is a DOS app, so fix this to DOS fullscreen
    1100                     pDetails->progt.progc = PROG_VDM;
     1224                    Details.progt.progc = PROG_VDM;
    11011225                }
    11021226                else
     
    11051229                    // set pszExecutable to NULL; this will
    11061230                    // have WinStartApp start a cmd shell
    1107                     pDetails->pszExecutable = NULL;
     1231                    Details.pszExecutable = NULL;
    11081232
    11091233            } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0)
     
    11121236                // check if the executable is fully qualified; if so,
    11131237                // check if the executable file exists
    1114                 if (    (pDetails->pszExecutable[1] == ':')
    1115                      && (strchr(pDetails->pszExecutable, '\\'))
     1238                if (    (Details.pszExecutable[1] == ':')
     1239                     && (strchr(Details.pszExecutable, '\\'))
    11161240                   )
    11171241                {
    11181242                    ULONG ulAttr;
    1119                     if (!(arc = doshQueryPathAttr(pDetails->pszExecutable,
     1243                    if (!(arc = doshQueryPathAttr(Details.pszExecutable,
    11201244                                                  &ulAttr)))
    11211245                    {
    11221246                        // make sure startup dir is really a directory
    1123                         if (pDetails->pszStartupDir)
     1247                        if (Details.pszStartupDir)
    11241248                        {
    11251249                            // it is valid to specify a startup dir of "C:"
    1126                             if (    (strlen(pDetails->pszStartupDir) > 2)
    1127                                  && (!(arc = doshQueryPathAttr(pDetails->pszStartupDir,
     1250                            if (    (strlen(Details.pszStartupDir) > 2)
     1251                                 && (!(arc = doshQueryPathAttr(Details.pszStartupDir,
    11281252                                                               &ulAttr)))
    11291253                                 && (!(ulAttr & FILE_DIRECTORY))
     
    11391263                    CHAR    szFQExecutable[CCHMAXPATH];
    11401264                    if (!(arc = doshSearchPath("PATH",
    1141                                                pDetails->pszExecutable,
     1265                                               Details.pszExecutable,
    11421266                                               szFQExecutable,
    11431267                                               sizeof(szFQExecutable))))
    11441268                    {
    11451269                        // alright, found it:
    1146                         xstrcpy(pstrExecutablePatched, szFQExecutable, 0);
    1147                         pDetails->pszExecutable = pstrExecutablePatched->psz;
     1270                        xstrcpy(&strExecutablePatched, szFQExecutable, 0);
     1271                        Details.pszExecutable = strExecutablePatched.psz;
    11481272                    }
    11491273                }
     
    11521276                {
    11531277                    PSZ pszExtension;
    1154                     switch (pDetails->progt.progc)
     1278                    switch (Details.progt.progc)
    11551279                    {
    11561280                        /*
     
    11621286                        case PROG_WINDOWABLEVIO:    // OS/2 window
    11631287                        {
    1164                             if (    (pszExtension = doshGetExtension(pDetails->pszExecutable))
     1288                            if (    (pszExtension = doshGetExtension(Details.pszExecutable))
    11651289                                 && (!stricmp(pszExtension, "CMD"))
    11661290                               )
    11671291                            {
    1168                                 CallBatchCorrectly(pDetails,
    1169                                                    pstrParamsPatched,
     1292                                CallBatchCorrectly(&Details,
     1293                                                   &strParamsPatched,
    11701294                                                   "OS2_SHELL",
    11711295                                                   "CMD.EXE");
     
    11771301                        case PROG_WINDOWEDVDM:      // DOS window
    11781302                        {
    1179                             if (    (pszExtension = doshGetExtension(pDetails->pszExecutable))
     1303                            if (    (pszExtension = doshGetExtension(Details.pszExecutable))
    11801304                                 && (!stricmp(pszExtension, "BAT"))
    11811305                               )
    11821306                            {
    1183                                 CallBatchCorrectly(pDetails,
    1184                                                    pstrParamsPatched,
     1307                                CallBatchCorrectly(&Details,
     1308                                                   &strParamsPatched,
    11851309                                                   NULL,
    11861310                                                   "COMMAND.COM");
     
    11881312                        }
    11891313                        break;
    1190                     } // end switch (pDetails->progt.progc)
     1314                    } // end switch (Details.progt.progc)
    11911315                }
    11921316            }
     
    11961320        {
    11971321            if (    (ulIsWinApp)
    1198                  && (    (pDetails->pszEnvironment == NULL)
    1199                       || (!strlen(pDetails->pszEnvironment))
     1322                 && (    (Details.pszEnvironment == NULL)
     1323                      || (!strlen(Details.pszEnvironment))
    12001324                    )
    12011325               )
     
    12091333
    12101334                // get standard WIN-OS/2 environment
    1211                 PSZ pszTemp = appQueryDefaultWin31Environment();
    1212 
    1213                 if (!(arc = appParseEnvironment(pszTemp,
    1214                                                 &Env)))
     1335                PSZ pszTemp;
     1336                if (!(arc = appQueryDefaultWin31Environment(&pszTemp)))
    12151337                {
    1216                     // now override KBD_CTRL_BYPASS=CTRL_ESC
    1217                     if (    (!(arc = appSetEnvironmentVar(&Env,
    1218                                                           "KBD_CTRL_BYPASS=CTRL_ESC",
    1219                                                           FALSE)))        // add last
    1220                          && (!(arc = appConvertEnvironment(&Env,
    1221                                                            ppszWinOS2Env,   // freed at bottom
    1222                                                            NULL)))
    1223                        )
    1224                         pDetails->pszEnvironment = *ppszWinOS2Env;
    1225 
    1226                     appFreeEnvironment(&Env);
     1338                    if (!(arc = appParseEnvironment(pszTemp,
     1339                                                    &Env)))
     1340                    {
     1341                        // now override KBD_CTRL_BYPASS=CTRL_ESC
     1342                        if (    (!(arc = appSetEnvironmentVar(&Env,
     1343                                                              "KBD_CTRL_BYPASS=CTRL_ESC",
     1344                                                              FALSE)))        // add last
     1345                             && (!(arc = appConvertEnvironment(&Env,
     1346                                                               &pszWinOS2Env,   // freed at bottom
     1347                                                               NULL)))
     1348                           )
     1349                            Details.pszEnvironment = pszWinOS2Env;
     1350
     1351                        appFreeEnvironment(&Env);
     1352                    }
     1353
     1354                    free(pszTemp);
    12271355                }
    1228 
    1229                 free(pszTemp);
    12301356            }
    12311357
    12321358            if (!arc)
    12331359            {
    1234                 if (!pDetails->pszTitle)
    1235                     pDetails->pszTitle = pDetails->pszExecutable;
     1360                // if no title is given, use the executable
     1361                if (!Details.pszTitle)
     1362                    Details.pszTitle = Details.pszExecutable;
    12361363
    12371364                // make sure params have a leading space
    12381365                // V0.9.18 (2002-03-27) [umoeller]
    1239                 if (pstrParamsPatched->ulLength)
     1366                if (strParamsPatched.ulLength)
    12401367                {
    1241                     if (pstrParamsPatched->psz[0] != ' ')
     1368                    if (strParamsPatched.psz[0] != ' ')
    12421369                    {
    12431370                        XSTRING str2;
    12441371                        xstrInit(&str2, 0);
    12451372                        xstrcpy(&str2, " ", 1);
    1246                         xstrcats(&str2, pstrParamsPatched);
    1247                         xstrcpys(pstrParamsPatched, &str2);
     1373                        xstrcats(&str2, &strParamsPatched);
     1374                        xstrcpys(&strParamsPatched, &str2);
    12481375                        xstrClear(&str2);
    12491376                                // we really need xstrInsert or something
    12501377                    }
    1251                     pDetails->pszParameters = pstrParamsPatched->psz;
     1378                    Details.pszParameters = strParamsPatched.psz;
    12521379                }
    12531380                else
    1254                     pDetails->pszParameters = "";
    1255 
    1256                 if (!pDetails->pszIcon)
    1257                     pDetails->pszIcon = "";
    1258 
    1259                 if (!pDetails->pszStartupDir)
    1260                     pDetails->pszStartupDir = "";
     1381                    // never pass null pointers
     1382                    Details.pszParameters = "";
     1383
     1384                // never pass null pointers
     1385                if (!Details.pszIcon)
     1386                    Details.pszIcon = "";
     1387
     1388                // never pass null pointers
     1389                if (!Details.pszStartupDir)
     1390                    Details.pszStartupDir = "";
    12611391
    12621392            }
    12631393        }
    12641394    }
     1395
     1396    /*
     1397     * part 2:
     1398     *      pack the fixed PROGDETAILS fields
     1399     */
     1400
     1401    if (!arc)
     1402    {
     1403        ULONG   cb,
     1404                cbTitle,
     1405                cbExecutable,
     1406                cbParameters,
     1407                cbStartupDir,
     1408                cbIcon,
     1409                cbEnvironment;
     1410
     1411        // allocate a chunk of tiled memory from OS/2 to make sure
     1412        // this is aligned on a 64K memory (backed up by a 16-bit
     1413        // LDT selector); if it is not, and the environment
     1414        // crosses segments, it gets truncated!!
     1415        cb = sizeof(PROGDETAILS);
     1416        if (cbTitle = strhSize(Details.pszTitle))
     1417            cb += cbTitle;
     1418
     1419        if (cbExecutable = strhSize(Details.pszExecutable))
     1420            cb += cbExecutable;
     1421
     1422        if (cbParameters = strhSize(Details.pszParameters))
     1423            cb += cbParameters;
     1424
     1425        if (cbStartupDir = strhSize(Details.pszStartupDir))
     1426            cb += cbStartupDir;
     1427
     1428        if (cbIcon = strhSize(Details.pszIcon))
     1429            cb += cbIcon;
     1430
     1431        if (cbEnvironment = appQueryEnvironmentLen(Details.pszEnvironment))
     1432            cb += cbEnvironment;
     1433
     1434        if (cb > 60000)     // to be on the safe side
     1435            arc = ERROR_BAD_ENVIRONMENT; // 10;
     1436        else
     1437        {
     1438            PPROGDETAILS pNewProgDetails;
     1439            // alright, allocate the shared memory now
     1440            if (!(arc = DosAllocSharedMem((PVOID*)&pNewProgDetails,
     1441                                          NULL,
     1442                                          cb,
     1443                                          PAG_COMMIT | OBJ_GETTABLE | OBJ_TILE | PAG_EXECUTE | PAG_READ | PAG_WRITE)))
     1444            {
     1445                // and copy stuff
     1446                PBYTE pThis;
     1447
     1448                memset(pNewProgDetails, 0, cb);
     1449
     1450                pNewProgDetails->Length = sizeof(PROGDETAILS);
     1451
     1452                pNewProgDetails->progt.progc = Details.progt.progc;
     1453
     1454                pNewProgDetails->progt.fbVisible = Details.progt.fbVisible;
     1455                memcpy(&pNewProgDetails->swpInitial, &Details.swpInitial, sizeof(SWP));
     1456
     1457                // start copying into buffer right after PROGDETAILS
     1458                pThis = (PBYTE)(pNewProgDetails + 1);
     1459
     1460                // handy macro to avoid typos
     1461                #define COPY(id) if (cb ## id) { \
     1462                    memcpy(pThis, Details.psz ## id, cb ## id); \
     1463                    pNewProgDetails->psz ## id = pThis; \
     1464                    pThis += cb ## id; }
     1465
     1466                COPY(Title);
     1467                COPY(Executable);
     1468                COPY(Parameters);
     1469                COPY(StartupDir);
     1470                COPY(Icon);
     1471                COPY(Environment);
     1472
     1473                *ppDetails = pNewProgDetails;
     1474            }
     1475        }
     1476    }
     1477
     1478    xstrClear(&strParamsPatched);
     1479    xstrClear(&strExecutablePatched);
     1480
     1481    if (pszWinOS2Env)
     1482        free(pszWinOS2Env);
    12651483
    12661484    return (arc);
     
    14341652                              PSZ pszFailingName)
    14351653{
    1436     ULONG   cb,
    1437             cbTitle,
    1438             cbExecutable,
    1439             cbParameters,
    1440             cbStartupDir,
    1441             cbIcon,
    1442             cbEnvironment;
    1443 
    1444     APIRET  arc = NO_ERROR;
    1445 
    1446     /*
    1447     if (WinMessageBox(HWND_DESKTOP,
    1448                       NULLHANDLE,
    1449                       (ProgDetails.pszExecutable) ? ProgDetails.pszExecutable : "NULL",
    1450                       "Start?",
    1451                       0,
    1452                       MB_YESNO | MB_MOVEABLE)
    1453               != MBID_YES)
    1454         return (ERROR_INTERRUPT);
    1455     */
    1456 
    1457     // allocate a chunk of tiled memory from OS/2 to make sure
    1458     // this is aligned on a 64K memory (backed up by a 16-bit
    1459     // LDT selector)
    1460     cb = sizeof(PROGDETAILS);
    1461     if (cbTitle = strhSize(pcProgDetails->pszTitle))
    1462         cb += cbTitle;
    1463     else
     1654    APIRET arc = NO_ERROR;
     1655
     1656    if (!pcProgDetails)
    14641657        return (ERROR_INVALID_PARAMETER);
    1465     _Pmpf((__FUNCTION__ ": cbTitle is %d", cbTitle));
    1466 
    1467     if (cbExecutable = strhSize(pcProgDetails->pszExecutable))
    1468         cb += cbExecutable;
    1469     else
    1470         return (ERROR_INVALID_PARAMETER);
    1471     _Pmpf(("    cbExecutable is %d", cbExecutable));
    1472 
    1473     if (cbParameters = strhSize(pcProgDetails->pszParameters))
    1474         cb += cbParameters;
    1475     else
    1476         return (ERROR_INVALID_PARAMETER);
    1477     _Pmpf(("    cbParameters is %d", cbExecutable));
    1478 
    1479     if (cbStartupDir = strhSize(pcProgDetails->pszStartupDir))
    1480         cb += cbStartupDir;
    1481     else
    1482         return (ERROR_INVALID_PARAMETER);
    1483     _Pmpf(("    cbStartupDir is %d", cbStartupDir));
    1484 
    1485     if (cbIcon = strhSize(pcProgDetails->pszIcon))
    1486         cb += cbIcon;
    1487     else
    1488         return (ERROR_INVALID_PARAMETER);
    1489     _Pmpf(("    cbIcon is %d", cbIcon));
    1490 
    1491     if (cbEnvironment = appQueryEnvironmentLen(pcProgDetails->pszEnvironment))
    1492         cb += cbEnvironment;
    1493     _Pmpf(("    cbEnvironment is %d", cbEnvironment));
    1494 
    1495     _Pmpf(("    cbTotal is %d", cb));
    1496 
    1497     if (cb > 60000)     // to be on the safe side
    1498         arc = ERROR_BAD_ENVIRONMENT; // 10;
    1499     else
    1500     {
    1501         PPROGDETAILS pNewProgDetails;
    1502         if (!(arc = DosAllocMem((PVOID*)&pNewProgDetails,
    1503                                 cb,
    1504                                 PAG_COMMIT | OBJ_TILE | PAG_READ | PAG_WRITE)))
    1505         {
    1506             // alright, copy stuff
    1507             memset(pNewProgDetails, 0, sizeof(PROGDETAILS));
    1508 
    1509             pNewProgDetails->Length = sizeof(PROGDETAILS);
    1510 
    1511             if (!(pNewProgDetails->progt.progc = pcProgDetails->progt.progc))
    1512                 arc = ERROR_BAD_FORMAT;
    1513                         // this should never happen because we check
    1514                         // for this in appStartApp
    1515             else
     1658
     1659    if (pszFailingName)
     1660        *pszFailingName = '\0';
     1661
     1662    if (!(*phapp = WinStartApp(hwndNotify,
     1663                                        // receives WM_APPTERMINATENOTIFY
     1664                               (PPROGDETAILS)pcProgDetails,
     1665                               pcProgDetails->pszParameters,
     1666                               NULL,            // "reserved", PMREF says...
     1667                               SAF_INSTALLEDCMDLINE)))
     1668                                    // we MUST use SAF_INSTALLEDCMDLINE
     1669                                    // or no Win-OS/2 session will start...
     1670                                    // whatever is going on here... Warp 4 FP11
     1671
     1672                                    // do not use SAF_STARTCHILDAPP, or the
     1673                                    // app will be terminated automatically
     1674                                    // when the calling process terminates!
     1675    {
     1676        // cannot start app:
     1677        PERRINFO pei;
     1678
     1679        #ifdef DEBUG_PROGRAMSTART
     1680            _Pmpf((__FUNCTION__ ": WinStartApp failed"));
     1681        #endif
     1682
     1683        // unfortunately WinStartApp doesn't
     1684        // return meaningful codes like DosStartSession, so
     1685        // try to see what happened
     1686
     1687        if (pei = WinGetErrorInfo(0))
     1688        {
     1689            #ifdef DEBUG_PROGRAMSTART
     1690                _Pmpf(("  WinGetErrorInfo returned 0x%lX, errorid 0x%lX, %d",
     1691                            pei,
     1692                            pei->idError,
     1693                            ERRORIDERROR(pei->idError)));
     1694            #endif
     1695
     1696            switch (ERRORIDERROR(pei->idError))
    15161697            {
    1517                 PBYTE pThis;
    1518 
    1519                 pNewProgDetails->progt.fbVisible = pcProgDetails->progt.fbVisible;
    1520                 memcpy(&pNewProgDetails->swpInitial, &pcProgDetails->swpInitial, sizeof(SWP));
    1521 
    1522                 // start copying into buffer right after PROGDETAILS
    1523                 pThis = (PBYTE)(pNewProgDetails + 1);
    1524 
    1525                 #define COPY(id) if (cb ## id) { \
    1526                     memcpy(pThis, pcProgDetails->psz ## id, cb ## id); \
    1527                     pNewProgDetails->psz ## id = pThis; \
    1528                     pThis += cb ## id; }
    1529 
    1530                 COPY(Title);
    1531                 COPY(Executable);
    1532                 COPY(Parameters);
    1533                 COPY(StartupDir);
    1534                 COPY(Icon);
    1535                 COPY(Environment);
    1536 
    1537                 #ifdef DEBUG_PROGRAMSTART
    1538                     _Pmpf((__FUNCTION__ ": progt.progc: %d", pNewProgDetails->progt.progc));
    1539                     _Pmpf(("    progt.fbVisible: 0x%lX", pNewProgDetails->progt.fbVisible));
    1540                     _Pmpf(("    progt.pszTitle: \"%s\"", (pNewProgDetails->pszTitle) ? pNewProgDetails->pszTitle : "NULL"));
    1541                     _Pmpf(("    exec: \"%s\"", (pNewProgDetails->pszExecutable) ? pNewProgDetails->pszExecutable : "NULL"));
    1542                     _Pmpf(("    params: \"%s\"", (pNewProgDetails->pszParameters) ? pNewProgDetails->pszParameters : "NULL"));
    1543                     _Pmpf(("    startup: \"%s\"", (pNewProgDetails->pszStartupDir) ? pNewProgDetails->pszStartupDir : "NULL"));
    1544                     _Pmpf(("    pszIcon: \"%s\"", (pNewProgDetails->pszIcon) ? pNewProgDetails->pszIcon : "NULL"));
    1545                     _Pmpf(("    environment: "));
    1546                     {
    1547                         PSZ pszThis = pNewProgDetails->pszEnvironment;
    1548                         while (pszThis && *pszThis)
    1549                         {
    1550                             _Pmpf(("      \"%s\"", pszThis));
    1551                             pszThis += strlen(pszThis) + 1;
    1552                         }
    1553                     }
    1554 
    1555                     _Pmpf(("    swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",
    1556                                 pNewProgDetails->swpInitial.fl,
    1557                                 pNewProgDetails->swpInitial.x,
    1558                                 pNewProgDetails->swpInitial.y,
    1559                                 pNewProgDetails->swpInitial.cx,
    1560                                 pNewProgDetails->swpInitial.cy));
    1561                     _Pmpf(("    behind = %d, hwnd = %d, res1 = %d, res2 = %d",
    1562                                 pNewProgDetails->swpInitial.hwndInsertBehind,
    1563                                 pNewProgDetails->swpInitial.hwnd,
    1564                                 pNewProgDetails->swpInitial.ulReserved1,
    1565                                 pNewProgDetails->swpInitial.ulReserved2));
    1566 
    1567                     /* DumpMemoryBlock((PBYTE)pNewProgDetails,
    1568                                     cb,
    1569                                     8); */
    1570 
    1571                 #endif
    1572 
    1573                 /* if (!(appIsWindowsApp(pNewProgDetails->progt.progc)))
    1574                     arc = CallDosStartSession(phapp,
    1575                                               pNewProgDetails,
     1698                case PMERR_DOS_ERROR: //  (0x1200)
     1699                {
     1700                    /*
     1701                    PUSHORT pausMsgOfs = (PUSHORT)(((PBYTE)pei) + pei->offaoffszMsg);
     1702                    PULONG  pulData    = (PULONG)(((PBYTE)pei) + pei->offBinaryData);
     1703                    PSZ     pszMsg     = (PSZ)(((PBYTE)pei) + *pausMsgOfs);
     1704
     1705                    CHAR szMsg[1000];
     1706                    sprintf(szMsg, "cDetail: %d\nmsg: %s\n*pul: %d",
     1707                            pei->cDetailLevel,
     1708                            pszMsg,
     1709                            *(pulData - 1));
     1710
     1711                    WinMessageBox(HWND_DESKTOP,
     1712                                  NULLHANDLE,
     1713                                  szMsg,
     1714                                  "Error",
     1715                                  0,
     1716                                  MB_OK | MB_MOVEABLE);
     1717
     1718                    // Very helpful. The message is "UNK 1200 E",
     1719                    // where I assume "UNK" means "unknown", which is
     1720                    // exactly what I was trying to find out. Oh my.
     1721                    // And cDetailLevel is always 1, which isn't terribly
     1722                    // helpful either. V0.9.18 (2002-03-27) [umoeller]
     1723                    // WHO THE &%õ$ CREATED THESE APIS?
     1724
     1725                    */
     1726
     1727                    // this is probably the case where the module
     1728                    // couldn't be loaded, so try DosStartSession
     1729                    // to get a meaningful return code... note that
     1730                    // this cannot handle hwndNotify then
     1731                    /* arc = CallDosStartSession(phapp,
     1732                                              pcProgDetails,
    15761733                                              cbFailingName,
    1577                                               pszFailingName);
    1578                 else */
    1579                     // windoze app: use WinStartApp
    1580 
    1581                 if (!(*phapp = WinStartApp(hwndNotify,
    1582                                                     // receives WM_APPTERMINATENOTIFY
    1583                                            pNewProgDetails,
    1584                                            pNewProgDetails->pszParameters,
    1585                                            NULL,            // "reserved", PMREF says...
    1586                                            SAF_INSTALLEDCMDLINE)))
    1587                                                 // we MUST use SAF_INSTALLEDCMDLINE
    1588                                                 // or no Win-OS/2 session will start...
    1589                                                 // whatever is going on here... Warp 4 FP11
    1590 
    1591                                                 // do not use SAF_STARTCHILDAPP, or the
    1592                                                 // app will be terminated automatically
    1593                                                 // when the WPS terminates!
    1594                 {
    1595                     // cannot start app:
    1596                     PERRINFO pei;
    1597 
    1598                     #ifdef DEBUG_PROGRAMSTART
    1599                         _Pmpf((__FUNCTION__ ": WinStartApp failed"));
    1600                     #endif
    1601 
    1602                     // unfortunately WinStartApp doesn't
    1603                     // return meaningful codes like DosStartSession, so
    1604                     // try to see what happened
    1605 
    1606                     if (pei = WinGetErrorInfo(0))
    1607                     {
    1608                         #ifdef DEBUG_PROGRAMSTART
    1609                             _Pmpf(("  WinGetErrorInfo returned 0x%lX, errorid 0x%lX, %d",
    1610                                         pei,
    1611                                         pei->idError,
    1612                                         ERRORIDERROR(pei->idError)));
    1613                         #endif
    1614 
    1615                         switch (ERRORIDERROR(pei->idError))
    1616                         {
    1617                             case PMERR_DOS_ERROR: //  (0x1200)
    1618                             {
    1619                                 /*
    1620                                 PUSHORT pausMsgOfs = (PUSHORT)(((PBYTE)pei) + pei->offaoffszMsg);
    1621                                 PULONG  pulData    = (PULONG)(((PBYTE)pei) + pei->offBinaryData);
    1622                                 PSZ     pszMsg     = (PSZ)(((PBYTE)pei) + *pausMsgOfs);
    1623 
    1624                                 CHAR szMsg[1000];
    1625                                 sprintf(szMsg, "cDetail: %d\nmsg: %s\n*pul: %d",
    1626                                         pei->cDetailLevel,
    1627                                         pszMsg,
    1628                                         *(pulData - 1));
    1629 
    1630                                 WinMessageBox(HWND_DESKTOP,
    1631                                               NULLHANDLE,
    1632                                               szMsg,
    1633                                               "Error",
    1634                                               0,
    1635                                               MB_OK | MB_MOVEABLE);
    1636 
    1637                                 // Very helpful. The message is "UNK 1200 E",
    1638                                 // where I assume "UNK" means "unknown", which is
    1639                                 // exactly what I was trying to find out. Oh my.
    1640                                 // And cDetailLevel is always 1, which isn't terribly
    1641                                 // helpful either. V0.9.18 (2002-03-27) [umoeller]
    1642                                 // WHO THE &%õ$ CREATED THESE APIS?
    1643 
    1644                                 */
    1645 
    1646                                 // this is probably the case where the module
    1647                                 // couldn't be loaded, so try DosStartSession
    1648                                 // to get a meaningful return code... note that
    1649                                 // this cannot handle hwndNotify then
    1650                                 arc = CallDosStartSession(phapp,
    1651                                                           pNewProgDetails,
    1652                                                           cbFailingName,
    1653                                                           pszFailingName);
    1654                             }
    1655                             break;
    1656 
    1657                             case PMERR_INVALID_APPL: //  (0x1530)
    1658                                     // Attempted to start an application whose type is not
    1659                                     // recognized by OS/2.
    1660                                     // This we get also if the executable doesn't exist...
    1661                                     // V0.9.18 (2002-03-27) [umoeller]
    1662                                 // arc = ERROR_INVALID_EXE_SIGNATURE;
    1663                                 arc = ERROR_FILE_NOT_FOUND;
    1664                             break;
    1665 
    1666                             case PMERR_INVALID_PARAMETERS: //  (0x1208)
    1667                                     // An application parameter value is invalid for
    1668                                     // its converted PM type. For  example: a 4-byte
    1669                                     // value outside the range -32 768 to +32 767 cannot be
    1670                                     // converted to a SHORT, and a negative number cannot
    1671                                     // be converted to a ULONG or USHORT.
    1672                                 arc = ERROR_INVALID_DATA;
    1673                             break;
    1674 
    1675                             case PMERR_STARTED_IN_BACKGROUND: //  (0x1532)
    1676                                     // The application started a new session in the
    1677                                     // background.
    1678                                 arc = ERROR_SMG_START_IN_BACKGROUND;
    1679                             break;
    1680 
    1681                             case PMERR_INVALID_WINDOW: // (0x1206)
    1682                                     // The window specified with a Window List call
    1683                                     // is not a valid frame window.
    1684 
    1685                             default:
    1686                                 arc = ERROR_BAD_FORMAT;
    1687                             break;
    1688                         }
    1689 
    1690                         WinFreeErrorInfo(pei);
    1691                     }
     1734                                              pszFailingName); */
     1735                    arc = ERROR_FILE_NOT_FOUND;
    16921736                }
     1737                break;
     1738
     1739                case PMERR_INVALID_APPL: //  (0x1530)
     1740                        // Attempted to start an application whose type is not
     1741                        // recognized by OS/2.
     1742                        // This we get also if the executable doesn't exist...
     1743                        // V0.9.18 (2002-03-27) [umoeller]
     1744                    // arc = ERROR_INVALID_EXE_SIGNATURE;
     1745                    arc = ERROR_FILE_NOT_FOUND;
     1746                break;
     1747
     1748                case PMERR_INVALID_PARAMETERS: //  (0x1208)
     1749                        // An application parameter value is invalid for
     1750                        // its converted PM type. For  example: a 4-byte
     1751                        // value outside the range -32 768 to +32 767 cannot be
     1752                        // converted to a SHORT, and a negative number cannot
     1753                        // be converted to a ULONG or USHORT.
     1754                    arc = ERROR_INVALID_DATA;
     1755                break;
     1756
     1757                case PMERR_STARTED_IN_BACKGROUND: //  (0x1532)
     1758                        // The application started a new session in the
     1759                        // background.
     1760                    arc = ERROR_SMG_START_IN_BACKGROUND;
     1761                break;
     1762
     1763                case PMERR_INVALID_WINDOW: // (0x1206)
     1764                        // The window specified with a Window List call
     1765                        // is not a valid frame window.
     1766
     1767                default:
     1768                    arc = ERROR_BAD_FORMAT;
     1769                break;
    16931770            }
    16941771
    1695             DosFreeMem(pNewProgDetails);
     1772            WinFreeErrorInfo(pei);
    16961773        }
    16971774    }
     
    17061783 *      work with all executable types.
    17071784 *
    1708  *      This fixes the executable info to support:
    1709  *
    1710  *      -- starting "*" executables (command prompts
    1711  *         for OS/2, DOS, Win-OS/2);
    1712  *
    1713  *      -- starting ".CMD" and ".BAT" files as
    1714  *         PROGDETAILS.pszExecutable;
    1715  *
    1716  *      -- starting apps which are not fully qualified
    1717  *         and therefore assumed to be on the PATH.
    1718  *
    1719  *      Unless it is "*", PROGDETAILS.pszExecutable must
    1720  *      be a proper file name. The full path may be omitted
    1721  *      if it is on the PATH, but the extension (.EXE etc.)
    1722  *      must be given. You can use doshFindExecutable to
    1723  *      find executables if you don't know the extension.
    1724  *
    1725  *      This also handles and merges special and default
    1726  *      environments for the app to be started. The
    1727  *      following should be respected:
    1728  *
    1729  *      --  As with WinStartApp, if PROGDETAILS.pszEnvironment
    1730  *          is NULL, the new app inherits a default environment
    1731  *          from the shell.
    1732  *
    1733  *      --  However, if you specify an environment, you _must_
    1734  *          specify a complete environment. This function
    1735  *          will not merge environments. Use
    1736  *          appSetEnvironmentVar to change environment
    1737  *          variables in a complete environment set.
    1738  *
    1739  *      --  If PROGDETAILS specifies a Win-OS/2 session
    1740  *          and PROGDETAILS.pszEnvironment is empty,
    1741  *          this uses the default Win-OS/2 environment.
    1742  *          See appQueryDefaultWin31Environment.
    1743  *
    1744  *      Even though this isn't clearly said in PMREF,
    1745  *      PROGDETAILS.swpInitial is important:
    1746  *
    1747  *      -- To start a session minimized, set SWP_MINIMIZE.
    1748  *
    1749  *      -- To start a VIO session with auto-close disabled,
    1750  *         set the half-documented SWP_NOAUTOCLOSE flag (0x8000)
    1751  *         This flag is now in the newer toolkit headers.
    1752  *
    1753  *      In addition, this supports the following session
    1754  *      flags with ulFlags if PROG_DEFAULT is specified:
    1755  *
    1756  *      --  APP_RUN_FULLSCREEN
    1757  *
    1758  *      --  APP_RUN_ENHANCED
    1759  *
    1760  *      --  APP_RUN_STANDARD
    1761  *
    1762  *      --  APP_RUN_SEPARATE
     1785 *      This first calls appBuildProgDetails (see
     1786 *      remarks there) and then calls WinStartApp.
    17631787 *
    17641788 *      Since this calls WinStartApp in turn, this
     
    17751799 *          See remarks below.
    17761800 *
    1777  *      --  ERROR_INVALID_PARAMETER: pcProgDetails or
    1778  *          phapp is NULL; or PROGDETAILS.pszExecutable is NULL.
    1779  *
    1780  *      --  ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND:
    1781  *          PROGDETAILS.pszExecutable and/or PROGDETAILS.pszStartupDir
    1782  *          are invalid.
    1783  *          A NULL PROGDETAILS.pszStartupDir is supported though.
    1784  *
    17851801 *      --  ERROR_NOT_ENOUGH_MEMORY
     1802 *
     1803 *      plus the many error codes from appBuildProgDetails,
     1804 *      which gets called in turn.
    17861805 *
    17871806 *      <B>About enforcing thread 1</B>
     
    17971816 *          this is not running on thread 1.
    17981817 *
    1799  *      --  By contrast, WinStartApp hangs the system with
    1800  *          VIO sessions if we do the XWorkplace tricky of
    1801  *          redirecting WPProgram::wpOpen to thread 1
    1802  *          via WinPostMsg to the kernel thread-1 object
    1803  *          window. This also happens with DosStartSession,
    1804  *          so I suspect the bug is somewhere deeper in
    1805  *          SESMGR or wherever. So we no longer return
    1806  *          ERROR_INVALID_THREADID for non-Win-OS/2 sessions
    1807  *          (V0.9.18).
     1818 *      --  By contrast, there are many situations where
     1819 *          calling WinStartApp from within the Workplace
     1820 *          process will hang the system, most notably
     1821 *          with VIO sessions. I have been unable to figure
     1822 *          out why this happens, so XWorkplace now uses
     1823 *          its daemon to call WinStartApp instead.
     1824 *
     1825 *          As a word of wisdom, do not call this from
     1826 *          within the Workplace process. For some strange
     1827 *          reason though, the XWorkplace "Run" dialog
     1828 *          (which uses this) _does_ work. Whatever.
    18081829 *
    18091830 *@@added V0.9.6 (2000-10-16) [umoeller]
     
    18221843 *@@changed V0.9.18 (2002-02-13) [umoeller]: added CallWinStartApp to fix possible memory problems
    18231844 *@@changed V0.9.18 (2002-03-27) [umoeller]: no longer returning ERROR_INVALID_THREADID, except for Win-OS/2 sessions
    1824  *@@changed V0.9.18 (2002-03-27) [umoeller]: extracted appFixProgDetails
     1845 *@@changed V0.9.18 (2002-03-27) [umoeller]: extracted appBuildProgDetails
     1846 *@@changed V0.9.19 (2002-03-28) [umoeller]: adjusted for new appBuildProgDetails
    18251847 */
    18261848
     
    18331855{
    18341856    APIRET          arc;
    1835     PROGDETAILS     ProgDetails;
    1836     XSTRING         strExecutablePatched,
    1837                     strParamsPatched;
    1838     PSZ             pszWinOS2Env = 0;
    1839 
    1840     if (pszFailingName)
    1841         *pszFailingName = '\0';
    1842 
    1843     if (!pcProgDetails || !phapp)
     1857
     1858    PPROGDETAILS    pDetails;
     1859
     1860    if (!phapp)
    18441861        return (ERROR_INVALID_PARAMETER);
    18451862
    1846     xstrInit(&strExecutablePatched, 0);
    1847     xstrInit(&strParamsPatched, 0);
    1848 
    1849     if (!(arc = appFixProgDetails(&ProgDetails,
    1850                                   pcProgDetails,
    1851                                   ulFlags,
    1852                                   &strExecutablePatched,
    1853                                   &strParamsPatched,
    1854                                   &pszWinOS2Env)))
     1863    if (!(arc = appBuildProgDetails(&pDetails,
     1864                                    pcProgDetails,
     1865                                    ulFlags)))
    18551866    {
    18561867        if (pszFailingName)
    1857             strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName);
    1858 
    1859         if (    (appIsWindowsApp(ProgDetails.progt.progc))
     1868            strhncpy0(pszFailingName, pDetails->pszExecutable, cbFailingName);
     1869
     1870        if (    (appIsWindowsApp(pDetails->progt.progc))
    18601871             && (doshMyTID() != 1)          // V0.9.16 (2001-10-19) [umoeller]
    18611872           )
     
    18641875            arc = CallWinStartApp(phapp,
    18651876                                  hwndNotify,
    1866                                   &ProgDetails,
     1877                                  pDetails,
    18671878                                  cbFailingName,
    18681879                                  pszFailingName);
     1880
     1881        DosFreeMem(pDetails);
     1882
    18691883    } // end if (ProgDetails.pszExecutable)
    1870 
    1871     xstrClear(&strParamsPatched);
    1872     xstrClear(&strExecutablePatched);
    1873 
    1874     if (pszWinOS2Env)
    1875         free(pszWinOS2Env);
    18761884
    18771885    #ifdef DEBUG_PROGRAMSTART
Note: See TracChangeset for help on using the changeset viewer.