Ignore:
Timestamp:
Jan 5, 2002, 8:11:10 PM (24 years ago)
Author:
umoeller
Message:

Tons of updates for turbo folders and replacement icons.

File:
1 edited

Legend:

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

    r123 r127  
    3333
    3434#define INCL_DOSPROCESS
     35#define INCL_DOSMODULEMGR
    3536#define INCL_DOSSESMGR
    3637#define INCL_DOSERRORS
    3738
    3839#define INCL_WINPROGRAMLIST     // needed for PROGDETAILS, wppgm.h
     40#define INCL_WINERRORS
     41#define INCL_SHLERRORS
    3942#include <os2.h>
    4043
     
    107110
    108111APIRET appParseEnvironment(const char *pcszEnv,
    109                            PDOSENVIRONMENT pEnv)
     112                           PDOSENVIRONMENT pEnv)        // out: new environment
    110113{
    111114    APIRET arc = NO_ERROR;
     
    123126        }
    124127
    125         pEnv->cVars = cVars;
     128        pEnv->cVars = 0;
    126129        pEnv->papszVars = 0;
    127130
    128131        if (cVars)
    129132        {
    130             PSZ *papsz = (PSZ*)malloc(sizeof(PSZ) * cVars);
    131             if (!papsz)
     133            ULONG cbArray = sizeof(PSZ) * cVars;
     134            PSZ *papsz;
     135            if (!(papsz = (PSZ*)malloc(cbArray)))
    132136                arc = ERROR_NOT_ENOUGH_MEMORY;
    133137            else
    134138            {
    135139                PSZ *ppszTarget = papsz;
    136                 memset(papsz, 0, sizeof(PSZ) * cVars);
     140                memset(papsz, 0, cbArray);
    137141                pszVarThis = (PSZ)pcszEnv;
    138142                while (*pszVarThis)
    139143                {
    140                     *ppszTarget = strdup(pszVarThis);
     144                    ULONG ulThisLen;
     145                    if (!(*ppszTarget = strhdup(pszVarThis, &ulThisLen)))
     146                    {
     147                        arc = ERROR_NOT_ENOUGH_MEMORY;
     148                        break;
     149                    }
     150                    (pEnv->cVars)++;
    141151                    ppszTarget++;
    142                     pszVarThis += strlen(pszVarThis) + 1;
     152                    pszVarThis += ulThisLen + 1;
    143153                }
    144154
     
    156166 *      process environment, which is retrieved from
    157167 *      the info blocks.
     168 *
     169 *      Returns:
     170 *
     171 *      --  NO_ERROR:
     172 *
     173 *      --  ERROR_INVALID_PARAMETER
     174 *
     175 *      --  ERROR_BAD_ENVIRONMENT: no environment found in
     176 *          info blocks.
    158177 *
    159178 *@@added V0.9.4 (2000-07-19) [umoeller]
     
    173192        if (arc == NO_ERROR)
    174193        {
    175             PSZ pszEnv = ppib->pib_pchenv;
    176             if (pszEnv)
     194            PSZ pszEnv;
     195            if (pszEnv = ppib->pib_pchenv)
    177196                arc = appParseEnvironment(pszEnv, pEnv);
    178197            else
     
    200219 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    201220 *@@changed V0.9.12 (2001-05-27) [umoeller]: moved from dosh2.c to apps.c
     221 *@@changed V0.9.16 (2002-01-01) [umoeller]: removed extra heap allocation
    202222 */
    203223
     
    205225                           PSZ pszVarName)
    206226{
    207     PSZ *ppszRet = 0;
    208     if (pEnv)
    209     {
    210         if ((pEnv->papszVars) && (pszVarName))
    211         {
    212             PSZ     *ppszThis = pEnv->papszVars;
    213             // PSZ     pszThis;
    214             ULONG   ul = 0;
    215             ULONG   ulVarNameLen = 0;
    216 
    217             PSZ     pszSearch = NULL; // receives "VARNAME="
    218             PSZ     pFirstEqual = strchr(pszVarName, '=');
    219             if (pFirstEqual)
    220                 pszSearch = strhSubstr(pszVarName, pFirstEqual + 1);
    221             else
    222             {
    223                 ulVarNameLen = strlen(pszVarName);
    224                 pszSearch = (PSZ)malloc(ulVarNameLen + 2);
    225                 memcpy(pszSearch, pszVarName, ulVarNameLen);
    226                 *(pszSearch + ulVarNameLen) = '=';
    227                 *(pszSearch + ulVarNameLen + 1) = 0;
    228             }
    229 
    230             ulVarNameLen = strlen(pszSearch);
    231 
    232             for (ul = 0;
    233                  ul < pEnv->cVars;
    234                  ul++)
    235             {
    236                 if (strnicmp(*ppszThis, pszSearch, ulVarNameLen) == 0)
     227    PSZ     *ppszRet = 0;
     228
     229    if (    (pEnv)
     230         && (pEnv->papszVars)
     231         && (pszVarName)
     232       )
     233    {
     234        ULONG   ul = 0;
     235        ULONG   ulVarNameLen = 0;
     236
     237        PSZ     pFirstEqual;
     238        // rewrote all the following for speed V0.9.16 (2002-01-01) [umoeller]
     239        if (pFirstEqual = strchr(pszVarName, '='))
     240            // VAR=VALUE
     241            //    ^ pFirstEqual
     242            ulVarNameLen = pFirstEqual - pszVarName;
     243        else
     244            ulVarNameLen = strlen(pszVarName);
     245
     246        for (ul = 0;
     247             ul < pEnv->cVars;
     248             ul++)
     249        {
     250            PSZ pszThis = pEnv->papszVars[ul];
     251            if (pFirstEqual = strchr(pszThis, '='))
     252            {
     253                ULONG ulLenThis = pFirstEqual - pszThis;
     254                if (    (ulLenThis == ulVarNameLen)
     255                     && (!memicmp(pszThis,
     256                                  pszVarName,
     257                                  ulVarNameLen))
     258                   )
    237259                {
    238                     ppszRet = ppszThis;
     260                    ppszRet = &pEnv->papszVars[ul];
    239261                    break;
    240262                }
    241 
    242                 // next environment string
    243                 ppszThis++;
    244             }
    245 
    246             free(pszSearch);        // was missing V0.9.12 (2001-05-21) [umoeller]
     263            }
    247264        }
    248265    }
     
    296313        else
    297314        {
    298             PSZ *ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv);
    299             if (ppszEnvLine)
    300             {
     315            PSZ *ppszEnvLine;
     316            if (ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv))
    301317                // was set already: replace
    302                 free(*ppszEnvLine);
    303                 *ppszEnvLine = strdup(pszNewEnv);
    304                 if (!(*ppszEnvLine))
    305                     arc = ERROR_NOT_ENOUGH_MEMORY;
    306             }
     318                arc = strhStore(ppszEnvLine,
     319                                pszNewEnv,
     320                                NULL);
    307321            else
    308322            {
     
    312326                // allocate new array, with one new entry
    313327                // fixed V0.9.12 (2001-05-26) [umoeller], this crashed
    314                 PSZ *papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1));
    315 
    316                 if (!papszNew)
     328                PSZ *papszNew;
     329
     330                if (!(papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1))))
    317331                    arc = ERROR_NOT_ENOUGH_MEMORY;
    318332                else
     
    339353                    }
    340354
    341                     if (pEnv->papszVars)
    342                         free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    343 
     355                    free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    344356                    pEnv->papszVars = papszNew;
    345357                    pEnv->cVars++;
     
    374386{
    375387    APIRET  arc = NO_ERROR;
    376     if (!pEnv)
     388    if (    (!pEnv)
     389         || (!pEnv->papszVars)
     390       )
    377391        arc = ERROR_INVALID_PARAMETER;
    378392    else
    379393    {
    380         if (!pEnv->papszVars)
    381             arc = ERROR_INVALID_PARAMETER;
     394        // count memory needed for all strings
     395        ULONG   cbNeeded = 0,
     396                ul = 0;
     397        PSZ     *ppszThis = pEnv->papszVars;
     398
     399        for (ul = 0;
     400             ul < pEnv->cVars;
     401             ul++)
     402        {
     403            cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
     404
     405            // next environment string
     406            ppszThis++;
     407        }
     408
     409        cbNeeded++;     // for another null terminator
     410
     411        if (!(*ppszEnv = (PSZ)malloc(cbNeeded)))
     412            arc = ERROR_NOT_ENOUGH_MEMORY;
    382413        else
    383414        {
    384             // count memory needed for all strings
    385             ULONG   cbNeeded = 0,
    386                     ul = 0;
    387             PSZ     *ppszThis = pEnv->papszVars;
    388 
     415            PSZ     pTarget = *ppszEnv;
     416            if (pulSize)
     417                *pulSize = cbNeeded;
     418            ppszThis = pEnv->papszVars;
     419
     420            // now copy each string
    389421            for (ul = 0;
    390422                 ul < pEnv->cVars;
    391423                 ul++)
    392424            {
    393                 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
     425                PSZ pSource = *ppszThis;
     426
     427                while ((*pTarget++ = *pSource++))
     428                    ;
     429
     430                // *pTarget++ = 0;     // append null terminator per string
    394431
    395432                // next environment string
     
    397434            }
    398435
    399             cbNeeded++;     // for another null terminator
    400 
    401             *ppszEnv = (PSZ)malloc(cbNeeded);
    402             if (!(*ppszEnv))
    403                 arc = ERROR_NOT_ENOUGH_MEMORY;
    404             else
    405             {
    406                 PSZ     pTarget = *ppszEnv;
    407                 if (pulSize)
    408                     *pulSize = cbNeeded;
    409                 ppszThis = pEnv->papszVars;
    410 
    411                 // now copy each string
    412                 for (ul = 0;
    413                      ul < pEnv->cVars;
    414                      ul++)
    415                 {
    416                     PSZ pSource = *ppszThis;
    417 
    418                     while ((*pTarget++ = *pSource++))
    419                         ;
    420 
    421                     // *pTarget++ = 0;     // append null terminator per string
    422 
    423                     // next environment string
    424                     ppszThis++;
    425                 }
    426 
    427                 *pTarget++ = 0;     // append second null terminator
    428             }
     436            *pTarget++ = 0;     // append second null terminator
    429437        }
    430438    }
     
    444452{
    445453    APIRET  arc = NO_ERROR;
    446     if (!pEnv)
     454    if (    (!pEnv)
     455         || (!pEnv->papszVars)
     456       )
    447457        arc = ERROR_INVALID_PARAMETER;
    448458    else
    449459    {
    450         if (!pEnv->papszVars)
    451             arc = ERROR_INVALID_PARAMETER;
    452         else
    453         {
    454             PSZ     *ppszThis = pEnv->papszVars;
    455             PSZ     pszThis;
    456             ULONG   ul = 0;
    457 
    458             for (ul = 0;
    459                  ul < pEnv->cVars;
    460                  ul++)
    461             {
    462                 pszThis = *ppszThis;
    463                 free(pszThis);
    464                 // *ppszThis = NULL;
    465                 // next environment string
    466                 ppszThis++;
    467             }
    468 
    469             free(pEnv->papszVars);
    470             pEnv->cVars = 0;
    471         }
     460        PSZ     *ppszThis = pEnv->papszVars;
     461        PSZ     pszThis;
     462        ULONG   ul = 0;
     463
     464        for (ul = 0;
     465             ul < pEnv->cVars;
     466             ul++)
     467        {
     468            pszThis = *ppszThis;
     469            free(pszThis);
     470            // *ppszThis = NULL;
     471            // next environment string
     472            ppszThis++;
     473        }
     474
     475        free(pEnv->papszVars);
     476        pEnv->cVars = 0;
    472477    }
    473478
     
    920925 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check
    921926 *@@changed V0.9.16 (2001-12-06) [umoeller]: now using doshSearchPath for finding pszExecutable if not qualified
     927 *@@changed V0.9.16 (2002-01-04) [umoeller]: removed error report if startup directory was drive letter only
     928 *@@changed V0.9.16 (2002-01-04) [umoeller]: added more detailed error reports and *FailingName params
    922929 */
    923930
     
    925932                   const PROGDETAILS *pcProgDetails, // in: program spec (req.)
    926933                   ULONG ulFlags,          // in: APP_RUN_* flags
    927                    HAPP *phapp)            // out: application handle if NO_ERROR is returned
     934                   HAPP *phapp,            // out: application handle if NO_ERROR is returned
     935                   ULONG cbFailingName,
     936                   PSZ pszFailingName)
    928937{
    929938    APIRET          arc = NO_ERROR;
    930939    PROGDETAILS     ProgDetails;
     940
     941    if (pszFailingName)
     942        *pszFailingName = '\0';
    931943
    932944    if (!pcProgDetails || !phapp)
     
    10811093                    if (ProgDetails.pszStartupDir)
    10821094                    {
    1083                         if (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
    1084                                                       &ulAttr)))
    1085                             if (!(ulAttr & FILE_DIRECTORY))
    1086                                 arc = ERROR_PATH_NOT_FOUND;
     1095                        // it is valid to specify a startup dir of "C:"
     1096                        if (    (strlen(ProgDetails.pszStartupDir) > 2)
     1097                             && (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir,
     1098                                                           &ulAttr)))
     1099                             && (!(ulAttr & FILE_DIRECTORY))
     1100                           )
     1101                            arc = ERROR_PATH_NOT_FOUND;
    10871102                    }
    10881103                }
     
    12221237                                  MB_YESNO | MB_MOVEABLE)
    12231238                          == MBID_YES) */
     1239
     1240                if (pszFailingName)
     1241                    strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName);
     1242
    12241243                if (!(*phapp = WinStartApp(hwndNotify,
    12251244                                                    // receives WM_APPTERMINATENOTIFY
     
    12351254                                                // app will be terminated automatically
    12361255                                                // when the WPS terminates!
    1237                     arc = ERROR_BAD_FORMAT;
    1238                             // @@todo we can probably do better
    1239                             // V0.9.16 (2001-10-19) [umoeller]
    1240 
    1241                 // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
     1256                {
     1257                    // cannot start app: unfortunately WinStartApp doesn't
     1258                    // return meaningful codes like DosStartSession, so
     1259                    // try to see what happened
     1260                    switch (ERRORIDERROR(WinGetLastError(0)))
     1261                    {
     1262                        case PMERR_DOS_ERROR: //  (0x1200)
     1263                        {
     1264                            // this is probably the case where the module
     1265                            // couldn't be loaded, so try DosStartSession
     1266                            // to get a meaningful return code... note that
     1267                            // this cannot handle hwndNotify then
     1268                            RESULTCODES result;
     1269                            arc = DosExecPgm(pszFailingName,
     1270                                             cbFailingName,
     1271                                             EXEC_ASYNC,
     1272                                             NULL, // ProgDetails.pszParameters,
     1273                                             NULL, // ProgDetails.pszEnvironment,
     1274                                             &result,
     1275                                             ProgDetails.pszExecutable);
     1276
     1277                            /* ULONG sid, pid;
     1278                            STARTDATA   SData;
     1279                            SData.Length  = sizeof(STARTDATA);
     1280                            SData.Related = SSF_RELATED_CHILD; //INDEPENDENT;
     1281                            SData.FgBg    = SSF_FGBG_FORE;
     1282                            SData.TraceOpt = SSF_TRACEOPT_NONE;
     1283
     1284                            SData.PgmTitle = ProgDetails.pszTitle;
     1285                            SData.PgmName = ProgDetails.pszExecutable;
     1286                            SData.PgmInputs = ProgDetails.pszParameters;
     1287
     1288                            SData.TermQ = NULL;
     1289                            SData.Environment = ProgDetails.pszEnvironment;
     1290                            SData.InheritOpt = SSF_INHERTOPT_PARENT;    // ignored
     1291                            SData.SessionType = SSF_TYPE_DEFAULT;
     1292                            SData.IconFile = 0;
     1293                            SData.PgmHandle = 0;
     1294
     1295                            SData.PgmControl = SSF_CONTROL_VISIBLE;
     1296
     1297                            SData.InitXPos  = 30;
     1298                            SData.InitYPos  = 40;
     1299                            SData.InitXSize = 200;
     1300                            SData.InitYSize = 140;
     1301                            SData.Reserved = 0;
     1302                            SData.ObjectBuffer  = pszFailingName;
     1303                            SData.ObjectBuffLen = cbFailingName;
     1304
     1305                            arc = DosStartSession(&SData, &sid, &pid);
     1306                            */
     1307                        }
     1308                        break;
     1309
     1310                        case PMERR_INVALID_APPL: //  (0x1530)
     1311                                // Attempted to start an application whose type is not
     1312                                // recognized by OS/2.
     1313                            arc = ERROR_INVALID_EXE_SIGNATURE;
     1314                        break;
     1315
     1316                        case PMERR_INVALID_PARAMETERS: //  (0x1208)
     1317                                // An application parameter value is invalid for
     1318                                // its converted PM type. For  example: a 4-byte
     1319                                // value outside the range -32 768 to +32 767 cannot be
     1320                                // converted to a SHORT, and a negative number cannot
     1321                                // be converted to a ULONG or USHORT.
     1322                            arc = ERROR_INVALID_DATA;
     1323                        break;
     1324
     1325                        case PMERR_STARTED_IN_BACKGROUND: //  (0x1532)
     1326                                // The application started a new session in the
     1327                                // background.
     1328                            arc = ERROR_SMG_START_IN_BACKGROUND;
     1329                        break;
     1330
     1331                        case PMERR_INVALID_WINDOW: // (0x1206)
     1332                                // The window specified with a Window List call
     1333                                // is not a valid frame window.
     1334
     1335                        default:
     1336                            arc = ERROR_BAD_FORMAT;
     1337                        break;
     1338                    }
     1339                }
    12421340            }
    12431341        }
     
    13441442                          &pd,
    13451443                          0,
    1346                           &happ))
     1444                          &happ,
     1445                          0,
     1446                          NULL))
    13471447       )
    13481448    {
Note: See TracChangeset for help on using the changeset viewer.