#ifndef BP_LIB_INITFS_H
#define BP_LIB_INITFS_H
#include <Uefi.h>
#include <Protocol/SimpleFileSystem.h>
#include "../include/disk.h"
#define BP_INITFS_INITFS_SUPPORTED_VERSION 0x0001
#pragma pack(1)
typedef struct {
  UINT8 sig[8];
  UINT16 bootloader_version;
  UINT16 initfs_version;
  UINT32 os_version;
  UINT8 installation_id[48];
  UINT64 initfs_size;
  UINT64 table_size;
  UINT64 files_area_size;
  UINT64 entries_width;
  UINT64 entries_count;
  UINT64 files_area_offset;
  UINT64 entropy_check1;
  UINT64 check1;
  UINT8 entries_table_hash[64];
  UINT8 files_area_hash[64];
  UINT8 installation_id_hash_hash[64];
  UINT8 padding[128];
  UINT8 header_hash[64];
} bp_initfs_INITFS_HEADER;
#pragma pack()
#pragma pack(1)
typedef struct {
  UINT64 file_offset;
  UINT64 file_size;
  UINT8 pk[64];
  UINT8 hash[64];
  UINT8 file_name[112];
} bp_initfs_FILE_ENTRY;
#pragma pack()
#pragma pack(1)
typedef struct {
  bp_initfs_FILE_ENTRY *files_entries;
  UINT64 file_count;
} bp_initfs_FILES_TABLE;
#pragma pack()
#pragma pack(1)
typedef struct {
  UINT8 sign[8];
  UINT16 bootloader_version;
  UINT16 initfs_version;
  UINT32 os_version;
  UINT8 installation_id[48];
  UINT64 signature_size;
  UINT64 signature_count;
  UINT64 signsyst_size;
  UINT64 signature_block_size;
  UINT8 signature_block_hash[64];
  UINT8 padding[288];
  UINT8 header_hash[64];
} bp_initfs_SIGNSYST_HEADER;
#pragma pack()
#pragma pack(1)
typedef struct {
  bp_initfs_INITFS_HEADER *header;
  bp_initfs_FILES_TABLE *files_table;
  UINT8 *files_area;
} bp_initfs_INITFS;
#pragma pack()
#pragma pack(1)
typedef struct {
  bp_initfs_SIGNSYST_HEADER *header;
  UINT8 *signature_area;
} bp_initfs_SIGNSYST;
#pragma pack()
EFI_STATUS bp_initfs_parse_initfs_header(UINT8 *header_data,UINTN buffer_size,bp_initfs_INITFS_HEADER **header);
EFI_STATUS bp_initfs_generate_padding(UINTN size,UINT8 byte,UINT8 **result);
EFI_STATUS bp_initfs_check_initfs_header(bp_initfs_INITFS_HEADER *header,EFI_FILE_PROTOCOL *root);
EFI_STATUS bp_initfs_parse_signsyst_header(UINT8 *header_data,UINTN buffer_size,bp_initfs_SIGNSYST_HEADER **header);
EFI_STATUS bp_initfs_check_signsyst_header(bp_initfs_SIGNSYST_HEADER *header,EFI_FILE_PROTOCOL *root);
EFI_STATUS bp_initfs_cross_check_headers(bp_initfs_INITFS_HEADER *initfs,bp_initfs_SIGNSYST_HEADER *signsyst);
EFI_STATUS bp_initfs_create_initfs_structure(bp_initfs_INITFS_HEADER *supposed_header,UINT8 *loaded_initfs,bp_initfs_INITFS **initfs);
EFI_STATUS bp_initfs_create_signsyst_structure(bp_initfs_SIGNSYST_HEADER *supposed_header,UINT8 *loaded_signsyst,bp_initfs_SIGNSYST **signsyst);
EFI_STATUS bp_initfs_check_initfs_integrity(bp_initfs_INITFS *initfs,bp_initfs_SIGNSYST *signsyst);
EFI_STATUS bp_initfs_generate_file_name(CHAR8 *file_name_in,UINT8 **file_name_out);
EFI_STATUS bp_initfs_read_file(bp_initfs_INITFS *initfs,CHAR8 *file_name,bp_disk_FILE **file);
#endif
