[es/tiktool] start eticket.

This commit is contained in:
jakcron 2017-07-22 16:59:06 +08:00
parent 90cab5d7c3
commit e8c39ace04
16 changed files with 1349 additions and 1 deletions

View file

@ -12,6 +12,9 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ncatool", "programs\ncatool\ncatool.vcxproj", "{7DA88C6F-4470-495D-995A-4F633F3370C1}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ncatool", "programs\ncatool\ncatool.vcxproj", "{7DA88C6F-4470-495D-995A-4F633F3370C1}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{170B4A09-1B67-4A62-93AB-116EBCFF4A8C}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{170B4A09-1B67-4A62-93AB-116EBCFF4A8C}"
ProjectSection(SolutionItems) = preProject
lib\makefile = lib\makefile
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npdmtool", "programs\npdmtool\npdmtool.vcxproj", "{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npdmtool", "programs\npdmtool\npdmtool.vcxproj", "{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C}"
EndProject EndProject
@ -24,10 +27,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore .gitignore = .gitignore
makefile = makefile makefile = makefile
README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pfstool", "programs\pfstool\pfstool.vcxproj", "{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pfstool", "programs\pfstool\pfstool.vcxproj", "{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libes", "lib\es\es.vcxproj", "{7BE99936-0D40-410D-944B-4513C2EFF8DC}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tiktool", "programs\tiktool\tiktool.vcxproj", "{2200B834-F15A-4C6E-9DDB-6012B9A5C246}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64 Debug|x64 = Debug|x64
@ -84,6 +92,22 @@ Global
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x64.Build.0 = Release|x64 {BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x64.Build.0 = Release|x64
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.ActiveCfg = Release|Win32 {BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.ActiveCfg = Release|Win32
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.Build.0 = Release|Win32 {BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB}.Release|x86.Build.0 = Release|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x64.ActiveCfg = Debug|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x64.Build.0 = Debug|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x86.ActiveCfg = Debug|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Debug|x86.Build.0 = Debug|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x64.ActiveCfg = Release|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x64.Build.0 = Release|x64
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x86.ActiveCfg = Release|Win32
{7BE99936-0D40-410D-944B-4513C2EFF8DC}.Release|x86.Build.0 = Release|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x64.ActiveCfg = Debug|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x64.Build.0 = Debug|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x86.ActiveCfg = Debug|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Debug|x86.Build.0 = Debug|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x64.ActiveCfg = Release|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x64.Build.0 = Release|x64
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x86.ActiveCfg = Release|Win32
{2200B834-F15A-4C6E-9DDB-6012B9A5C246}.Release|x86.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@ -95,5 +119,7 @@ Global
{7DA88C6F-4470-495D-995A-4F633F3370C1} = {E0863FCC-8E72-490D-BE1B-458F12CA8298} {7DA88C6F-4470-495D-995A-4F633F3370C1} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C} = {E0863FCC-8E72-490D-BE1B-458F12CA8298} {550C6AC3-EBE0-46CA-AE6C-EEEB59DDF35C} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB} = {E0863FCC-8E72-490D-BE1B-458F12CA8298} {BC2F2D07-BAB3-469C-9C25-8CC54F96F7AB} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
{7BE99936-0D40-410D-944B-4513C2EFF8DC} = {170B4A09-1B67-4A62-93AB-116EBCFF4A8C}
{2200B834-F15A-4C6E-9DDB-6012B9A5C246} = {E0863FCC-8E72-490D-BE1B-458F12CA8298}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

356
lib/es/ETicketBody_V2.cpp Normal file
View file

@ -0,0 +1,356 @@
#include "ETicketBody_V2.h"
es::ETicketBody_V2::ETicketBody_V2()
{
clear();
}
es::ETicketBody_V2::ETicketBody_V2(const ETicketBody_V2 & other)
{
copyFrom(other);
}
es::ETicketBody_V2::ETicketBody_V2(const u8 * bytes, size_t len)
{
importBinary(bytes, len);
}
bool es::ETicketBody_V2::operator==(const ETicketBody_V2 & other) const
{
return isEqual(other);
}
bool es::ETicketBody_V2::operator!=(const ETicketBody_V2 & other) const
{
return !isEqual(other);
}
void es::ETicketBody_V2::operator=(const ETicketBody_V2 & other)
{
copyFrom(other);
}
const u8 * es::ETicketBody_V2::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::ETicketBody_V2::getSize() const
{
return mBinaryBlob.getSize();
}
bool es::ETicketBody_V2::isEqual(const ETicketBody_V2 & other) const
{
return (mIssuer == other.mIssuer) \
&& (memcmp(mEncTitleKey, other.mEncTitleKey, kEncTitleKeyLen) == 0) \
&& (mEncType == other.mEncType) \
&& (mTicketVersion == other.mTicketVersion) \
&& (mLicenseType == other.mLicenseType) \
&& (mPreInstall == other.mPreInstall) \
&& (mSharedTitle == other.mSharedTitle) \
&& (mAllowAllContent == other.mAllowAllContent) \
&& (memcmp(mReservedRegion, other.mReservedRegion, kReservedRegionLen) == 0) \
&& (mTicketId == other.mTicketId) \
&& (mDeviceId == other.mDeviceId) \
&& (memcmp(mRightsId, other.mRightsId, kRightsIdLen) == 0) \
&& (mAccountId == other.mAccountId) \
&& (mSectTotalSize == other.mSectTotalSize) \
&& (mSectHeaderOffset == other.mSectHeaderOffset) \
&& (mSectNum == other.mSectNum) \
&& (mSectEntrySize == other.mSectEntrySize);
}
void es::ETicketBody_V2::copyFrom(const ETicketBody_V2 & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
clear();
mIssuer = other.mIssuer;
memcpy(mEncTitleKey, other.mEncTitleKey, kEncTitleKeyLen);
mEncType = other.mEncType;
mTicketVersion = other.mTicketVersion;
mLicenseType = other.mLicenseType;
mPreInstall = other.mPreInstall;
mSharedTitle = other.mSharedTitle;
mAllowAllContent = other.mAllowAllContent;
memcpy(mReservedRegion, other.mReservedRegion, kReservedRegionLen);
mTicketId = other.mTicketId;
mDeviceId = other.mDeviceId;
memcpy(mRightsId, other.mRightsId, kRightsIdLen);
mAccountId = other.mAccountId;
mSectTotalSize = other.mSectTotalSize;
mSectHeaderOffset = other.mSectHeaderOffset;
mSectNum = other.mSectNum;
mSectEntrySize = other.mSectEntrySize;
}
}
void es::ETicketBody_V2::exportBinary()
{
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
body->set_format_version(kFormatVersion);
body->set_issuer(mIssuer.c_str());
body->set_enc_title_key(mEncTitleKey, kEncTitleKeyLen);
body->set_title_key_enc_type(mEncType);
body->set_ticket_version(mTicketVersion);
u8 property_mask = 0;
property_mask |= mPreInstall ? BIT(FLAG_PRE_INSTALL) : 0;
property_mask |= mSharedTitle ? BIT(FLAG_SHARED_TITLE) : 0;
property_mask |= mAllowAllContent ? BIT(FLAG_ALLOW_ALL_CONTENT) : 0;
body->set_property_mask(property_mask);
body->set_reserved_region(mReservedRegion, kReservedRegionLen);
body->set_ticket_id(mTicketId);
body->set_device_id(mDeviceId);
body->set_rights_id(mRightsId);
body->set_account_id(mAccountId);
body->set_sect_total_size(mSectTotalSize);
body->set_sect_header_offset(mSectHeaderOffset);
body->set_sect_num(mSectNum);
body->set_sect_entry_size(mSectEntrySize);
}
void es::ETicketBody_V2::importBinary(const u8 * bytes, size_t len)
{
if (len < sizeof(sTicketBody_v2))
{
throw fnd::Exception(kModuleName, "Header size too small");
}
clear();
mBinaryBlob.alloc(sizeof(sTicketBody_v2));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sTicketBody_v2* body = (sTicketBody_v2*)mBinaryBlob.getBytes();
if (body->format_version() != kFormatVersion)
{
throw fnd::Exception(kModuleName, "Unsupported format version");
}
mIssuer.append(body->issuer(), kIssuerLen);
memcpy(mEncTitleKey, body->enc_title_key(), kEncTitleKeyLen);
mEncType = (TitleKeyEncType)body->title_key_enc_type();
mTicketVersion = body->ticket_version();
mLicenseType = (LicenseType)body->license_type();
mPreInstall = (body->property_mask() & BIT(FLAG_PRE_INSTALL)) == BIT(FLAG_PRE_INSTALL);
mSharedTitle = (body->property_mask() & BIT(FLAG_SHARED_TITLE)) == BIT(FLAG_SHARED_TITLE);
mAllowAllContent = (body->property_mask() & BIT(FLAG_ALLOW_ALL_CONTENT)) == BIT(FLAG_ALLOW_ALL_CONTENT);
memcpy(mReservedRegion, body->reserved_region(), kReservedRegionLen);
mTicketId = body->ticket_id();
mDeviceId = body->device_id();
memcpy(mRightsId, body->rights_id(), kRightsIdLen);
mAccountId = body->account_id();
mSectTotalSize = body->sect_total_size();
mSectHeaderOffset = body->sect_header_offset();
mSectNum = body->sect_num();
mSectEntrySize = body->sect_entry_size();
}
void es::ETicketBody_V2::clear()
{
mBinaryBlob.clear();
mIssuer.clear();
memset(mEncTitleKey, 0, kEncTitleKeyLen);
mEncType = AES128_CBC;
mTicketVersion = 0;
mLicenseType = ES_LICENSE_PERMANENT;
mPreInstall = false;
mSharedTitle = false;
mAllowAllContent = false;
memset(mReservedRegion, 0, kReservedRegionLen);
mTicketId = 0;
mDeviceId = 0;
memset(mRightsId, 0, kRightsIdLen);
mAccountId = 0;
mSectTotalSize = 0;
mSectHeaderOffset = 0;
mSectNum = 0;
mSectEntrySize = 0;
}
const std::string & es::ETicketBody_V2::getIssuer() const
{
return mIssuer;
}
void es::ETicketBody_V2::setIssuer(const std::string & issuer)
{
if (issuer.length() > kIssuerLen)
{
throw fnd::Exception(kModuleName, "Issuer is too long");
}
mIssuer = issuer;
}
const u8 * es::ETicketBody_V2::getEncTitleKey() const
{
return mEncTitleKey;
}
void es::ETicketBody_V2::setEncTitleKey(const u8 * data, size_t len)
{
memset(mEncTitleKey, 0, kEncTitleKeyLen);
memcpy(mEncTitleKey, data, MIN(len, kEncTitleKeyLen));
}
es::ETicketBody_V2::TitleKeyEncType es::ETicketBody_V2::getTitleKeyEncType() const
{
return mEncType;
}
void es::ETicketBody_V2::setTitleKeyEncType(TitleKeyEncType type)
{
mEncType = type;
}
u16 es::ETicketBody_V2::getTicketVersion() const
{
return mTicketVersion;
}
void es::ETicketBody_V2::setTicketVersion(u16 version)
{
mTicketVersion = version;
}
es::ETicketBody_V2::LicenseType es::ETicketBody_V2::getLicenseType() const
{
return mLicenseType;
}
void es::ETicketBody_V2::setLicenseType(LicenseType type)
{
mLicenseType = type;
}
bool es::ETicketBody_V2::isPreInstall() const
{
return mPreInstall;
}
void es::ETicketBody_V2::setIsPreInstall(bool isPreInstall)
{
mPreInstall = isPreInstall;
}
bool es::ETicketBody_V2::isSharedTitle() const
{
return mSharedTitle;
}
void es::ETicketBody_V2::setIsSharedTitle(bool isSharedTitle)
{
mSharedTitle = isSharedTitle;
}
bool es::ETicketBody_V2::allowAllContent() const
{
return mAllowAllContent;
}
void es::ETicketBody_V2::setAllowAllContent(bool allowAllContent)
{
mAllowAllContent = allowAllContent;
}
const u8 * es::ETicketBody_V2::getReservedRegion() const
{
return mReservedRegion;
}
void es::ETicketBody_V2::setReservedRegion(const u8 * data, size_t len)
{
memset(mReservedRegion, 0, kReservedRegionLen);
memcpy(mReservedRegion, data, MIN(len, kReservedRegionLen));
}
u64 es::ETicketBody_V2::getTicketId() const
{
return mTicketId;
}
void es::ETicketBody_V2::setTicketId(u64 id)
{
mTicketId = id;
}
u64 es::ETicketBody_V2::getDeviceId() const
{
return mDeviceId;
}
void es::ETicketBody_V2::setDeviceId(u64 id)
{
mDeviceId = id;
}
const u8 * es::ETicketBody_V2::getRightsId() const
{
return mRightsId;
}
void es::ETicketBody_V2::setRightsId(const u8 * id)
{
memcpy(mRightsId, id, kRightsIdLen);
}
u32 es::ETicketBody_V2::getAccountId() const
{
return mAccountId;
}
void es::ETicketBody_V2::setAccountId(u32 id)
{
mAccountId = id;
}
u32 es::ETicketBody_V2::getSectionTotalSize() const
{
return mSectTotalSize;
}
void es::ETicketBody_V2::setSectionTotalSize(u32 size)
{
mSectTotalSize = size;
}
u32 es::ETicketBody_V2::getSectionHeaderOffset() const
{
return mSectHeaderOffset;
}
void es::ETicketBody_V2::setSectionHeaderOffset(u32 offset)
{
mSectHeaderOffset = offset;
}
u16 es::ETicketBody_V2::getSectionNum() const
{
return mSectNum;
}
void es::ETicketBody_V2::setSectionNum(u16 num)
{
mSectNum = num;
}
u16 es::ETicketBody_V2::getSectionEntrySize() const
{
return mSectEntrySize;
}
void es::ETicketBody_V2::setSectionEntrySize(u16 size)
{
mSectEntrySize = size;
}

219
lib/es/ETicketBody_V2.h Normal file
View file

@ -0,0 +1,219 @@
#pragma once
#include <string>
#include <fnd/memory_blob.h>
#include <fnd/ISerialiseableBinary.h>
#include <crypto/rsa.h>
namespace es
{
class ETicketBody_V2 :
public fnd::ISerialiseableBinary
{
public:
enum TitleKeyEncType
{
AES128_CBC,
RSA2048
};
enum LicenseType
{
ES_LICENSE_PERMANENT = 0,
ES_LICENSE_DEMO = 1,
ES_LICENSE_TRIAL = 2,
ES_LICENSE_RENTAL = 3,
ES_LICENSE_SUBSCRIPTION = 4,
ES_LICENSE_SERVICE = 5,
};
ETicketBody_V2();
ETicketBody_V2(const ETicketBody_V2& other);
ETicketBody_V2(const u8* bytes, size_t len);
bool operator==(const ETicketBody_V2& other) const;
bool operator!=(const ETicketBody_V2& other) const;
void operator=(const ETicketBody_V2& other);
// to be used after export
const u8* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const u8* bytes, size_t len);
// variables
virtual void clear();
const std::string& getIssuer() const;
void setIssuer(const std::string& issuer);
const u8* getEncTitleKey() const;
void setEncTitleKey(const u8* data, size_t len);
TitleKeyEncType getTitleKeyEncType() const;
void setTitleKeyEncType(TitleKeyEncType type);
u16 getTicketVersion() const;
void setTicketVersion(u16 version);
LicenseType getLicenseType() const;
void setLicenseType(LicenseType type);
bool isPreInstall() const;
void setIsPreInstall(bool isPreInstall);
bool isSharedTitle() const;
void setIsSharedTitle(bool isSharedTitle);
bool allowAllContent() const;
void setAllowAllContent(bool allowAllContent);
const u8* getReservedRegion() const;
void setReservedRegion(const u8* data, size_t len);
u64 getTicketId() const;
void setTicketId(u64 id);
u64 getDeviceId() const;
void setDeviceId(u64 id);
const u8* getRightsId() const;
void setRightsId(const u8* id);
u32 getAccountId() const;
void setAccountId(u32 id);
u32 getSectionTotalSize() const;
void setSectionTotalSize(u32 size);
u32 getSectionHeaderOffset() const;
void setSectionHeaderOffset(u32 offset);
u16 getSectionNum() const;
void setSectionNum(u16 num);
u16 getSectionEntrySize() const;
void setSectionEntrySize(u16 size);
private:
const std::string kModuleName = "ES_ETICKET_BODY_V2";
static const size_t kIssuerLen = 0x40;
static const u8 kFormatVersion = 2;
static const size_t kEncTitleKeyLen = crypto::rsa::kRsa2048Size;
static const size_t kReservedRegionLen = 8;
static const size_t kRightsIdLen = 16;
enum PropertyMaskFlags
{
FLAG_PRE_INSTALL,
FLAG_SHARED_TITLE,
FLAG_ALLOW_ALL_CONTENT
};
#pragma pack (push, 1)
struct sTicketBody_v2
{
private:
char issuer_[kIssuerLen];
u8 enc_title_key_[kEncTitleKeyLen];
u8 format_version_;
u8 title_key_enc_type_;
u16 ticket_version_;
u8 license_type_;
u8 common_key_id_;
u8 property_mask_;
u8 reserved_0_;
u8 reserved_region_[kReservedRegionLen]; // explicitly reserved
u64 ticket_id_;
u64 device_id_;
u8 rights_id_[kRightsIdLen];
u32 account_id_;
u32 sect_total_size_;
u32 sect_header_offset_;
u16 sect_num_;
u16 sect_entry_size_;
public:
const char* issuer() const { return issuer_; }
void set_issuer(const char issuer[kIssuerLen]) { strncpy(issuer_, issuer, kIssuerLen); }
const u8* enc_title_key() const { return enc_title_key_; }
void set_enc_title_key(const u8* enc_title_key, size_t len) { memset(enc_title_key_, 0, kEncTitleKeyLen); memcpy(enc_title_key_, enc_title_key, MIN(len, kEncTitleKeyLen)); }
u8 format_version() const { return format_version_; }
void set_format_version(u8 version) { format_version_ = version; }
u8 title_key_enc_type() const { return title_key_enc_type_; }
void set_title_key_enc_type(u8 type) { title_key_enc_type_ = type; }
u16 ticket_version() const { return le_hword(ticket_version_); }
void set_ticket_version(u16 version) { ticket_version_ = le_hword(version); }
u8 license_type() const { return license_type_; }
void set_license_type(u8 license_type) { license_type_ = license_type; }
u8 common_key_id() const { return common_key_id_; }
void set_common_key_id(u8 common_key_id) { common_key_id_ = common_key_id; }
u8 property_mask() const { return property_mask_; }
void set_property_mask(u8 mask) { property_mask_ = mask; }
const u8* reserved_region() const { return reserved_region_; }
void set_reserved_region(const u8* reserved_region, size_t len) { memcpy(reserved_region_, reserved_region, MIN(len, kReservedRegionLen)); }
u64 ticket_id() const { return le_dword(ticket_id_); }
void set_ticket_id(u64 ticket_id) { ticket_id_ = le_dword(ticket_id); }
u64 device_id() const { return le_dword(device_id_); }
void set_device_id(u64 device_id) { device_id_ = le_dword(device_id); }
const u8* rights_id() const { return rights_id_; }
void set_rights_id(const u8 rights_id[kRightsIdLen]) { memcpy(rights_id_, rights_id, kRightsIdLen); }
u32 account_id() const { return le_word(account_id_); }
void set_account_id(u32 id) { account_id_ = le_word(id); }
u32 sect_total_size() const { return le_word(sect_total_size_); }
void set_sect_total_size(u32 size) { sect_total_size_ = le_word(size); }
u32 sect_header_offset() const { return le_word(sect_header_offset_); }
void set_sect_header_offset(u32 offset) { sect_header_offset_ = le_word(offset); }
u16 sect_num() const { return le_hword(sect_num_); }
void set_sect_num(u16 num) { sect_num_ = num; }
u16 sect_entry_size() const { return le_hword(sect_entry_size_); }
void set_sect_entry_size(u16 size) { sect_entry_size_ = le_hword(size); }
};
#pragma pack (pop)
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
std::string mIssuer;
u8 mEncTitleKey[kEncTitleKeyLen];
TitleKeyEncType mEncType; // 0 = aes-cbc, 1 = rsa2048
u16 mTicketVersion;
LicenseType mLicenseType;
u8 kCommonKeyId;
bool mPreInstall;
bool mSharedTitle;
bool mAllowAllContent;
u8 mReservedRegion[kReservedRegionLen]; // explicitly reserved
u64 mTicketId;
u64 mDeviceId;
u8 mRightsId[kRightsIdLen];
u32 mAccountId;
u32 mSectTotalSize;
u32 mSectHeaderOffset;
u16 mSectNum;
u16 mSectEntrySize;
// helpers
bool isEqual(const ETicketBody_V2& other) const;
void copyFrom(const ETicketBody_V2& other);
};
}

View file

@ -0,0 +1,6 @@
#include "ETicketContentRecord_V1.h"
es::ETicketContentRecord_V1::ETicketContentRecord_V1()
{}

View file

@ -0,0 +1,46 @@
#pragma once
#include <string>
#include <fnd/memory_blob.h>
#include <fnd/List.h>
#include <fnd/ISerialiseableBinary.h>
namespace es
{
class ETicketContentRecord_V1 :
public fnd::ISerialiseableBinary
{
public:
ETicketContentRecord_V1();
private:
#pragma pack (push, 1)
struct sContentRecord_v1
{
private:
static const size_t kAccessMaskSize = 0x80;
static const u16 kGroupMask = 0xFC00;
static const u16 kAccessMaskMask = 0x3FF;
u32 group_;
u8 access_mask_[kAccessMaskSize];
public:
u32 index_group() const { return be_word(group_); }
bool is_index_enabled(u16 index) const
{
return (index_group() == get_group(index)) \
&& ((access_mask_[get_access_mask(index) / 8] & BIT(get_access_mask(index) % 8)) != 0);
}
void clear() { memset(this, 0, sizeof(sContentRecord_v1)); }
void set_index_group(u16 index) { group_ = be_hword(get_group(index)); }
void enable_index(u16 index) { access_mask_[get_access_mask(index) / 8] |= BIT(get_access_mask(index) % 8); }
void disable_index(u16 index) { access_mask_[get_access_mask(index) / 8] &= ~BIT(get_access_mask(index) % 8); }
inline u16 get_access_mask(u16 index) const { return index & kAccessMaskMask; }
inline u16 get_group(u16 index) const { return index & kGroupMask; }
};
#pragma pack (pop)
};
}

View file

@ -0,0 +1,161 @@
#include "ETicketSectionHeader_V2.h"
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2()
{}
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2(const ETicketSectionHeader_V2 & other)
{
copyFrom(other);
}
es::ETicketSectionHeader_V2::ETicketSectionHeader_V2(const u8 * bytes, size_t len)
{
importBinary(bytes, len);
}
bool es::ETicketSectionHeader_V2::operator==(const ETicketSectionHeader_V2 & other) const
{
return isEqual(other);
}
bool es::ETicketSectionHeader_V2::operator!=(const ETicketSectionHeader_V2 & other) const
{
return !isEqual(other);
}
void es::ETicketSectionHeader_V2::operator=(const ETicketSectionHeader_V2 & other)
{
copyFrom(other);
}
const u8 * es::ETicketSectionHeader_V2::getBytes() const
{
return mBinaryBlob.getBytes();
}
size_t es::ETicketSectionHeader_V2::getSize() const
{
return mBinaryBlob.getSize();
}
void es::ETicketSectionHeader_V2::exportBinary()
{
mBinaryBlob.alloc(sizeof(sSectionHeader_v2));
sSectionHeader_v2* hdr = (sSectionHeader_v2*)mBinaryBlob.getBytes();
hdr->set_section_offset(mSectionOffset);
hdr->set_record_size(mRecordSize);
hdr->set_section_size(mSectionSize);
hdr->set_record_num(mRecordNum);
hdr->set_section_type(mSectionType);
}
void es::ETicketSectionHeader_V2::importBinary(const u8 * bytes, size_t len)
{
if (len < sizeof(sSectionHeader_v2))
{
throw fnd::Exception(kModuleName, "Binary too small");
}
clear();
mBinaryBlob.alloc(sizeof(sSectionHeader_v2));
memcpy(mBinaryBlob.getBytes(), bytes, mBinaryBlob.getSize());
sSectionHeader_v2* hdr = (sSectionHeader_v2*)mBinaryBlob.getBytes();
mSectionOffset = hdr->section_offset();
mRecordSize = hdr->record_size();
mSectionSize = hdr->section_size();
mRecordNum = hdr->record_num();
mSectionType = (SectionType)hdr->section_type();
}
bool es::ETicketSectionHeader_V2::isEqual(const ETicketSectionHeader_V2 & other) const
{
return (mSectionOffset == other.mSectionOffset) \
&& (mRecordSize == other.mRecordSize) \
&& (mSectionSize == other.mSectionSize) \
&& (mRecordNum == other.mRecordNum) \
&& (mSectionType == other.mSectionType);
}
void es::ETicketSectionHeader_V2::copyFrom(const ETicketSectionHeader_V2 & other)
{
if (other.getSize())
{
importBinary(other.getBytes(), other.getSize());
}
else
{
mBinaryBlob.clear();
mSectionOffset = other.mSectionOffset;
mRecordSize = other.mRecordSize;
mSectionSize = other.mSectionSize;
mRecordNum = other.mRecordNum;
mSectionType = other.mSectionType;
}
}
void es::ETicketSectionHeader_V2::clear()
{
mBinaryBlob.clear();
mSectionOffset = 0;
mRecordSize = 0;
mSectionSize = 0;
mRecordNum = 0;
mSectionType = PERMANENT;
}
u32 es::ETicketSectionHeader_V2::getSectionOffset() const
{
return mSectionOffset;
}
void es::ETicketSectionHeader_V2::setSectionOffset(u32 offset)
{
mSectionOffset = offset;
}
u32 es::ETicketSectionHeader_V2::getRecordSize() const
{
return mRecordSize;
}
void es::ETicketSectionHeader_V2::setRecordSize(u32 size)
{
mRecordSize = size;
}
u32 es::ETicketSectionHeader_V2::getSectionSize() const
{
return mSectionSize;
}
void es::ETicketSectionHeader_V2::getSectionSize(u32 size)
{
mSectionSize = size;
}
u16 es::ETicketSectionHeader_V2::getRecordNum() const
{
return mRecordNum;
}
void es::ETicketSectionHeader_V2::setRecordNum(u16 record_num)
{
mRecordNum = record_num;
}
es::ETicketSectionHeader_V2::SectionType es::ETicketSectionHeader_V2::getSectionType() const
{
return mSectionType;
}
void es::ETicketSectionHeader_V2::setSectionType(SectionType type)
{
mSectionType = type;
}

View file

@ -0,0 +1,101 @@
#pragma once
#include <string>
#include <fnd/memory_blob.h>
#include <fnd/ISerialiseableBinary.h>
namespace es
{
class ETicketSectionHeader_V2 :
public fnd::ISerialiseableBinary
{
public:
enum SectionType
{
PERMANENT = 1,
SUBSCRIPTION = 2,
CONTENT = 3,
CONTENT_CONSUMPTION = 4,
ACCESS_TITLE = 5,
LIMITED_RESOURCE = 6,
};
ETicketSectionHeader_V2();
ETicketSectionHeader_V2(const ETicketSectionHeader_V2& other);
ETicketSectionHeader_V2(const u8* bytes, size_t len);
bool operator==(const ETicketSectionHeader_V2& other) const;
bool operator!=(const ETicketSectionHeader_V2& other) const;
void operator=(const ETicketSectionHeader_V2& other);
// to be used after export
const u8* getBytes() const;
size_t getSize() const;
// export/import binary
virtual void exportBinary();
virtual void importBinary(const u8* bytes, size_t len);
// variables
virtual void clear();
u32 getSectionOffset() const;
void setSectionOffset(u32 offset);
u32 getRecordSize() const;
void setRecordSize(u32 size);
u32 getSectionSize() const;
void getSectionSize(u32 size);
u16 getRecordNum() const;
void setRecordNum(u16 record_num);
SectionType getSectionType() const;
void setSectionType(SectionType type);
private:
const std::string kModuleName = "ETICKET_SECTION_HEADER_V2";
#pragma pack (push, 1)
struct sSectionHeader_v2
{
private:
u32 section_offset_;
u32 record_size_;
u32 section_size_;
u16 record_num_;
u16 section_type_;
public:
u32 section_offset() const { return le_word(section_offset_); }
void set_section_offset(u32 offset) { section_offset_ = le_word(offset); }
u32 record_size() const { return le_word(record_size_); }
void set_record_size(u32 size) { record_size_ = le_word(size); }
u32 section_size() const { return le_word(section_size_); }
void set_section_size(u32 size) { section_size_ = le_word(size); }
u16 record_num() const { return le_hword(record_num_); }
void set_record_num(u16 num) { record_num_ = le_hword(num); }
u16 section_type() const { return le_hword(section_type_); }
void set_section_type(u16 type) { section_type_ = le_hword(type); }
};
#pragma pack (pop)
// raw binary
fnd::MemoryBlob mBinaryBlob;
// variables
u32 mSectionOffset;
u32 mRecordSize;
u32 mSectionSize;
u16 mRecordNum;
SectionType mSectionType;
// helpers
bool isEqual(const ETicketSectionHeader_V2& other) const;
void copyFrom(const ETicketSectionHeader_V2& other);
};
}

133
lib/es/es.vcxproj Normal file
View file

@ -0,0 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7BE99936-0D40-410D-944B-4513C2EFF8DC}</ProjectGuid>
<RootNamespace>es</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>libes</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ETicketBody_V2.h" />
<ClInclude Include="ETicketContentRecord_V1.h" />
<ClInclude Include="ETicketSectionHeader_V2.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ETicketBody_V2.cpp" />
<ClCompile Include="ETicketContentRecord_V1.cpp" />
<ClCompile Include="ETicketSectionHeader_V2.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

42
lib/es/es.vcxproj.filters Normal file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="ETicketBody_V2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ETicketSectionHeader_V2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ETicketContentRecord_V1.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ETicketBody_V2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ETicketSectionHeader_V2.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ETicketContentRecord_V1.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

33
lib/es/makefile Normal file
View file

@ -0,0 +1,33 @@
# Sources
SRC_DIR = .
OBJS = $(foreach dir,$(SRC_DIR),$(subst .cpp,.o,$(wildcard $(dir)/*.cpp))) $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c)))
INC_DIR = ..
INCS = $(foreach dir,$(INC_DIR), -I"$(dir)/")
# Compiler Settings
CXXFLAGS = -std=c++11 $(INCS) -D__STDC_FORMAT_MACROS -Wall -Wno-unused-but-set-variable -Wno-unused-value
ifeq ($(OS),Windows_NT)
# Windows Only Flags/Libs
CC = x86_64-w64-mingw32-gcc
CXX = x86_64-w64-mingw32-g++
CFLAGS +=
CXXFLAGS +=
else
# *nix Only Flags/Libs
CFLAGS +=
CXXFLAGS +=
endif
# Output
OUTPUT = ../lib$(shell basename $(CURDIR)).a
main: build
rebuild: clean build
build: $(OBJS)
ar cr -o $(OUTPUT) $(OBJS)
clean:
rm -rf $(OUTPUT) $(OBJS)

View file

@ -204,4 +204,7 @@
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
</Project> </Project>

View file

@ -1,4 +1,4 @@
PROGS = ncatool npdmtool pfstool PROGS = ncatool npdmtool pfstool tiktool
main: build main: build

33
programs/tiktool/main.cpp Normal file
View file

@ -0,0 +1,33 @@
#include <cstdio>
#include <crypto/aes.h>
#include <fnd/io.h>
#include <fnd/memory_blob.h>
#include <es/ETicketBody_V2.h>
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("usage: tiktool <file>\n");
return 1;
}
try
{
fnd::MemoryBlob file;
fnd::io::readFile(argv[1], file);
// import
es::ETicketBody_V2 body;
body.importBinary(file.getBytes() + 0x140, file.getSize() - 0x140);
printf("Issuer: %s\n", body.getIssuer().c_str());
} catch (const fnd::Exception& e)
{
printf("%s\n", e.what());
}
return 0;
}

39
programs/tiktool/makefile Normal file
View file

@ -0,0 +1,39 @@
# Sources
SRC_DIR = .
OBJS = $(foreach dir,$(SRC_DIR),$(subst .cpp,.o,$(wildcard $(dir)/*.cpp))) $(foreach dir,$(SRC_DIR),$(subst .c,.o,$(wildcard $(dir)/*.c)))
#local dependencies
DEPENDS = es crypto fnd
LIB_DIR = ../../lib
LIBS = -L"$(LIB_DIR)" $(foreach dep,$(DEPENDS), -l"$(dep)")
INCS = -I"$(LIB_DIR)/"
OUTPUT = ../../bin/$(shell basename $(CURDIR))
# Compiler Settings
CXXFLAGS = -std=c++11 $(INCS) -D__STDC_FORMAT_MACROS -Wall -Wno-unused-but-set-variable -Wno-unused-value
ifeq ($(OS),Windows_NT)
# Windows Only Flags/Libs
CC = x86_64-w64-mingw32-gcc
CXX = x86_64-w64-mingw32-g++
CFLAGS +=
CXXFLAGS +=
LIBS += -static
else
# *nix Only Flags/Libs
CFLAGS +=
CXXFLAGS +=
LIBS +=
endif
all: build
rebuild: clean build
build: $(OBJS)
$(CXX) $(OBJS) $(LIBS) -o $(OUTPUT)
clean:
rm -rf $(OBJS) $(OUTPUT)

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{2200B834-F15A-4C6E-9DDB-6012B9A5C246}</ProjectGuid>
<RootNamespace>tiktool</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\lib</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="makefile" />
</ItemGroup>
</Project>