blob: 2395c459578d73248fcabefc6fd6312f1fa5822c [file] [log] [blame]
Thomas Heijligend1e04572023-11-27 14:28:55 +00001
2#include <stdio.h>
Thomas Heijligenb00b3162023-11-29 10:02:31 +00003#include <errno.h>
4#include <string.h>
Thomas Heijligend1e04572023-11-27 14:28:55 +00005
Thomas Heijligen62268ee2023-11-27 15:10:41 +00006#include "blockdev.h"
Thomas Heijligend1e04572023-11-27 14:28:55 +00007
Thomas Heijligendc1a84b2023-12-04 13:39:42 +00008// private
9static FILE* block_device = NULL;
10static size_t device_size = 0;
11
12// from filo
13unsigned long part_start = 0;
14unsigned long part_length = 0;
Thomas Heijligend1e04572023-11-27 14:28:55 +000015
16
17int devopen(const char* name, int* reopen)
18{
19 block_device = fopen(name, "rwb");
20 if (!block_device) {
Thomas Heijligenb00b3162023-11-29 10:02:31 +000021 fprintf(stderr, "devopen: %s.\n", strerror(errno));
Thomas Heijligend1e04572023-11-27 14:28:55 +000022 return 0;
23 }
Thomas Heijligenb00b3162023-11-29 10:02:31 +000024 int seek_res = 0;
25 seek_res |= fseek(block_device, 0, SEEK_END);
Thomas Heijligen62268ee2023-11-27 15:10:41 +000026 device_size = ftell(block_device);
Thomas Heijligenb00b3162023-11-29 10:02:31 +000027 seek_res |= fseek(block_device, 0, SEEK_SET);
28 if (seek_res || device_size == -1L || device_size % 512) {
29 fprintf(stderr, "devopen: Bad file %s.\n", name);
30 devclose();
31 return 0;
32 }
33
Thomas Heijligendc1a84b2023-12-04 13:39:42 +000034 part_start = 0;
35 part_length = device_size;
36
Thomas Heijligend1e04572023-11-27 14:28:55 +000037 return 1;
38}
39
40
41void devclose(void)
42{
Thomas Heijligen62268ee2023-11-27 15:10:41 +000043 if (block_device) {
Thomas Heijligend1e04572023-11-27 14:28:55 +000044 fclose(block_device);
Thomas Heijligen62268ee2023-11-27 15:10:41 +000045 }
Thomas Heijligend1e04572023-11-27 14:28:55 +000046 block_device = NULL;
47 device_size = 0;
Thomas Heijligendc1a84b2023-12-04 13:39:42 +000048 part_start = 0;
49 part_length = 0;
Thomas Heijligend1e04572023-11-27 14:28:55 +000050}
51
52int devread(unsigned long sector, unsigned long byte_offset, unsigned long byte_len, void *buf)
53{
54 if (!block_device) {
Thomas Heijligen62268ee2023-11-27 15:10:41 +000055 fprintf(stderr, "devread: Device not open.\n");
Thomas Heijligend1e04572023-11-27 14:28:55 +000056 return 0;
57 }
58
59 const unsigned long offset = sector * 512 + byte_offset;
Thomas Heijligen62268ee2023-11-27 15:10:41 +000060 if (offset + byte_len > device_size) {
61 fprintf(stderr, "devread: Attempt to read beyond device.\n");
Thomas Heijligend1e04572023-11-27 14:28:55 +000062 return 0;
63 }
64
Thomas Heijligen62268ee2023-11-27 15:10:41 +000065 if (fseek(block_device, sector * 512 + byte_offset, SEEK_SET) != 0) {
66 fprintf(stderr, "devread: Failed to set offset on device.\n");
67 return 0;
68 }
Nico Hubera68ee402024-01-23 16:17:36 +010069 if (fread(buf, byte_len, 1, block_device) != 1) {
Thomas Heijligen62268ee2023-11-27 15:10:41 +000070 fprintf(stderr, "devread: Failed to read from device.\n");
Thomas Heijligend1e04572023-11-27 14:28:55 +000071 return 0;
72 }
73 return 1;
74}
75
76
77
Thomas Heijligendc1a84b2023-12-04 13:39:42 +000078void dev_set_partition(unsigned long start, unsigned long size)
79{
80 if (start + size <= device_size) {
81 part_start = start;
82 part_length = size;
83 }
84}
Thomas Heijligend1e04572023-11-27 14:28:55 +000085
Thomas Heijligendc1a84b2023-12-04 13:39:42 +000086void dev_get_partition(unsigned long *start, unsigned long *size)
87{
88 *start = part_start;
89 *size = part_length;
90}
91