//---------------------------------------------------------------------------
#include <windows.h>
//---------------------------------------------------------------------------

/*
	このプロジェクトは、XP3 アーカイブに格納されるファイルを暗号化する
	サンプルです。
	暗号化は復号化時にパフォーマンス上の障害とならない程度に単純である
	必要があります。
	また、仕様上、復号関数 (TVPSetXP3ArchiveExtractionFilter で指定する
	関数) は、一つのファイルに対し、任意のオフセットとサイズを伴って呼び
	出され、復号化は一回の呼び出し内で完結しなければなりません。つまり、
	その境界をまたがるような復号化、たとえばバイトの順序を入れ替えたり、
	前の入力バイトに依存した復号化処理は行うことができません。
	これは、暗号化関数にも言えます。
	現実的には、バイトごとの XOR や 加算、減算程度のみ使用可能と考えてくだ
	さい。
	ただし、ファイル中におけるオフセットとファイルごとにほぼ異なる値(ハッ
	シュ値)が与えられるので、ファイル中のオフセットに応じて局所的に暗号化
	をかけたり、ファイルのハッシュを利用してファイルごとに異なる暗号化を
	かけたりが可能です。

	暗号化を行えば、対応する復号化吉里吉里用プラグインを用いなければ
	XP3 アーカイブを読み込めなくなります。つまり、将来的に吉里吉里本体が
	Windows 以外に移植され、その作品が他プラットフォームで動く可能性を、
	かなり否定することになります。

	保護を行う要求が、作品の公開性と可搬性を上回る場合にご使用ください。

	この DLL の名前は xp3enc.dll である必要があります。また、Releaser
	(krkrrel.exe) と同じフォルダに配置される必要があります。
*/


//---------------------------------------------------------------------------
//#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
	// DLL エントリポイント
	return 1;
}
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
/*
	ファイルを暗号化する関数を定義します。関数名は
	XP3ArchiveAttractFilter_v の後にこの関数の用いるインターフェース
	バージョンを指定します。
	現在のインターフェースバージョンは 2 です。
	(バージョン1は吉里吉里２ 2.23 beta1 より使用不可になりました)
	呼び出し規約には必ず _stdcall を用います。
	ここで指定した関数名は、かならず .def ファイル中の exports 節に書き、
	DLL からエクスポートする必要があります。
*/
extern "C" void __stdcall XP3ArchiveAttractFilter_v2(
	unsigned __int32 hash,
	unsigned __int64 offset, void * buffer, long bufferlen)
{
	// バージョン 2 関数は以下の引数を受け取ります。
	// hash      : 入力ファイルの(暗号化解除時の)32bitハッシュです。
	// offset    : "buffer" 引数が示すデータが、ファイルの先頭から何バイト目
	//             であるか (ファイルが圧縮される場合、無圧縮の状態のバイト
	//             オフセットです )
	// buffer    : 対象となるデータです。ファイルが圧縮される場合は、圧縮され
	//             る前のデータです。
	//             ( ファイルが圧縮された後のデータにこの関数で変更を加えるこ
	//             とは出来ません )
	// bufferlen : "buffer" 引数が表すデータの長さです。

	// しかしここではサンプルとして、hash の最下位バイトを XOR する方法を
	// 示します。

	int i;
	for(i = 0; i < bufferlen; i++) ((unsigned char*)buffer)[i] ^= hash;

}
//---------------------------------------------------------------------------

