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; }
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; }
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; }
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; }
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; }