| |
| #include <stdio.h> |
| #include <errno.h> |
| #include <string.h> |
| |
| #include "blockdev.h" |
| |
| // private |
| static FILE* block_device = NULL; |
| static size_t device_size = 0; |
| |
| // from filo |
| unsigned long part_start = 0; |
| unsigned long part_length = 0; |
| |
| |
| int devopen(const char* name, int* reopen) |
| { |
| block_device = fopen(name, "rwb"); |
| if (!block_device) { |
| fprintf(stderr, "devopen: %s.\n", strerror(errno)); |
| return 0; |
| } |
| int seek_res = 0; |
| seek_res |= fseek(block_device, 0, SEEK_END); |
| device_size = ftell(block_device); |
| seek_res |= fseek(block_device, 0, SEEK_SET); |
| if (seek_res || device_size == -1L || device_size % 512) { |
| fprintf(stderr, "devopen: Bad file %s.\n", name); |
| devclose(); |
| return 0; |
| } |
| |
| part_start = 0; |
| part_length = device_size; |
| |
| return 1; |
| } |
| |
| |
| void devclose(void) |
| { |
| if (block_device) { |
| fclose(block_device); |
| } |
| block_device = NULL; |
| device_size = 0; |
| part_start = 0; |
| part_length = 0; |
| } |
| |
| int devread(unsigned long sector, unsigned long byte_offset, unsigned long byte_len, void *buf) |
| { |
| if (!block_device) { |
| fprintf(stderr, "devread: Device not open.\n"); |
| return 0; |
| } |
| |
| const unsigned long offset = sector * 512 + byte_offset; |
| if (offset + byte_len > device_size) { |
| fprintf(stderr, "devread: Attempt to read beyond device.\n"); |
| return 0; |
| } |
| |
| if (fseek(block_device, sector * 512 + byte_offset, SEEK_SET) != 0) { |
| fprintf(stderr, "devread: Failed to set offset on device.\n"); |
| return 0; |
| } |
| if (fread(buf, byte_len, 1, block_device) != byte_len) { |
| fprintf(stderr, "devread: Failed to read from device.\n"); |
| return 0; |
| } |
| return 1; |
| } |
| |
| |
| |
| void dev_set_partition(unsigned long start, unsigned long size) |
| { |
| if (start + size <= device_size) { |
| part_start = start; |
| part_length = size; |
| } |
| } |
| |
| void dev_get_partition(unsigned long *start, unsigned long *size) |
| { |
| *start = part_start; |
| *size = part_length; |
| } |
| |