Changeset 127 for trunk/src/helpers/apps.c
- Timestamp:
- Jan 5, 2002, 8:11:10 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/apps.c
r123 r127 33 33 34 34 #define INCL_DOSPROCESS 35 #define INCL_DOSMODULEMGR 35 36 #define INCL_DOSSESMGR 36 37 #define INCL_DOSERRORS 37 38 38 39 #define INCL_WINPROGRAMLIST // needed for PROGDETAILS, wppgm.h 40 #define INCL_WINERRORS 41 #define INCL_SHLERRORS 39 42 #include <os2.h> 40 43 … … 107 110 108 111 APIRET appParseEnvironment(const char *pcszEnv, 109 PDOSENVIRONMENT pEnv) 112 PDOSENVIRONMENT pEnv) // out: new environment 110 113 { 111 114 APIRET arc = NO_ERROR; … … 123 126 } 124 127 125 pEnv->cVars = cVars;128 pEnv->cVars = 0; 126 129 pEnv->papszVars = 0; 127 130 128 131 if (cVars) 129 132 { 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))) 132 136 arc = ERROR_NOT_ENOUGH_MEMORY; 133 137 else 134 138 { 135 139 PSZ *ppszTarget = papsz; 136 memset(papsz, 0, sizeof(PSZ) * cVars);140 memset(papsz, 0, cbArray); 137 141 pszVarThis = (PSZ)pcszEnv; 138 142 while (*pszVarThis) 139 143 { 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)++; 141 151 ppszTarget++; 142 pszVarThis += strlen(pszVarThis)+ 1;152 pszVarThis += ulThisLen + 1; 143 153 } 144 154 … … 156 166 * process environment, which is retrieved from 157 167 * 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. 158 177 * 159 178 *@@added V0.9.4 (2000-07-19) [umoeller] … … 173 192 if (arc == NO_ERROR) 174 193 { 175 PSZ pszEnv = ppib->pib_pchenv;176 if (pszEnv )194 PSZ pszEnv; 195 if (pszEnv = ppib->pib_pchenv) 177 196 arc = appParseEnvironment(pszEnv, pEnv); 178 197 else … … 200 219 *@@changed V0.9.12 (2001-05-21) [umoeller]: fixed memory leak 201 220 *@@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 202 222 */ 203 223 … … 205 225 PSZ pszVarName) 206 226 { 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 ) 237 259 { 238 ppszRet = ppszThis;260 ppszRet = &pEnv->papszVars[ul]; 239 261 break; 240 262 } 241 242 // next environment string 243 ppszThis++; 244 } 245 246 free(pszSearch); // was missing V0.9.12 (2001-05-21) [umoeller] 263 } 247 264 } 248 265 } … … 296 313 else 297 314 { 298 PSZ *ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv); 299 if (ppszEnvLine) 300 { 315 PSZ *ppszEnvLine; 316 if (ppszEnvLine = appFindEnvironmentVar(pEnv, pszNewEnv)) 301 317 // 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); 307 321 else 308 322 { … … 312 326 // allocate new array, with one new entry 313 327 // 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)))) 317 331 arc = ERROR_NOT_ENOUGH_MEMORY; 318 332 else … … 339 353 } 340 354 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] 344 356 pEnv->papszVars = papszNew; 345 357 pEnv->cVars++; … … 374 386 { 375 387 APIRET arc = NO_ERROR; 376 if (!pEnv) 388 if ( (!pEnv) 389 || (!pEnv->papszVars) 390 ) 377 391 arc = ERROR_INVALID_PARAMETER; 378 392 else 379 393 { 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; 382 413 else 383 414 { 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 389 421 for (ul = 0; 390 422 ul < pEnv->cVars; 391 423 ul++) 392 424 { 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 394 431 395 432 // next environment string … … 397 434 } 398 435 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 429 437 } 430 438 } … … 444 452 { 445 453 APIRET arc = NO_ERROR; 446 if (!pEnv) 454 if ( (!pEnv) 455 || (!pEnv->papszVars) 456 ) 447 457 arc = ERROR_INVALID_PARAMETER; 448 458 else 449 459 { 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; 472 477 } 473 478 … … 920 925 *@@changed V0.9.16 (2001-10-19) [umoeller]: added thread-1 check 921 926 *@@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 922 929 */ 923 930 … … 925 932 const PROGDETAILS *pcProgDetails, // in: program spec (req.) 926 933 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) 928 937 { 929 938 APIRET arc = NO_ERROR; 930 939 PROGDETAILS ProgDetails; 940 941 if (pszFailingName) 942 *pszFailingName = '\0'; 931 943 932 944 if (!pcProgDetails || !phapp) … … 1081 1093 if (ProgDetails.pszStartupDir) 1082 1094 { 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; 1087 1102 } 1088 1103 } … … 1222 1237 MB_YESNO | MB_MOVEABLE) 1223 1238 == MBID_YES) */ 1239 1240 if (pszFailingName) 1241 strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName); 1242 1224 1243 if (!(*phapp = WinStartApp(hwndNotify, 1225 1244 // receives WM_APPTERMINATENOTIFY … … 1235 1254 // app will be terminated automatically 1236 1255 // 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 } 1242 1340 } 1243 1341 } … … 1344 1442 &pd, 1345 1443 0, 1346 &happ)) 1444 &happ, 1445 0, 1446 NULL)) 1347 1447 ) 1348 1448 {
Note:
See TracChangeset
for help on using the changeset viewer.