FFFTPのUTF8対応改造について

家ではWinXPLinux、会社ではLinuxを使っているのだが、家から会社のLinux(UTF8)にSSH経由のFTP接続をする際、FFFTPではファイル一覧のUTF8対応してないため漢字コードが化けるという問題があった。とりあえずNextFTPを使って代用してきたが、他のサーバにつなげるときにはFFFTPで、会社につなげるときだけNextFTPという使い方にそろそろ我慢できず、FTP UTF8というキーワードでぐぐってみたところ、FFFTPの改造方法が『後の末莉』さんのところにあるのを見つけた。おー!!
(FFFTP本家)
http://www2.biglobe.ne.jp/~sota/ffftp.html
(FFFTPUTF-8対応改造)
http://homepage1.nifty.com/kisa/dailylife/diary/200502t.html
それを参考にしながらFFFTPを改造(作成にかかった時間=ソースをVS2005に取り込んでからReleaseビルドするまで=AM4:02からAM6:09=2時間ぐらい)
『後の末莉』さんのやり方で、それをもちょっと詳しく書いたメモを以下に残す。
ちなみにcodecnv-utf8.cppのコードはごみが残りまくって汚いです。(;´Д`)
こんな感じでやれば動くよってことで....

                                                                                              • -

VS2005によるffftpソースのビルド
ffftp-1.92a-src.zipを展開しソリューションを開く。
(ffftpffftp_Englishの2プロジェクトがあるが、とりあえずffftpのみビルドすることにする)

・プロジェクトプロパティで、
[追加の依存ファイル]から ctl3d32.lib を削除。
[特定のライブラリを無視]に ctl3d32.lib を追加。

・ダイアログ[hset_code_dlg]の修正
[Source Files]のffftp.rcをクリックし、その中のhset_code_dlgを選択。
レイアウトを調整しながら、[ファイル名の漢字コード]にRadio Buttonをコピーで追加。
caption を [UTF-8] に変更
IDを [HSET_FN_UTF8_CNV] に変更
[書式]-[タブオーダー] で左上から順番になるようタブオーダーを変更

・ソース[hostman.c]の修正
1800行目のstatic const RADIOBUTTON NameKanjiButton[] に
{ HSET_FN_UTF8_CNV, KANJI_UTF_8 }
を追加。

・ソース[common.h]の修正
626行目の#define KANJI_SMB_CAPの下に
#define KANJI_UTF_8 5 /*UTF-8 */
を追加
1383行目ぐらいのint ConvSJIStoSMB_CAP(CODECONVINFO *cInfo)の下に
#ifdef __cplusplus
extern "C"
{
#endif
int ConvUTF8toSJIS(CODECONVINFO *cInfo);
int ConvSJIStoUTF8(CODECONVINFO *cInfo);
#ifdef __cplusplus
}
#endif
を追加

・ソース[remote.c]の修正
1341行目ぐらいのChangeFnameRemote2Local()のcase文の中に,
case KANJI_UTF_8 :
ConvUTF8toSJIS(&cInfo);
strcpy(Fname, Buf);
break;
を追加
1427行目ぐらいのChangeFnameLocal2Remote()のcase文の中に,
case KANJI_UTF_8 :
ConvSJIStoUTF8(&cInfo);
strcpy(Fname, Buf);
break;
を追加

・ソース[codecnv-utf8.cpp]の追加(codecnv.cを参考)
codecnv-utf8.cpp を新規作成し、プロジェクトに追加。

        • (ここから)----

#define STRICT
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "common.h"
#include "resource.h"

#include

int ConvUTF8toSJIS(CODECONVINFO *cInfo){
char *Str;
char *Put;
char *Limit;
int Continue;

Continue = NO;
Str = cInfo->Str;
Put = cInfo->Buf;
Limit = cInfo->Buf + cInfo->BufSize - 2;
const int cchWideChar = ::MultiByteToWideChar(CP_UTF8, 0, Str, -1, NULL, 0);
LPWSTR lpw = new WCHAR [cchWideChar];
if (lpw == NULL) return Continue;
*lpw = L'\0';
const int nUnicodeCount = ::MultiByteToWideChar(CP_UTF8, 0, Str, -1, lpw, cchWideChar);
if( nUnicodeCount <= 0 ){
delete lpw;
return Continue;
}
const int cchMultiByte = ::WideCharToMultiByte(CP_ACP, 0, lpw, -1, NULL, 0, NULL, NULL);

const int nMultiCount = ::WideCharToMultiByte(CP_ACP, 0, lpw, -1, Put, cchMultiByte, NULL, NULL);
if( nMultiCount <= 0 ){
delete lpw;
return Continue;
}
delete lpw;
return(Continue);
}

int ConvSJIStoUTF8(CODECONVINFO *cInfo){
char *Str;
char *Put;
char *Limit;
int Continue;

Continue = NO;
Str = cInfo->Str;
Put = cInfo->Buf;
Limit = cInfo->Buf + cInfo->BufSize - 6;
const int cchWideChar = ::MultiByteToWideChar(CP_ACP, 0, Str, -1, NULL, 0);
LPWSTR lpw = new WCHAR [cchWideChar];
if (lpw == NULL) return Continue;
*lpw = L'\0';
const int nUnicodeCount = ::MultiByteToWideChar(CP_ACP, 0, Str, -1, lpw, cchWideChar);
if( nUnicodeCount <= 0 ){
delete lpw;
return Continue;
}
const int cchMultiByte = ::WideCharToMultiByte(CP_UTF8, 0, lpw, -1, NULL, 0, NULL, NULL);

const int nMultiCount = ::WideCharToMultiByte(CP_UTF8, 0, lpw, -1, Put, cchMultiByte, NULL, NULL);
if( nMultiCount <= 0 ){
delete lpw;
return Continue;
}
delete
lpw;
cInfo->Str = Str;
cInfo->OutLen = nMultiCount;
return(Continue);
}

        • (ここまで)----