Changeset 152 for trunk/src/helpers/apps.c
- Timestamp:
- Mar 27, 2002, 9:27:02 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/helpers/apps.c
r151 r152 33 33 34 34 #define INCL_DOSPROCESS 35 #define INCL_DOSEXCEPTIONS 35 36 #define INCL_DOSMODULEMGR 36 37 #define INCL_DOSSESMGR … … 43 44 44 45 #include <stdio.h> 46 #include <setjmp.h> // needed for except.h 47 #include <assert.h> // needed for except.h 45 48 46 49 #include "setup.h" // code generation and debugging options … … 48 51 #include "helpers\apps.h" 49 52 #include "helpers\dosh.h" 53 #include "helpers\except.h" // exception handling 50 54 #include "helpers\prfh.h" 51 55 #include "helpers\standards.h" // some standard macros … … 556 560 557 561 APIRET appQueryAppType(const char *pcszExecutable, 558 PULONG pulDosAppType, 559 PULONG pulWinAppType) 562 PULONG pulDosAppType, // out: DOS app type 563 PULONG pulWinAppType) // out: PROG_* app type 560 564 { 561 565 APIRET arc; … … 875 879 } 876 880 881 #ifdef _PMPRINTF_ 882 883 static void DumpMemoryBlock(PBYTE pb, // in: start address 884 ULONG ulSize, // in: size of block 885 ULONG ulIndent) // in: how many spaces to put 886 // before each output line 887 { 888 TRY_QUIET(excpt1) 889 { 890 PBYTE pbCurrent = pb; // current byte 891 ULONG ulCount = 0, 892 ulCharsInLine = 0; // if this grows > 7, a new line is started 893 CHAR szTemp[1000]; 894 CHAR szLine[400] = "", 895 szAscii[30] = " "; // ASCII representation; filled for every line 896 PSZ pszLine = szLine, 897 pszAscii = szAscii; 898 899 for (pbCurrent = pb; 900 ulCount < ulSize; 901 pbCurrent++, ulCount++) 902 { 903 if (ulCharsInLine == 0) 904 { 905 memset(szLine, ' ', ulIndent); 906 pszLine += ulIndent; 907 } 908 pszLine += sprintf(pszLine, "%02lX ", (ULONG)*pbCurrent); 909 910 if ( (*pbCurrent > 31) && (*pbCurrent < 127) ) 911 // printable character: 912 *pszAscii = *pbCurrent; 913 else 914 *pszAscii = '.'; 915 pszAscii++; 916 917 ulCharsInLine++; 918 if ( (ulCharsInLine > 7) // 8 bytes added? 919 || (ulCount == ulSize-1) // end of buffer reached? 920 ) 921 { 922 // if we haven't had eight bytes yet, 923 // fill buffer up to eight bytes with spaces 924 ULONG ul2; 925 for (ul2 = ulCharsInLine; 926 ul2 < 8; 927 ul2++) 928 pszLine += sprintf(pszLine, " "); 929 930 sprintf(szTemp, "%04lX: %s %ss", 931 (ulCount & 0xFFFFFFF8), // offset in hex 932 szLine, // bytes string 933 szAscii); // ASCII string 934 935 _Pmpf(("%s", szTemp)); 936 937 // restart line buffer 938 pszLine = szLine; 939 940 // clear ASCII buffer 941 strcpy(szAscii, " "); 942 pszAscii = szAscii; 943 944 // reset line counter 945 ulCharsInLine = 0; 946 } 947 } 948 949 } 950 CATCH(excpt1) 951 { 952 _Pmpf(("Crash in " __FUNCTION__ )); 953 } END_CATCH(); 954 } 955 956 #endif 957 958 /* 959 *@@ appFixProgDetails: 960 * extracted code from appStartApp to fix the 961 * given PROGDETAILS data to support the typical 962 * WPS stuff. 963 * 964 * This is now used by XWP's progOpenProgram 965 * directly as a temporary fix for all the 966 * session hangs. 967 * 968 * The caller is responsible for cleaning out 969 * the given three memory buffers. 970 * 971 *@@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 980 { 981 APIRET arc = NO_ERROR; 982 983 memcpy(pDetails, pcProgDetails, sizeof(PROGDETAILS)); 984 // pointers still point into old prog details buffer 985 pDetails->Length = sizeof(PROGDETAILS); 986 pDetails->progt.fbVisible = SHE_VISIBLE; 987 988 // all this only makes sense if this contains something... 989 // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller] 990 if ( (!pDetails->pszExecutable) 991 || (!(*(pDetails->pszExecutable))) 992 ) 993 arc = ERROR_INVALID_PARAMETER; 994 else 995 { 996 ULONG ulIsWinApp; 997 998 // memset(&pDetails->swpInitial, 0, sizeof(SWP)); 999 // this wasn't a good idea... WPProgram stores stuff 1000 // in here, such as the "minimize on startup" -> SWP_MINIMIZE 1001 1002 // duplicate parameters... 1003 // we need this for string manipulations below... 1004 if ( (pDetails->pszParameters) 1005 && (*pDetails->pszParameters) // V0.9.18 1006 ) 1007 xstrcpy(pstrParamsPatched, 1008 pDetails->pszParameters, 1009 0); 1010 1011 #ifdef DEBUG_PROGRAMSTART 1012 _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)); 1015 #endif 1016 1017 // program type fixups 1018 switch (pDetails->progt.progc) // that's a ULONG 1019 { 1020 case ((ULONG)-1): // we get that sometimes... 1021 case PROG_DEFAULT: 1022 { 1023 // V0.9.12 (2001-05-26) [umoeller] 1024 ULONG ulDosAppType; 1025 appQueryAppType(pDetails->pszExecutable, 1026 &ulDosAppType, 1027 &pDetails->progt.progc); 1028 } 1029 break; 1030 } 1031 1032 // set session type from option flags 1033 if (ulFlags & APP_RUN_FULLSCREEN) 1034 { 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)) 1042 { 1043 if (ulFlags & APP_RUN_FULLSCREEN) 1044 pDetails->progt.progc = (ulFlags & APP_RUN_ENHANCED) 1045 ? PROG_31_ENH 1046 : PROG_31_STD; 1047 else 1048 { 1049 if (ulFlags & APP_RUN_STANDARD) 1050 pDetails->progt.progc = (ulFlags & APP_RUN_SEPARATE) 1051 ? PROG_31_STDSEAMLESSVDM 1052 : PROG_31_STDSEAMLESSCOMMON; 1053 else if (ulFlags & APP_RUN_ENHANCED) 1054 pDetails->progt.progc = (ulFlags & APP_RUN_SEPARATE) 1055 ? PROG_31_ENHSEAMLESSVDM 1056 : PROG_31_ENHSEAMLESSCOMMON; 1057 } 1058 1059 // re-run V0.9.16 (2001-10-19) [umoeller] 1060 ulIsWinApp = appIsWindowsApp(pDetails->progt.progc); 1061 } 1062 1063 if (!arc) 1064 { 1065 /* 1066 * command lines fixups: 1067 * 1068 */ 1069 1070 if (!strcmp(pDetails->pszExecutable, "*")) 1071 { 1072 /* 1073 * "*" for command sessions: 1074 * 1075 */ 1076 1077 if (ulIsWinApp == 2) 1078 { 1079 // enhanced Win-OS/2 session: 1080 PSZ psz = NULL; 1081 if (pstrParamsPatched->ulLength) 1082 // "/3 " + existing params 1083 psz = strdup(pstrParamsPatched->psz); 1084 1085 xstrcpy(pstrParamsPatched, "/3 ", 0); 1086 1087 if (psz) 1088 { 1089 xstrcat(pstrParamsPatched, psz, 0); 1090 free(psz); 1091 } 1092 } 1093 1094 if (ulIsWinApp) 1095 { 1096 // cheat: WinStartApp doesn't support NULL 1097 // for Win-OS2 sessions, so manually start winos2.com 1098 pDetails->pszExecutable = "WINOS2.COM"; 1099 // this is a DOS app, so fix this to DOS fullscreen 1100 pDetails->progt.progc = PROG_VDM; 1101 } 1102 else 1103 // for all other executable types 1104 // (including OS/2 and DOS sessions), 1105 // set pszExecutable to NULL; this will 1106 // have WinStartApp start a cmd shell 1107 pDetails->pszExecutable = NULL; 1108 1109 } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0) 1110 else 1111 { 1112 // check if the executable is fully qualified; if so, 1113 // check if the executable file exists 1114 if ( (pDetails->pszExecutable[1] == ':') 1115 && (strchr(pDetails->pszExecutable, '\\')) 1116 ) 1117 { 1118 ULONG ulAttr; 1119 if (!(arc = doshQueryPathAttr(pDetails->pszExecutable, 1120 &ulAttr))) 1121 { 1122 // make sure startup dir is really a directory 1123 if (pDetails->pszStartupDir) 1124 { 1125 // it is valid to specify a startup dir of "C:" 1126 if ( (strlen(pDetails->pszStartupDir) > 2) 1127 && (!(arc = doshQueryPathAttr(pDetails->pszStartupDir, 1128 &ulAttr))) 1129 && (!(ulAttr & FILE_DIRECTORY)) 1130 ) 1131 arc = ERROR_PATH_NOT_FOUND; 1132 } 1133 } 1134 } 1135 else 1136 { 1137 // _not_ fully qualified: look it up on the PATH then 1138 // V0.9.16 (2001-12-06) [umoeller] 1139 CHAR szFQExecutable[CCHMAXPATH]; 1140 if (!(arc = doshSearchPath("PATH", 1141 pDetails->pszExecutable, 1142 szFQExecutable, 1143 sizeof(szFQExecutable)))) 1144 { 1145 // alright, found it: 1146 xstrcpy(pstrExecutablePatched, szFQExecutable, 0); 1147 pDetails->pszExecutable = pstrExecutablePatched->psz; 1148 } 1149 } 1150 1151 if (!arc) 1152 { 1153 PSZ pszExtension; 1154 switch (pDetails->progt.progc) 1155 { 1156 /* 1157 * .CMD files fixups 1158 * 1159 */ 1160 1161 case PROG_FULLSCREEN: // OS/2 fullscreen 1162 case PROG_WINDOWABLEVIO: // OS/2 window 1163 { 1164 if ( (pszExtension = doshGetExtension(pDetails->pszExecutable)) 1165 && (!stricmp(pszExtension, "CMD")) 1166 ) 1167 { 1168 CallBatchCorrectly(pDetails, 1169 pstrParamsPatched, 1170 "OS2_SHELL", 1171 "CMD.EXE"); 1172 } 1173 } 1174 break; 1175 1176 case PROG_VDM: // DOS fullscreen 1177 case PROG_WINDOWEDVDM: // DOS window 1178 { 1179 if ( (pszExtension = doshGetExtension(pDetails->pszExecutable)) 1180 && (!stricmp(pszExtension, "BAT")) 1181 ) 1182 { 1183 CallBatchCorrectly(pDetails, 1184 pstrParamsPatched, 1185 NULL, 1186 "COMMAND.COM"); 1187 } 1188 } 1189 break; 1190 } // end switch (pDetails->progt.progc) 1191 } 1192 } 1193 } 1194 1195 if (!arc) 1196 { 1197 if ( (ulIsWinApp) 1198 && ( (pDetails->pszEnvironment == NULL) 1199 || (!strlen(pDetails->pszEnvironment)) 1200 ) 1201 ) 1202 { 1203 // this is a windoze app, and caller didn't bother 1204 // to give us an environment: 1205 // we MUST set one then, or we'll get the strangest 1206 // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller] 1207 1208 DOSENVIRONMENT Env = {0}; 1209 1210 // get standard WIN-OS/2 environment 1211 PSZ pszTemp = appQueryDefaultWin31Environment(); 1212 1213 if (!(arc = appParseEnvironment(pszTemp, 1214 &Env))) 1215 { 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); 1227 } 1228 1229 free(pszTemp); 1230 } 1231 1232 if (!arc) 1233 { 1234 if (!pDetails->pszTitle) 1235 pDetails->pszTitle = pDetails->pszExecutable; 1236 1237 // make sure params have a leading space 1238 // V0.9.18 (2002-03-27) [umoeller] 1239 if (pstrParamsPatched->ulLength) 1240 { 1241 if (pstrParamsPatched->psz[0] != ' ') 1242 { 1243 XSTRING str2; 1244 xstrInit(&str2, 0); 1245 xstrcpy(&str2, " ", 1); 1246 xstrcats(&str2, pstrParamsPatched); 1247 xstrcpys(pstrParamsPatched, &str2); 1248 xstrClear(&str2); 1249 // we really need xstrInsert or something 1250 } 1251 pDetails->pszParameters = pstrParamsPatched->psz; 1252 } 1253 else 1254 pDetails->pszParameters = ""; 1255 1256 if (!pDetails->pszIcon) 1257 pDetails->pszIcon = ""; 1258 1259 if (!pDetails->pszStartupDir) 1260 pDetails->pszStartupDir = ""; 1261 1262 } 1263 } 1264 } 1265 1266 return (arc); 1267 } 1268 1269 /* 1270 *@@ CallDosStartSession: 1271 * 1272 *@@added V0.9.18 (2002-03-27) [umoeller] 1273 */ 1274 1275 static APIRET CallDosStartSession(HAPP *phapp, 1276 const PROGDETAILS *pNewProgDetails, // in: program spec (req.) 1277 ULONG cbFailingName, 1278 PSZ pszFailingName) 1279 { 1280 APIRET arc = NO_ERROR; 1281 1282 BOOL fCrit = FALSE, 1283 fResetDir = FALSE; 1284 CHAR szCurrentDir[CCHMAXPATH]; 1285 1286 ULONG sid, 1287 pid; 1288 STARTDATA SData; 1289 SData.Length = sizeof(STARTDATA); 1290 SData.Related = SSF_RELATED_INDEPENDENT; // SSF_RELATED_CHILD; 1291 // per default, try to start this in the foreground 1292 SData.FgBg = SSF_FGBG_FORE; 1293 SData.TraceOpt = SSF_TRACEOPT_NONE; 1294 1295 SData.PgmTitle = pNewProgDetails->pszTitle; 1296 SData.PgmName = pNewProgDetails->pszExecutable; 1297 SData.PgmInputs = pNewProgDetails->pszParameters; 1298 1299 SData.TermQ = NULL; 1300 SData.Environment = pNewProgDetails->pszEnvironment; 1301 SData.InheritOpt = SSF_INHERTOPT_PARENT; // ignored 1302 1303 switch (pNewProgDetails->progt.progc) 1304 { 1305 case PROG_FULLSCREEN: 1306 SData.SessionType = SSF_TYPE_FULLSCREEN; 1307 break; 1308 1309 case PROG_WINDOWABLEVIO: 1310 SData.SessionType = SSF_TYPE_WINDOWABLEVIO; 1311 break; 1312 1313 case PROG_PM: 1314 SData.SessionType = SSF_TYPE_PM; 1315 SData.FgBg = SSF_FGBG_BACK; // otherwise we get ERROR_SMG_START_IN_BACKGROUND 1316 break; 1317 1318 case PROG_VDM: 1319 SData.SessionType = SSF_TYPE_VDM; 1320 break; 1321 1322 case PROG_WINDOWEDVDM: 1323 SData.SessionType = SSF_TYPE_WINDOWEDVDM; 1324 break; 1325 1326 default: 1327 SData.SessionType = SSF_TYPE_DEFAULT; 1328 } 1329 1330 SData.IconFile = 0; 1331 SData.PgmHandle = 0; 1332 1333 SData.PgmControl = 0; 1334 1335 if (pNewProgDetails->progt.fbVisible == SHE_VISIBLE) 1336 SData.PgmControl |= SSF_CONTROL_VISIBLE; 1337 1338 if (pNewProgDetails->swpInitial.fl & SWP_HIDE) 1339 SData.PgmControl |= SSF_CONTROL_INVISIBLE; 1340 1341 if (pNewProgDetails->swpInitial.fl & SWP_MAXIMIZE) 1342 SData.PgmControl |= SSF_CONTROL_MAXIMIZE; 1343 if (pNewProgDetails->swpInitial.fl & SWP_MINIMIZE) 1344 { 1345 SData.PgmControl |= SSF_CONTROL_MINIMIZE; 1346 // use background then 1347 SData.FgBg = SSF_FGBG_BACK; 1348 } 1349 if (pNewProgDetails->swpInitial.fl & SWP_MOVE) 1350 SData.PgmControl |= SSF_CONTROL_SETPOS; 1351 if (pNewProgDetails->swpInitial.fl & SWP_NOAUTOCLOSE) 1352 SData.PgmControl |= SSF_CONTROL_NOAUTOCLOSE; 1353 1354 SData.InitXPos = pNewProgDetails->swpInitial.x; 1355 SData.InitYPos = pNewProgDetails->swpInitial.y; 1356 SData.InitXSize = pNewProgDetails->swpInitial.cx; 1357 SData.InitYSize = pNewProgDetails->swpInitial.cy; 1358 1359 SData.Reserved = 0; 1360 SData.ObjectBuffer = pszFailingName; 1361 SData.ObjectBuffLen = cbFailingName; 1362 1363 // now, if a required module cannot be found, 1364 // DosStartSession still returns ERROR_FILE_NOT_FOUND 1365 // (2), but pszFailingName will be set to something 1366 // meaningful... so set it to a null string first 1367 // and we can then check if it has changed 1368 if (pszFailingName) 1369 *pszFailingName = '\0'; 1370 1371 TRY_QUIET(excpt1) 1372 { 1373 if ( (pNewProgDetails->pszStartupDir) 1374 && (pNewProgDetails->pszStartupDir[0]) 1375 ) 1376 { 1377 fCrit = !DosEnterCritSec(); 1378 if ( (!(arc = doshQueryCurrentDir(szCurrentDir))) 1379 && (!(arc = doshSetCurrentDir(pNewProgDetails->pszStartupDir))) 1380 ) 1381 fResetDir = TRUE; 1382 } 1383 1384 if ( (!arc) 1385 && (!(arc = DosStartSession(&SData, &sid, &pid))) 1386 ) 1387 { 1388 // app started: 1389 // compose HAPP from that 1390 *phapp = sid; 1391 } 1392 else if (pszFailingName && *pszFailingName) 1393 // DosStartSession has set this to something 1394 // other than NULL: then use error code 1804, 1395 // as cmd.exe does 1396 arc = 1804; 1397 } 1398 CATCH(excpt1) 1399 { 1400 arc = ERROR_PROTECTION_VIOLATION; 1401 } END_CATCH(); 1402 1403 if (fResetDir) 1404 doshSetCurrentDir(szCurrentDir); 1405 1406 if (fCrit) 1407 DosExitCritSec(); 1408 1409 #ifdef DEBUG_PROGRAMSTART 1410 _Pmpf((" DosStartSession returned %d, pszFailingName: \"%s\"", 1411 arc, pszFailingName)); 1412 #endif 1413 1414 return (arc); 1415 } 1416 877 1417 /* 878 1418 *@@ CallWinStartApp: … … 885 1425 * 886 1426 *@@added V0.9.18 (2002-02-13) [umoeller] 1427 *@@changed V0.9.18 (2002-03-27) [umoeller]: made failing modules work 887 1428 */ 888 1429 … … 890 1431 HWND hwndNotify, // in: notify window or NULLHANDLE 891 1432 const PROGDETAILS *pcProgDetails, // in: program spec (req.) 892 PCSZ pcszParamsPatched) 1433 ULONG cbFailingName, 1434 PSZ pszFailingName) 893 1435 { 894 1436 ULONG cb, … … 919 1461 if (cbTitle = strhSize(pcProgDetails->pszTitle)) 920 1462 cb += cbTitle; 1463 else 1464 return (ERROR_INVALID_PARAMETER); 1465 _Pmpf((__FUNCTION__ ": cbTitle is %d", cbTitle)); 1466 921 1467 if (cbExecutable = strhSize(pcProgDetails->pszExecutable)) 922 1468 cb += cbExecutable; 1469 else 1470 return (ERROR_INVALID_PARAMETER); 1471 _Pmpf((" cbExecutable is %d", cbExecutable)); 1472 923 1473 if (cbParameters = strhSize(pcProgDetails->pszParameters)) 924 1474 cb += cbParameters; 1475 else 1476 return (ERROR_INVALID_PARAMETER); 1477 _Pmpf((" cbParameters is %d", cbExecutable)); 1478 925 1479 if (cbStartupDir = strhSize(pcProgDetails->pszStartupDir)) 926 1480 cb += cbStartupDir; 1481 else 1482 return (ERROR_INVALID_PARAMETER); 1483 _Pmpf((" cbStartupDir is %d", cbStartupDir)); 1484 927 1485 if (cbIcon = strhSize(pcProgDetails->pszIcon)) 928 1486 cb += cbIcon; 1487 else 1488 return (ERROR_INVALID_PARAMETER); 1489 _Pmpf((" cbIcon is %d", cbIcon)); 1490 929 1491 if (cbEnvironment = appQueryEnvironmentLen(pcProgDetails->pszEnvironment)) 930 1492 cb += cbEnvironment; 1493 _Pmpf((" cbEnvironment is %d", cbEnvironment)); 1494 1495 _Pmpf((" cbTotal is %d", cb)); 931 1496 932 1497 if (cb > 60000) // to be on the safe side … … 940 1505 { 941 1506 // alright, copy stuff 942 PBYTE pThis;943 944 1507 memset(pNewProgDetails, 0, sizeof(PROGDETAILS)); 945 1508 946 1509 pNewProgDetails->Length = sizeof(PROGDETAILS); 947 pNewProgDetails->progt.progc = pcProgDetails->progt.progc; 948 pNewProgDetails->progt.fbVisible = pcProgDetails->progt.fbVisible; 949 memcpy(&pNewProgDetails->swpInitial, &pcProgDetails->swpInitial, sizeof(SWP)); 950 951 pThis = (PBYTE)(pNewProgDetails + 1); 952 953 if (cbTitle) 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 954 1516 { 955 memcpy(pThis, pcProgDetails->pszTitle, cbTitle); 956 pNewProgDetails->pszTitle = pThis; 957 pThis += cbTitle; 958 } 959 960 if (cbExecutable) 961 { 962 memcpy(pThis, pcProgDetails->pszExecutable, cbExecutable); 963 pNewProgDetails->pszExecutable = pThis; 964 pThis += cbExecutable; 965 } 966 967 if (cbParameters) 968 { 969 memcpy(pThis, pcProgDetails->pszParameters, cbParameters); 970 pNewProgDetails->pszParameters = pThis; 971 pThis += cbParameters; 972 } 973 974 if (cbStartupDir) 975 { 976 memcpy(pThis, pcProgDetails->pszStartupDir, cbStartupDir); 977 pNewProgDetails->pszStartupDir = pThis; 978 pThis += cbStartupDir; 979 } 980 981 if (cbIcon) 982 { 983 memcpy(pThis, pcProgDetails->pszIcon, cbIcon); 984 pNewProgDetails->pszIcon = pThis; 985 pThis += cbIcon; 986 } 987 988 if (cbEnvironment) 989 { 990 memcpy(pThis, pcProgDetails->pszEnvironment, cbEnvironment); 991 pNewProgDetails->pszEnvironment = pThis; 992 pThis += cbEnvironment; 993 } 994 995 #ifdef DEBUG_PROGRAMSTART 996 _Pmpf((__FUNCTION__ ": progt.progc: %d", pNewProgDetails->progt.progc)); 997 _Pmpf((" progt.fbVisible: 0x%lX", pNewProgDetails->progt.fbVisible)); 998 _Pmpf((" progt.pszTitle: \"%s\"", (pNewProgDetails->pszTitle) ? pNewProgDetails->pszTitle : "NULL")); 999 _Pmpf((" exec: \"%s\"", (pNewProgDetails->pszExecutable) ? pNewProgDetails->pszExecutable : "NULL")); 1000 _Pmpf((" params: \"%s\"", (pNewProgDetails->pszParameters) ? pNewProgDetails->pszParameters : "NULL")); 1001 _Pmpf((" startup: \"%s\"", (pNewProgDetails->pszStartupDir) ? pNewProgDetails->pszStartupDir : "NULL")); 1002 _Pmpf((" pszIcon: \"%s\"", (pNewProgDetails->pszIcon) ? pNewProgDetails->pszIcon : "NULL")); 1003 _Pmpf((" environment: ")); 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, 1576 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! 1004 1594 { 1005 PSZ pszThis = pNewProgDetails->pszEnvironment; 1006 while (pszThis && *pszThis) 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)) 1007 1607 { 1008 _Pmpf((" \"%s\"", pszThis)); 1009 pszThis += strlen(pszThis) + 1; 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); 1010 1691 } 1011 1692 } 1012 1013 _Pmpf((" swpInitial.fl = 0x%lX, x = %d, y = %d, cx = %d, cy = %d:",1014 pNewProgDetails->swpInitial.fl,1015 pNewProgDetails->swpInitial.x,1016 pNewProgDetails->swpInitial.y,1017 pNewProgDetails->swpInitial.cx,1018 pNewProgDetails->swpInitial.cy));1019 _Pmpf((" behind = %d, hwnd = %d, res1 = %d, res2 = %d",1020 pNewProgDetails->swpInitial.hwndInsertBehind,1021 pNewProgDetails->swpInitial.hwnd,1022 pNewProgDetails->swpInitial.ulReserved1,1023 pNewProgDetails->swpInitial.ulReserved2));1024 #endif1025 1026 if (!(*phapp = WinStartApp(hwndNotify,1027 // receives WM_APPTERMINATENOTIFY1028 pNewProgDetails,1029 pNewProgDetails->pszParameters,1030 NULL, // "reserved", PMREF says...1031 SAF_INSTALLEDCMDLINE)))1032 // we MUST use SAF_INSTALLEDCMDLINE1033 // or no Win-OS/2 session will start...1034 // whatever is going on here... Warp 4 FP111035 1036 // do not use SAF_STARTCHILDAPP, or the1037 // app will be terminated automatically1038 // when the WPS terminates!1039 {1040 // cannot start app:1041 #ifdef DEBUG_PROGRAMSTART1042 _Pmpf((__FUNCTION__ ": WinStartApp failed"));1043 #endif1044 1045 arc = ERROR_FILE_NOT_FOUND;1046 // unfortunately WinStartApp doesn't1047 // return meaningful codes like DosStartSession, so1048 // try to see what happened1049 /*1050 switch (ERRORIDERROR(WinGetLastError(0)))1051 {1052 case PMERR_DOS_ERROR: // (0x1200)1053 {1054 arc = ERROR_FILE_NOT_FOUND;1055 1056 // this is probably the case where the module1057 // couldn't be loaded, so try DosStartSession1058 // to get a meaningful return code... note that1059 // this cannot handle hwndNotify then1060 RESULTCODES result;1061 arc = DosExecPgm(pszFailingName,1062 cbFailingName,1063 EXEC_ASYNC,1064 NULL, // ProgDetails.pszParameters,1065 NULL, // ProgDetails.pszEnvironment,1066 &result,1067 ProgDetails.pszExecutable);1068 ULONG sid, pid;1069 STARTDATA SData;1070 SData.Length = sizeof(STARTDATA);1071 SData.Related = SSF_RELATED_CHILD; //INDEPENDENT;1072 SData.FgBg = SSF_FGBG_FORE;1073 SData.TraceOpt = SSF_TRACEOPT_NONE;1074 1075 SData.PgmTitle = ProgDetails.pszTitle;1076 SData.PgmName = ProgDetails.pszExecutable;1077 SData.PgmInputs = ProgDetails.pszParameters;1078 1079 SData.TermQ = NULL;1080 SData.Environment = ProgDetails.pszEnvironment;1081 SData.InheritOpt = SSF_INHERTOPT_PARENT; // ignored1082 SData.SessionType = SSF_TYPE_DEFAULT;1083 SData.IconFile = 0;1084 SData.PgmHandle = 0;1085 1086 SData.PgmControl = SSF_CONTROL_VISIBLE;1087 1088 SData.InitXPos = 30;1089 SData.InitYPos = 40;1090 SData.InitXSize = 200;1091 SData.InitYSize = 140;1092 SData.Reserved = 0;1093 SData.ObjectBuffer = pszFailingName;1094 SData.ObjectBuffLen = cbFailingName;1095 1096 arc = DosStartSession(&SData, &sid, &pid);1097 }1098 break;1099 1100 case PMERR_INVALID_APPL: // (0x1530)1101 // Attempted to start an application whose type is not1102 // recognized by OS/2.1103 arc = ERROR_INVALID_EXE_SIGNATURE;1104 break;1105 1106 case PMERR_INVALID_PARAMETERS: // (0x1208)1107 // An application parameter value is invalid for1108 // its converted PM type. For example: a 4-byte1109 // value outside the range -32 768 to +32 767 cannot be1110 // converted to a SHORT, and a negative number cannot1111 // be converted to a ULONG or USHORT.1112 arc = ERROR_INVALID_DATA;1113 break;1114 1115 case PMERR_STARTED_IN_BACKGROUND: // (0x1532)1116 // The application started a new session in the1117 // background.1118 arc = ERROR_SMG_START_IN_BACKGROUND;1119 break;1120 1121 case PMERR_INVALID_WINDOW: // (0x1206)1122 // The window specified with a Window List call1123 // is not a valid frame window.1124 1125 default:1126 arc = ERROR_BAD_FORMAT;1127 break;1128 }1129 */1130 1693 } 1131 1694 … … 1210 1773 * 1211 1774 * -- ERROR_INVALID_THREADID: not running on thread 1. 1212 * Since this uses WinStartApp internally and 1213 * WinStartApp completely hangs the session manager 1214 * if a Win-OS/2 full-screen session is started from 1215 * a thread that is NOT thread 1, this will now fail 1216 * with this error for safety (V0.9.16). 1775 * See remarks below. 1217 1776 * 1218 1777 * -- ERROR_INVALID_PARAMETER: pcProgDetails or … … 1225 1784 * 1226 1785 * -- ERROR_NOT_ENOUGH_MEMORY 1786 * 1787 * <B>About enforcing thread 1</B> 1788 * 1789 * OK, after long, long debugging hours, I have found 1790 * that WinStartApp hangs the system in the following 1791 * cases hard: 1792 * 1793 * -- If a Win-OS/2 session is started and WinStartApp 1794 * is _not_ on thread 1. For this reason, we check 1795 * if the caller is trying to start a Win-OS/2 1796 * session and return ERROR_INVALID_THREADID if 1797 * this is not running on thread 1. 1798 * 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). 1227 1808 * 1228 1809 *@@added V0.9.6 (2000-10-16) [umoeller] … … 1240 1821 *@@changed V0.9.16 (2002-01-04) [umoeller]: added more detailed error reports and *FailingName params 1241 1822 *@@changed V0.9.18 (2002-02-13) [umoeller]: added CallWinStartApp to fix possible memory problems 1823 *@@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 1242 1825 */ 1243 1826 1244 1827 APIRET appStartApp(HWND hwndNotify, // in: notify window or NULLHANDLE 1245 1828 const PROGDETAILS *pcProgDetails, // in: program spec (req.) 1246 ULONG ulFlags, // in: APP_RUN_* flags 1829 ULONG ulFlags, // in: APP_RUN_* flags or 0 1247 1830 HAPP *phapp, // out: application handle if NO_ERROR is returned 1248 1831 ULONG cbFailingName, 1249 1832 PSZ pszFailingName) 1250 1833 { 1251 APIRET arc = NO_ERROR;1834 APIRET arc; 1252 1835 PROGDETAILS ProgDetails; 1836 XSTRING strExecutablePatched, 1837 strParamsPatched; 1838 PSZ pszWinOS2Env = 0; 1253 1839 1254 1840 if (pszFailingName) … … 1258 1844 return (ERROR_INVALID_PARAMETER); 1259 1845 1260 memcpy(&ProgDetails, pcProgDetails, sizeof(PROGDETAILS)); 1261 // pointers still point into old prog details buffer 1262 ProgDetails.Length = sizeof(PROGDETAILS); 1263 ProgDetails.progt.fbVisible = SHE_VISIBLE; 1264 1265 // all this only makes sense if this contains something... 1266 // besides, this crashed on string comparisons V0.9.9 (2001-01-27) [umoeller] 1267 if ( (!ProgDetails.pszExecutable) 1268 || (!(*(ProgDetails.pszExecutable))) 1269 ) 1270 arc = ERROR_INVALID_PARAMETER; 1271 else if (doshMyTID() != 1) // V0.9.16 (2001-10-19) [umoeller] 1272 arc = ERROR_INVALID_THREADID; 1273 else 1274 { 1275 ULONG ulIsWinApp; 1276 1277 CHAR szFQExecutable[CCHMAXPATH]; 1278 1279 XSTRING strParamsPatched; 1280 PSZ pszWinOS2Env = 0; 1281 1282 // memset(&ProgDetails.swpInitial, 0, sizeof(SWP)); 1283 // this wasn't a good idea... WPProgram stores stuff 1284 // in here, such as the "minimize on startup" -> SWP_MINIMIZE 1285 1286 // duplicate parameters... 1287 // we need this for string manipulations below... 1288 if (ProgDetails.pszParameters) 1289 xstrInitCopy(&strParamsPatched, 1290 ProgDetails.pszParameters, 1291 100); 1846 xstrInit(&strExecutablePatched, 0); 1847 xstrInit(&strParamsPatched, 0); 1848 1849 if (!(arc = appFixProgDetails(&ProgDetails, 1850 pcProgDetails, 1851 ulFlags, 1852 &strExecutablePatched, 1853 &strParamsPatched, 1854 &pszWinOS2Env))) 1855 { 1856 if (pszFailingName) 1857 strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName); 1858 1859 if ( (appIsWindowsApp(ProgDetails.progt.progc)) 1860 && (doshMyTID() != 1) // V0.9.16 (2001-10-19) [umoeller] 1861 ) 1862 arc = ERROR_INVALID_THREADID; 1292 1863 else 1293 // no old params: 1294 xstrInit(&strParamsPatched, 100); 1295 1296 #ifdef DEBUG_PROGRAMSTART 1297 _Pmpf((__FUNCTION__ ": old progc: 0x%lX", pcProgDetails->progt.progc)); 1298 _Pmpf((" pszTitle: %s", (ProgDetails.pszTitle) ? ProgDetails.pszTitle : NULL)); 1299 _Pmpf((" pszIcon: %s", (ProgDetails.pszIcon) ? ProgDetails.pszIcon : NULL)); 1300 #endif 1301 1302 // program type fixups 1303 switch (ProgDetails.progt.progc) // that's a ULONG 1304 { 1305 case ((ULONG)-1): // we get that sometimes... 1306 case PROG_DEFAULT: 1307 { 1308 // V0.9.12 (2001-05-26) [umoeller] 1309 ULONG ulDosAppType; 1310 appQueryAppType(ProgDetails.pszExecutable, 1311 &ulDosAppType, 1312 &ProgDetails.progt.progc); 1313 } 1314 break; 1315 } 1316 1317 // set session type from option flags 1318 if (ulFlags & APP_RUN_FULLSCREEN) 1319 { 1320 if (ProgDetails.progt.progc == PROG_WINDOWABLEVIO) 1321 ProgDetails.progt.progc = PROG_FULLSCREEN; 1322 1323 if (ProgDetails.progt.progc == PROG_WINDOWEDVDM) 1324 ProgDetails.progt.progc = PROG_VDM; 1325 } 1326 1327 if (ulIsWinApp = appIsWindowsApp(ProgDetails.progt.progc)) 1328 { 1329 if (ulFlags & APP_RUN_FULLSCREEN) 1330 ProgDetails.progt.progc = (ulFlags & APP_RUN_ENHANCED) 1331 ? PROG_31_ENH 1332 : PROG_31_STD; 1333 else 1334 { 1335 if (ulFlags & APP_RUN_STANDARD) 1336 ProgDetails.progt.progc = (ulFlags & APP_RUN_SEPARATE) 1337 ? PROG_31_STDSEAMLESSVDM 1338 : PROG_31_STDSEAMLESSCOMMON; 1339 1340 if (ulFlags & APP_RUN_ENHANCED) 1341 ProgDetails.progt.progc = (ulFlags & APP_RUN_SEPARATE) 1342 ? PROG_31_ENHSEAMLESSVDM 1343 : PROG_31_ENHSEAMLESSCOMMON; 1344 } 1345 1346 // re-run V0.9.16 (2001-10-19) [umoeller] 1347 ulIsWinApp = appIsWindowsApp(ProgDetails.progt.progc); 1348 } 1349 1350 /* 1351 * command lines fixups: 1352 * 1353 */ 1354 1355 if (!strcmp(ProgDetails.pszExecutable, "*")) 1356 { 1357 /* 1358 * "*" for command sessions: 1359 * 1360 */ 1361 1362 if (ulIsWinApp == 2) 1363 { 1364 // enhanced Win-OS/2 session: 1365 PSZ psz = NULL; 1366 if (strParamsPatched.ulLength) 1367 // "/3 " + existing params 1368 psz = strdup(strParamsPatched.psz); 1369 1370 xstrcpy(&strParamsPatched, "/3 ", 0); 1371 1372 if (psz) 1373 { 1374 xstrcat(&strParamsPatched, psz, 0); 1375 free(psz); 1376 } 1377 } 1378 1379 if (ulIsWinApp) 1380 { 1381 // cheat: WinStartApp doesn't support NULL 1382 // for Win-OS2 sessions, so manually start winos2.com 1383 ProgDetails.pszExecutable = "WINOS2.COM"; 1384 // this is a DOS app, so fix this to DOS fullscreen 1385 ProgDetails.progt.progc = PROG_VDM; 1386 } 1387 else 1388 // for all other executable types 1389 // (including OS/2 and DOS sessions), 1390 // set pszExecutable to NULL; this will 1391 // have WinStartApp start a cmd shell 1392 ProgDetails.pszExecutable = NULL; 1393 1394 } // end if (strcmp(pProgDetails->pszExecutable, "*") == 0) 1395 else 1396 { 1397 // check if the executable is fully qualified; if so, 1398 // check if the executable file exists 1399 if ( (ProgDetails.pszExecutable[1] == ':') 1400 && (strchr(ProgDetails.pszExecutable, '\\')) 1401 ) 1402 { 1403 ULONG ulAttr; 1404 if (!(arc = doshQueryPathAttr(ProgDetails.pszExecutable, 1405 &ulAttr))) 1406 { 1407 // make sure startup dir is really a directory 1408 if (ProgDetails.pszStartupDir) 1409 { 1410 // it is valid to specify a startup dir of "C:" 1411 if ( (strlen(ProgDetails.pszStartupDir) > 2) 1412 && (!(arc = doshQueryPathAttr(ProgDetails.pszStartupDir, 1413 &ulAttr))) 1414 && (!(ulAttr & FILE_DIRECTORY)) 1415 ) 1416 arc = ERROR_PATH_NOT_FOUND; 1417 } 1418 } 1419 } 1420 else 1421 { 1422 // _not_ fully qualified: look it up on the PATH then 1423 // V0.9.16 (2001-12-06) [umoeller] 1424 if (!(arc = doshSearchPath("PATH", 1425 ProgDetails.pszExecutable, 1426 szFQExecutable, 1427 sizeof(szFQExecutable)))) 1428 // alright, found it: 1429 ProgDetails.pszExecutable = szFQExecutable; 1430 } 1431 1432 if (!arc) 1433 { 1434 PSZ pszExtension; 1435 switch (ProgDetails.progt.progc) 1436 { 1437 /* 1438 * .CMD files fixups 1439 * 1440 */ 1441 1442 case PROG_FULLSCREEN: // OS/2 fullscreen 1443 case PROG_WINDOWABLEVIO: // OS/2 window 1444 { 1445 if ( (pszExtension = doshGetExtension(ProgDetails.pszExecutable)) 1446 && (!stricmp(pszExtension, "CMD")) 1447 ) 1448 { 1449 CallBatchCorrectly(&ProgDetails, 1450 &strParamsPatched, 1451 "OS2_SHELL", 1452 "CMD.EXE"); 1453 } 1454 break; } 1455 1456 case PROG_VDM: // DOS fullscreen 1457 case PROG_WINDOWEDVDM: // DOS window 1458 { 1459 if ( (pszExtension = doshGetExtension(ProgDetails.pszExecutable)) 1460 && (!stricmp(pszExtension, "BAT")) 1461 ) 1462 { 1463 CallBatchCorrectly(&ProgDetails, 1464 &strParamsPatched, 1465 NULL, 1466 "COMMAND.COM"); 1467 } 1468 break; } 1469 } // end switch (ProgDetails.progt.progc) 1470 } 1471 } 1472 1473 if (!arc) 1474 { 1475 if ( (ulIsWinApp) 1476 && ( (ProgDetails.pszEnvironment == NULL) 1477 || (!strlen(ProgDetails.pszEnvironment)) 1478 ) 1479 ) 1480 { 1481 // this is a windoze app, and caller didn't bother 1482 // to give us an environment: 1483 // we MUST set one then, or we'll get the strangest 1484 // errors, up to system hangs. V0.9.12 (2001-05-26) [umoeller] 1485 1486 DOSENVIRONMENT Env = {0}; 1487 1488 // get standard WIN-OS/2 environment 1489 PSZ pszTemp = appQueryDefaultWin31Environment(); 1490 1491 if (!(arc = appParseEnvironment(pszTemp, 1492 &Env))) 1493 { 1494 // now override KBD_CTRL_BYPASS=CTRL_ESC 1495 if ( (!(arc = appSetEnvironmentVar(&Env, 1496 "KBD_CTRL_BYPASS=CTRL_ESC", 1497 FALSE))) // add last 1498 && (!(arc = appConvertEnvironment(&Env, 1499 &pszWinOS2Env, // freed at bottom 1500 NULL))) 1501 ) 1502 ProgDetails.pszEnvironment = pszWinOS2Env; 1503 1504 appFreeEnvironment(&Env); 1505 } 1506 1507 free(pszTemp); 1508 } 1509 1510 if (!arc) 1511 { 1512 if (!ProgDetails.pszTitle) 1513 ProgDetails.pszTitle = ProgDetails.pszExecutable; 1514 1515 ProgDetails.pszParameters = strParamsPatched.psz; 1516 1517 if (pszFailingName) 1518 strhncpy0(pszFailingName, ProgDetails.pszExecutable, cbFailingName); 1519 1520 arc = CallWinStartApp(phapp, 1521 hwndNotify, 1522 &ProgDetails, 1523 strParamsPatched.psz); 1524 } 1525 } 1526 1527 xstrClear(&strParamsPatched); 1528 if (pszWinOS2Env) 1529 free(pszWinOS2Env); 1864 arc = CallWinStartApp(phapp, 1865 hwndNotify, 1866 &ProgDetails, 1867 cbFailingName, 1868 pszFailingName); 1530 1869 } // end if (ProgDetails.pszExecutable) 1870 1871 xstrClear(&strParamsPatched); 1872 xstrClear(&strExecutablePatched); 1873 1874 if (pszWinOS2Env) 1875 free(pszWinOS2Env); 1531 1876 1532 1877 #ifdef DEBUG_PROGRAMSTART … … 1618 1963 if (p = strrchr(pcszFile, '\\')) 1619 1964 { 1620 strhncpy0(szDir,1621 pcszFile,1622 p - pcszFile);1623 pd.pszStartupDir = szDir;1965 strhncpy0(szDir, 1966 pcszFile, 1967 p - pcszFile); 1968 pd.pszStartupDir = szDir; 1624 1969 } 1625 1970
Note:
See TracChangeset
for help on using the changeset viewer.