#ifndef _IOSPatcher_H_
#define _IOSPatcher_H_

#ifdef __cplusplus
extern "C" {
#endif

#define ISALIGNED(x)    ((((u32)x)&0x1F)==0)

typedef struct {
    u32 iosVersion;
    u32 iosRevision;
    bool esTruchaPatch;
    bool esIdentifyPatch;
    bool nandPatch;
    bool addticketPatch;
    bool setuidcheckPatch;
    bool koreanKeyPatch;
    bool haveFakeSign;
    bool haveNandPerm;
    int esOtherPatches;
    int diPatches;
    u32 location;
    u16 newrevision;
} patchSettings;

typedef struct {
    signed_blob *certs;
    signed_blob *ticket;
    signed_blob *tmd;
    signed_blob *crl;

    u32 certs_size;
    u32 ticket_size;
    u32 tmd_size;
    u32 crl_size;

    u8 **encrypted_buffer;
    u8 **decrypted_buffer;
    u32 *buffer_size;

    u32 content_count;
}ATTRIBUTE_PACKED IOS;

void get_title_key(signed_blob *s_tik, u8 *key);
void decrypt_IOS(IOS *ios);
s32 Init_IOS(IOS **ios);
void free_IOS(IOS **ios);
s32 get_IOS(IOS **ios, u32 iosnr, u16 revision);
s32 set_content_count(IOS *ios, u32 count);
s32 IosInstall(patchSettings settings);
s32 IosInstallUnpatched(u32 iosversion, u32 revision);
s32 IosDowngrade(u32 iosVersion, u32 highRevision, u32 lowRevision);
s32 Downgrade_TMD_Revision(const signed_blob* ptmd, u32 tmd_size, void* certs,
    u32 certs_size);
int patch_fake_sign_check(u8 *buf, u32 size);
int patch_identify_check(u8 *buf, u32 size);
s32 brute_tik2(tik *p_tik);
void clearPatchSettings(patchSettings* settings);
#ifdef __cplusplus
}
#endif
#endif
