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;
}
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;
}
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;
}
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;
}
/* 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;
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);
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;
}
tprintf(T("Chunk Size = %u\n"), WIM_CHUNK_SIZE);
tfputs (T("GUID = "), stdout);
- print_byte_field(hdr->guid, WIM_GID_LEN);
+ print_byte_field(hdr->guid, WIM_GID_LEN, stdout);
tputchar(T('\n'));
tprintf(T("Part Number = %hu\n"), w->hdr.part_number);
tprintf(T("Total Parts = %hu\n"), w->hdr.total_parts);