Changeset 76


Ignore:
Timestamp:
May 27, 2001, 8:10:36 AM (24 years ago)
Author:
umoeller
Message:

Misc changes.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/dosh.h

    r69 r76  
    376376                                 PULONG pulSID,
    377377                                 PPID ppid);
    378 
    379     /* ******************************************************************
    380      *
    381      *   Environment helpers
    382      *
    383      ********************************************************************/
    384 
    385     /*
    386      *@@ DOSENVIRONMENT:
    387      *      structure holding an array of environment
    388      *      variables (papszVars). This is initialized
    389      *      doshGetEnvironment,
    390      *
    391      *@@added V0.9.4 (2000-07-19) [umoeller]
    392      */
    393 
    394     typedef struct _DOSENVIRONMENT
    395     {
    396         ULONG       cVars;              // count of vars in papzVars
    397         PSZ         *papszVars;         // array of PSZ's to environment strings (VAR=VALUE)
    398     } DOSENVIRONMENT, *PDOSENVIRONMENT;
    399 
    400     APIRET doshParseEnvironment(const char *pcszEnv,
    401                                 PDOSENVIRONMENT pEnv);
    402 
    403     APIRET doshGetEnvironment(PDOSENVIRONMENT pEnv);
    404 
    405     PSZ* doshFindEnvironmentVar(PDOSENVIRONMENT pEnv,
    406                                 PSZ pszVarName);
    407 
    408     APIRET doshSetEnvironmentVar(PDOSENVIRONMENT pEnv,
    409                                  PSZ pszNewEnv,
    410                                  BOOL fAddFirst);
    411 
    412     APIRET doshConvertEnvironment(PDOSENVIRONMENT pEnv,
    413                                   PSZ *ppszEnv,
    414                                   PULONG pulSize);
    415 
    416     APIRET doshFreeEnvironment(PDOSENVIRONMENT pEnv);
    417378
    418379    /********************************************************************
  • trunk/include/helpers/winh.h

    r73 r76  
    4040 *@@include #define INCL_WINSHELLDATA
    4141 *@@include #define INCL_WINSWITCHLIST      // for winhQuerySwitchList
    42  *@@include #define INCL_WINPROGRAMLIST     // for winhStartApp
     42 *@@include #define INCL_WINPROGRAMLIST     // for appStartApp
    4343 *@@include #define INCL_WINHELP            // for help manager helpers
    4444 *@@include #include <os2.h>
     
    682682     ********************************************************************/
    683683
    684     #ifdef INCL_WINPROGRAMLIST
    685         // additional PROG_* flags for winhQueryAppType
    686         #define PROG_XWP_DLL            998      // dynamic link library
    687 
    688         APIRET winhQueryAppType(const char *pcszExecutable,
    689                                 PULONG pulDosAppType,
    690                                 PULONG pulWinAppType);
    691 
    692         HAPP XWPENTRY winhStartApp(HWND hwndNotify, const PROGDETAILS *pcProgDetails);
    693     #endif
    694 
    695684    BOOL XWPENTRY winhAnotherInstance(const char *pcszSemName, BOOL fSwitch);
    696685
  • trunk/src/helpers/dosh2.c

    r71 r76  
    349349
    350350    return (arc);       // V0.9.9 (2001-04-04) [umoeller]
    351 }
    352 
    353 /*
    354  *@@category: Helpers\Control program helpers\Environment management
    355  *      helpers for managing those ugly environment string arrays
    356  *      that are used with DosStartSession and WinStartApp.
    357  */
    358 
    359 /* ******************************************************************
    360  *
    361  *   Environment helpers
    362  *
    363  ********************************************************************/
    364 
    365 /*
    366  *@@ doshParseEnvironment:
    367  *      this takes one of those ugly environment strings
    368  *      as used by DosStartSession and WinStartApp (with
    369  *      lots of zero-terminated strings one after another
    370  *      and a duplicate zero byte as a terminator) as
    371  *      input and splits it into an array of separate
    372  *      strings in pEnv.
    373  *
    374  *      The newly allocated strings are stored in in
    375  *      pEnv->papszVars. The array count is stored in
    376  *      pEnv->cVars.
    377  *
    378  *      Each environment variable will be copied into
    379  *      one newly allocated string in the array. Use
    380  *      doshFreeEnvironment to free the memory allocated
    381  *      by this function.
    382  *
    383  *      Use the following code to browse thru the array:
    384  +
    385  +          DOSENVIRONMENT Env = {0};
    386  +          if (doshParseEnvironment(pszEnv,
    387  +                                   &Env)
    388  +                  == NO_ERROR)
    389  +          {
    390  +              if (Env.papszVars)
    391  +              {
    392  +                  PSZ *ppszThis = Env.papszVars;
    393  +                  for (ul = 0;
    394  +                       ul < Env.cVars;
    395  +                       ul++)
    396  +                  {
    397  +                      PSZ pszThis = *ppszThis;
    398  +                      // pszThis now has something like PATH=C:\TEMP
    399  +                      // ...
    400  +                      // next environment string
    401  +                      ppszThis++;
    402  +                  }
    403  +              }
    404  +              doshFreeEnvironment(&Env);
    405  +          }
    406  *
    407  *@@added V0.9.4 (2000-08-02) [umoeller]
    408  */
    409 
    410 APIRET doshParseEnvironment(const char *pcszEnv,
    411                             PDOSENVIRONMENT pEnv)
    412 {
    413     APIRET arc = NO_ERROR;
    414     if (!pcszEnv)
    415         arc = ERROR_INVALID_PARAMETER;
    416     else
    417     {
    418         PSZ     pszVarThis = (PSZ)pcszEnv;
    419         ULONG   cVars = 0;
    420         // count strings
    421         while (*pszVarThis)
    422         {
    423             cVars++;
    424             pszVarThis += strlen(pszVarThis) + 1;
    425         }
    426 
    427         pEnv->cVars = cVars;
    428         pEnv->papszVars = 0;
    429 
    430         if (cVars)
    431         {
    432             PSZ *papsz = (PSZ*)malloc(sizeof(PSZ) * cVars);
    433             if (!papsz)
    434                 arc = ERROR_NOT_ENOUGH_MEMORY;
    435             else
    436             {
    437                 PSZ *ppszTarget = papsz;
    438                 memset(papsz, 0, sizeof(PSZ) * cVars);
    439                 pszVarThis = (PSZ)pcszEnv;
    440                 while (*pszVarThis)
    441                 {
    442                     *ppszTarget = strdup(pszVarThis);
    443                     ppszTarget++;
    444                     pszVarThis += strlen(pszVarThis) + 1;
    445                 }
    446 
    447                 pEnv->papszVars = papsz;
    448             }
    449         }
    450     }
    451 
    452     return (arc);
    453 }
    454 
    455 /*
    456  *@@ doshGetEnvironment:
    457  *      calls doshParseEnvironment for the current
    458  *      process environment, which is retrieved from
    459  *      the info blocks.
    460  *
    461  *@@added V0.9.4 (2000-07-19) [umoeller]
    462  */
    463 
    464 APIRET doshGetEnvironment(PDOSENVIRONMENT pEnv)
    465 {
    466     APIRET  arc = NO_ERROR;
    467     if (!pEnv)
    468         arc = ERROR_INVALID_PARAMETER;
    469     else
    470     {
    471         PTIB    ptib = 0;
    472         PPIB    ppib = 0;
    473         arc = DosGetInfoBlocks(&ptib, &ppib);
    474         if (arc == NO_ERROR)
    475         {
    476             PSZ pszEnv = ppib->pib_pchenv;
    477             if (pszEnv)
    478                 arc = doshParseEnvironment(pszEnv, pEnv);
    479             else
    480                 arc = ERROR_BAD_ENVIRONMENT;
    481         }
    482     }
    483 
    484     return (arc);
    485 }
    486 
    487 /*
    488  *@@ doshFindEnvironmentVar:
    489  *      returns the PSZ* in the pEnv->papszVars array
    490  *      which specifies the environment variable in pszVarName.
    491  *
    492  *      With pszVarName, you can either specify the variable
    493  *      name only ("VARNAME") or a full environment string
    494  *      ("VARNAME=BLAH"). In any case, only the variable name
    495  *      is compared.
    496  *
    497  *      Returns NULL if no such variable name was found in
    498  *      the array.
    499  *
    500  *@@added V0.9.4 (2000-07-19) [umoeller]
    501  *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    502  */
    503 
    504 PSZ* doshFindEnvironmentVar(PDOSENVIRONMENT pEnv,
    505                             PSZ pszVarName)
    506 {
    507     PSZ *ppszRet = 0;
    508     if (pEnv)
    509     {
    510         if ((pEnv->papszVars) && (pszVarName))
    511         {
    512             PSZ     *ppszThis = pEnv->papszVars;
    513             PSZ     pszThis;
    514             ULONG   ul = 0;
    515             ULONG   ulVarNameLen = 0;
    516 
    517             PSZ     pszSearch = NULL; // receives "VARNAME="
    518             PSZ     pFirstEqual = strchr(pszVarName, '=');
    519             if (pFirstEqual)
    520                 pszSearch = strhSubstr(pszVarName, pFirstEqual + 1);
    521             else
    522             {
    523                 ulVarNameLen = strlen(pszVarName);
    524                 pszSearch = (PSZ)malloc(ulVarNameLen + 2);
    525                 memcpy(pszSearch, pszVarName, ulVarNameLen);
    526                 *(pszSearch + ulVarNameLen) = '=';
    527                 *(pszSearch + ulVarNameLen + 1) = 0;
    528             }
    529 
    530             ulVarNameLen = strlen(pszSearch);
    531 
    532             for (ul = 0;
    533                  ul < pEnv->cVars;
    534                  ul++)
    535             {
    536                 pszThis = *ppszThis;
    537 
    538                 if (strnicmp(*ppszThis, pszSearch, ulVarNameLen) == 0)
    539                 {
    540                     ppszRet = ppszThis;
    541                     break;
    542                 }
    543 
    544                 // next environment string
    545                 ppszThis++;
    546             }
    547 
    548             free(pszSearch);        // was missing V0.9.12 (2001-05-21) [umoeller]
    549         }
    550     }
    551 
    552     return (ppszRet);
    553 }
    554 
    555 /*
    556  *@@ doshSetEnvironmentVar:
    557  *      sets an environment variable in the specified
    558  *      environment, which must have been initialized
    559  *      using doshGetEnvironment first.
    560  *
    561  *      pszNewEnv must be a full environment string
    562  *      in the form "VARNAME=VALUE".
    563  *
    564  *      If "VARNAME" has already been set to something
    565  *      in the string array in pEnv, that array item
    566  *      is replaced.
    567  *
    568  *      OTOH, if "VARNAME" has not been set yet, a new
    569  *      item is added to the array, and pEnv->cVars is
    570  *      raised by one. In that case, fAddFirst determines
    571  *      whether the new array item is added to the front
    572  *      or the tail of the environment list.
    573  *
    574  *@@added V0.9.4 (2000-07-19) [umoeller]
    575  *@@changed V0.9.7 (2000-12-17) [umoeller]: added fAddFirst
    576  *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak
    577  */
    578 
    579 APIRET doshSetEnvironmentVar(PDOSENVIRONMENT pEnv,
    580                              PSZ pszNewEnv,
    581                              BOOL fAddFirst)
    582 {
    583     APIRET  arc = NO_ERROR;
    584     if (!pEnv)
    585         arc = ERROR_INVALID_PARAMETER;
    586     else
    587     {
    588         if ((!pEnv->papszVars) || (!pszNewEnv))
    589             arc = ERROR_INVALID_PARAMETER;
    590         else
    591         {
    592             PSZ *ppszEnvLine = doshFindEnvironmentVar(pEnv, pszNewEnv);
    593             if (ppszEnvLine)
    594             {
    595                 // was set already: replace
    596                 free(*ppszEnvLine);
    597                 *ppszEnvLine = strdup(pszNewEnv);
    598                 if (!(*ppszEnvLine))
    599                     arc = ERROR_NOT_ENOUGH_MEMORY;
    600             }
    601             else
    602             {
    603                 PSZ *ppszNew = NULL;
    604                 PSZ *papszNew = NULL;
    605                 // not set already:
    606                 if (fAddFirst)
    607                 {
    608                     // add as first entry:
    609                     papszNew = (PSZ*)malloc(sizeof(PSZ) * (pEnv->cVars + 1));
    610                     // overwrite first entry
    611                     ppszNew = papszNew;
    612                     // copy old entries
    613                     memcpy(papszNew + 1,                // second new entry
    614                            pEnv->papszVars,             // first old entry
    615                            sizeof(PSZ) * pEnv->cVars);
    616                 }
    617                 else
    618                 {
    619                     // append at the tail:
    620                     // reallocate array and add new string
    621                     papszNew = (PSZ*)realloc(pEnv->papszVars,
    622                                              sizeof(PSZ) * (pEnv->cVars + 1));
    623                     // overwrite last entry
    624                     ppszNew = papszNew + pEnv->cVars;
    625                 }
    626 
    627                 if (!papszNew)
    628                     arc = ERROR_NOT_ENOUGH_MEMORY;
    629                 else
    630                 {
    631                     if (pEnv->papszVars)
    632                         free(pEnv->papszVars);      // was missing V0.9.12 (2001-05-21) [umoeller]
    633 
    634                     pEnv->papszVars = papszNew;
    635                     pEnv->cVars++;
    636                     *ppszNew = strdup(pszNewEnv);
    637                 }
    638             }
    639         }
    640     }
    641 
    642     return (arc);
    643 }
    644 
    645 /*
    646  *@@ doshConvertEnvironment:
    647  *      converts an environment initialized by doshGetEnvironment
    648  *      to the string format required by WinStartApp and DosExecPgm,
    649  *      that is, one memory block is allocated in *ppszEnv and all
    650  *      strings in pEnv->papszVars are copied to that block. Each
    651  *      string is terminated with a null character; the last string
    652  *      is terminated with two null characters.
    653  *
    654  *      Use free() to free the memory block allocated by this
    655  *      function in *ppszEnv.
    656  *
    657  *@@added V0.9.4 (2000-07-19) [umoeller]
    658  */
    659 
    660 APIRET doshConvertEnvironment(PDOSENVIRONMENT pEnv,
    661                               PSZ *ppszEnv,     // out: environment string
    662                               PULONG pulSize)  // out: size of block allocated in *ppszEnv; ptr can be NULL
    663 {
    664     APIRET  arc = NO_ERROR;
    665     if (!pEnv)
    666         arc = ERROR_INVALID_PARAMETER;
    667     else
    668     {
    669         if (!pEnv->papszVars)
    670             arc = ERROR_INVALID_PARAMETER;
    671         else
    672         {
    673             // count memory needed for all strings
    674             ULONG   cbNeeded = 0,
    675                     ul = 0;
    676             PSZ     *ppszThis = pEnv->papszVars;
    677 
    678             for (ul = 0;
    679                  ul < pEnv->cVars;
    680                  ul++)
    681             {
    682                 cbNeeded += strlen(*ppszThis) + 1; // length of string plus null terminator
    683 
    684                 // next environment string
    685                 ppszThis++;
    686             }
    687 
    688             cbNeeded++;     // for another null terminator
    689 
    690             *ppszEnv = (PSZ)malloc(cbNeeded);
    691             if (!(*ppszEnv))
    692                 arc = ERROR_NOT_ENOUGH_MEMORY;
    693             else
    694             {
    695                 PSZ     pTarget = *ppszEnv;
    696                 if (pulSize)
    697                     *pulSize = cbNeeded;
    698                 ppszThis = pEnv->papszVars;
    699 
    700                 // now copy each string
    701                 for (ul = 0;
    702                      ul < pEnv->cVars;
    703                      ul++)
    704                 {
    705                     PSZ pSource = *ppszThis;
    706 
    707                     while ((*pTarget++ = *pSource++))
    708                         ;
    709 
    710                     // *pTarget++ = 0;     // append null terminator per string
    711 
    712                     // next environment string
    713                     ppszThis++;
    714                 }
    715 
    716                 *pTarget++ = 0;     // append second null terminator
    717             }
    718         }
    719     }
    720 
    721     return (arc);
    722 }
    723 
    724 /*
    725  *@@ doshFreeEnvironment:
    726  *      frees memory allocated by doshGetEnvironment.
    727  *
    728  *@@added V0.9.4 (2000-07-19) [umoeller]
    729  */
    730 
    731 APIRET doshFreeEnvironment(PDOSENVIRONMENT pEnv)
    732 {
    733     APIRET  arc = NO_ERROR;
    734     if (!pEnv)
    735         arc = ERROR_INVALID_PARAMETER;
    736     else
    737     {
    738         if (!pEnv->papszVars)
    739             arc = ERROR_INVALID_PARAMETER;
    740         else
    741         {
    742             PSZ     *ppszThis = pEnv->papszVars;
    743             PSZ     pszThis;
    744             ULONG   ul = 0;
    745 
    746             for (ul = 0;
    747                  ul < pEnv->cVars;
    748                  ul++)
    749             {
    750                 pszThis = *ppszThis;
    751                 free(pszThis);
    752                 // *ppszThis = NULL;
    753                 // next environment string
    754                 ppszThis++;
    755             }
    756 
    757             free(pEnv->papszVars);
    758             pEnv->cVars = 0;
    759         }
    760     }
    761 
    762     return (arc);
    763351}
    764352
  • trunk/src/helpers/helpers_pre.in

    r75 r76  
    7373OBJS = $(CPOBJS) \
    7474$(OUTPUTDIR)\animate.obj \
     75$(OUTPUTDIR)\apps.obj \
    7576$(OUTPUTDIR)\cctl_chart.obj \
    7677$(OUTPUTDIR)\cctl_checkcnr.obj \
  • trunk/src/helpers/winh.c

    r73 r76  
    29722972
    29732973/*
    2974  *@@ CallBatchCorrectly:
    2975  *      fixes the specified PROGDETAILS for
    2976  *      command files in the executable part
    2977  *      by inserting /C XXX into the parameters
    2978  *      and setting the executable according
    2979  *      to an environment variable.
    2980  *
    2981  *@@added V0.9.6 (2000-10-16) [umoeller]
    2982  *@@changed V0.9.7 (2001-01-15) [umoeller]: now using XSTRING
    2983  */
    2984 
    2985 VOID CallBatchCorrectly(PPROGDETAILS pProgDetails,
    2986                         PXSTRING pstrParams,        // in/out: modified parameters (reallocated)
    2987                         const char *pcszEnvVar,     // in: env var spec'g command proc
    2988                                                     // (e.g. "OS2_SHELL"); can be NULL
    2989                         const char *pcszDefProc)    // in: def't command proc (e.g. "CMD.EXE")
    2990 {
    2991     // XXX.CMD file as executable:
    2992     // fix args to /C XXX.CMD
    2993 
    2994     PSZ     pszOldParams = NULL;
    2995     ULONG   ulOldParamsLength = pstrParams->ulLength;
    2996     if (ulOldParamsLength)
    2997         // we have parameters already:
    2998         // make a backup... we'll append that later
    2999         pszOldParams = strdup(pstrParams->psz);
    3000 
    3001     // set new params to "/C filename.cmd"
    3002     xstrcpy(pstrParams, "/C ", 0);
    3003     xstrcat(pstrParams,
    3004             pProgDetails->pszExecutable,
    3005             0);
    3006 
    3007     if (pszOldParams)
    3008     {
    3009         // .cmd had params:
    3010         // append space and old params
    3011         xstrcatc(pstrParams, ' ');
    3012         xstrcat(pstrParams,
    3013                 pszOldParams,
    3014                 ulOldParamsLength);
    3015         free(pszOldParams);
    3016     }
    3017 
    3018     // set executable to $(OS2_SHELL)
    3019     pProgDetails->pszExecutable = NULL;
    3020     if (pcszEnvVar)
    3021         pProgDetails->pszExecutable = getenv(pcszEnvVar);
    3022     if (!pProgDetails->pszExecutable)
    3023         pProgDetails->pszExecutable = (PSZ)pcszDefProc;
    3024                 // should be on PATH
    3025 }
    3026 
    3027 /*
    3028  *@@ winhQueryAppType:
    3029  *      returns the Control Program (Dos) and
    3030  *      Win* PROG_* application types for the
    3031  *      specified executable. Essentially, this
    3032  *      is a wrapper around DosQueryAppType.
    3033  *
    3034  *      pcszExecutable must be fully qualified.
    3035  *      You can use doshFindExecutable to qualify
    3036  *      it.
    3037  *
    3038  *      This returns the APIRET of DosQueryAppType.
    3039  *      If this is NO_ERROR; *pulDosAppType receives
    3040  *      the app type of DosQueryAppType. In addition,
    3041  *      *pulWinAppType is set to one of the following:
    3042  *
    3043  *      --  PROG_FULLSCREEN
    3044  *
    3045  *      --  PROG_PDD
    3046  *
    3047  *      --  PROG_VDD
    3048  *
    3049  *      --  PROG_XWP_DLL: new apptype defined in winh.h for
    3050  *          dynamic link libraries.
    3051  *
    3052  *      --  PROG_WINDOWEDVDM
    3053  *
    3054  *      --  PROG_PM
    3055  *
    3056  *      --  PROG_31_ENH
    3057  *
    3058  *      --  PROG_WINDOWABLEVIO
    3059  *
    3060  *@@added V0.9.9 (2001-03-07) [umoeller]
    3061  */
    3062 
    3063 APIRET winhQueryAppType(const char *pcszExecutable,
    3064                         PULONG pulDosAppType,
    3065                         PULONG pulWinAppType)
    3066 {
    3067     APIRET arc = DosQueryAppType((PSZ)pcszExecutable, pulDosAppType);
    3068     if (arc == NO_ERROR)
    3069     {
    3070         ULONG _ulDosAppType = *pulDosAppType;
    3071 
    3072         if (_ulDosAppType == 0)
    3073             *pulWinAppType = PROG_FULLSCREEN;
    3074         else if (_ulDosAppType & 0x40)
    3075             *pulWinAppType = PROG_PDD;
    3076         else if (_ulDosAppType & 0x80)
    3077             *pulWinAppType = PROG_VDD;
    3078         else if ((_ulDosAppType & 0xF0) == 0x10)
    3079             // DLL bit set
    3080             *pulWinAppType = PROG_XWP_DLL;
    3081         else if (_ulDosAppType & 0x20)
    3082             // DOS bit set?
    3083             *pulWinAppType = PROG_WINDOWEDVDM;
    3084         else if ((_ulDosAppType & 0x0003) == 0x0003) // "Window-API" == PM
    3085             *pulWinAppType = PROG_PM;
    3086         else if (   ((_ulDosAppType & 0xFFFF) == 0x1000) // windows program (?!?)
    3087                  || ((_ulDosAppType & 0xFFFF) == 0x0400) // windows program (?!?)
    3088                 )
    3089             *pulWinAppType = PROG_31_ENH;
    3090         else if ((_ulDosAppType & 0x03) == 0x02)
    3091             *pulWinAppType = PROG_WINDOWABLEVIO;
    3092         else if ((_ulDosAppType & 0x03) == 0x01)
    3093             *pulWinAppType = PROG_FULLSCREEN;
    3094     }
    3095 
    3096     return (arc);
    3097 }
    3098 
    3099 /*
    3100  *@@ winhStartApp:
    3101  *      wrapper around WinStartApp which fixes the
    3102  *      specified PROGDETAILS to (hopefully) work
    3103  *      work with all executable types.
    3104  *
    3105  *      This fixes the executable info to support:
    3106  *
    3107  *      -- starting "*" executables (command prompts
    3108  *         for OS/2, DOS, Win-OS/2);
    3109  *
    3110  *      -- starting ".CMD" and ".BAT" files as
    3111  *         PROGDETAILS.pszExecutable.
    3112  *
    3113  *      Unless it is "*", PROGDETAILS.pszExecutable must
    3114  *      be a proper file name. The full path may be omitted
    3115  *      if it is on the PATH, but the extension (.EXE etc.)
    3116  *      must be given. You can use doshFindExecutable to
    3117  *      find executables if you don't know the extension.
    3118  *
    3119  *      This also handles and merges special and default
    3120  *      environments for the app to be started.
    3121  *      If PROGDETAILS.pszEnvironment is empty
    3122  *      and the application is a Win-OS/2 app,
    3123  *      this uses the default Win-OS/2 settings
    3124  *      as specified in the "Win-OS/2" WPS settings
    3125  *      object.
    3126  *
    3127  *      Even though this isn't clearly said in PMREF,
    3128  *      PROGDETAILS.swpInitial is important:
    3129  *
    3130  *      -- To start a session minimized, set SWP_MINIMIZE.
    3131  *
    3132  *      -- To start a VIO session without auto-close, set
    3133  *         the half-documented SWP_NOAUTOCLOSE flag (0x8000)
    3134  *         This flag is now in the newer toolkit headers.
    3135  *
    3136  *      Since this calls WinStartApp in turn, this
    3137  *      requires a message queue on the calling thread.
    3138  *
    3139  *@@added V0.9.6 (2000-10-16) [umoeller]
    3140  *@@changed V0.9.7 (2000-12-10) [umoeller]: PROGDETAILS.swpInitial no longer zeroed... this broke VIOs
    3141  *@@changed V0.9.7 (2000-12-17) [umoeller]: PROGDETAILS.pszEnvironment no longer zeroed
    3142  *@@changed V0.9.9 (2001-01-27) [umoeller]: crashed if PROGDETAILS.pszExecutable was NULL
    3143  *@@todo PROG_DEFAULT ain't working; test winhQueryAppType
    3144  */
    3145 
    3146 HAPP winhStartApp(HWND hwndNotify,                  // in: notify window (as with WinStartApp)
    3147                   const PROGDETAILS *pcProgDetails) // in: program data
    3148 {
    3149     HAPP            happ = NULLHANDLE;
    3150     XSTRING         strParamsPatched;
    3151     BOOL            fIsWindowsApp = FALSE,
    3152                     fIsWindowsEnhApp = FALSE;
    3153     PROGDETAILS     ProgDetails;
    3154     PSZ             pszWinOS2Env = 0;
    3155 
    3156     memcpy(&ProgDetails, pcProgDetails, sizeof(PROGDETAILS));
    3157             // pointers still point into old prog details buffer
    3158     ProgDetails.Length = sizeof(PROGDETAILS);
    3159     ProgDetails.progt.fbVisible = SHE_VISIBLE;
    3160     // ProgDetails.pszEnvironment = 0;
    3161 
    3162     // all this only makes sense if this contains something...
    3163     // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller]
    3164     if (ProgDetails.pszExecutable)
    3165     {
    3166         // memset(&ProgDetails.swpInitial, 0, sizeof(SWP));
    3167         // this wasn't a good idea... WPProgram stores stuff
    3168         // in here, such as the "minimize on startup" -> SWP_MINIMIZE
    3169 
    3170         // duplicate parameters...
    3171         // we need this for string manipulations below...
    3172         if (ProgDetails.pszParameters)
    3173             xstrInitCopy(&strParamsPatched,
    3174                          ProgDetails.pszParameters,
    3175                          100);
    3176         else
    3177             // no old params:
    3178             xstrInit(&strParamsPatched, 100);
    3179 
    3180         // _Pmpf((__FUNCTION__ ": old progc: 0x%lX", pcProgDetails->progt.progc));
    3181         // _Pmpf(("  pszTitle: %s", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : NULL));
    3182         // _Pmpf(("  pszIcon: %s", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : NULL));
    3183 
    3184         // program type fixups
    3185         switch (ProgDetails.progt.progc)        // that's a ULONG
    3186         {
    3187             case ((ULONG)-1):       // we get that sometimes...
    3188             case PROG_DEFAULT:
    3189                 // @@todo
    3190             break;
    3191         }
    3192 
    3193         // now try again...
    3194         switch (ProgDetails.progt.progc)
    3195         {
    3196             case PROG_31_ENHSEAMLESSVDM:        // 17
    3197             case PROG_31_ENHSEAMLESSCOMMON:     // 18
    3198             case PROG_31_ENH:                   // 19
    3199                 fIsWindowsApp = TRUE;
    3200                 fIsWindowsEnhApp = TRUE;
    3201             break;
    3202 
    3203     #ifndef PROG_30_STD
    3204         #define PROG_30_STD (PROGCATEGORY)11
    3205     #endif
    3206 
    3207     #ifndef PROG_30_STDSEAMLESSVDM
    3208         #define PROG_30_STDSEAMLESSVDM (PROGCATEGORY)13
    3209     #endif
    3210 
    3211             case PROG_WINDOW_REAL:              // 10
    3212             case PROG_30_STD:                   // 11
    3213             case PROG_WINDOW_AUTO:              // 12
    3214             case PROG_30_STDSEAMLESSVDM:        // 13
    3215             case PROG_30_STDSEAMLESSCOMMON:     // 14
    3216             case PROG_31_STDSEAMLESSVDM:        // 15
    3217             case PROG_31_STDSEAMLESSCOMMON:     // 16
    3218             case PROG_31_STD:                   // 20
    3219                 fIsWindowsApp = TRUE;
    3220             break;
    3221         }
    3222 
    3223         /*
    3224          * command lines fixups:
    3225          *
    3226          */
    3227 
    3228         if (strcmp(ProgDetails.pszExecutable, "*") == 0)
    3229         {
    3230             /*
    3231              * "*" for command sessions:
    3232              *
    3233              */
    3234 
    3235             if (fIsWindowsEnhApp)
    3236             {
    3237                 // enhanced Win-OS/2 session:
    3238                 PSZ psz = NULL;
    3239                 if (strParamsPatched.ulLength)
    3240                     // "/3 " + existing params
    3241                     psz = strdup(strParamsPatched.psz);
    3242 
    3243                 xstrcpy(&strParamsPatched, "/3 ", 0);
    3244 
    3245                 if (psz)
    3246                 {
    3247                     xstrcat(&strParamsPatched, psz, 0);
    3248                     free(psz);
    3249                 }
    3250             }
    3251 
    3252             if (fIsWindowsApp)
    3253             {
    3254                 // cheat: WinStartApp doesn't support NULL
    3255                 // for Win-OS2 sessions, so manually start winos2.com
    3256                 ProgDetails.pszExecutable = "WINOS2.COM";
    3257                 // this is a DOS app, so fix this to DOS fullscreen
    3258                 ProgDetails.progt.progc = PROG_VDM;
    3259             }
    3260             else
    3261                 // for all other executable types
    3262                 // (including OS/2 and DOS sessions),
    3263                 // set pszExecutable to NULL; this will
    3264                 // have WinStartApp start a cmd shell
    3265                 ProgDetails.pszExecutable = NULL;
    3266 
    3267         } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0)
    3268         else
    3269             switch (ProgDetails.progt.progc)
    3270             {
    3271                 /*
    3272                  *  .CMD files fixups
    3273                  *
    3274                  */
    3275 
    3276                 case PROG_FULLSCREEN:       // OS/2 fullscreen
    3277                 case PROG_WINDOWABLEVIO:    // OS/2 window
    3278                 {
    3279                     PSZ pszExtension = doshGetExtension(ProgDetails.pszExecutable);
    3280                     if (pszExtension)
    3281                     {
    3282                         if (stricmp(pszExtension, "CMD") == 0)
    3283                         {
    3284                             CallBatchCorrectly(&ProgDetails,
    3285                                                &strParamsPatched,
    3286                                                "OS2_SHELL",
    3287                                                "CMD.EXE");
    3288                         }
    3289                     }
    3290                 break; }
    3291 
    3292                 case PROG_VDM:              // DOS fullscreen
    3293                 case PROG_WINDOWEDVDM:      // DOS window
    3294                 {
    3295                     PSZ pszExtension = doshGetExtension(ProgDetails.pszExecutable);
    3296                     if (pszExtension)
    3297                     {
    3298                         if (stricmp(pszExtension, "BAT") == 0)
    3299                         {
    3300                             CallBatchCorrectly(&ProgDetails,
    3301                                                &strParamsPatched,
    3302                                                NULL,
    3303                                                "COMMAND.COM");
    3304                         }
    3305                     }
    3306                 break; }
    3307             } // end switch (ProgDetails.progt.progc)
    3308 
    3309         /*
    3310          *  Fix environment for Win-OS/2
    3311          *
    3312          */
    3313 
    3314         if (    !(xstrIsString(ProgDetails.pszEnvironment)) // env empty
    3315              && (fIsWindowsApp)                             // and win-os2 app
    3316            )
    3317         {
    3318             ULONG ulSize = 0;
    3319             // get default environment (from Win-OS/2 settings object)
    3320             // from OS2.INI
    3321             PSZ pszDefEnv = prfhQueryProfileData(HINI_USER,
    3322                                                  "WINOS2",
    3323                                                  "PM_GlobalWindows31Settings",
    3324                                                  &ulSize);
    3325             if (pszDefEnv)
    3326             {
    3327                 PSZ pszDefEnv2 = (PSZ)malloc(ulSize + 2);
    3328                 if (pszDefEnv2)
    3329                 {
    3330                     PSZ p = pszDefEnv2;
    3331                     memset(pszDefEnv2, 0, ulSize + 2);
    3332                     memcpy(pszDefEnv2, pszDefEnv, ulSize);
    3333 
    3334                     for (p = pszDefEnv2;
    3335                          p < pszDefEnv2 + ulSize;
    3336                          p++)
    3337                         if (*p == ';')
    3338                             *p = 0;
    3339 
    3340                     // okay.... now we got an OS/2-style environment
    3341                     // with 0, 0, 00 strings
    3342 
    3343                     pszWinOS2Env = pszDefEnv2;  // freed below
    3344 
    3345                     // use this
    3346                     ProgDetails.pszEnvironment = pszWinOS2Env;
    3347                 }
    3348 
    3349                 free(pszDefEnv);
    3350             }
    3351         }
    3352 
    3353         ProgDetails.pszParameters = strParamsPatched.psz;
    3354 
    3355         happ = WinStartApp(hwndNotify,
    3356                                     // receives WM_APPTERMINATENOTIFY
    3357                            &ProgDetails,
    3358                            strParamsPatched.psz,
    3359                            NULL,            // "reserved", PMREF says...
    3360                            SAF_INSTALLEDCMDLINE);
    3361                                 // we MUST use SAF_INSTALLEDCMDLINE
    3362                                 // or no Win-OS/2 session will start...
    3363                                 // whatever is going on here... Warp 4 FP11
    3364 
    3365                                 // do not use SAF_STARTCHILDAPP, or the
    3366                                 // app will be terminated automatically
    3367                                 // when the WPS terminates!
    3368 
    3369         // _Pmpf((__FUNCTION__ ": got happ 0x%lX", happ));
    3370 
    3371         xstrClear(&strParamsPatched);
    3372         if (pszWinOS2Env)
    3373             free(pszWinOS2Env);
    3374     } // end if (ProgDetails.pszExecutable)
    3375 
    3376     return (happ);
    3377 }
    3378 
    3379 /*
    33802974 *@@ winhAnotherInstance:
    33812975 *      this tests whether another instance of the same
Note: See TracChangeset for help on using the changeset viewer.