goto out;
}
- ret = extract_full_wim_resource_to_fd(lte, out_fd);
+ ret = extract_wim_resource_to_fd(lte, out_fd, wim_resource_size(lte));
if (ret != 0) {
ERROR("Failed to extract resource to `%s'", output_path);
goto out;
#include <stdlib.h>
#include <unistd.h>
+static int extract_wim_chunk_to_ntfs_attr(const u8 *buf, size_t len,
+ u64 offset, void *arg)
+{
+ ntfs_attr *na = arg;
+ if (ntfs_attr_pwrite(na, offset, len, buf) == len) {
+ return 0;
+ } else {
+ ERROR_WITH_ERRNO("Error extracting WIM resource to NTFS attribute");
+ return WIMLIB_ERR_WRITE;
+ }
+}
+
/*
* Extracts a WIM resource to a NTFS attribute.
*/
extract_wim_resource_to_ntfs_attr(const struct lookup_table_entry *lte,
ntfs_attr *na)
{
- u64 bytes_remaining = wim_resource_size(lte);
- u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
- u64 offset = 0;
- int ret = 0;
- u8 hash[SHA1_HASH_SIZE];
-
- SHA_CTX ctx;
- sha1_init(&ctx);
-
- while (bytes_remaining) {
- u64 to_read = min(bytes_remaining, WIM_CHUNK_SIZE);
- ret = read_wim_resource(lte, buf, to_read, offset, 0);
- if (ret != 0)
- break;
- sha1_update(&ctx, buf, to_read);
- if (ntfs_attr_pwrite(na, offset, to_read, buf) != to_read) {
- ERROR_WITH_ERRNO("Error extracting WIM resource");
- return WIMLIB_ERR_WRITE;
- }
- bytes_remaining -= to_read;
- offset += to_read;
- }
- sha1_final(hash, &ctx);
- if (!hashes_equal(hash, lte->hash)) {
- ERROR("Invalid checksum on a WIM resource "
- "(detected when extracting to NTFS stream)");
- ERROR("The following WIM resource is invalid:");
- print_lookup_table_entry(lte);
- return WIMLIB_ERR_INVALID_RESOURCE_HASH;
- }
- return 0;
+ return extract_wim_resource(lte, wim_resource_size(lte),
+ extract_wim_chunk_to_ntfs_attr, na);
}
/* Writes the data streams to a NTFS file
* wimlib; if not, see http://www.gnu.org/licenses/.
*/
-#include "config.h"
-
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "dentry.h"
-
#include "wimlib_internal.h"
+#include "dentry.h"
#include "lookup_table.h"
#include "buffer_io.h"
#include "lzx.h"
#include "xpress.h"
#include "sha1.h"
-#include <unistd.h>
+
#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
#ifdef WITH_NTFS_3G
#include <time.h>
#include <ntfs-3g/dir.h>
#endif
-
/*
* Reads all or part of a compressed resource into an in-memory buffer.
*
return 0;
}
-
-
-
/* Reads the contents of a struct resource_entry, as represented in the on-disk
* format, from the memory pointed to by @p, and fills in the fields of @entry.
* A pointer to the byte after the memory read at @p is returned. */
return read_wim_resource(lte, buf, wim_resource_size(lte), 0, flags);
}
-/*
- * Extracts the first @size bytes of the WIM resource specified by @lte to the
- * open file descriptor @fd.
- *
- * Returns 0 on success; nonzero on failure.
- */
-int extract_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd,
- u64 size)
+int extract_wim_resource(const struct lookup_table_entry *lte,
+ u64 size,
+ extract_chunk_func_t extract_chunk,
+ void *extract_chunk_arg)
{
u64 bytes_remaining = size;
u8 buf[min(WIM_CHUNK_SIZE, bytes_remaining)];
sha1_init(&ctx);
while (bytes_remaining) {
- u64 to_read = min(bytes_remaining, WIM_CHUNK_SIZE);
+ u64 to_read = min(bytes_remaining, sizeof(buf));
ret = read_wim_resource(lte, buf, to_read, offset, 0);
if (ret != 0)
break;
sha1_update(&ctx, buf, to_read);
- if (full_write(fd, buf, to_read) < to_read) {
+ ret = extract_chunk(buf, to_read, offset, extract_chunk_arg);
+ if (ret != 0) {
ERROR_WITH_ERRNO("Error extracting WIM resource");
- return WIMLIB_ERR_WRITE;
+ return ret;
}
bytes_remaining -= to_read;
offset += to_read;
}
sha1_final(hash, &ctx);
if (!hashes_equal(hash, lte->hash)) {
- ERROR("Invalid checksum on a WIM resource "
- "(detected when extracting to external file)");
- ERROR("The following WIM resource is invalid:");
+ #ifdef ENABLE_ERROR_MESSAGES
+ ERROR("Invalid checksum on the following WIM resource:");
print_lookup_table_entry(lte);
+ #endif
return WIMLIB_ERR_INVALID_RESOURCE_HASH;
}
return 0;
}
-/*
- * Extracts the WIM resource specified by @lte to the open file descriptor @fd.
+/* Write @n bytes from @buf to the file descriptor @fd, retrying on interupt and
+ * on short writes.
*
- * Returns 0 on success; nonzero on failure.
- */
-int extract_full_wim_resource_to_fd(const struct lookup_table_entry *lte, int fd)
+ * Returns short count and set errno on failure. */
+static ssize_t full_write(int fd, const void *buf, size_t n)
+{
+ const char *p = buf;
+ ssize_t ret;
+ ssize_t total = 0;
+
+ while (total != n) {
+ ret = write(fd, p, n);
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ else
+ break;
+ }
+ total += ret;
+ p += ret;
+ }
+ return total;
+}
+
+int extract_wim_chunk_to_fd(const u8 *buf, size_t len,
+ u64 offset, void *arg)
{
- return extract_wim_resource_to_fd(lte, fd, wim_resource_size(lte));
+ int fd = *(int*)arg;
+ ssize_t ret = full_write(fd, buf, len);
+ if (ret < len) {
+ ERROR_WITH_ERRNO("Error writing to file descriptor");
+ return WIMLIB_ERR_WRITE;
+ } else {
+ return 0;
+ }
}
/*
return orig_utf16_str;
}
-/* Write @n bytes from @buf to the file descriptor @fd, retrying on interupt and
- * on short writes.
- *
- * Returns short count and set errno on failure. */
-ssize_t full_write(int fd, const void *buf, size_t n)
-{
- const char *p = buf;
- ssize_t ret;
- ssize_t total = 0;
-
- while (total != n) {
- ret = write(fd, p, n);
- if (ret < 0) {
- if (errno == EINTR)
- continue;
- else
- break;
- }
- total += ret;
- p += ret;
- }
- return total;
-}
-
-
static bool seeded = false;
static void seed_random()
extern int get_num_path_components(const char *path);
-extern ssize_t full_write(int fd, const void *buf, size_t n);
-
static inline void print_byte_field(const u8 field[], size_t len)
{
while (len--)
unsigned num_additional_swms,
struct lookup_table **table_ret);
+/* metadata_resource.c */
+
+extern int read_metadata_resource(WIMStruct *w,
+ struct image_metadata *image_metadata);
+extern int write_metadata_resource(WIMStruct *w);
+
/* ntfs-apply.c */
struct apply_args {
struct resource_entry *out_res_entry,
int flags);
-extern int extract_wim_resource_to_fd(const struct lookup_table_entry *lte,
- int fd, u64 size);
+typedef int (*extract_chunk_func_t)(const u8 *, size_t, u64, void *);
-extern int extract_full_wim_resource_to_fd(const struct lookup_table_entry *lte,
- int fd);
+extern int extract_wim_chunk_to_fd(const u8 *buf, size_t len,
+ u64 offset, void *arg);
-extern int read_metadata_resource(WIMStruct *w,
- struct image_metadata *image_metadata);
+extern int extract_wim_resource(const struct lookup_table_entry *lte,
+ u64 size, extract_chunk_func_t extract_chunk,
+ void *extract_chunk_arg);
+/*
+ * Extracts the first @size bytes of the WIM resource specified by @lte to the
+ * open file descriptor @fd.
+ *
+ * Returns 0 on success; nonzero on failure.
+ */
+static inline int
+extract_wim_resource_to_fd(const struct lookup_table_entry *lte,
+ int fd, u64 size)
+{
+ return extract_wim_resource(lte, size,
+ extract_wim_chunk_to_fd, &fd);
+}
extern int write_dentry_resources(struct dentry *dentry, void *wim_p);
extern int copy_resource(struct lookup_table_entry *lte, void *w);
-extern int write_metadata_resource(WIMStruct *w);
/* security.c */