Changeset 76 for trunk/src/helpers/winh.c
- Timestamp:
- May 27, 2001, 8:10:36 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/winh.c
r73 r76 2972 2972 2973 2973 /* 2974 *@@ CallBatchCorrectly:2975 * fixes the specified PROGDETAILS for2976 * command files in the executable part2977 * by inserting /C XXX into the parameters2978 * and setting the executable according2979 * 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 XSTRING2983 */2984 2985 VOID CallBatchCorrectly(PPROGDETAILS pProgDetails,2986 PXSTRING pstrParams, // in/out: modified parameters (reallocated)2987 const char *pcszEnvVar, // in: env var spec'g command proc2988 // (e.g. "OS2_SHELL"); can be NULL2989 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.CMD2993 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 later2999 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 params3011 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 PATH3025 }3026 3027 /*3028 *@@ winhQueryAppType:3029 * returns the Control Program (Dos) and3030 * Win* PROG_* application types for the3031 * specified executable. Essentially, this3032 * is a wrapper around DosQueryAppType.3033 *3034 * pcszExecutable must be fully qualified.3035 * You can use doshFindExecutable to qualify3036 * it.3037 *3038 * This returns the APIRET of DosQueryAppType.3039 * If this is NO_ERROR; *pulDosAppType receives3040 * the app type of DosQueryAppType. In addition,3041 * *pulWinAppType is set to one of the following:3042 *3043 * -- PROG_FULLSCREEN3044 *3045 * -- PROG_PDD3046 *3047 * -- PROG_VDD3048 *3049 * -- PROG_XWP_DLL: new apptype defined in winh.h for3050 * dynamic link libraries.3051 *3052 * -- PROG_WINDOWEDVDM3053 *3054 * -- PROG_PM3055 *3056 * -- PROG_31_ENH3057 *3058 * -- PROG_WINDOWABLEVIO3059 *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 set3080 *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" == PM3085 *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 the3102 * specified PROGDETAILS to (hopefully) work3103 * work with all executable types.3104 *3105 * This fixes the executable info to support:3106 *3107 * -- starting "*" executables (command prompts3108 * for OS/2, DOS, Win-OS/2);3109 *3110 * -- starting ".CMD" and ".BAT" files as3111 * PROGDETAILS.pszExecutable.3112 *3113 * Unless it is "*", PROGDETAILS.pszExecutable must3114 * be a proper file name. The full path may be omitted3115 * if it is on the PATH, but the extension (.EXE etc.)3116 * must be given. You can use doshFindExecutable to3117 * find executables if you don't know the extension.3118 *3119 * This also handles and merges special and default3120 * environments for the app to be started.3121 * If PROGDETAILS.pszEnvironment is empty3122 * and the application is a Win-OS/2 app,3123 * this uses the default Win-OS/2 settings3124 * as specified in the "Win-OS/2" WPS settings3125 * 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, set3133 * 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, this3137 * 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 VIOs3141 *@@changed V0.9.7 (2000-12-17) [umoeller]: PROGDETAILS.pszEnvironment no longer zeroed3142 *@@changed V0.9.9 (2001-01-27) [umoeller]: crashed if PROGDETAILS.pszExecutable was NULL3143 *@@todo PROG_DEFAULT ain't working; test winhQueryAppType3144 */3145 3146 HAPP winhStartApp(HWND hwndNotify, // in: notify window (as with WinStartApp)3147 const PROGDETAILS *pcProgDetails) // in: program data3148 {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 buffer3158 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 stuff3168 // in here, such as the "minimize on startup" -> SWP_MINIMIZE3169 3170 // duplicate parameters...3171 // we need this for string manipulations below...3172 if (ProgDetails.pszParameters)3173 xstrInitCopy(&strParamsPatched,3174 ProgDetails.pszParameters,3175 100);3176 else3177 // 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 fixups3185 switch (ProgDetails.progt.progc) // that's a ULONG3186 {3187 case ((ULONG)-1): // we get that sometimes...3188 case PROG_DEFAULT:3189 // @@todo3190 break;3191 }3192 3193 // now try again...3194 switch (ProgDetails.progt.progc)3195 {3196 case PROG_31_ENHSEAMLESSVDM: // 173197 case PROG_31_ENHSEAMLESSCOMMON: // 183198 case PROG_31_ENH: // 193199 fIsWindowsApp = TRUE;3200 fIsWindowsEnhApp = TRUE;3201 break;3202 3203 #ifndef PROG_30_STD3204 #define PROG_30_STD (PROGCATEGORY)113205 #endif3206 3207 #ifndef PROG_30_STDSEAMLESSVDM3208 #define PROG_30_STDSEAMLESSVDM (PROGCATEGORY)133209 #endif3210 3211 case PROG_WINDOW_REAL: // 103212 case PROG_30_STD: // 113213 case PROG_WINDOW_AUTO: // 123214 case PROG_30_STDSEAMLESSVDM: // 133215 case PROG_30_STDSEAMLESSCOMMON: // 143216 case PROG_31_STDSEAMLESSVDM: // 153217 case PROG_31_STDSEAMLESSCOMMON: // 163218 case PROG_31_STD: // 203219 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 params3241 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 NULL3255 // for Win-OS2 sessions, so manually start winos2.com3256 ProgDetails.pszExecutable = "WINOS2.COM";3257 // this is a DOS app, so fix this to DOS fullscreen3258 ProgDetails.progt.progc = PROG_VDM;3259 }3260 else3261 // for all other executable types3262 // (including OS/2 and DOS sessions),3263 // set pszExecutable to NULL; this will3264 // have WinStartApp start a cmd shell3265 ProgDetails.pszExecutable = NULL;3266 3267 } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0)3268 else3269 switch (ProgDetails.progt.progc)3270 {3271 /*3272 * .CMD files fixups3273 *3274 */3275 3276 case PROG_FULLSCREEN: // OS/2 fullscreen3277 case PROG_WINDOWABLEVIO: // OS/2 window3278 {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 fullscreen3293 case PROG_WINDOWEDVDM: // DOS window3294 {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/23311 *3312 */3313 3314 if ( !(xstrIsString(ProgDetails.pszEnvironment)) // env empty3315 && (fIsWindowsApp) // and win-os2 app3316 )3317 {3318 ULONG ulSize = 0;3319 // get default environment (from Win-OS/2 settings object)3320 // from OS2.INI3321 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 environment3341 // with 0, 0, 00 strings3342 3343 pszWinOS2Env = pszDefEnv2; // freed below3344 3345 // use this3346 ProgDetails.pszEnvironment = pszWinOS2Env;3347 }3348 3349 free(pszDefEnv);3350 }3351 }3352 3353 ProgDetails.pszParameters = strParamsPatched.psz;3354 3355 happ = WinStartApp(hwndNotify,3356 // receives WM_APPTERMINATENOTIFY3357 &ProgDetails,3358 strParamsPatched.psz,3359 NULL, // "reserved", PMREF says...3360 SAF_INSTALLEDCMDLINE);3361 // we MUST use SAF_INSTALLEDCMDLINE3362 // or no Win-OS/2 session will start...3363 // whatever is going on here... Warp 4 FP113364 3365 // do not use SAF_STARTCHILDAPP, or the3366 // app will be terminated automatically3367 // 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 /*3380 2974 *@@ winhAnotherInstance: 3381 2975 * this tests whether another instance of the same
Note:
See TracChangeset
for help on using the changeset viewer.