2023-01-05 06:20:40 +01:00
|
|
|
/*
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
UMKa - User-Mode KolibriOS developer tools
|
|
|
|
vdisk - virtual disk, raw format
|
|
|
|
|
|
|
|
Copyright (C) 2023 Ivan Baravy <dunkaist@gmail.com>
|
|
|
|
*/
|
|
|
|
|
2023-01-04 01:15:40 +01:00
|
|
|
#include <errno.h>
|
2023-01-16 04:14:48 +01:00
|
|
|
#include <fcntl.h>
|
2023-01-04 01:15:40 +01:00
|
|
|
#include <stdlib.h>
|
2023-01-16 04:14:48 +01:00
|
|
|
#include <unistd.h>
|
2023-01-04 01:15:40 +01:00
|
|
|
#include "../trace.h"
|
2023-02-01 19:30:44 +01:00
|
|
|
#include "umkaio.h"
|
2023-01-04 01:15:40 +01:00
|
|
|
#include "raw.h"
|
|
|
|
|
2023-01-05 06:20:40 +01:00
|
|
|
struct vdisk_raw {
|
|
|
|
struct vdisk vdisk;
|
2023-01-16 04:14:48 +01:00
|
|
|
int fd;
|
2023-01-05 06:20:40 +01:00
|
|
|
};
|
|
|
|
|
2023-01-04 01:15:40 +01:00
|
|
|
STDCALL void
|
|
|
|
vdisk_raw_close(void *userdata) {
|
|
|
|
COVERAGE_OFF();
|
|
|
|
struct vdisk_raw *disk = userdata;
|
2023-01-16 04:14:48 +01:00
|
|
|
close(disk->fd);
|
2023-01-04 01:15:40 +01:00
|
|
|
free(disk);
|
|
|
|
COVERAGE_ON();
|
|
|
|
}
|
|
|
|
|
|
|
|
STDCALL int
|
|
|
|
vdisk_raw_read(void *userdata, void *buffer, off_t startsector,
|
|
|
|
size_t *numsectors) {
|
|
|
|
COVERAGE_OFF();
|
|
|
|
struct vdisk_raw *disk = userdata;
|
2023-01-16 04:14:48 +01:00
|
|
|
lseek(disk->fd, startsector * disk->vdisk.sect_size, SEEK_SET);
|
2023-01-16 05:54:34 +01:00
|
|
|
io_read(disk->fd, buffer, *numsectors * disk->vdisk.sect_size,
|
2023-01-17 01:49:11 +01:00
|
|
|
disk->vdisk.io);
|
2023-01-04 01:15:40 +01:00
|
|
|
COVERAGE_ON();
|
2023-02-01 19:30:44 +01:00
|
|
|
return KOS_ERROR_SUCCESS;
|
2023-01-04 01:15:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
STDCALL int
|
|
|
|
vdisk_raw_write(void *userdata, void *buffer, off_t startsector,
|
|
|
|
size_t *numsectors) {
|
|
|
|
COVERAGE_OFF();
|
|
|
|
struct vdisk_raw *disk = userdata;
|
2023-01-16 04:14:48 +01:00
|
|
|
lseek(disk->fd, startsector * disk->vdisk.sect_size, SEEK_SET);
|
2023-01-16 05:54:34 +01:00
|
|
|
io_write(disk->fd, buffer, *numsectors * disk->vdisk.sect_size,
|
2023-01-17 01:49:11 +01:00
|
|
|
disk->vdisk.io);
|
2023-01-04 01:15:40 +01:00
|
|
|
COVERAGE_ON();
|
2023-02-01 19:30:44 +01:00
|
|
|
return KOS_ERROR_SUCCESS;
|
2023-01-04 01:15:40 +01:00
|
|
|
}
|
|
|
|
|
2023-01-05 06:20:40 +01:00
|
|
|
struct vdisk*
|
2023-02-06 17:01:37 +01:00
|
|
|
vdisk_init_raw(const char *fname, const struct umka_io *io) {
|
2023-02-06 15:16:35 +01:00
|
|
|
int fd = open(fname, O_RDONLY | O_BINARY);
|
2023-01-16 04:14:48 +01:00
|
|
|
if (!fd) {
|
2023-01-04 01:15:40 +01:00
|
|
|
printf("[vdisk.raw]: can't open file '%s': %s\n", fname, strerror(errno));
|
|
|
|
return NULL;
|
|
|
|
}
|
2023-01-16 04:14:48 +01:00
|
|
|
off_t fsize = lseek(fd, 0, SEEK_END);
|
|
|
|
lseek(fd, 0, SEEK_SET);
|
2023-01-04 01:15:40 +01:00
|
|
|
size_t sect_size = 512;
|
|
|
|
if (strstr(fname, "s4096") != NULL || strstr(fname, "s4k") != NULL) {
|
|
|
|
sect_size = 4096;
|
|
|
|
}
|
|
|
|
struct vdisk_raw *disk = (struct vdisk_raw*)malloc(sizeof(struct vdisk_raw));
|
|
|
|
*disk = (struct vdisk_raw){
|
|
|
|
.vdisk = {.diskfunc = {.strucsize = sizeof(diskfunc_t),
|
|
|
|
.close = vdisk_raw_close,
|
|
|
|
.read = vdisk_raw_read,
|
|
|
|
.write = vdisk_raw_write,
|
|
|
|
},
|
|
|
|
.sect_size = sect_size,
|
|
|
|
.sect_cnt = (uint64_t)fsize / sect_size,
|
2023-01-18 09:29:08 +01:00
|
|
|
.io = io,
|
2023-01-04 01:15:40 +01:00
|
|
|
},
|
2023-01-16 04:14:48 +01:00
|
|
|
.fd = fd,
|
2023-01-04 01:15:40 +01:00
|
|
|
};
|
2023-01-05 06:20:40 +01:00
|
|
|
return (struct vdisk*)disk;
|
2023-01-04 01:15:40 +01:00
|
|
|
}
|