﻿//`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`
//              reces by x@rgs
//              under NYSL Version 0.9982
//
//`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`~^`

・ソースコードについて
 under NYSL Version 0.9982ですが、初心者が書いたものですので、
 見れたものではありません。参考になるような情報もありません。
 ライセンスの条文については同梱の「NYSL_withfaq.TXT」をご覧下さいませ。
 ただし、各書庫ライブラリについてはそれぞれのライセンスに従いますのでご注意下さいませませ。


・コンパイル方法
   ソリューションファイル「reces.sln」を開き、「ビルド」->「ソリューションのビルド」をクリックして下さい。


・備忘録
   http://frostmoon.sakura.ne.jp/diary/ に詳細あり。今すぐアクセス!


 [Ver.0.00r34]
     ・「～.part1.rar」及び「～.rar」「～.r00」に関する処理を追加しました。今まで全く考慮していませんでした。
     ・分割LZH書庫等の処理が全く出来なかった不具合を修正しました。
       ファイルの結合をしながらも、処理するライブラリの確定を分割されたままのファイルで行っていました。

 [Ver.0.00r33]
     ・7-Zipの仕様変更で「--」以降だとリストファイル指定「@list_file」ができなくなりました。
       history.txt内、「--」以前に「-i@list_file」で指定してねとあるけれども...違う、そうじゃない。
       現在は「--」ではなく、必ず「"」で囲むことで「-」から始まるファイル名に対応しています。
     ・/mn,/mNで置換結果を前もって知るため「/T」を実装。置換前・置換後のファイル名を出力します。
       これで君も正規表現マスターだ!!
       同オプションで、「/mc」「/me」のリストファイル出力も実装予定でしたが、不要と判断。
     ・Console::outputString()は常に引数を可変長として処理していたため、文字列に「%n」が含まれると強制終了してしまっていました。
     ・プラグイン側が設定していないコールバックを呼び出そうとするWCXがあったため対応。
     ・LZH自己解凍書庫の作成でおかしな引数を指定していたため正常に作成できない不具合を修正。(r10からの不具合。r5～r9では正しく実装されていました^q^)

 [Ver.0.00r32]
     ・正規表現ライブラリをVC++のregexに変更。
     ・「/mn」「/mN」で指定する置換条件について、/mn,/mN以下の引数で省略すると、処理前に入力を求めるように。
       引数で指定するとエスケープが面倒なので実装^q^

 [Ver.0.00r31]
     ・パスワード入力処理を_fgetts()で行っていたため、日本語が使用できない不具合修正。
       ReadConsole()で処理するように。
     ・入力処理を全てWINAPIで行うようになったので、freopen()をCloseFile()/CreateFile()/SetStdHandle()に置き換え。
     ・Ctrl+Cで処理を強制終了すると、Reces::ctrlCEvent()内でプログレスバー破棄処理でフリーズしてしまう不具合を修正。
       正常終了時はpost()しますが、Ctrl+Cであれば、その場でdeleteするようにしました。
     ・書庫内ファイルをリネームする「/mn」追加。
     ・PasswordDialog::onOk()の引数にWPARAMとLPARAMを追加し忘れていたため、gui4recesでログウインドウを表示するとパスワード入力が処理されない不具合修正。

 [Ver.0.00r30]
     ・一部環境では、_tsetlocale(LC_ALL,_tsetlocale(LC_CTYPE,_T("")))でフリーズしてしまうらしい。
     ・lz4圧縮のため、「/ooke」オプションを追加。
     ・7z.dll対応版7-zip32.dll/7-zip64.dllをサポート。そのため、Total7zip.wcx/Total7zip.wcx64の導入は非推奨に。

 [Ver.0.00r29]
     ・UnhookWindowsHookEx()後のSendMessageTimeout()をPostMessage()に。
     ・fileoperation::createDirectory()内で'\\?\'を付加して処理していたため、
       例えば、「reces /me /c "arc  .zip"」とすると末尾にスペースを含む無効なディレクトリ「arc  」も作成されていた問題を解消。
     ・	7-zip32.dll系ライブラリについて、-oで指定するディレクトリにスペースが2つ以上含まれると1つに削られてしまうため、
        予めSetCurrentDirectory()で移動するように。
     ・7-zip32.dllを使用する形式で/mCするとディレクトリ構造を無視した内容と構造を維持した内容が重複して圧縮される不具合を修正。(r13からの不具合...)
     ・b2e32.dllを利用した圧縮だと作成する書庫名が分からないのが痛い。
     ・b2e32.dllによる圧縮では異なる階層のファイルを同時に圧縮できないため、/mCは対応しないことに。
     ・b2e32.dllでのフィルタ利用は見送り。
     ・b2e32.dllを単純64bit化し、同梱。
     ・zip書庫文字化け対策のため、同梱の7-zip32.dllについてmlangを使用するように修正。
       自動選択(50001,_autodetect_all)で正しく判定されない書庫は、
       オプション「-mcp」 or SetUnicodeMode(BOOL)で文字コード指定。
     ・コンパイラをMicrosoft Visual C++ 2015に変更。


 [Ver.0.00r28]
     ・rar書庫でディレクトリ階層を無視した解凍が出来ない不具合を修正しました。(r12からの不具合^q^)
     ・プログレスバーの更新が分を跨ぐと止まる不具合を修正しました。
     ・書庫の構造によってはフィルタ処理で関係のないディレクトリが除外される不具合を修正。
       #FileInfo.cppのFileTree、書き直さないと...
     ・/mtで対象書庫にライブラリ対応確認を行う処理一部復活。阿呆な処理ではなかった。
     ・既存ファイルがあれば圧縮前に予め削除する「/NF」オプションを実装。
       誤った拡張子を持つ書庫の再圧縮に対応するため。判断をユーザ様に投げる残念仕様。
     ・統合アーカイバプロジェクトでunrar32.dll Ver.0.17が公開されたため、unrar32.dll/unrar64j.dllの同梱を中止しました。


 [Ver.0.00r27]
     ・/UESCオプションを削除。文字化けzipについては文字化け対策版7-zip32.dllがあれば大丈夫!!!
     ・プログレスバーの更新頻度を100ms程度に。処理が(少しだけ)高速化。
       他の解凍ソフトより速くなった!?
     ・書庫からファイルを削除する「/md」追加。
     ・↑のため、「/mr」で削除コマンドは使用しないように。
     ・gui4reces Ver.0.0.1.4のログウインドウ表示に対応するため、パスワード入力ダイアログをこっそり実装。
       環境変数PASSWORD_DIALOGに親にしたいダイアログのハンドルを代入すると表示されます。
     ・Ctrl+Cで偶に落ちる問題(DlgHook.dllが原因)はLibraryクラスを使用することで解決?FreeLibrary()のタイミングが遅くなったから?
     ・ヘッダ暗号化7z書庫の/mlが出来なかった不具合修正。パスワードを事前に設定するArc7zip32::isSupportedArchive()が呼ばれていなかった。
     ・gui4reces Ver.0.0.1.4のログウインドウ表示に対応するため、パスワード入力ダイアログに対してShowWindow(SW_SHOWNA)するように。(ax7z_s.spi対策)


 [Ver.0.00r26]
     ・/LARGEADDRESSAWAREオプションを付加、32bit版で2GB以上のメモリが使用出来るように。
     ・tar32.dll/unrar32.dll/XacRett.dllでFileInfo.cpp内のマッチ判定関数を呼び出していたため、
       /i:ad及び/x:adが反映されない悲しい不具合発見。
       ->FileTreeを使用するように。
     ・そもそも、この二つのフィルタが正しく処理されていたことがあったのかどうか...^^;
     ・unrar32.dllについて、-s(厳密比較)を指定していなかったため、
       意図しないファイルもフィルタの対象となっていた。
       (なんとr12から!!)
       (しかも-sなしでは機能しない-rだけを指定していた)
     ・Reces::run()内の書庫処理関数を(見た目だけ)分割、整理(と見せかけた何か)。
     ・遂に正規表現フィルタ実装!!
       Nozomu Kato氏による「SRELL」を利用させて頂いています。


 [Ver.0.00r25]
     ・64bit版を同梱するように。誰が使うんだこんなの。
     ・UNBYPASS.DLL/ZBYPASSA.SPHの動作を確認。
     ・7-zip32.dll/7-zip64.dll文字化け対策版を同梱するように。ファイルサイズが増えたね!
     ・Total7zip.wcx64で処理するとTotal7zip.xmlが作成されるのを阻止するため、
       大胆にもCreateFileW()のcallをnopで潰してしまおう!!
       Ver.0.8.5.6であれば、
           0005302A: FF 90
       (ただ、こんな方法で良いのか全く自信がない^^;)
     ・巨大なreces.cppを分割。どう見ても失敗。
     ・7-zip32.dll Ver.9.38.00.01 beta以降だとディレクトリのタイムスタンプを復元してくれるようなので、
       /DIRTSオプションをデフォルトでオフに。
       *タイムスタンプが保持されていないディレクトリは/DIRTSで!!
     ・Ctrl+Cで落ちる不具合を極力修正。たぶん3回目くらい。それでも完全ではない様子。
     ・処理開始時に進捗状況+ファイル名を表示するように。
       これでヘッダ暗号化書庫のパスワード入力で悩むことがなくなる!!!


 [Ver.0.00r24]
     ・隠し設定「/wait:」実装。解凍時のみ有効。(Special Thanks!:kiyohiro様)
     ・/mtで対象書庫にライブラリ対応確認を行う阿呆な処理を廃止。
     ・/ms時のパラメータ処理が行われていなかった。(r21からの不具合)
     ・オプション指定を表す文字から「:」を削除。
     ・/mr@で統合アーカイバ以外のライブラリの指定を考えていなかった。
     ・/r時に入力ファイルパスを環境変数に代入するように。
       これにより非対応形式への(無理矢理な)圧縮がしやすくなりました。
     ・Total7zip.wcxで処理するとTotal7zip.xmlが作成されるのを阻止するには、
       CreateFileW()の第一引数を潰すこと。
       Ver.0.8.5.6であれば、
            0004443B: FF 6A
            0004443C: 75 00
            0004443D: 0C 90
       (ただ、こんな方法で良いのか全く自信がない^^;)
     ・最上層ファイル、パス付ファイルの順に格納されている書庫の場合、
       二重ディレクトリ判定が正しく行われていなかった。
       なんと二重ディレクトリ防止オプションを実装したr9からの不具合!!!
     ・applyFilters()にあったお粗末な不具合。
       こちらはr13から!!
          for(std::vector<int>::iterator ite=v.begin(),
              end=v.end();
              ite!=end;){//vector iterators incompatible
              if(f(*ite)){
                  ite=v.erase(ite);
                  continue;
              }
              ++ite;
          }


 [Ver.0.00r23]
     ・誰得wcx対応。国産対応ソフトは皆無?
     ・Double Commander付属zip.wcxはUTF-8-MACで格納されていても正しく処理出来、
       Susie Plug-inと違い、Unicode文字にも対応しています。
     ・ただし、/mSzip.wcxすると落ちます。
     ・spi/wcxの共通パス除外を解凍時に行う様にしました。
     ・wcxによる圧縮対応は見送り。


 [Ver.0.00r22]
     ・今回は細かな不具合修正のみ。
     ・次バージョンでは某プラグインに対応する予定。


 [Ver.0.00r21]
     ・何故か再圧縮時のみ戻り値を設定していなかった。
     ・テスト時も戻り値を設定していなかった。
     ・Nobuyuki Honda氏のamzip.spi/Yak!氏の7z.dllとax7z_s.spiでお馴染みMac文字化けzipの解凍を確認。
       amzip.spiで処理が出来る一方、ax7z_s.spiで処理が出来ない書庫もある?
     ・/mSを実装したものの、Susie Plug-in位でしか役に立たないかも。統合アーカイバライブラリのszOptionBufferとかiModeとかは見ないふり。
     ・ごちゃごちゃした部分のほんのごく一部を整理しました。
     ・7-zip32.dll Ver.9.22.00.01の不具合修正によりsslib::Windowとおさらば。
     ・同じく7-zip32.dll Ver.9.22.00.01より、WIN_LONG_PATH定義でのビルドとなり、MAX_PATH以上であっても処理できるように!!!
       ただし、reces側は中途半端な対応に留まり、細かいところはテスト出来ていません。
       /me,/ml,/mtで入力ファイルがMAX_PATH以上のパスであれば、勝手に7-zip32.dllを使用するようにしました。
       出力については確認しません。
     ・圧縮/解凍後直ぐにライブラリを解放するように。
     ・DlgHook.dllを一時ディレクトリに書き出すように。
     ・書庫用Susie Plug-inかどうかの判定をファイル名ではなくGetPluginInfo()で行うようにすることで、
       amzip.spiの利用が可能に。


 [Ver.0.00r20]
     ・一部ライブラリのプログレスバーをファイル単位とすることで処理高速化。
     ・「/eb[level]」オプションについて、MoveFile()に失敗した場合、コピー->削除で対応するように。
     ・24x24アイコンを削除。
     ・ファイルサイズを少し削減。


 [Ver.0.00r19]
     ・LMZIP32.dll最高や! /LCID、/UESCなんて最初からいらんかったんや!
     ・ただ、複数ファイルの圧縮はr10,r11での7-zip32.dllと同じ処理しか思いつかない為、圧縮処理未対応としました。
       LMZIP32.dllはマルチバイト文字(日本語など)を用いたパスワード書庫が作成出来るので、
       可能であれば対応したかったのですが--;
     ・LMZIP32.dllでの処理時のプログレスバーはサイズではなくファイル数を元に表示しています。


 [Ver.0.00r18]
     ・reces経由でax7z_s.spiを使用すると、zipが処理出来ない不具合は、対応拡張子の列挙が不完全(GetPluginInfo()関連)であった為。
     ・偶にRemoveDirectory()に失敗し、Tempにディレクトリが残ってしまう不具合発見。
       ディレクトリの削除に失敗したならば、SHFileOperation()で再度削除を行う様にする様に。
     ・ディレクトリのタイムスタンプ復元処理で、C++と言うよりプログラミングそのものに関する初歩的なミスにより落ちる不具合を修正。


 [Ver.0.00r17]
     ・XacRett.dllでのリストファイル指定は「@」も二重引用符内に記述する必要があった様子。
       ["@list file"]
       7環境では気付けない不具合でした。


 [Ver.0.00r16]
     ・複数の二重引用符+末尾'\'パスが処理出来ない不具合について、__getmainargs()では対応できないため、
       GetCommandLine()で取得した文字列を自前で分割、ワイルドカード展開を行うように。
       ->r16a時点ではオプション中文字列に空白があると分割が失敗する不具合が...
     ・/msでライブラリのプレフィックスを指定出来るようにし、対応外の統合アーカイバライブラリも扱えるように。
     ・解凍レンジの「パス情報を最適化して展開する」や、tarの「--strip-components」風の/eb[level|x]を実装。
       ただし解凍後の処理となります。


 [Ver.0.00r15]
     ・今回より不具合修正版の公開の方法を変更。(候補aをVer.0.00rxxa、候補bをVer.0.00rxxb...)
     ・XacRett.dllはSetOwnerWindow()系が使用出来ないため、APIフックを用いて情報を取得し、プログレスバー出力に対応しました。
       具体的には、
       ・GetTextExtentPointA()をフック、lpSize->cx=0によりPathSetDlgItemPath()によるパスの省略を防止。
       ・GetDlgItem()をフック、引数nIDDlgItemがIDC_ENAME(1004)ならハンドルを保存。
       ・SetWindowTextA()をフック、引数hWndが保存したハンドルなら処理。
       と言う回りくどいことをしています。
     ・ディレクトリのタイムスタンプ復元にSystemTimeToFileTime()->LocalFileTimeToFileTime()としていた馬鹿な不具合を修正。
     ・ヘッダ暗号化7zの解凍を行うと無限ループに陥る不具合を修正。
       FindFirst()の戻り値を確認していなかったため発生していた模様。
       isSupportedArchive()の時点でsetDefaultPassword()することで解決。
     ・Applocaleを使用することで、文字化け書庫の解凍に対応。
       ただし、ロケールの切り替えのため、最大3つのreces.exeが起動してしまう。
           1.reces.exe[1]がロケールを切り替えてreces.exe[2]を起動。
           2.解凍であれば、ここで終了。再圧縮の場合、ロケールを元に戻してreces.exe[3]を起動...
     ・ファイル名に含まれるUnicodeエスケープシーケンスのデコードを行えるようにすることで、文字化け?書庫の解凍に対応。


 [Ver.0.00r14]
     ・r13は設定ファイルの取り扱いが手抜きだったので、最悪強制終了する始末...
     ・拡張子からの形式推測実装し忘れ(r12,r13)発覚。
     ・b2e32.dllに/msでのみ対応。/Dbと/P、/{と/}の組み合わせである程度使えるレベルにはなる筈...
     ・同梱のunrar32.dll x64/ユニコード対応版をversion 0.16にバージョンアップ。
     ・7-zip32.dllでの書庫判定処理を変更し、処理速度アップ?
     ・フィルタ適用処理の改善で速度アップ?
     ・DlgHook.dllについて、SendMessageTimeout()により解放されない問題を解決?
     ・reces.workspaceを追加。


 [Ver.0.00r13]
     ・r12がメモリリークのオンパレードであったため、人柱版を何度も公開することに。
     ・念願のspi対応。
     ・b2eへの対応は制限が多いため断念。
     ・メインのコンパイラをMicrosoft Visual C++ 2010 Expressに変更。
     ・Readme.txtのQ&Aコーナーが復活。


 [Ver.0.00r12]
     ・三度目の全ソース書き直し。と言いつつそのまま持ってきたものも...
     ・b2e32.dllやspiは次バージョンでのサポートを検討中。
     ・unrar.dll 5.xを用いるとディレクトリの解凍で問題が発生し、正しく解凍できない?
     ・VC++EEで作成したプロジェクトファイルを追加しました。あまり確認していませんのでご注意を。


 [Ver.0.00r11]
     ・bregonig.dllやB2E32.DLLのサポートを検討するもややこしいことになってきたので今回は見送ることに。


 [Ver.0.00r10]
     ・一部メッセージが英語であるのは、途中(非公開のTarHeart Ver.1.00～reces Ver.0.00r10 ANSI版)までメッセージをすべて英語で表示していた頃の名残(笑)です。
     ・cab書庫の再圧縮と圧縮はcab32.dllに何らかの動きがあり次第、実装を試みる予定です。それまでは面倒なので実装しないと思います。
     ・Readme.txtにも書きましたが、XacRett.dllによるパスワード付zip書庫の解凍が確認できません。自前で修正してビルドしようにも何やら面倒そう...
     ・「DlgHook.dll」はソースファイル名からもわかるように、パスワード入力ダイアログをフックし、
       recesで文字列入力、OKボタン押下するためのものです。
     ・Unicode&4GB対応を謳っていますが余り確認していませんのでご注意を。
     ・現在、7-zip32.dllによる複数ファイル/ディレクトリの圧縮にはaコマンドとuコマンドを組み合わせて用いています。
       7-zipCMD.txtには「注：.7z ソリッド書庫の更新は幾つか再圧縮が必要になるので時間が掛ります。」
       とありますが、
       この方法以外に複数ファイル/ディレクトリを圧縮する方法が思いつかないので仕方がない...
      ・追記:7-zip32.dllによる圧縮方法はr12で改善されました。
