- u8 *buf;
- u32 dentry_offset;
- int ret;
- struct dentry *dentry;
- struct inode_table inode_tab;
- const struct lookup_table_entry *metadata_lte;
- u64 metadata_len;
- struct hlist_head inode_list;
-
- metadata_lte = imd->metadata_lte;
- metadata_len = wim_resource_size(metadata_lte);
-
- DEBUG("Reading metadata resource: length = %"PRIu64", "
- "offset = %"PRIu64"", metadata_len,
- metadata_lte->resource_entry.offset);
-
- /* There is no way the metadata resource could possibly be less than (8
- * + WIM_DENTRY_DISK_SIZE) bytes, where the 8 is for security data (with
- * no security descriptors) and WIM_DENTRY_DISK_SIZE is for the root
- * dentry. */
- if (metadata_len < 8 + WIM_DENTRY_DISK_SIZE) {
- ERROR("Expected at least %u bytes for the metadata resource",
- 8 + WIM_DENTRY_DISK_SIZE);
- return WIMLIB_ERR_INVALID_RESOURCE_SIZE;
- }
-
- if (sizeof(size_t) < 8 && metadata_len > 0xffffffff) {
- ERROR("Metadata resource is too large (%"PRIu64" bytes",
- metadata_len);
- return WIMLIB_ERR_INVALID_RESOURCE_SIZE;
- }
-
- /* Allocate memory for the uncompressed metadata resource. */
- buf = MALLOC(metadata_len);
-
- if (!buf) {
- ERROR("Failed to allocate %"PRIu64" bytes for uncompressed "
- "metadata resource", metadata_len);
- return WIMLIB_ERR_NOMEM;
- }
-
- /* Read the metadata resource into memory. (It may be compressed.) */
- ret = read_full_wim_resource(metadata_lte, buf, 0);
- if (ret != 0)
- goto out_free_buf;
-
- DEBUG("Finished reading metadata resource into memory.");
-
- /* The root directory entry starts after security data, aligned on an
- * 8-byte boundary within the metadata resource.
- *
- * The security data starts with a 4-byte integer giving its total
- * length, so if we round that up to an 8-byte boundary that gives us
- * the offset of the root dentry.
- *
- * Here we read the security data into a wim_security_data structure,
- * and if successful, go ahead and calculate the offset in the metadata
- * resource of the root dentry. */
-
- wimlib_assert(imd->security_data == NULL);
- ret = read_security_data(buf, metadata_len, &imd->security_data);
- if (ret != 0)
- goto out_free_buf;
-
- dentry_offset = (imd->security_data->total_length + 7) & ~7;
-
- if (dentry_offset == 0) {
- ERROR("Integer overflow while reading metadata resource");
- ret = WIMLIB_ERR_INVALID_SECURITY_DATA;
- goto out_free_security_data;
- }
-
- DEBUG("Reading root dentry");
+ static const read_resource_prefix_handler_t handlers[] = {
+ [RESOURCE_IN_WIM] = read_wim_resource_prefix,
+ [RESOURCE_IN_FILE_ON_DISK] = read_file_on_disk_prefix,
+ [RESOURCE_IN_ATTACHED_BUFFER] = read_buffer_prefix,
+ #ifdef WITH_FUSE
+ [RESOURCE_IN_STAGING_FILE] = read_file_on_disk_prefix,
+ #endif
+ #ifdef WITH_NTFS_3G
+ [RESOURCE_IN_NTFS_VOLUME] = read_ntfs_file_prefix,
+ #endif
+ #ifdef __WIN32__
+ [RESOURCE_WIN32] = read_win32_file_prefix,
+ [RESOURCE_WIN32_ENCRYPTED] = read_win32_encrypted_file_prefix,
+ #endif
+ };
+ wimlib_assert(lte->resource_location < ARRAY_LEN(handlers)
+ && handlers[lte->resource_location] != NULL);
+ return handlers[lte->resource_location](lte, size, cb, ctx_or_buf, flags);
+}