/* sue445謹製アーカイブシステム WakanaArc Ver0.01 http://www.sue445.net/ sue4455t@hotmail.com ●ファイル構成 ・WakanaArcSDK.lib :アーカイブライブラリ(VC++6.0以外では動作未確認) ・WakanaArcSDK.h :インクルードヘッダ&説明書(このファイルです) ・WakanaArc.dll :WakanaArcSDK.libのDLL版 ・makearc.exe :ドラッグしたフォルダを丸ごとWakanaArc形式でアーカイブします ・axwakana.spi :WakanaArcに対応したSusieプラグイン ・readme.txt :リードミー。WakanaArcSDK.hを見るように促すだけ(笑) ●特徴 1.任意に設定するパスワードで暗号化を施すので、第三者には絶対に中身を見られることがない。 パスワードは0〜4294967295までの数値(要はDWORDのとりうる範囲)で指定可能 2.アーカイブの中身はファイルごとに完全に独立しているので、 同じバイナリ・同じパスワードで圧縮するかぎりは同じバイナリが出力される。 つまり、バージョンアップの際にWDiffのような差分作成ツールが使えるということ。 3.jpegやpngのように元から圧縮がかかっている場合でもパスワードに応じて暗号化がかかる 4.アーカイブファイルの先頭4バイト部分(WakanaArcではヘッダIDと呼称)を自由に設定 できるので、そもそもWakanaArcでアーカイブしているということすら分からない(笑) ●使い方・その1(ライブラリを内包する(推奨)) このファイル(WakanaArcSDK.h)とWakanaArc.libをプロジェクトに加え、 適当にWakanaArcSDK.hをインクルードする。 ●使い方・その2(DLLで動的リンクする(C/C++以外から使用する人むけ)) プログラムの内部で適当にWakanaArc.dllにリンクする。 ただし、プログラムの内部でLoadLibraryとFreeLibraryを何回も繰り返すと DLL内部のキャッシュ情報(後述)もその都度解放されてしまうので、LoadLibraryと FreeLibraryはプログラムの最初と最後だけにしておいてください。 (Basic系言語のDeclareを使う場合はこの心配はありません) 関数の詳しい説明についてはこのファイル(WakanaArcSDK.h)の下の方をご覧ください ●仕様や注意点など ・1つのアーカイブの中に含めることのできるファイル数は65535までです これを超えるとWkArcCompress時にエラーが返ります ・makearc.exeなりWkArcCompressで圧縮した場合、圧縮した時のフォルダ名がパスの先頭に つきます。例えばarcフォルダからarc.datを作成した場合、 arcフォルダ内のversion.txtを呼び出す場合のパスは"arc/version.txt"となります。 ・アーカイブ内のファイルはメモリに展開されます。ファイル書き出しなんて スマートじゃないし、HDDにアクセスする分プログラムの実行速度にも影響を及ぼすので ハナから未実装です(爆) どうしてもファイル書き出しが必要な場合は自前で用意してください。 ・メモリに展開されたファイルを実際に使用するためのインターフェースはやっぱり 自前で用意してください(メモリに展開したwaveをDirectSoundに渡して音を鳴らすとか) ・makearc.exeとaxwakana.spiはWakanaArcSDK.libを内包しているので、単体で動作します また、この2つでWakanaArc.iniという共通の設定ファイルを使用することができます このファイルはmakearc.exeかaxwakana.spiのどちらかを一度でも起動すると作成されます。 ・WakanaArc.ini内の[NoCompressExt]には、デフォルトで圧縮しない拡張子を列挙しています。 (詳しくはWkArcCompressの項にて) makearc.exe起動時の初期設定 [NoCompressExt] Ext00=mp3 Ext01=ogg Ext02=jpg Ext03=jpeg Ext04=png Ext05=gif Ext06=mpg Ext07=mpeg 必要に応じて拡張子を追加するなり削除するなりしてください。WakanaArc.iniはmakearc.exe 起動時に一度しか読み込まれないので、makearc.exeが起動していない時にWakanaArc.ini を編集してください(makearc.exe起動時に編集すると終了時に編集前のやつが上書きされてしまうので) ただしツールの関係上、この拡張子はExt00〜Ext99の計100個までしか定義できません (普通は100個もあれば十分かと^^;) ・axwakana.spiを使用する前にはSusieのプラグイン設定ダイアログでパスワードと ヘッダIDを設定しておいてください ・libは動作確認してますが、DLLは動作確認してないので外部から関数を実際に呼び出せるか どうか微妙です(^^; (Susieプラグイン製作の時と同じようにexport.defを書いたので問題ないとは思いますが、、、) ・「WakanaArc」の名前の由来は、自分の萌えキャラの名前をつけただけです(笑) ●著作権について この「WakanaArc」の著作権はsue445にあります。 「アーカイブファイル単体での解析は不可能」ということをウリにしている(笑)ので、 WakanaArc.libのソースファイルの公開には応じません (GPLとかLGPLとかいったわずらわしいものは一切使用していませんのでご心配なく) ●使用条件について このWakanaArcはフリーウェアなので使用に関してもフリーウェアと同等に考えてもらって けっこうですが、細かいことをいくつか書いておきます。 ・商用、非商用問わず自由に使用可 ・DLLの付属やLibを内包した実行ファイルの公開なども同様に自由。ただし、それ以外の ファイル(WakanaArcSDK.hやWakanaArcSDK.libなど)を単体で公開するのは禁止。 DLLを付属する場合は解析対策にファイル名を変えておいた方がいいかもしれません(ぉ ・こちらへの連絡は任意。その場合も「こんなゲーム作りました〜」みたいな事後連絡程度 で構いません。ついでに開発・動作環境(OSやコンパイラなど)も教えてもらえれば いろいろと助かります(^^; ・ドキュメント等への「sue445氏の『WakanaArc』というライブラリを使用しています」 といった著作権情報の表記も自由です。ただし、表記する場合はこちらへご一報ください。 (自分の知らないところで勝手に名前を使われているというのもアレですので^^;) 逆に言えば、僕の名前さえ表に出さなければ連絡不用でOKということです(笑) ●開発履歴 Ver0.01:2005/04/02 ・初版 */ #ifndef _INC_WAKANAARCSDK // 2回読むな(笑) #define _INC_WAKANAARCSDK // 「Windows.h」の不要項目を除外 #define WIN32_LEAN_AND_MEAN // 最低限windows.hだけは必要 #include // ここからlibコンパイル時のみに使用するコード ///////////////////////////////////////////////////////// // 普通のLIBを作る #ifndef MAKE_DLL # ifndef DLLEXPORT # define DLLEXPORT # endif # ifndef STDCALL # define STDCALL # endif // DLL用のLIBを作る #else # ifndef DLLEXPORT # define DLLEXPORT __declspec(dllexport) # endif # ifndef STDCALL # define STDCALL __stdcall # endif #endif ///////////////////////////////////////////////////////// // ここまで // エラー番号 #define WAR_ALL_RIGHT 0 // 正常終了 #define WAR_NO_DIR 1 // 送られた文字列がディレクトリ名じゃない(圧縮時専用) #define WAR_OVER_FILE 2 // ファイルが多すぎる。1つのアーカイブには最大65535まで(圧縮時専用) #define WAR_FILE_WRITE_ERROR 3 // ファイル書き出しエラー(圧縮時専用) #define WAR_FILE_READ_ERROR 4 // ファイル読み込みエラー #define WAR_DECODE_ERROR 5 // 展開エラー #define WAR_NO_MATCH_HEADER_ID 6 // ヘッダIDが一致しない #define WAR_OVER_CACHE 7 // キャッシュに入りきらない #define WAR_FILE_NOT_FOUND 8 // ファイルが見つからない // ここからWakanaArcの関数 ///////////////////////////////////////////////////////// // 指定したディレクトリ以下を圧縮して1つのアーカイブファイルにします(ファイル単体での圧縮は不可) int DLLEXPORT STDCALL WkArcCompress(char* szDir, char cHeaderID[4], DWORD dwPassword, char* szExt="dat", char** szNoCompExt=NULL, HWND hOwner=NULL); /* szDir :圧縮するディレクトリ cHeaderID[4]:ファイル先頭部に書き込むヘッダID(4バイト以内) dwPassword :アーカイブにかけるパスワード。 0〜4294967295までの数値を指定可能(要はDWORDのとりうる範囲) アーカイブ全体をXORマスクなんて生ぬるいものではありません(笑) 前述のヘッダIDとパスワードが一致していないとファイルは展開できません szExt :生成するアーカイブファイルの拡張子(省略時はdat) 拡張子を使いたくない場合は NULL(または "")にしておいてください アーカイブファイルは szDir+szExt の形式で出力されます szNoCompExt :圧縮しない拡張子のリストを設定します。すでに圧縮されているような形式(jpegやpngなど)を 設定するといいかもしれません。ここで指定した拡張子を持つファイルに対しては始めから 圧縮を試みないので、圧縮時はもちろんのこと展開時も'理論上は'動作が速くなるはずです。 基本的にいくつ設定しても構いませんが、終端部は必ず NULL(または "")にしてください 例) char* szExt[] = {"mp3", "ogg", "jpg", "png", NULL}; hOwner :途中経過を表示するウィンドウ(「12/30」のように表示)。 テキストコントロールやEDITコントロールなどを指定してください。 省略すると途中経過の表示をしません。 コールバック関数を使ってない時点で相当手抜きです(爆) 戻り値 :正常終了時は0が返る。エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) */ // アーカイブファイルに含まれるファイルのリストをキャッシュに読み込みます // 一度キャッシュにファイルリストをキャッシュしておけば、WkArcGetFile_Cacheで手軽に呼び出せます // (WkArcGetFile_Fileはその都度ヘッダIDとパスワードが必要なので面倒くさい^^;) // キャッシュできるアーカイブファイルは計100個 int DLLEXPORT STDCALL WkArcReadCache(char* szArcFile, char cHeaderID[4], DWORD dwPassword); /* szArcFile :読み込むアーカイブファイル(絶対パスと相対パスのどちらでも可) cHeaderID[4]:アーカイブファイルのヘッダID(WkArcCompressで指定したのと同じもの) dwPassword :アーカイブファイルにかけられたパスワード(WkArcCompressで指定したのと同じもの) 戻り値 :正常終了時は0が返る。エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) すでにキャッシュされている場合は0が返る */ // ファイルを展開する // 検索対象は事前にWkArcReadCacheで読み込んだ全アーカイブファイル int DLLEXPORT STDCALL WkArcGetFile_Cache(char* szName, BYTE*& lpDst, DWORD* dwDstSize); /* szName :展開するファイル。呼び出す時のファイル名は以下を参照に。 正) "data/hoge.bmp" "data/Koumakan/Sakuya.jpg" 誤) "./data/hoge.bmp" (文字列の先頭に余計なものがついてる) "data\\Koumakan\\Sakuya.jpg"(\\には非対応。ていうか、いちいち\\と入力するのが めんどいのできりました(爆)) 先にも書いたとおり、圧縮時に元のフォルダ名がつくので忘れないようにしてください。 lpDst :ファイルを展開する場所。メモリ領域は内部で勝手に確保されます 必要がなくなったら delete[] lpDst してください (C/C++以外の場合は後述の WkArcRelease を使ってください) dwDstSize :lpDstのバッファサイズ 戻り値 :正常終了時は0が返る。エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) */ // ファイルを展開する // 検索対象はszArcFileで指定したアーカイブファイルのみ int DLLEXPORT STDCALL WkArcGetFile_File(char* szName, BYTE*& lpDst, DWORD* dwDstSize, char* szArcFile, char cHeaderID[4], DWORD dwPassword); /* szName :展開するファイル。呼び出す時のファイル名は以下を参照に。 正) "data/hoge.bmp" "data/Koumakan/Sakuya.jpg" 誤) "./data/hoge.bmp" (文字列の先頭に余計なものがついてる) "data\\Koumakan\\Sakuya.jpg"(\\には非対応。ていうか、いちいち\\と入力するのが めんどいのできりました(爆)) 先にも書いたとおり、圧縮時に元のフォルダ名がつくので忘れないようにしてください。 lpDst :ファイルを展開する場所。メモリ領域は内部で勝手に確保されます 必要がなくなったら delete[] lpDst してください (C/C++以外の場合は後述の WkArcRelease を使ってください) dwDstSize :lpDstのバッファサイズ szArcFile :読み込むアーカイブファイル(絶対パスと相対パスのどちらでも可) cHeaderID[4]:アーカイブファイルのヘッダID(WkArcCompressで指定したのと同じもの) dwPassword :アーカイブファイルにかけられたパスワード(WkArcCompressで指定したのと同じもの) 戻り値 :正常終了時は0が返る。エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) */ // WkArcReadCacheで読み込んだキャッシュの中にszNameがあるかどうか調べます int DLLEXPORT STDCALL WkArcSearchCache(char* szName); /* szName :探すファイル。呼び出す時のファイル名は以下を参照に。 正) "data/hoge.bmp" "data/Koumakan/Sakuya.jpg" 誤) "./data/hoge.bmp" (文字列の先頭に余計なものがついてる) "data\\Koumakan\\Sakuya.jpg"(\\には非対応。ていうか、いちいち\\と入力するのが めんどいのできりました(爆)) 先にも書いたとおり、圧縮時に元のフォルダ名がつくので忘れないようにしてください。 戻り値 :szNameが見つかれば1(TRUE)を、見つからなければ0(FALSE)を返す */ // szArcFileの中にszNameがあるかどうか調べます int DLLEXPORT STDCALL WkArcSearchFile(char* szName, char* szArcFile, char cHeaderID[4], DWORD dwPassword); /* szName :探すファイル。呼び出す時のファイル名は以下を参照に。 正) "data/hoge.bmp" "data/Koumakan/Sakuya.jpg" 誤) "./data/hoge.bmp" (文字列の先頭に余計なものがついてる) "data\\Koumakan\\Sakuya.jpg"(\\には非対応。ていうか、いちいち\\と入力するのが めんどいのできりました(爆)) 先にも書いたとおり、圧縮時に元のフォルダ名がつくので忘れないようにしてください。 szArcFile :読み込むアーカイブファイル(絶対パスと相対パスのどちらでも可) cHeaderID[4]:アーカイブファイルのヘッダID(WkArcCompressで指定したのと同じもの) dwPassword :アーカイブファイルにかけられたパスワード(WkArcCompressで指定したのと同じもの) 戻り値 :szNameが見つかれば1(TRUE)を、見つからなければ0(FALSE)を返す */ // WakanaArc形式で圧縮する // セーブデータやリプレイデータのように単体で圧縮&暗号したい場合に void DLLEXPORT STDCALL WkArcEncode(BYTE* lpSrc, BYTE*& lpDst, DWORD dwSrcSize, DWORD* dwDstSize, DWORD dwPassword, BOOL bNoComp=FALSE); /* lpSrc :圧縮元のバッファ(非圧縮データ) lpDst :圧縮先のバッファ(圧縮データ) メモリ領域は内部で勝手に確保されます 必要がなくなったら delete[] lpDst してください (C/C++以外の場合は後述の WkArcRelease を使ってください) dwSrcSize :lpSrcのバッファサイズ dwDstSize :lpDstのバッファサイズ bNoComp :圧縮を実行しないで、暗号化処理だけを行う場合はTRUE(1)を指定してください。 そうでない(圧縮を実行する)場合はFALSE(0)を設定してください。省略時はFALSEです。 */ // WkArcEncodeで圧縮したバッファを展開する int DLLEXPORT STDCALL WkArcDecode(BYTE* lpSrc, BYTE*& lpDst, DWORD dwSrcSize, DWORD dwDstSize, DWORD dwPassword); /* lpSrc :圧縮元のバッファ(圧縮データ) lpDst :圧縮先のバッファ(非圧縮データ) メモリ領域は内部で勝手に確保されます 必要がなくなったら delete[] lpDst してください (C/C++以外の場合は後述の WkArcRelease を使ってください) dwSrcSize :lpSrcのバッファサイズ dwDstSize :lpDstのバッファサイズ 戻り値 :正常終了時は0が返る。エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) */ // アーカイブファイルの中身が不正に書き換えられてないか調べる // ファイル総数によっては微妙に時間がかかる場合があるカモ(汗 int DLLEXPORT STDCALL WkArcAllCheck(char* szArcFile, char cHeaderID[4], DWORD dwPassword); /* szArcFile :読み込むアーカイブファイル(絶対パスと相対パスのどちらでも可) cHeaderID[4]:アーカイブファイルのヘッダID(WkArcCompressで指定したのと同じもの) dwPassword :アーカイブファイルにかけられたパスワード(WkArcCompressで指定したのと同じもの) 戻り値 :正常終了時(バイナリは不正に書き換えられてない)は0が返る。 エラー時は非0が返る(詳しくは冒頭のエラー番号を参照のこと) バイナリが不正に書き換えられている可能性がある場合はWAR_DECODE_ERRORが返ります ヘッダIDやパスワードを間違えていてもやっぱりエラーが返ってくるのでご注意あれ */ // WkArcGetFile_Cache や WkArcGetFile_File で確保したメモリを解放する // 内部で delete[] lpBuffer してるだけなので、C/C++の人は直接deleteしてもらっていいかと(^^; // あくまで、C/C++以外からDLLとして呼び出した場合の救済策 void DLLEXPORT STDCALL WkArcRelease(BYTE* lpBuffer); /* lpBuffer :解放するメモリ */ #endif