OvmfPkg/FswHfsPlus/fsw_hfsplus.c
/* Lookup a directory's child dnode by name. This function is called on a
 * directory to retrieve the directory entry with the given name. A dnode
 * is constructed for this entry and returned. The core makes sure that
 * fsw_hfsplus_dno_fill has been called and the dnode is actually a directory.
 */
Lookup a directory's child dnode by name. This function is called on a
directory to retrieve the directory entry with the given name. A dnode
is constructed for this entry and returned. The core makes sure that
fsw_hfsplus_dno_fill has been called and the dnode is actually a directory.
Lookup a directory ' s child dnode by name . This function is called on a directory to retrieve the directory entry with the given name . A dnode is constructed for this entry and returned . The core makes sure that fsw_hfsplus_dno_fill has been called and the dnode is actually a directory .
static fsw_status_t
fsw_hfsplus_dir_get(struct fsw_hfsplus_volume *v, struct fsw_hfsplus_dnode *d,
                    struct fsw_string *name, struct fsw_hfsplus_dnode **d_out)
{
    BTNodeDescriptor     *btnode;
    fsw_u32              child_dno_id, child_dno_type;
    HFSPlusCatalogKey    sk, *tk;
    HFSPlusCatalogRecord *rec;
    fsw_status_t         status;
int i;
DEBUG ((EFI_D_INFO, "GLS: dir_get: parent=%d name: ", d->g.dnode_id));
for (i = 0; i < name->len; i++)
  DEBUG((EFI_D_INFO, "%c", ((fsw_u16 *)name->data)[i]));
DEBUG((EFI_D_INFO, "\n"));
    if (name->type != FSW_STRING_TYPE_UTF16 ||
        name->size > sizeof(sk.nodeName.unicode))
        return FSW_UNSUPPORTED;
    status = fsw_alloc(v->catf->bt_ndsz, &btnode);
    if (status)
        return status;
    sk.parentID = d->g.dnode_id;
    sk.nodeName.length = name->len;
    fsw_memcpy(sk.nodeName.unicode, name->data, name->size);
    sk.keyLength = sizeof(sk.parentID) +
                   sizeof(sk.nodeName.length) + name->size;
    status = fsw_hfsplus_bt_search(v->catf,
                                   (HFSPlusBTKey *)&sk, fsw_hfsplus_cat_cmp,
                                   0,
                                   btnode, (HFSPlusBTKey **)&tk);
    if (status)
        goto done;
    rec = fsw_hfsplus_bt_rec_skip_key((HFSPlusBTKey *)tk);
    switch (fsw_u16_be_swap(rec->recordType)) {
    case kHFSPlusFolderRecord:
        child_dno_id = fsw_u32_be_swap(rec->folderRecord.folderID);
        child_dno_type = FSW_DNODE_TYPE_DIR;
        break;
    case kHFSPlusFileRecord:
        child_dno_id = fsw_u32_be_swap(rec->fileRecord.fileID);
        child_dno_type = FSW_DNODE_TYPE_FILE;
        break;
    default:
        child_dno_id = 0;
        child_dno_type = FSW_DNODE_TYPE_UNKNOWN;
        break;
    }
    status = fsw_dnode_create(d, child_dno_id, child_dno_type, name, d_out);
    if (status)
        goto done;
    switch (child_dno_type) {
    case FSW_DNODE_TYPE_DIR:
        (*d_out)->ct = fsw_u32_be_swap(rec->folderRecord.createDate);
        (*d_out)->mt = fsw_u32_be_swap(rec->folderRecord.contentModDate);
        (*d_out)->at = fsw_u32_be_swap(rec->folderRecord.accessDate);
        break;
    case FSW_DNODE_TYPE_FILE:
        (*d_out)->g.size =
            fsw_u64_be_swap(rec->fileRecord.dataFork.logicalSize);
        fsw_memcpy((*d_out)->extents, &rec->fileRecord.dataFork.extents,
                   sizeof(HFSPlusExtentRecord));
        (*d_out)->ct = fsw_u32_be_swap(rec->fileRecord.createDate);
        (*d_out)->mt = fsw_u32_be_swap(rec->fileRecord.contentModDate);
        (*d_out)->at = fsw_u32_be_swap(rec->fileRecord.accessDate);
        break;
    default:
        (*d_out)->ct = 0;
        (*d_out)->mt = 0;
        (*d_out)->at = 0;
        break;
    }
done:
    fsw_free(btnode);
    return status;
}
static fsw_status_t fsw_hfsplus_dir_get ( struct fsw_hfsplus_volume * v , struct fsw_hfsplus_dnode * d , struct fsw_string * name , struct fsw_hfsplus_dnode * * d_out ) { BTNodeDescriptor * btnode ; fsw_u32 child_dno_id , child_dno_type ; HFSPlusCatalogKey sk , * tk ; HFSPlusCatalogRecord * rec ; fsw_status_t status ; int i ; DEBUG ( ( EFI_D_INFO , " " , d -> g . dnode_id ) ) ; for ( i = 0 ; i < name -> len ; i ++ ) DEBUG ( ( EFI_D_INFO , " " , ( ( fsw_u16 * ) name -> data ) [ i ] ) ) ; DEBUG ( ( EFI_D_INFO , " \n " ) ) ; if ( name -> type != FSW_STRING_TYPE_UTF16 || name -> size > sizeof ( sk . nodeName . unicode ) ) return FSW_UNSUPPORTED ; status = fsw_alloc ( v -> catf -> bt_ndsz , & btnode ) ; if ( status ) return status ; sk . parentID = d -> g . dnode_id ; sk . nodeName . length = name -> len ; fsw_memcpy ( sk . nodeName . unicode , name -> data , name -> size ) ; sk . keyLength = sizeof ( sk . parentID ) + sizeof ( sk . nodeName . length ) + name -> size ; status = fsw_hfsplus_bt_search ( v -> catf , ( HFSPlusBTKey * ) & sk , fsw_hfsplus_cat_cmp , 0 , btnode , ( HFSPlusBTKey * * ) & tk ) ; if ( status ) goto done ; rec = fsw_hfsplus_bt_rec_skip_key ( ( HFSPlusBTKey * ) tk ) ; switch ( fsw_u16_be_swap ( rec -> recordType ) ) { case kHFSPlusFolderRecord : child_dno_id = fsw_u32_be_swap ( rec -> folderRecord . folderID ) ; child_dno_type = FSW_DNODE_TYPE_DIR ; break ; case kHFSPlusFileRecord : child_dno_id = fsw_u32_be_swap ( rec -> fileRecord . fileID ) ; child_dno_type = FSW_DNODE_TYPE_FILE ; break ; default : child_dno_id = 0 ; child_dno_type = FSW_DNODE_TYPE_UNKNOWN ; break ; } status = fsw_dnode_create ( d , child_dno_id , child_dno_type , name , d_out ) ; if ( status ) goto done ; switch ( child_dno_type ) { case FSW_DNODE_TYPE_DIR : ( * d_out ) -> ct = fsw_u32_be_swap ( rec -> folderRecord . createDate ) ; ( * d_out ) -> mt = fsw_u32_be_swap ( rec -> folderRecord . contentModDate ) ; ( * d_out ) -> at = fsw_u32_be_swap ( rec -> folderRecord . accessDate ) ; break ; case FSW_DNODE_TYPE_FILE : ( * d_out ) -> g . size = fsw_u64_be_swap ( rec -> fileRecord . dataFork . logicalSize ) ; fsw_memcpy ( ( * d_out ) -> extents , & rec -> fileRecord . dataFork . extents , sizeof ( HFSPlusExtentRecord ) ) ; ( * d_out ) -> ct = fsw_u32_be_swap ( rec -> fileRecord . createDate ) ; ( * d_out ) -> mt = fsw_u32_be_swap ( rec -> fileRecord . contentModDate ) ; ( * d_out ) -> at = fsw_u32_be_swap ( rec -> fileRecord . accessDate ) ; break ; default : ( * d_out ) -> ct = 0 ; ( * d_out ) -> mt = 0 ; ( * d_out ) -> at = 0 ; break ; } done : fsw_free ( btnode ) ; return status ; }
Lookup a directory's child dnode by name.
Lookup a directory ' s child dnode by name .
// we only support FSW_STRING_TYPE_UTF16 names: // pre-allocate bt-node buffer for use by search function: // search catalog file for child named by 'name': // NOTE: keyLength not used in search, setting only for completeness: // figure out type of child dnode: // allocate child dnode: // grab additional child dnode status data: