CoolPotOS/include/iso9660.h
2024-05-18 23:44:25 +08:00

170 lines
4.2 KiB
C

#ifndef CRASHPOWEROS_ISO9660_H
#define CRASHPOWEROS_ISO9660_H
#define L9660_SEEK_END -1
#define L9660_SEEK_SET 0
#define L9660_SEEK_CUR +1
#include <stdint.h>
#include <stddef.h>
#include "common.h"
typedef enum {
/*! Success! */
L9660_OK = 0,
/*! read_sector callback returned false */
L9660_EIO,
/*! file system is bad */
L9660_EBADFS,
/*! specified name does not exist */
L9660_ENOENT,
/*! attempted to open a non-file (e.g. a directory) as a file */
L9660_ENOTFILE,
/*! attempted to open a non-directory (e.g. a file) as a directory
* may be returned by l9660_openat if e.g. you pass path "a/b" and
* "a" is a file
*/
L9660_ENOTDIR,
} l9660_status;
typedef struct {
uint8_t le[2];
} l9660_luint16;
typedef struct {
uint8_t be[2];
} l9660_buint16;
typedef struct {
uint8_t le[2], be[2];
} l9660_duint16;
typedef struct {
uint8_t le[4];
} l9660_luint32;
typedef struct {
uint8_t be[4];
} l9660_buint32;
typedef struct {
uint8_t le[4], be[4];
} l9660_duint32;
/* Descriptor time format */
typedef struct {
char d[17];
} l9660_desctime;
/* File time format */
typedef struct {
char d[7];
} l9660_filetime;
/* Directory entry */
typedef struct {
uint8_t length;
uint8_t xattr_length;
l9660_duint32 sector;
l9660_duint32 size;
l9660_filetime time;
uint8_t flags;
uint8_t unit_size;
uint8_t gap_size;
l9660_duint16 vol_seq_number;
uint8_t name_len;
char name[/*name_len*/];
} l9660_dirent;
/* Volume descriptor header */
typedef struct {
uint8_t type;
char magic[5];
uint8_t version;
} l9660_vdesc_header;
/* Primary volume descriptor */
typedef struct {
l9660_vdesc_header hdr;
char pad0[1];
char system_id[32];
char volume_id[32];
char pad1[8];
l9660_duint32 volume_space_size;
char pad2[32];
l9660_duint16 volume_set_size;
l9660_duint16 volume_seq_number;
l9660_duint16 logical_block_size;
l9660_duint32 path_table_size;
l9660_luint32 path_table_le;
l9660_luint32 path_table_opt_le;
l9660_buint32 path_table_be;
l9660_buint32 path_table_opt_be;
union {
l9660_dirent root_dir_ent;
char pad3[34];
};
char volume_set_id[128];
char data_preparer_id[128];
char app_id[128];
char copyright_file[38];
char abstract_file[36];
char bibliography_file[37];
l9660_desctime volume_created,
volume_modified,
volume_expires,
volume_effective;
uint8_t file_structure_version;
char pad4[1];
char app_reserved[512];
char reserved[653];
} l9660_vdesc_primary;
/* A generic volume descriptor (i.e. 2048 bytes) */
typedef union {
l9660_vdesc_header hdr;
char _bits[2048];
} l9660_vdesc;
/* File system structure.
* Stick this inside your own structure and cast/offset as appropriate to store
* private data
*/
typedef struct l9660_fs {
#ifdef L9660_SINGLEBUFFER
union {
l9660_dirent root_dir_ent;
char root_dir_pad[34];
};
#else
/* Sector buffer to hold the PVD */
l9660_vdesc pvd;
#endif
/* read_sector func */
bool (*read_sector)(struct l9660_fs *fs, void *buf, uint32_t sector);
} l9660_fs;
typedef struct {
#ifndef L9660_SINGLEBUFFER
/* single sector buffer */
char buf[2048];
#endif
l9660_fs *fs;
uint32_t first_sector;
uint32_t position;
uint32_t length;
} l9660_file;
typedef struct {
/* directories are mostly just files with special accessors, but we like type safetey */
l9660_file file;
} l9660_dir;
uint32_t l9660_tell(l9660_file *f);
l9660_status l9660_read(l9660_file *f, void *buf, size_t size, size_t *read);
l9660_status l9660_seek(l9660_file *f, int whence, int32_t offset);
l9660_status l9660_openat(l9660_file *child, l9660_dir *parent, const char *name);
l9660_status l9660_readdir(l9660_dir *dir, l9660_dirent **pdirent);
l9660_status l9660_opendirat(l9660_dir *dir, l9660_dir *parent, const char *path);
l9660_status l9660_fs_open_root(l9660_dir *dir, l9660_fs *fs);
l9660_status l9660_openfs(l9660_fs *fs, bool (*read_sector)(l9660_fs *fs, void *buf, uint32_t sector,uint8_t disk_number),uint8_t disk_number);
void init_iso9660();
#endif