- Timestamp:
- Dec 26, 2021 1:27:48 AM (3 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/UnattendedImpl.h
r91502 r93082 232 232 HRESULT i_innerDetectIsoOSWindows(RTVFS hVfsIso, DETECTBUFFER *puBuf, VBOXOSTYPE *penmOsType); 233 233 HRESULT i_innerDetectIsoOSLinux(RTVFS hVfsIso, DETECTBUFFER *puBuf, VBOXOSTYPE *penmOsType); 234 HRESULT i_innerDetectIsoOSOs2(RTVFS hVfsIso, DETECTBUFFER *puBuf, VBOXOSTYPE *penmOsType); 234 235 235 236 /** -
trunk/src/VBox/Main/src-server/UnattendedImpl.cpp
r92732 r93082 141 141 } 142 142 } UnattendedInstallationDisk; 143 144 145 /** 146 * OS/2 syslevel file header. 147 */ 148 #pragma pack(1) 149 typedef struct OS2SYSLEVELHDR 150 { 151 uint16_t uMinusOne; /**< 0x00: UINT16_MAX */ 152 char achSignature[8]; /**< 0x02: "SYSLEVEL" */ 153 uint8_t abReserved1[5]; /**< 0x0a: Usually zero. Ignore. */ 154 uint16_t uSyslevelFileVer; /**< 0x0f: The syslevel file version: 1. */ 155 uint8_t abReserved2[16]; /**< 0x11: Zero. Ignore. */ 156 uint32_t offTable; /**< 0x21: Offset of the syslevel table. */ 157 } OS2SYSLEVELHDR; 158 #pragma pack() 159 AssertCompileSize(OS2SYSLEVELHDR, 0x25); 160 161 /** 162 * OS/2 syslevel table entry. 163 */ 164 #pragma pack(1) 165 typedef struct OS2SYSLEVELENTRY 166 { 167 uint16_t id; /**< 0x00: ? */ 168 uint8_t bEdition; /**< 0x02: The OS/2 edition: 0=standard, 1=extended, x=component defined */ 169 uint8_t bVersion; /**< 0x03: 0x45 = 4.5 */ 170 uint8_t bModify; /**< 0x04: Lower nibble is added to bVersion, so 0x45 0x02 => 4.52 */ 171 uint8_t abReserved1[2]; /**< 0x05: Zero. Ignore. */ 172 char achCsdLevel[8]; /**< 0x07: The current CSD level. */ 173 char achCsdPrior[8]; /**< 0x0f: The prior CSD level. */ 174 char szName[80]; /**< 0x5f: System/component name. */ 175 char achId[9]; /**< 0x67: System/component ID. */ 176 uint8_t bRefresh; /**< 0x70: Single digit refresh version, ignored if zero. */ 177 char szType[9]; /**< 0x71: Some kind of type string. Optional */ 178 uint8_t abReserved2[6]; /**< 0x7a: Zero. Ignore. */ 179 } OS2SYSLEVELENTRY; 180 #pragma pack() 181 AssertCompileSize(OS2SYSLEVELENTRY, 0x80); 143 182 144 183 … … 349 388 if (hrc == S_FALSE && enmOsType == VBOXOSTYPE_Unknown) 350 389 hrc = i_innerDetectIsoOSLinux(hVfsIso, &uBuf, &enmOsType); 390 if (hrc == S_FALSE && enmOsType == VBOXOSTYPE_Unknown) 391 hrc = i_innerDetectIsoOSOs2(hVfsIso, &uBuf, &enmOsType); 351 392 if (enmOsType != VBOXOSTYPE_Unknown) 352 393 { … … 1181 1222 1182 1223 1224 /** 1225 * Detect OS/2 installation ISOs. 1226 * 1227 * Mainly aiming at ACP2/MCP2 as that's what we currently use in our testing. 1228 * 1229 * @returns COM status code. 1230 * @retval S_OK if detected 1231 * @retval S_FALSE if not fully detected. 1232 * 1233 * @param hVfsIso The ISO file system. 1234 * @param pBuf Read buffer. 1235 * @param penmOsType Where to return the OS type. This is initialized to 1236 * VBOXOSTYPE_Unknown. 1237 */ 1238 HRESULT Unattended::i_innerDetectIsoOSOs2(RTVFS hVfsIso, DETECTBUFFER *pBuf, VBOXOSTYPE *penmOsType) 1239 { 1240 /* 1241 * The OS2SE20.SRC contains the location of the tree with the diskette 1242 * images, typically "\OS2IMAGE". 1243 */ 1244 RTVFSFILE hVfsFile; 1245 int vrc = RTVfsFileOpen(hVfsIso, "OS2SE20.SRC", RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile); 1246 if (RT_SUCCESS(vrc)) 1247 { 1248 size_t cbRead = 0; 1249 vrc = RTVfsFileRead(hVfsFile, pBuf->sz, sizeof(pBuf->sz) - 1, &cbRead); 1250 RTVfsFileRelease(hVfsFile); 1251 if (RT_SUCCESS(vrc)) 1252 { 1253 pBuf->sz[cbRead] = '\0'; 1254 RTStrStrip(pBuf->sz); 1255 vrc = RTStrValidateEncoding(pBuf->sz); 1256 if (RT_SUCCESS(vrc)) 1257 LogRelFlow(("Unattended: OS2SE20.SRC=%s\n", pBuf->sz)); 1258 else 1259 LogRel(("Unattended: OS2SE20.SRC invalid encoding: %Rrc, %.*Rhxs\n", vrc, cbRead, pBuf->sz)); 1260 } 1261 else 1262 LogRel(("Unattended: Error reading OS2SE20.SRC: %\n", vrc)); 1263 } 1264 /* 1265 * ArcaOS has dropped the file, assume it's \OS2IMAGE and see if it's there. 1266 */ 1267 else if (vrc == VERR_FILE_NOT_FOUND) 1268 RTStrCopy(pBuf->sz, sizeof(pBuf->sz), "\\OS2IMAGE"); 1269 else 1270 return S_FALSE; 1271 1272 /* 1273 * Check that the directory directory exists and has a DISK_0 under it 1274 * with an OS2LDR on it. 1275 */ 1276 size_t const cchOs2Image = strlen(pBuf->sz); 1277 vrc = RTPathAppend(pBuf->sz, sizeof(pBuf->sz), "DISK_0/OS2LDR"); 1278 RTFSOBJINFO ObjInfo = {0}; 1279 vrc = RTVfsQueryPathInfo(hVfsIso, pBuf->sz, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 1280 if (vrc == VERR_FILE_NOT_FOUND) 1281 { 1282 RTStrCat(pBuf->sz, sizeof(pBuf->sz), "."); /* eCS 2.0 image includes the dot from the 8.3 name. */ 1283 vrc = RTVfsQueryPathInfo(hVfsIso, pBuf->sz, &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 1284 } 1285 if ( RT_FAILURE(vrc) 1286 || !RTFS_IS_FILE(ObjInfo.Attr.fMode)) 1287 { 1288 LogRel(("Unattended: RTVfsQueryPathInfo(, '%s' (from OS2SE20.SRC),) -> %Rrc, fMode=%#x\n", 1289 pBuf->sz, vrc, ObjInfo.Attr.fMode)); 1290 return S_FALSE; 1291 } 1292 1293 /* 1294 * So, it's some kind of OS/2 2.x or later ISO alright. 1295 */ 1296 *penmOsType = VBOXOSTYPE_OS2; 1297 mStrDetectedOSHints.printf("OS2SE20.SRC=%.*s", cchOs2Image, pBuf->sz); 1298 1299 /* 1300 * ArcaOS ISOs seems to have a AOSBOOT dir on them. 1301 * This contains a ARCANOAE.FLG file with content we can use for the version: 1302 * ArcaOS 5.0.7 EN 1303 * Built 2021-12-07 18:34:34 1304 * We drop the "ArcaOS" bit, as it's covered by penmOsType. Then we pull up 1305 * the second line. 1306 * 1307 * Note! Yet to find a way to do unattended install of ArcaOS, as it comes 1308 * with no CD-boot floppy images, only simple .PF archive files for 1309 * unpacking onto the ram disk or whatever. Modifying these is 1310 * possible (ibsen's aPLib v0.36 compression with some simple custom 1311 * headers), but it would probably be a royal pain. Could perhaps 1312 * cook something from OS2IMAGE\DISK_0 thru 3... 1313 */ 1314 vrc = RTVfsQueryPathInfo(hVfsIso, "AOSBOOT", &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 1315 if ( RT_SUCCESS(vrc) 1316 && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 1317 { 1318 *penmOsType = VBOXOSTYPE_ArcaOS; 1319 1320 /* Read the version file: */ 1321 vrc = RTVfsFileOpen(hVfsIso, "SYS/ARCANOAE.FLG", RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile); 1322 if (RT_SUCCESS(vrc)) 1323 { 1324 size_t cbRead = 0; 1325 vrc = RTVfsFileRead(hVfsFile, pBuf->sz, sizeof(pBuf->sz) - 1, &cbRead); 1326 RTVfsFileRelease(hVfsFile); 1327 pBuf->sz[cbRead] = '\0'; 1328 if (RT_SUCCESS(vrc)) 1329 { 1330 /* Strip the OS name: */ 1331 char *pszVersion = RTStrStrip(pBuf->sz); 1332 static char s_szArcaOS[] = "ArcaOS"; 1333 if (RTStrStartsWith(pszVersion, s_szArcaOS)) 1334 pszVersion = RTStrStripL(pszVersion + sizeof(s_szArcaOS) - 1); 1335 1336 /* Pull up the 2nd line if it, condensing the \r\n into a single space. */ 1337 char *pszNewLine = strchr(pszVersion, '\n'); 1338 if (pszNewLine && RTStrStartsWith(pszNewLine + 1, "Built 20")) 1339 { 1340 size_t offRemove = 0; 1341 while (RT_C_IS_SPACE(pszNewLine[-1 - offRemove])) 1342 offRemove++; 1343 if (offRemove > 0) 1344 { 1345 pszNewLine -= offRemove; 1346 memmove(pszNewLine, pszNewLine + offRemove, strlen(pszNewLine + offRemove) - 1); 1347 } 1348 *pszNewLine = ' '; 1349 } 1350 1351 /* Drop any additional lines: */ 1352 pszNewLine = strchr(pszVersion, '\n'); 1353 if (pszNewLine) 1354 *pszNewLine = '\0'; 1355 RTStrStripR(pszVersion); 1356 1357 /* Done (hope it makes some sense). */ 1358 mStrDetectedOSVersion = pszVersion; 1359 } 1360 else 1361 LogRel(("Unattended: failed to read AOSBOOT/ARCANOAE.FLG: %Rrc\n", vrc)); 1362 } 1363 else 1364 LogRel(("Unattended: failed to open AOSBOOT/ARCANOAE.FLG for reading: %Rrc\n", vrc)); 1365 } 1366 /* 1367 * Similarly, eCS has an ECS directory and it typically contains a 1368 * ECS_INST.FLG file with the version info. Content differs a little: 1369 * eComStation 2.0 EN_US Thu May 13 10:27:54 pm 2010 1370 * Built on ECS60441318 1371 * Here we drop the "eComStation" bit and leave the 2nd line as it. 1372 * 1373 * Note! At least 2.0 has a DISKIMGS folder with what looks like boot 1374 * disks, so we could probably get something going here without 1375 * needing to write an OS2 boot sector... 1376 */ 1377 else 1378 { 1379 vrc = RTVfsQueryPathInfo(hVfsIso, "ECS", &ObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 1380 if ( RT_SUCCESS(vrc) 1381 && RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode)) 1382 { 1383 *penmOsType = VBOXOSTYPE_ECS; 1384 1385 /* Read the version file: */ 1386 vrc = RTVfsFileOpen(hVfsIso, "ECS/ECS_INST.FLG", RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile); 1387 if (RT_SUCCESS(vrc)) 1388 { 1389 size_t cbRead = 0; 1390 vrc = RTVfsFileRead(hVfsFile, pBuf->sz, sizeof(pBuf->sz) - 1, &cbRead); 1391 RTVfsFileRelease(hVfsFile); 1392 pBuf->sz[cbRead] = '\0'; 1393 if (RT_SUCCESS(vrc)) 1394 { 1395 /* Strip the OS name: */ 1396 char *pszVersion = RTStrStrip(pBuf->sz); 1397 static char s_szECS[] = "eComStation"; 1398 if (RTStrStartsWith(pszVersion, s_szECS)) 1399 pszVersion = RTStrStripL(pszVersion + sizeof(s_szECS) - 1); 1400 1401 /* Drop any additional lines: */ 1402 char *pszNewLine = strchr(pszVersion, '\n'); 1403 if (pszNewLine) 1404 *pszNewLine = '\0'; 1405 RTStrStripR(pszVersion); 1406 1407 /* Done (hope it makes some sense). */ 1408 mStrDetectedOSVersion = pszVersion; 1409 } 1410 else 1411 LogRel(("Unattended: failed to read ECS/ECS_INST.FLG: %Rrc\n", vrc)); 1412 } 1413 else 1414 LogRel(("Unattended: failed to open ECS/ECS_INST.FLG for reading: %Rrc\n", vrc)); 1415 } 1416 else 1417 { 1418 /* 1419 * Official IBM OS/2 builds doesn't have any .FLG file on them, 1420 * so need to pry the information out in some other way. Best way 1421 * is to read the SYSLEVEL.OS2 file, which is typically on disk #2, 1422 * though on earlier versions (warp3) it was disk #1. 1423 */ 1424 vrc = RTPathJoin(pBuf->sz, sizeof(pBuf->sz), strchr(mStrDetectedOSHints.c_str(), '=') + 1, 1425 "/DISK_2/SYSLEVEL.OS2"); 1426 if (RT_SUCCESS(vrc)) 1427 { 1428 vrc = RTVfsFileOpen(hVfsIso, pBuf->sz, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile); 1429 if (vrc == VERR_FILE_NOT_FOUND) 1430 { 1431 RTPathJoin(pBuf->sz, sizeof(pBuf->sz), strchr(mStrDetectedOSHints.c_str(), '=') + 1, "/DISK_1/SYSLEVEL.OS2"); 1432 vrc = RTVfsFileOpen(hVfsIso, pBuf->sz, RTFILE_O_READ | RTFILE_O_DENY_NONE | RTFILE_O_OPEN, &hVfsFile); 1433 } 1434 if (RT_SUCCESS(vrc)) 1435 { 1436 RT_ZERO(pBuf->ab); 1437 size_t cbRead = 0; 1438 vrc = RTVfsFileRead(hVfsFile, pBuf->ab, sizeof(pBuf->ab), &cbRead); 1439 RTVfsFileRelease(hVfsFile); 1440 if (RT_SUCCESS(vrc)) 1441 { 1442 /* Check the header. */ 1443 OS2SYSLEVELHDR const *pHdr = (OS2SYSLEVELHDR const *)&pBuf->ab[0]; 1444 if ( pHdr->uMinusOne == UINT16_MAX 1445 && pHdr->uSyslevelFileVer == 1 1446 && memcmp(pHdr->achSignature, RT_STR_TUPLE("SYSLEVEL")) == 0 1447 && pHdr->offTable < cbRead 1448 && pHdr->offTable + sizeof(OS2SYSLEVELENTRY) <= cbRead) 1449 { 1450 OS2SYSLEVELENTRY *pEntry = (OS2SYSLEVELENTRY *)&pBuf->ab[pHdr->offTable]; 1451 if ( RT_SUCCESS(RTStrValidateEncodingEx(pEntry->szName, sizeof(pEntry->szName), 1452 RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED)) 1453 && RT_SUCCESS(RTStrValidateEncodingEx(pEntry->achCsdLevel, sizeof(pEntry->achCsdLevel), 0)) 1454 && pEntry->bVersion != 0 1455 && ((pEntry->bVersion >> 4) & 0xf) < 10 1456 && (pEntry->bVersion & 0xf) < 10 1457 && pEntry->bModify < 10 1458 && pEntry->bRefresh < 10) 1459 { 1460 /* Flavor: */ 1461 char *pszName = RTStrStrip(pEntry->szName); 1462 if (pszName) 1463 mStrDetectedOSFlavor = pszName; 1464 1465 /* Version: */ 1466 if (pEntry->bRefresh != 0) 1467 mStrDetectedOSVersion.printf("%d.%d%d.%d", pEntry->bVersion >> 4, pEntry->bVersion & 0xf, 1468 pEntry->bModify, pEntry->bRefresh); 1469 else 1470 mStrDetectedOSVersion.printf("%d.%d%d", pEntry->bVersion >> 4, pEntry->bVersion & 0xf, 1471 pEntry->bModify); 1472 pEntry->achCsdLevel[sizeof(pEntry->achCsdLevel) - 1] = '\0'; 1473 char *pszCsd = RTStrStrip(pEntry->achCsdLevel); 1474 if (*pszCsd != '\0') 1475 { 1476 mStrDetectedOSVersion.append(' '); 1477 mStrDetectedOSVersion.append(pszCsd); 1478 } 1479 if (RTStrVersionCompare(mStrDetectedOSVersion.c_str(), "4.50") >= 0) 1480 *penmOsType = VBOXOSTYPE_OS2Warp45; 1481 else if (RTStrVersionCompare(mStrDetectedOSVersion.c_str(), "4.00") >= 0) 1482 *penmOsType = VBOXOSTYPE_OS2Warp4; 1483 else if (RTStrVersionCompare(mStrDetectedOSVersion.c_str(), "3.00") >= 0) 1484 *penmOsType = VBOXOSTYPE_OS2Warp3; 1485 } 1486 else 1487 LogRel(("Unattended: bogus SYSLEVEL.OS2 file entry: %.128Rhxd\n", pEntry)); 1488 } 1489 else 1490 LogRel(("Unattended: bogus SYSLEVEL.OS2 file header: uMinusOne=%#x uSyslevelFileVer=%#x achSignature=%.8Rhxs offTable=%#x vs cbRead=%#zx\n", 1491 pHdr->uMinusOne, pHdr->uSyslevelFileVer, pHdr->achSignature, pHdr->offTable, cbRead)); 1492 } 1493 else 1494 LogRel(("Unattended: failed to read SYSLEVEL.OS2: %Rrc\n", vrc)); 1495 } 1496 else 1497 LogRel(("Unattended: failed to open '%s' for reading: %Rrc\n", pBuf->sz, vrc)); 1498 } 1499 } 1500 } 1501 1502 /** @todo language detection? */ 1503 1504 /** @todo Return true if we can actually do an unattended installation 1505 * using this ISO. So far, we cannot from any OS/2 image. */ 1506 return S_FALSE; 1507 } 1508 1509 1183 1510 HRESULT Unattended::prepare() 1184 1511 { -
trunk/src/VBox/Main/src-server/UnattendedInstaller.cpp
r91718 r93082 65 65 else 66 66 pUinstaller = new UnattendedWindowsSifInstaller(pParent); 67 } 68 else if (enmOsType >= VBOXOSTYPE_OS2 && enmOsType < VBOXOSTYPE_Linux) 69 { 70 /** @todo OS/2 */ 67 71 } 68 72 else
Note:
See TracChangeset
for help on using the changeset viewer.