VirtualBox

Ignore:
Timestamp:
Dec 16, 2015 8:53:19 AM (9 years ago)
Author:
vboxsync
Message:

EFI: Updated HFS+ driver to support hard links.

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_efi.c

    r58835 r59146  
    10481048    EFI_FILE_INFO       *FileInfo;
    10491049    UINTN               RequiredSize;
     1050    struct fsw_dnode    *target_dno;
    10501051    struct fsw_dnode_stat sb;
    10511052
     
    10721073    ZeroMem(Buffer, RequiredSize);
    10731074    FileInfo = (EFI_FILE_INFO *)Buffer;
     1075
     1076    // must preserve the original file name
     1077    fsw_efi_strcpy(FileInfo->FileName, &dno->name);
     1078
     1079    // if the node is a symlink, also resolve it
     1080    Status = fsw_efi_map_status(fsw_dnode_resolve(dno, &target_dno), Volume);
     1081    fsw_dnode_release(dno);
     1082    if (EFI_ERROR(Status))
     1083        return Status;
     1084    dno = target_dno;
     1085    // make sure the dnode has complete info again
     1086    Status = fsw_efi_map_status(fsw_dnode_fill(dno), Volume);
     1087    if (EFI_ERROR(Status))
     1088        return Status;
     1089
    10741090    FileInfo->Size = RequiredSize;
    10751091    FileInfo->FileSize          = dno->size;
     
    10771093    if (dno->type == FSW_DNODE_TYPE_DIR)
    10781094        FileInfo->Attribute    |= EFI_FILE_DIRECTORY;
    1079     fsw_efi_strcpy(FileInfo->FileName, &dno->name);
    10801095
    10811096    // get the missing info from the fs driver
  • trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe/fsw_hfs.c

    r58835 r59146  
    4545#define BP(msg) DPRINT(msg)
    4646#else
     47#include <Library/PrintLib.h>
    4748#define DPRINT(x) do { } while (0)
    4849#define DPRINT2(x,y) do { } while (0)
     
    620621    return status;
    621622}
     623
    622624typedef struct
    623625{
     
    629631    fsw_u32                 ctime;
    630632    fsw_u32                 mtime;
     633    fsw_u32                 node_num;
    631634    HFSPlusExtentRecord     extents;
    632635} file_info_t;
     
    641644    file_info_t             file_info;
    642645} visitor_parameter_t;
     646
     647static void hfs_fill_info(struct fsw_hfs_volume *vol, HFSPlusCatalogKey *file_key, file_info_t *file_info)
     648{
     649    fsw_u8    * base;
     650    fsw_u16     rec_type;
     651
     652    /* for plain HFS "-(keySize & 1)" would be needed */
     653    base = (fsw_u8*)file_key + be16_to_cpu(file_key->keyLength) + 2;
     654    rec_type =  be16_to_cpu(*(fsw_u16*)base);
     655
     656    /** @todo: read additional info */
     657    switch (rec_type)
     658    {
     659        case kHFSPlusFolderRecord:
     660        {
     661            HFSPlusCatalogFolder* info = (HFSPlusCatalogFolder*)base;
     662
     663            file_info->id = be32_to_cpu(info->folderID);
     664            file_info->type = FSW_DNODE_TYPE_DIR;
     665            /* @todo: return number of elements, maybe use smth else */
     666            file_info->size = be32_to_cpu(info->valence);
     667            file_info->used = be32_to_cpu(info->valence);
     668            file_info->ctime = be32_to_cpu(info->createDate);
     669            file_info->mtime = be32_to_cpu(info->contentModDate);
     670            break;
     671        }
     672        case kHFSPlusFileRecord:
     673        {
     674            HFSPlusCatalogFile* info = (HFSPlusCatalogFile*)base;
     675            uint32_t    creator = be32_to_cpu(info->userInfo.fdCreator);
     676            uint32_t    crtype  = be32_to_cpu(info->userInfo.fdType);
     677
     678            file_info->id = be32_to_cpu(info->fileID);
     679            file_info->type = FSW_DNODE_TYPE_FILE;
     680            file_info->size = be64_to_cpu(info->dataFork.logicalSize);
     681            file_info->used = LShiftU64(be32_to_cpu(info->dataFork.totalBlocks), vol->block_size_shift);
     682            file_info->ctime = be32_to_cpu(info->createDate);
     683            file_info->mtime = be32_to_cpu(info->contentModDate);
     684            fsw_memcpy(&file_info->extents, &info->dataFork.extents,
     685                       sizeof file_info->extents);
     686            if (creator == kHFSPlusCreator && crtype == kHardLinkFileType)
     687            {
     688                /* Only hard links currently supported. */
     689                file_info->type     = FSW_DNODE_TYPE_SYMLINK;
     690                file_info->node_num = be32_to_cpu(info->bsdInfo.special.iNodeNum);
     691            }
     692            break;
     693        }
     694        case kHFSPlusFolderThreadRecord:
     695        case kHFSPlusFileThreadRecord:
     696        {
     697            /* Do nothing. */
     698            break;
     699        }
     700        default:
     701            BP("unknown file type\n");
     702            file_info->type = FSW_DNODE_TYPE_UNKNOWN;
     703
     704            break;
     705    }
     706}
    643707
    644708static int
     
    661725        return 0;
    662726
    663     switch (rec_type)
    664     {
    665         case kHFSPlusFolderRecord:
    666         {
    667             HFSPlusCatalogFolder* folder_info = (HFSPlusCatalogFolder*)base;
    668 
    669             vp->file_info.id = be32_to_cpu(folder_info->folderID);
    670             vp->file_info.type = FSW_DNODE_TYPE_DIR;
    671             vp->file_info.size = be32_to_cpu(folder_info->valence);
    672             vp->file_info.used = be32_to_cpu(folder_info->valence);
    673             vp->file_info.ctime = be32_to_cpu(folder_info->createDate);
    674             vp->file_info.mtime = be32_to_cpu(folder_info->contentModDate);
    675             break;
    676         }
    677         case kHFSPlusFileRecord:
    678         {
    679             HFSPlusCatalogFile* file_info = (HFSPlusCatalogFile*)base;
    680 
    681             vp->file_info.id = be32_to_cpu(file_info->fileID);
    682             vp->file_info.type = FSW_DNODE_TYPE_FILE;
    683             vp->file_info.size = be64_to_cpu(file_info->dataFork.logicalSize);
    684             vp->file_info.used = LShiftU64(be32_to_cpu(file_info->dataFork.totalBlocks),
    685                                            vp->vol->block_size_shift);
    686             vp->file_info.ctime = be32_to_cpu(file_info->createDate);
    687             vp->file_info.mtime = be32_to_cpu(file_info->contentModDate);
    688             fsw_memcpy(&vp->file_info.extents, &file_info->dataFork.extents,
    689                        sizeof vp->file_info.extents);
    690             break;
    691         }
    692         case kHFSPlusFolderThreadRecord:
    693         case kHFSPlusFileThreadRecord:
    694         {
    695             vp->shandle->pos++;
    696             return 0;
    697         }
    698         default:
    699             BP("unknown file type\n");
    700             vp->file_info.type = FSW_DNODE_TYPE_UNKNOWN;
    701             break;
    702     }
     727    if (rec_type == kHFSPlusFolderThreadRecord || rec_type == kHFSPlusFileThreadRecord)
     728    {
     729        vp->shandle->pos++;
     730        return 0;
     731    }
     732
     733    hfs_fill_info(vp->vol, cat_key, &vp->file_info);
    703734
    704735    name_len = be16_to_cpu(cat_key->nodeName.length);
     
    10261057    baby->ctime = file_info->ctime;
    10271058    baby->mtime = file_info->mtime;
     1059    baby->node_num = file_info->node_num;
    10281060
    10291061
     
    10551087    struct HFSPlusCatalogKey   catkey;
    10561088    fsw_u32                    ptr;
    1057     fsw_u16                    rec_type;
    10581089    BTNodeDescriptor *         node = NULL;
    10591090    struct fsw_string          rec_name;
     
    10611092    HFSPlusCatalogKey*         file_key;
    10621093    file_info_t                file_info;
    1063     fsw_u8*                    base;
    10641094
    10651095
     
    11081138#endif
    11091139
    1110     catkey.keyLength = (fsw_u16)(5 + rec_name.size);
     1140    catkey.keyLength = (fsw_u16)(6 + rec_name.len);
    11111141
    11121142    status = fsw_hfs_btree_search (&vol->catalog_tree,
     
    11191149
    11201150    file_key = (HFSPlusCatalogKey *)fsw_hfs_btree_rec (&vol->catalog_tree, node, ptr);
    1121     /* for plain HFS "-(keySize & 1)" would be needed */
    1122     base = (fsw_u8*)file_key + be16_to_cpu(file_key->keyLength) + 2;
    1123     rec_type =  be16_to_cpu(*(fsw_u16*)base);
    1124 
    1125     /** @todo: read additional info */
    1126     switch (rec_type)
    1127     {
    1128         case kHFSPlusFolderRecord:
    1129         {
    1130             HFSPlusCatalogFolder* info = (HFSPlusCatalogFolder*)base;
    1131 
    1132             file_info.id = be32_to_cpu(info->folderID);
    1133             file_info.type = FSW_DNODE_TYPE_DIR;
    1134             /* @todo: return number of elements, maybe use smth else */
    1135             file_info.size = be32_to_cpu(info->valence);
    1136             file_info.used = be32_to_cpu(info->valence);
    1137             file_info.ctime = be32_to_cpu(info->createDate);
    1138             file_info.mtime = be32_to_cpu(info->contentModDate);
    1139             break;
    1140         }
    1141         case kHFSPlusFileRecord:
    1142         {
    1143             HFSPlusCatalogFile* info = (HFSPlusCatalogFile*)base;
    1144 
    1145             file_info.id = be32_to_cpu(info->fileID);
    1146             file_info.type = FSW_DNODE_TYPE_FILE;
    1147             file_info.size = be64_to_cpu(info->dataFork.logicalSize);
    1148             file_info.used = LShiftU64(be32_to_cpu(info->dataFork.totalBlocks), vol->block_size_shift);
    1149             file_info.ctime = be32_to_cpu(info->createDate);
    1150             file_info.mtime = be32_to_cpu(info->contentModDate);
    1151             fsw_memcpy(&file_info.extents, &info->dataFork.extents,
    1152                        sizeof file_info.extents);
    1153             break;
    1154         }
    1155         default:
    1156             BP("unknown file type\n");
    1157             file_info.type = FSW_DNODE_TYPE_UNKNOWN;
    1158 
    1159             break;
    1160     }
     1151    hfs_fill_info(vol, file_key, &file_info);
     1152
    11611153#ifdef HFS_FILE_INJECTION
    11621154create:
     
    12381230}
    12391231
     1232static const char hfs_priv_prefix[] = "/\0\0\0\0HFS+ Private Data/" HFS_INODE_PREFIX;
     1233
    12401234/**
    12411235 * Get the target path of a symbolic link. This function is called when a symbolic
     
    12471241                                     struct fsw_string *link_target)
    12481242{
     1243    fsw_status_t    status;
     1244
     1245    if (dno->node_num)
     1246    {
     1247        struct fsw_string   tgt;
     1248
     1249        DPRINT2("hfs_readlink: %d\n", dno->node_num);
     1250        tgt.type = FSW_STRING_TYPE_ISO88591;
     1251        tgt.size = sizeof(hfs_priv_prefix) + 10;
     1252        tgt.len  = tgt.size - 1;
     1253        status = fsw_alloc(tgt.size, &tgt.data);
     1254        if (!status)
     1255        {
     1256            char *str = tgt.data;
     1257            fsw_memcpy(tgt.data, hfs_priv_prefix, sizeof(hfs_priv_prefix)); // null chars here!
     1258#ifdef HOST_POSIX
     1259            tgt.len = sprintf(&str[sizeof(hfs_priv_prefix) - 1], "%d", dno->node_num);
     1260#else
     1261            tgt.len = (int)AsciiSPrint(&str[sizeof(hfs_priv_prefix) - 1], tgt.len, "%d", dno->node_num);
     1262#endif
     1263            tgt.len += sizeof(hfs_priv_prefix) - 1;
     1264            status = fsw_strdup_coerce(link_target, vol->g.host_string_type, &tgt);
     1265            fsw_strfree(&tgt);
     1266        }
     1267        return status;
     1268    }
     1269
    12491270    return FSW_UNSUPPORTED;
    12501271}
  • trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxFsDxe/fsw_hfs.h

    r56292 r59146  
    8989  fsw_u32                   mtime;
    9090  fsw_u64                   used_bytes;
     91  fsw_u32                   node_num;
    9192};
    9293
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