X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fheader.c;h=ef0e5783b2e774a2373681eba3b54ad34bd86a8e;hb=e5c13f94058aedcea95236a9728093fa283d49b3;hp=bd2a0631ea31460eb57daef87af9c22c34d1ce0f;hpb=f8698b9c814a62a117982701b9551f699553b2a4;p=wimlib diff --git a/src/header.c b/src/header.c index bd2a0631..ef0e5783 100644 --- a/src/header.c +++ b/src/header.c @@ -31,62 +31,48 @@ static const u8 wim_magic_chars[WIM_MAGIC_LEN] = { 'M', 'S', 'W', 'I', 'M', '\0', '\0', '\0' }; -/* Reads the header for a WIM file. */ +/* Reads the header from a WIM file. */ int -read_header(FILE *fp, struct wim_header *hdr, int open_flags) +read_header(const tchar *filename, int in_fd, + struct wim_header *hdr, int open_flags) { size_t bytes_read; u8 buf[WIM_HEADER_DISK_SIZE]; - size_t hdr_rem_size; - const u8 *p; + const void *p; u32 hdr_size; u32 wim_version; u32 chunk_size; - DEBUG("Reading WIM header."); + DEBUG("Reading WIM header from \"%"TS"\".", filename); - bytes_read = fread(buf, 1, WIM_MAGIC_LEN, fp); + bytes_read = full_pread(in_fd, buf, WIM_HEADER_DISK_SIZE, 0); - if (bytes_read != WIM_MAGIC_LEN) - goto err; - - /* Byte 8 */ + if (bytes_read != WIM_HEADER_DISK_SIZE) { + ERROR_WITH_ERRNO("\"%"TS"\": Error reading header", filename); + return WIMLIB_ERR_READ; + } - if (memcmp(buf, wim_magic_chars, WIM_MAGIC_LEN) != 0) { - ERROR("Invalid magic characters in WIM header"); + p = buf; + if (memcmp(p, wim_magic_chars, WIM_MAGIC_LEN)) { + ERROR("\"%"TS"\": Invalid magic characters in header", filename); return WIMLIB_ERR_NOT_A_WIM_FILE; } - bytes_read = fread(&hdr_size, 1, sizeof(u32), fp); - if (bytes_read != sizeof(u32)) - goto err; - - hdr_size = le32_to_cpu(hdr_size); - - /* Byte 12 */ - + /* Byte 8 */ + p = get_u32(p + 8, &hdr_size); if (hdr_size != WIM_HEADER_DISK_SIZE) { - ERROR("Header is %u bytes (expected %u bytes)", - hdr_size, WIM_HEADER_DISK_SIZE); + ERROR("\"%"TS"\": Header is %u bytes (expected %u bytes)", + filename, hdr_size, WIM_HEADER_DISK_SIZE); return WIMLIB_ERR_INVALID_HEADER_SIZE; } - /* Read the rest of the header into a buffer. */ - - hdr_rem_size = WIM_HEADER_DISK_SIZE - WIM_MAGIC_LEN - sizeof(u32); - - bytes_read = fread(buf + WIM_MAGIC_LEN + sizeof(u32), 1, - hdr_rem_size, fp); - if (bytes_read != hdr_rem_size) - goto err; - + /* Byte 12 */ p = get_u32(buf + WIM_MAGIC_LEN + sizeof(u32), &wim_version); - if (wim_version != WIM_VERSION) { - ERROR("The WIM header says the WIM version is %u, but wimlib " - "only knows about version %u", - wim_version, WIM_VERSION); + ERROR("\"%"TS"\": The WIM header says the WIM version is %u, " + "but wimlib only knows about version %u", + filename, wim_version, WIM_VERSION); return WIMLIB_ERR_UNKNOWN_VERSION; } @@ -94,9 +80,9 @@ read_header(FILE *fp, struct wim_header *hdr, int open_flags) p = get_u32(p, &chunk_size); if (chunk_size != WIM_CHUNK_SIZE && (hdr->flags & WIM_HDR_FLAG_COMPRESSION)) { - ERROR("Unexpected chunk size of %u! Ask the author to " + ERROR("\"%"TS"\": Unexpected chunk size of %u! Ask the author to " "implement support for other chunk sizes.", - chunk_size); + filename, chunk_size); ERROR("(Or it might just be that the WIM header is invalid.)"); return WIMLIB_ERR_INVALID_CHUNK_SIZE; } @@ -109,16 +95,16 @@ read_header(FILE *fp, struct wim_header *hdr, int open_flags) hdr->part_number == 0 || hdr->part_number > hdr->total_parts) { - ERROR("Invalid WIM part number: %hu of %hu", - hdr->part_number, hdr->total_parts); + ERROR("\"%"TS"\": Invalid WIM part number: %hu of %hu", + filename, hdr->part_number, hdr->total_parts); return WIMLIB_ERR_INVALID_PART_NUMBER; } if (!(open_flags & WIMLIB_OPEN_FLAG_SPLIT_OK) && hdr->total_parts != 1) { - ERROR("This WIM is part %u of a %u-part WIM", - hdr->part_number, hdr->total_parts); + ERROR("\"%"TS"\": This WIM is part %u of a %u-part WIM", + filename, hdr->part_number, hdr->total_parts); return WIMLIB_ERR_SPLIT_UNSUPPORTED; } @@ -128,7 +114,8 @@ read_header(FILE *fp, struct wim_header *hdr, int open_flags) hdr->part_number, hdr->total_parts, hdr->image_count); if (hdr->image_count >= INT_MAX) { - ERROR("Invalid image count (%u)", hdr->image_count); + ERROR("\"%"TS"\": Invalid image count (%u)", + filename, hdr->image_count); return WIMLIB_ERR_IMAGE_COUNT; } @@ -153,25 +140,18 @@ read_header(FILE *fp, struct wim_header *hdr, int open_flags) /* Byte 208 */ return 0; - -err: - if (feof(fp)) - ERROR("Unexpected EOF while reading WIM header"); - else - ERROR_WITH_ERRNO("Error reading WIM header"); - return WIMLIB_ERR_READ; } /* * Writes the header for a WIM file. * * @hdr: A pointer to a struct wim_header structure that describes the header. - * @out: The FILE* for the output file, positioned at the appropriate - * place (the beginning of the file). - * @return: Zero on success, nonzero on failure. + * @out_fd: The file descriptor to the WIM file, opened for writing. + * + * Returns zero on success, nonzero on failure. */ int -write_header(const struct wim_header *hdr, FILE *out_fp) +write_header(const struct wim_header *hdr, int out_fd) { u8 buf[WIM_HEADER_DISK_SIZE]; u8 *p; @@ -183,12 +163,12 @@ write_header(const struct wim_header *hdr, FILE *out_fp) p = put_u32(p, hdr->flags); p = put_u32(p, (hdr->flags & WIM_HDR_FLAG_COMPRESSION) ? WIM_CHUNK_SIZE : 0); - /* byte 24 */ + /* Byte 24 */ p = put_bytes(p, WIM_GID_LEN, hdr->guid); p = put_u16(p, hdr->part_number); - /* byte 40 */ + /* Byte 40 */ p = put_u16(p, hdr->total_parts); p = put_u32(p, hdr->image_count); @@ -197,8 +177,10 @@ write_header(const struct wim_header *hdr, FILE *out_fp) p = put_resource_entry(p, &hdr->boot_metadata_res_entry); p = put_u32(p, hdr->boot_idx); p = put_resource_entry(p, &hdr->integrity); - memset(p, 0, WIM_UNUSED_LEN); - if (fwrite(buf, 1, sizeof(buf), out_fp) != sizeof(buf)) { + p = put_zeroes(p, WIM_UNUSED_LEN); + wimlib_assert(p - buf == sizeof(buf)); + + if (full_pwrite(out_fd, buf, sizeof(buf), 0) != sizeof(buf)) { ERROR_WITH_ERRNO("Failed to write WIM header"); return WIMLIB_ERR_WRITE; }