fsw_status_t fsw_dnode_readlink_data(struct fsw_dnode *dno, struct fsw_string *link_target)
{
    fsw_status_t    status;
    struct fsw_shandle shand;
    fsw_u32         buffer_size;
    char            buffer[FSW_PATH_MAX];

    struct fsw_string s;

    if (dno->size > FSW_PATH_MAX)
        return FSW_VOLUME_CORRUPTED;

    s.type = FSW_STRING_TYPE_ISO88591;
    s.size = s.len = (int)dno->size;
    s.data = buffer;

    // open shandle and read the data
    status = fsw_shandle_open(dno, &shand);
    if (status)
        return status;
    buffer_size = (fsw_u32)s.size;
    status = fsw_shandle_read(&shand, &buffer_size, buffer);
    fsw_shandle_close(&shand);
    if (status)
        return status;
    if ((int)buffer_size < s.size)
        return FSW_VOLUME_CORRUPTED;

    status = fsw_strdup_coerce(link_target, dno->vol->host_string_type, &s);
    return status;
}
Esempio n. 2
0
EFI_STATUS fsw_efi_dnode_to_FileHandle(IN struct fsw_dnode *dno,
                                       OUT EFI_FILE **NewFileHandle)
{
    EFI_STATUS          Status;
    FSW_FILE_DATA       *File;

    FSW_MSG_DEBUG((FSW_MSGSTR(__FUNCTION__ ": enter\n")));
    // make sure the dnode has complete info
    Status = fsw_efi_map_status(fsw_dnode_fill(dno), (FSW_VOLUME_DATA *)dno->vol->host_data);
    if (EFI_ERROR(Status)) {
        goto Done;
    }

    // check type
    if (dno->type != FSW_DNODE_TYPE_FILE && dno->type != FSW_DNODE_TYPE_DIR) {
        Status = EFI_UNSUPPORTED;
	goto Done;
    }

    // allocate file structure
    File = AllocateZeroPool(sizeof(FSW_FILE_DATA));
    File->Signature = FSW_FILE_DATA_SIGNATURE;
    if (dno->type == FSW_DNODE_TYPE_FILE)
        File->Type = FSW_EFI_FILE_TYPE_FILE;
    else if (dno->type == FSW_DNODE_TYPE_DIR)
        File->Type = FSW_EFI_FILE_TYPE_DIR;

    // open shandle
    Status = fsw_efi_map_status(fsw_shandle_open(dno, &File->shand),
                                (FSW_VOLUME_DATA *)dno->vol->host_data);
    if (EFI_ERROR(Status)) {
        FreePool(File);
        goto Done;
    }

    // populate the file handle
    File->FileHandle.Revision    = EFI_FILE_HANDLE_REVISION;
    File->FileHandle.Open        = fsw_efi_FileHandle_Open;
    File->FileHandle.Close       = fsw_efi_FileHandle_Close;
    File->FileHandle.Delete      = fsw_efi_FileHandle_Delete;
    File->FileHandle.Read        = fsw_efi_FileHandle_Read;
    File->FileHandle.Write       = fsw_efi_FileHandle_Write;
    File->FileHandle.GetPosition = fsw_efi_FileHandle_GetPosition;
    File->FileHandle.SetPosition = fsw_efi_FileHandle_SetPosition;
    File->FileHandle.GetInfo     = fsw_efi_FileHandle_GetInfo;
    File->FileHandle.SetInfo     = fsw_efi_FileHandle_SetInfo;
    File->FileHandle.Flush       = fsw_efi_FileHandle_Flush;

    *NewFileHandle = &File->FileHandle;
    Status = EFI_SUCCESS;

Done:
    FSW_MSG_DEBUG((FSW_MSGSTR(__FUNCTION__ ": leaving with %r\n"), Status));
    return Status;
}
Esempio n. 3
0
fsw_status_t fsw_posix_open_dno(struct fsw_posix_volume *pvol, const char *path, int required_type, struct fsw_shandle *shand)
{
    fsw_status_t        status;
    struct fsw_dnode    *dno;
    struct fsw_dnode    *target_dno;
    struct fsw_string   lookup_path;
    
    lookup_path.type = FSW_STRING_TYPE_ISO88591;
    lookup_path.len  = strlen(path);
    lookup_path.size = lookup_path.len;
    lookup_path.data = (void *)path;
    
    // resolve the path (symlinks along the way are automatically resolved)
    status = fsw_dnode_lookup_path(pvol->vol->root, &lookup_path, '/', &dno);
    if (status) {
        fprintf(stderr, "fsw_posix_open_dno: fsw_dnode_lookup_path returned %d\n", status);
        return status;
    }
    
    // if the final node is a symlink, also resolve it
    status = fsw_dnode_resolve(dno, &target_dno);
    fsw_dnode_release(dno);
    if (status) {
        fprintf(stderr, "fsw_posix_open_dno: fsw_dnode_resolve returned %d\n", status);
        return status;
    }
    dno = target_dno;
    
    // check that it is a regular file
    status = fsw_dnode_fill(dno);
    if (status) {
        fprintf(stderr, "fsw_posix_open_dno: fsw_dnode_fill returned %d\n", status);
        fsw_dnode_release(dno);
        return status;
    }
    if (dno->type != required_type) {
        fprintf(stderr, "fsw_posix_open_dno: dnode is not of the requested type\n");
        fsw_dnode_release(dno);
        return FSW_UNSUPPORTED;
    }
    
    // open shandle
    status = fsw_shandle_open(dno, shand);
    if (status) {
        fprintf(stderr, "fsw_posix_open_dno: fsw_shandle_open returned %d\n", status);
    }
    fsw_dnode_release(dno);
    return status;
}
Esempio n. 4
0
static fsw_status_t fsw_ext2_dir_lookup(struct fsw_ext2_volume *vol, struct fsw_ext2_dnode *dno,
                                        struct fsw_string *lookup_name, struct fsw_ext2_dnode **child_dno_out)
{
    fsw_status_t    status;
    struct fsw_shandle shand;
    fsw_u32         child_ino;
    struct ext2_dir_entry entry;
    struct fsw_string entry_name;

    // Preconditions: The caller has checked that dno is a directory node.

    entry_name.type = FSW_STRING_TYPE_ISO88591;

    // setup handle to read the directory
    status = fsw_shandle_open(dno, &shand);
    if (status)
        return status;

    // scan the directory for the file
    child_ino = 0;
    while (child_ino == 0) {
        // read next entry
        status = fsw_ext2_read_dentry(&shand, &entry);
        if (status)
            goto errorexit;
        if (entry.inode == 0) {
            // end of directory reached
            status = FSW_NOT_FOUND;
            goto errorexit;
        }

        // compare name
        entry_name.len = entry_name.size = entry.name_len;
        entry_name.data = entry.name;
        if (fsw_streq(lookup_name, &entry_name)) {
            child_ino = entry.inode;
            break;
        }
    }

    // setup a dnode for the child item
    status = fsw_dnode_create(dno, child_ino, FSW_DNODE_TYPE_UNKNOWN, &entry_name, child_dno_out);

errorexit:
    fsw_shandle_close(&shand);
    return status;
}
Esempio n. 5
0
static fsw_status_t fsw_iso9660_dir_lookup(struct fsw_iso9660_volume *vol, struct fsw_iso9660_dnode *dno,
                                           struct fsw_string *lookup_name, struct fsw_iso9660_dnode **child_dno_out)
{
    fsw_status_t    status;
    struct fsw_shandle shand;
    struct iso9660_dirrec_buffer dirrec_buffer;
    struct iso9660_dirrec *dirrec = &dirrec_buffer.dirrec;

    // Preconditions: The caller has checked that dno is a directory node.

    // setup handle to read the directory
    status = fsw_shandle_open(dno, &shand);
    if (status)
        return status;

    // scan the directory for the file
    while (1) {
        // read next entry
        status = fsw_iso9660_read_dirrec(vol, &shand, &dirrec_buffer);
        if (status)
            goto errorexit;
        if (dirrec->dirrec_length == 0) {
            // end of directory reached
            status = FSW_NOT_FOUND;
            goto errorexit;
        }

        // skip . and ..
        if (dirrec->file_identifier_length == 1 &&
            (dirrec->file_identifier[0] == 0 || dirrec->file_identifier[0] == 1))
            continue;

        // compare name
        if (fsw_streq(lookup_name, &dirrec_buffer.name))  // TODO: compare case-insensitively
            break;
    }

    // setup a dnode for the child item
    status = fsw_dnode_create(dno, dirrec_buffer.ino, FSW_DNODE_TYPE_UNKNOWN, &dirrec_buffer.name, child_dno_out);
    if (status == FSW_SUCCESS)
        fsw_memcpy(&(*child_dno_out)->dirrec, dirrec, sizeof(struct iso9660_dirrec));

errorexit:
    fsw_shandle_close(&shand);
    return status;
}