VirtualBox

Changeset 82400 in vbox


Ignore:
Timestamp:
Dec 4, 2019 9:20:24 PM (5 years ago)
Author:
vboxsync
Message:

EFI/VBoxPkg: Hacked up a routine to construct the path of the HFS+ blessed file.

Location:
trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe/fsw_hfs.c

    r76553 r82400  
    12731273}
    12741274
     1275static int fsw_hfs_btree_find_id(BTreeKey *record, void* param)
     1276{
     1277    visitor_parameter_t         *vp = (visitor_parameter_t*)param;
     1278    fsw_u8                      *base = (fsw_u8*)record->rawData + be16_to_cpu(record->length16) + 2;
     1279    fsw_u16                     rec_type = be16_to_cpu(*(fsw_u16*)base);
     1280    struct HFSPlusCatalogKey    *cat_key = (HFSPlusCatalogKey*)record;
     1281    fsw_u16                     name_len;
     1282    fsw_u16                     *name_ptr;
     1283    fsw_u16                     *old_ptr;
     1284    int                         i;
     1285    struct fsw_string           *file_name;
     1286    struct fsw_string           new_name;
     1287
     1288    if (be32_to_cpu(cat_key->parentID) != vp->parent)
     1289        return -1;
     1290
     1291    if (!vp->cur_pos)
     1292        vp->cur_pos = be32_to_cpu(cat_key->parentID);
     1293
     1294    /* Not what we're looking for. */
     1295    if (vp->file_info.id != vp->cur_pos++)
     1296        return 0;
     1297
     1298    if (rec_type == kHFSPlusFolderThreadRecord || rec_type == kHFSPlusFileThreadRecord)
     1299    {
     1300        HFSPlusCatalogThread    *thread;
     1301
     1302        thread = (HFSPlusCatalogThread *)base;
     1303        vp->file_info.id = be32_to_cpu(thread->parentID);
     1304
     1305        name_len = be16_to_cpu(thread->nodeName.length);
     1306
     1307        file_name = vp->file_info.name;
     1308
     1309        new_name.len = name_len + 1 + file_name->len;
     1310        new_name.size = 2 * new_name.len;
     1311        fsw_alloc(new_name.size, &new_name.data);
     1312        name_ptr = (fsw_u16*)new_name.data;
     1313        /* Tack on path separator. */
     1314        name_ptr[0] = L'/';
     1315        /* Copy over + swap the new path component. */
     1316        for (i = 0; i < name_len; i++)
     1317            name_ptr[i + 1] = be16_to_cpu(thread->nodeName.unicode[i]);
     1318        if (file_name->len) {
     1319            /* Tack on the previous path. */
     1320            old_ptr = (fsw_u16*)file_name->data;
     1321            for (++i; i < new_name.len; i++ )
     1322                name_ptr[i] = *old_ptr++;
     1323        }
     1324
     1325        fsw_free(file_name->data);
     1326        file_name->len  = new_name.len;
     1327        file_name->size = new_name.size;
     1328        file_name->data = new_name.data;
     1329        file_name->type = FSW_STRING_TYPE_UTF16;
     1330
     1331        /* This was it, stop iterating. */
     1332        return 1;
     1333    }
     1334
     1335    return 0;
     1336}
     1337
     1338/**
     1339 * Obtain the full path of a file given its CNID (Catalog Node ID), i.e.
     1340 * file or folder ID.
     1341 *
     1342 */
     1343static fsw_status_t fsw_hfs_get_path_from_cnid(struct fsw_hfs_volume *vol, fsw_u32 cnid, struct fsw_string *path)
     1344{
     1345    fsw_status_t                status = FSW_UNSUPPORTED;
     1346    fsw_u32                     ptr;
     1347    BTNodeDescriptor            *node = NULL;
     1348    struct HFSPlusCatalogKey    catkey;
     1349    visitor_parameter_t         param;
     1350    struct fsw_string           rec_name;
     1351
     1352    /* The CNID must be a valid user node ID. */
     1353    if (cnid < kHFSFirstUserCatalogNodeID)
     1354        goto done;
     1355
     1356    fsw_memzero(&param, sizeof(param));
     1357
     1358    catkey.parentID = cnid;
     1359    catkey.nodeName.length = 0;
     1360
     1361    param.vol = vol;
     1362    param.shandle = NULL;
     1363    param.file_info.id = cnid;
     1364    param.parent = cnid;
     1365    param.cur_pos = 0;
     1366
     1367    do {
     1368        rec_name.type = FSW_STRING_TYPE_EMPTY;
     1369        param.file_info.name = &rec_name;
     1370
     1371        status = fsw_hfs_btree_search(&vol->catalog_tree, (BTreeKey*)&catkey,
     1372                                      vol->case_sensitive ? fsw_hfs_cmp_catkey : fsw_hfs_cmpi_catkey,
     1373                                      &node, &ptr);
     1374        if (status)
     1375            goto done;
     1376
     1377        status = fsw_hfs_btree_iterate_node(&vol->catalog_tree, node, ptr,
     1378                                            fsw_hfs_btree_find_id, &param);
     1379        if (status)
     1380            goto done;
     1381
     1382        param.parent = param.file_info.id;
     1383        param.cur_pos = 0;
     1384
     1385        catkey.parentID = param.file_info.id;
     1386        catkey.nodeName.length = 0;
     1387    } while (catkey.parentID >= kHFSFirstUserCatalogNodeID);
     1388
     1389    /* If everything worked out , the final parent ID will be the root folder ID. */
     1390    if (catkey.parentID == kHFSRootFolderID)
     1391    {
     1392        *path = *param.file_info.name;
     1393        status = FSW_SUCCESS;
     1394    }
     1395    else
     1396        status = FSW_NOT_FOUND;
     1397
     1398done:
     1399    return status;
     1400}
     1401
     1402/**
     1403 * Get the path of the HFS+ blessed file, if any.
     1404 *
     1405 */
     1406/*static*/ fsw_status_t fsw_hfs_get_blessed_file(struct fsw_hfs_volume *vol, struct fsw_string *path)
     1407{
     1408    fsw_status_t                status = FSW_UNSUPPORTED;
     1409    fsw_u32                     bfile_id;
     1410    fsw_u32                     *finderinfo;
     1411
     1412    finderinfo = (fsw_u32 *)&vol->primary_voldesc->finderInfo;
     1413    bfile_id = finderinfo[1];
     1414    bfile_id = be32_to_cpu(bfile_id);
     1415
     1416    DPRINT2("Blessed file ID: %u\n", bfile_id);
     1417
     1418    status = fsw_hfs_get_path_from_cnid(vol, bfile_id, path);
     1419#ifdef HOST_POSIX
     1420    if (!status)
     1421    {
     1422        fsw_u16     *name_ptr;
     1423        int         i;
     1424
     1425        printf("Blessed file: ");
     1426        name_ptr = (fsw_u16*)path->data;
     1427        for (i = 0; i < path->len; i++)
     1428            printf("%c", name_ptr[i]);
     1429        printf("\n");
     1430    }
     1431#endif
     1432
     1433    return status;
     1434}
     1435
    12751436// EOF
  • trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe/test/lslr.c

    r69612 r82400  
    101101}
    102102
     103extern fsw_status_t fsw_hfs_get_blessed_file(struct fsw_hfs_volume *vol, struct fsw_string *link_target);
     104
    103105int main(int argc, char **argv)
    104106{
    105107    struct fsw_posix_volume *vol;
     108    struct fsw_string  blessed;
    106109    int i;
    107110
     
    128131    catfile(vol, "/System/Library/CoreServices/SystemVersion.plist");
    129132    //listdir(vol, "/", 0);
     133    fsw_hfs_get_blessed_file((struct fsw_hfs_volume *)vol->vol, &blessed);
    130134
    131135    fsw_posix_unmount(vol);
  • trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe/test/lsroot.c

    r69612 r82400  
    6969    }
    7070    while ((dent = fsw_posix_readdir(dir)) != NULL) {
    71         printf("%c %s\n", dent->d_type, dent->d_name);
     71        printf("%c %s %u\n", dent->d_type, dent->d_name, dent->d_fileno);
    7272    }
    7373    fsw_posix_closedir(dir);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette