Merge pull request #263 from ZystemOS/feature/mkfat32-any-stream
mkFAT32 use a anytype stream
This commit is contained in:
commit
ea6a0b7a9f
2 changed files with 49 additions and 49 deletions
|
@ -211,7 +211,13 @@ const Fat32BuilderStep = struct {
|
||||||
///
|
///
|
||||||
fn make(step: *Step) (error{EndOfStream} || File.OpenError || File.ReadError || File.WriteError || File.SeekError || Fat32.Error)!void {
|
fn make(step: *Step) (error{EndOfStream} || File.OpenError || File.ReadError || File.WriteError || File.SeekError || Fat32.Error)!void {
|
||||||
const self = @fieldParentPtr(Fat32BuilderStep, "step", step);
|
const self = @fieldParentPtr(Fat32BuilderStep, "step", step);
|
||||||
try Fat32.make(self.options, self.out_file_path);
|
// Open the out file
|
||||||
|
const image = try std.fs.cwd().createFile(self.out_file_path, .{ .read = true });
|
||||||
|
|
||||||
|
// If there was an error, delete the image as this will be invalid
|
||||||
|
errdefer (std.fs.cwd().deleteFile(self.out_file_path) catch unreachable);
|
||||||
|
defer image.close();
|
||||||
|
try Fat32.make(self.options, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
88
mkfat32.zig
88
mkfat32.zig
|
@ -1,5 +1,4 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const File = std.fs.File;
|
|
||||||
|
|
||||||
// This is the assembly for the FAT bootleader.
|
// This is the assembly for the FAT bootleader.
|
||||||
// [bits 16]
|
// [bits 16]
|
||||||
|
@ -350,23 +349,23 @@ pub const Fat32 = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Write the FSInfo and backup FSInfo sector to a image file. This uses a valid FAT32 boot
|
/// Write the FSInfo and backup FSInfo sector to a stream. This uses a valid FAT32 boot sector
|
||||||
/// sector header for creating the FSInfo sector.
|
/// header for creating the FSInfo sector.
|
||||||
///
|
///
|
||||||
/// Argument:
|
/// Argument:
|
||||||
/// IN/OUT image: File - The image file to write the FSInfo to.
|
/// IN/OUT stream: anytype - The stream to write the FSInfo to.
|
||||||
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FSInfo sector.
|
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FSInfo sector.
|
||||||
/// IN free_cluster_num: u32 - The number of free data clusters on the image.
|
/// IN free_cluster_num: u32 - The number of free data clusters on the image.
|
||||||
/// IN next_free_cluster: u32 - The next free data cluster to start looking for when writing
|
/// IN next_free_cluster: u32 - The next free data cluster to start looking for when writing
|
||||||
/// files.
|
/// files.
|
||||||
///
|
///
|
||||||
/// Error File.WriteError || File.SeekError
|
/// Error @TypeOf(stream).WriteError || @TypeOf(stream).SeekError
|
||||||
/// File.WriteError - If there is an error when writing to the image. See File.WriteError
|
/// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream.
|
||||||
/// File.SeekError - If there is an error when seeking the image. See File.SeekError
|
/// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream.
|
||||||
///
|
///
|
||||||
fn writeFSInfo(image: File, fat32_header: Header, free_cluster_num: u32, next_free_cluster: u32) (File.WriteError || File.SeekError)!void {
|
fn writeFSInfo(stream: anytype, fat32_header: Header, free_cluster_num: u32, next_free_cluster: u32) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void {
|
||||||
const seekable_stream = image.seekableStream();
|
const seekable_stream = stream.seekableStream();
|
||||||
const writer = image.writer();
|
const writer = stream.writer();
|
||||||
|
|
||||||
// Seek to the correct location
|
// Seek to the correct location
|
||||||
try seekable_stream.seekTo(fat32_header.fsinfo_sector * fat32_header.bytes_per_sector);
|
try seekable_stream.seekTo(fat32_header.fsinfo_sector * fat32_header.bytes_per_sector);
|
||||||
|
@ -404,20 +403,20 @@ pub const Fat32 = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Write the FAT to the image. This sets up a blank FAT with end marker of 0x0FFFFFFF and root
|
/// Write the FAT to the stream. This sets up a blank FAT with end marker of 0x0FFFFFFF and root
|
||||||
/// directory cluster of 0x0FFFFFFF (one cluster chain).
|
/// directory cluster of 0x0FFFFFFF (one cluster chain).
|
||||||
///
|
///
|
||||||
/// Argument:
|
/// Argument:
|
||||||
/// IN/OUT image: File - The image file to write the FSInfo to.
|
/// IN/OUT stream: anytype - The stream to write the FSInfo to.
|
||||||
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT.
|
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT.
|
||||||
///
|
///
|
||||||
/// Error File.WriteError || File.SeekError
|
/// Error @TypeOf(stream).WriteError || @TypeOf(stream).SeekError
|
||||||
/// File.WriteError - If there is an error when writing to the image. See File.WriteError
|
/// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream.
|
||||||
/// File.SeekError - If there is an error when seeking the image. See File.SeekError
|
/// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream.
|
||||||
///
|
///
|
||||||
fn writeFAT(image: File, fat32_header: Header) (File.WriteError || File.SeekError)!void {
|
fn writeFAT(stream: anytype, fat32_header: Header) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void {
|
||||||
const seekable_stream = image.seekableStream();
|
const seekable_stream = stream.seekableStream();
|
||||||
const writer = image.writer();
|
const writer = stream.writer();
|
||||||
|
|
||||||
// This FAT is below the reserved sectors
|
// This FAT is below the reserved sectors
|
||||||
try seekable_stream.seekTo(fat32_header.reserved_sectors * fat32_header.bytes_per_sector);
|
try seekable_stream.seekTo(fat32_header.reserved_sectors * fat32_header.bytes_per_sector);
|
||||||
|
@ -439,19 +438,19 @@ pub const Fat32 = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Write the FAT boot sector with the boot code and FAT32 header to the image.
|
/// Write the FAT boot sector with the boot code and FAT32 header to the stream.
|
||||||
///
|
///
|
||||||
/// Argument:
|
/// Argument:
|
||||||
/// IN/OUT image: File - The image file to write the FSInfo to.
|
/// IN/OUT stream: anytype - The stream to write the FSInfo to.
|
||||||
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT.
|
/// IN fat32_header: Header - A valid FAT32 boot header for creating the FAT.
|
||||||
///
|
///
|
||||||
/// Error: File.WriteError || File.SeekError
|
/// Error: @TypeOf(stream).WriteError || @TypeOf(stream).SeekError
|
||||||
/// File.WriteError - If there is an error when writing to the image. See File.WriteError.
|
/// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream.
|
||||||
/// File.SeekError - If there is an error when seeking the image. See File.SeekError.
|
/// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream.
|
||||||
///
|
///
|
||||||
fn writeBootSector(image: File, fat32_header: Header) (File.WriteError || File.SeekError)!void {
|
fn writeBootSector(stream: anytype, fat32_header: Header) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError)!void {
|
||||||
const seekable_stream = image.seekableStream();
|
const seekable_stream = stream.seekableStream();
|
||||||
const writer = image.writer();
|
const writer = stream.writer();
|
||||||
|
|
||||||
var boot_sector: [512]u8 = undefined;
|
var boot_sector: [512]u8 = undefined;
|
||||||
std.mem.copy(u8, &boot_sector, &bootsector_boot_code);
|
std.mem.copy(u8, &boot_sector, &bootsector_boot_code);
|
||||||
|
@ -538,43 +537,38 @@ pub const Fat32 = struct {
|
||||||
/// user. The file will be saved to the path specified.
|
/// user. The file will be saved to the path specified.
|
||||||
///
|
///
|
||||||
/// Argument:
|
/// Argument:
|
||||||
/// IN options: Options - The FAT32 options that the user can provide to change
|
/// IN options: Options - The FAT32 options that the user can provide to change the
|
||||||
/// the parameters of a FAT32 image.
|
/// parameters of a FAT32 image.
|
||||||
/// IN out_file_path: []const u8 - The location for which the FAT32 image will be created.
|
/// IN stream: anytype - The stream to create a new FAT32 image. This stream must support
|
||||||
|
/// reader(), writer() and seekableStream() interfaces.
|
||||||
///
|
///
|
||||||
/// Error: File.OpenError || File.WriteError || File.SeekError || Error
|
/// Error: @TypeOf(stream).WriteError || @TypeOf(stream).SeekError || Error
|
||||||
/// File.OpenError || File.WriteError || File.SeekError - Error relating to file operations. See std.fs.File.
|
/// @TypeOf(stream).WriteError - If there is an error when writing. See the relevant error for the stream.
|
||||||
|
/// @TypeOf(stream).SeekError - If there is an error when seeking. See the relevant error for the stream.
|
||||||
/// Error.InvalidOptionValue - In the user has provided invalid options.
|
/// Error.InvalidOptionValue - In the user has provided invalid options.
|
||||||
/// Error.TooLarge - The image size is too small. < 17.5KB.
|
/// Error.TooLarge - The stream size is too small. < 17.5KB.
|
||||||
/// Error.TooSmall - The image size is to large. > 2TB.
|
/// Error.TooSmall - The stream size is to large. > 2TB.
|
||||||
///
|
///
|
||||||
pub fn make(options: Options, out_file_path: []const u8) (File.OpenError || File.WriteError || File.SeekError || Error)!void {
|
pub fn make(options: Options, stream: anytype) (@TypeOf(stream).WriteError || @TypeOf(stream).SeekError || Error)!void {
|
||||||
// First set up the header
|
// First set up the header
|
||||||
const fat32_header = try Fat32.createFATHeader(options);
|
const fat32_header = try Fat32.createFATHeader(options);
|
||||||
// Get the total image size again. As the above has a check for the image size, we don't need one here again
|
// Get the total image size again. As the above has a check for the size, we don't need one here again
|
||||||
const image_size = std.mem.alignBackward(options.image_size, fat32_header.bytes_per_sector);
|
const image_size = std.mem.alignBackward(options.image_size, fat32_header.bytes_per_sector);
|
||||||
|
|
||||||
// Open the out file
|
// Initialise the stream with all zeros
|
||||||
const image = try std.fs.cwd().createFile(out_file_path, .{ .read = true });
|
try stream.writer().writeByteNTimes(0x00, image_size);
|
||||||
|
|
||||||
// If there was an error, delete the image as this will be invalid
|
|
||||||
errdefer (std.fs.cwd().deleteFile(out_file_path) catch unreachable);
|
|
||||||
defer image.close();
|
|
||||||
|
|
||||||
// Initialise the image with all zeros
|
|
||||||
try image.writer().writeByteNTimes(0x00, image_size);
|
|
||||||
|
|
||||||
// Write the boot sector with the bootstrap code and header and the backup boot sector.
|
// Write the boot sector with the bootstrap code and header and the backup boot sector.
|
||||||
try Fat32.writeBootSector(image, fat32_header);
|
try Fat32.writeBootSector(stream, fat32_header);
|
||||||
|
|
||||||
// Write the FAT and second FAT
|
// Write the FAT and second FAT
|
||||||
try Fat32.writeFAT(image, fat32_header);
|
try Fat32.writeFAT(stream, fat32_header);
|
||||||
|
|
||||||
// Calculate the usable clusters.
|
// Calculate the usable clusters.
|
||||||
const usable_sectors = fat32_header.total_sectors - fat32_header.reserved_sectors - (fat32_header.fat_count * fat32_header.sectors_per_fat);
|
const usable_sectors = fat32_header.total_sectors - fat32_header.reserved_sectors - (fat32_header.fat_count * fat32_header.sectors_per_fat);
|
||||||
const usable_clusters = @divFloor(usable_sectors, fat32_header.sectors_per_cluster) - 1;
|
const usable_clusters = @divFloor(usable_sectors, fat32_header.sectors_per_cluster) - 1;
|
||||||
|
|
||||||
// Write the FSInfo and backup FSInfo sectors
|
// Write the FSInfo and backup FSInfo sectors
|
||||||
try Fat32.writeFSInfo(image, fat32_header, usable_clusters, 2);
|
try Fat32.writeFSInfo(stream, fat32_header, usable_clusters, 2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue