X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=getput.c;h=48f0d632635dcd8e8f8b0ef7bf3080286a0bab49;hb=27e47ec02a3553a6e9b4e935a43dc28919d91c0d;hp=46dffebcff53e79fc59e84708e49f9c281a183ed;hpb=2bf85c03c1e059a2f75dbd48ef73be5961e12414;p=ffftp%2Fffftp.git diff --git a/getput.c b/getput.c index 46dffeb..48f0d63 100644 --- a/getput.c +++ b/getput.c @@ -1,6 +1,6 @@ -/*============================================================================= +/*============================================================================= * -* ƒ_ƒEƒ“ƒ[ƒh^ƒAƒbƒvƒ[ƒh +* ダウンロード/アップロード * =============================================================================== / Copyright (C) 1997-2007 Sota. All rights reserved. @@ -27,11 +27,11 @@ / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /============================================================================*/ -/* ‚±‚̃\[ƒX‚͈ꕔAWS_FTP Version 93.12.05 ‚̃\[ƒX‚ðŽQl‚É‚µ‚Ü‚µ‚½B */ -/* ƒXƒŒƒbƒh‚̍쐬^I—¹‚ÉŠÖ‚µ‚āA”óŒû“aì¬‚̃pƒbƒ`‚ð‘g‚ݍž‚Ý‚Ü‚µ‚½B */ +/* このソースは一部、WS_FTP Version 93.12.05 のソースを参考にしました。 */ +/* スレッドの作成/終了に関して、樋口殿作成のパッチを組み込みました。 */ /* - ˆê•”A‚‘¬‰»‚Ì‚½‚߂̃R[ƒh’ljÁ by H.Shirouzu at 2002/10/02 + 一部、高速化のためのコード追加 by H.Shirouzu at 2002/10/02 */ #define STRICT @@ -41,7 +41,9 @@ #include #include #include -#include +// IPv6対応 +//#include +#include #include #include #include @@ -57,20 +59,26 @@ #define SOCKBUF_SIZE (256 * 1024) /* End */ -#define TIMER_DISPLAY 1 /* •\Ž¦XV—pƒ^ƒCƒ}‚ÌID */ -#define DISPLAY_TIMING 500 /* •\Ž¦XVŽžŠÔ 0.5•b */ +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS +#undef BUFSIZE +#define BUFSIZE (64 * 1024) // RWIN値以下で充分な大きさが望ましいと思われる。 +#undef SET_BUFFER_SIZE +#endif + +#define TIMER_DISPLAY 1 /* 表示更新用タイマのID */ +#define DISPLAY_TIMING 500 /* 表示更新時間 0.5秒 */ #define ERR_MSG_LEN 1024 -/* íœŠm”Fƒ_ƒCƒAƒƒO‚̏î•ñ */ +/* 削除確認ダイアログの情報 */ typedef struct { int Cur; TRANSPACKET *Pkt; } MIRRORDELETEINFO; -/*===== ƒvƒƒgƒ^ƒCƒv =====*/ +/*===== プロトタイプ =====*/ static void DispTransPacket(TRANSPACKET *Pkt); static void EraseTransFileList(void); @@ -88,7 +96,9 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt); static int UpLoadNonPassive(TRANSPACKET *Pkt); static int UpLoadPassive(TRANSPACKET *Pkt); static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt); -static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii); +// 同時接続対応 +//static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii); +static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii, int *CancelCheckWork); static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode); static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode); static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam); @@ -99,36 +109,56 @@ static int IsSpecialDevice(char *Fname); static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt); static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam); static void SetErrorMsg(char *fmt, ...); +// 同時接続対応 +static char* GetErrMsg(); -/*===== ƒ[ƒJƒ‹‚ȃ[ƒN =====*/ +/*===== ローカルなワーク =====*/ -static HANDLE hTransferThread; +// 同時接続対応 +//static HANDLE hTransferThread; +static HANDLE hTransferThread[MAX_DATA_CONNECTION]; static int fTransferThreadExit = FALSE; -static HANDLE hRunMutex; /* “]‘—ƒXƒŒƒbƒhŽÀsƒ~ƒ…[ƒeƒbƒNƒX */ -static HANDLE hListAccMutex; /* “]‘—ƒtƒ@ƒCƒ‹ƒAƒNƒZƒX—pƒ~ƒ…[ƒeƒbƒNƒX */ +static HANDLE hRunMutex; /* 転送スレッド実行ミューテックス */ +static HANDLE hListAccMutex; /* 転送ファイルアクセス用ミューテックス */ -static int TransFiles = 0; /* “]‘—‘Ò‚¿ƒtƒ@ƒCƒ‹” */ -static TRANSPACKET *TransPacketBase = NULL; /* “]‘—ƒtƒ@ƒCƒ‹ƒŠƒXƒg */ +static int TransFiles = 0; /* 転送待ちファイル数 */ +static TRANSPACKET *TransPacketBase = NULL; /* 転送ファイルリスト */ +// 同時接続対応 +static TRANSPACKET *NextTransPacketBase = NULL; -static int Canceled; /* ’†Ž~ƒtƒ‰ƒO YES/NO */ -static int ClearAll; /* ‘S‚Ä’†Ž~ƒtƒ‰ƒO YES/NO */ +// 同時接続対応 +//static int Canceled; /* 中止フラグ YES/NO */ +static int Canceled[MAX_DATA_CONNECTION]; /* 中止フラグ YES/NO */ +static int ClearAll; /* 全て中止フラグ YES/NO */ -static int ForceAbort; /* “]‘—’†Ž~ƒtƒ‰ƒO */ - /* ‚±‚̃tƒ‰ƒO‚̓XƒŒƒbƒh‚ðI—¹‚³‚¹‚é‚Æ‚«‚ÉŽg‚¤ */ +static int ForceAbort; /* 転送中止フラグ */ + /* このフラグはスレッドを終了させるときに使う */ -static LONGLONG AllTransSizeNow; /* ¡‰ñ‚Ì“]‘—‚Å“]‘—‚µ‚½ƒTƒCƒY */ -static time_t TimeStart; /* “]‘—ŠJŽnŽžŠÔ */ +// 同時接続対応 +//static LONGLONG AllTransSizeNow; /* 今回の転送で転送したサイズ */ +//static time_t TimeStart; /* 転送開始時間 */ +static LONGLONG AllTransSizeNow[MAX_DATA_CONNECTION]; /* 今回の転送で転送したサイズ */ +static time_t TimeStart[MAX_DATA_CONNECTION]; /* 転送開始時間 */ -static int KeepDlg = NO; /* “]‘—’†ƒ_ƒCƒAƒƒO‚ðÁ‚³‚È‚¢‚©‚Ç‚¤‚© (YES/NO) */ -static int MoveToForeground = NO; /* ƒEƒCƒ“ƒhƒE‚ð‘O–ʂɈړ®‚·‚é‚©‚Ç‚¤‚© (YES/NO) */ +static int KeepDlg = NO; /* 転送中ダイアログを消さないかどうか (YES/NO) */ +static int MoveToForeground = NO; /* ウインドウを前面に移動するかどうか (YES/NO) */ -static char CurDir[FMAX_PATH+1] = { "" }; -static char ErrMsg[ERR_MSG_LEN+7]; +// 同時接続対応 +//static char CurDir[FMAX_PATH+1] = { "" }; +static char CurDir[MAX_DATA_CONNECTION][FMAX_PATH+1]; +// 同時接続対応 +//static char ErrMsg[ERR_MSG_LEN+7]; +static char ErrMsg[MAX_DATA_CONNECTION+1][ERR_MSG_LEN+7]; +static DWORD ErrMsgThreadId[MAX_DATA_CONNECTION+1]; +static HANDLE hErrMsgMutex; -/*===== ŠO•”ŽQÆ =====*/ +// 同時接続対応 +static int WaitForMainThread = NO; -/* Ý’è’l */ +/*===== 外部参照 =====*/ + +/* 設定値 */ extern int SaveTimeStamp; extern int RmEOF; // extern int TimeOut; @@ -139,74 +169,100 @@ extern int FolderAttr; extern int FolderAttrNum; -/*----- ƒtƒ@ƒCƒ‹“]‘—ƒXƒŒƒbƒh‚ð‹N“®‚·‚é ---------------------------------------- +/*----- ファイル転送スレッドを起動する ---------------------------------------- * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ int MakeTransferThread(void) { DWORD dwID; + int i; hListAccMutex = CreateMutex( NULL, FALSE, NULL ); hRunMutex = CreateMutex( NULL, TRUE, NULL ); + // 同時接続対応 + hErrMsgMutex = CreateMutex( NULL, FALSE, NULL ); ClearAll = NO; ForceAbort = NO; fTransferThreadExit = FALSE; - hTransferThread = (HANDLE)_beginthreadex(NULL, 0, TransferThread, 0, 0, &dwID); - if (hTransferThread == NULL) - return(FAIL); /* XXX */ + // 同時接続対応 +// hTransferThread = (HANDLE)_beginthreadex(NULL, 0, TransferThread, 0, 0, &dwID); +// if (hTransferThread == NULL) +// return(FFFTP_FAIL); /* XXX */ + for(i = 0; i < MAX_DATA_CONNECTION; i++) + { + hTransferThread[i] = (HANDLE)_beginthreadex(NULL, 0, TransferThread, (void*)i, 0, &dwID); + if(hTransferThread[i] == NULL) + return FFFTP_FAIL; + } - return(SUCCESS); + return(FFFTP_SUCCESS); } -/*----- ƒtƒ@ƒCƒ‹“]‘—ƒXƒŒƒbƒh‚ðI—¹‚·‚é ---------------------------------------- +/*----- ファイル転送スレッドを終了する ---------------------------------------- * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void CloseTransferThread(void) { - Canceled = YES; + int i; + // 同時接続対応 +// Canceled = YES; + for(i = 0; i < MAX_DATA_CONNECTION; i++) + Canceled[i] = YES; ClearAll = YES; ForceAbort = YES; fTransferThreadExit = TRUE; - while(WaitForSingleObject(hTransferThread, 10) == WAIT_TIMEOUT) + // 同時接続対応 +// while(WaitForSingleObject(hTransferThread, 10) == WAIT_TIMEOUT) +// { +// BackgrndMessageProc(); +// Canceled = YES; +// } +// CloseHandle(hTransferThread); + for(i = 0; i < MAX_DATA_CONNECTION; i++) { - BackgrndMessageProc(); - Canceled = YES; + while(WaitForSingleObject(hTransferThread[i], 10) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Canceled[i] = YES; + } + CloseHandle(hTransferThread[i]); } - CloseHandle(hTransferThread); ReleaseMutex( hRunMutex ); CloseHandle( hListAccMutex ); CloseHandle( hRunMutex ); + // 同時接続対応 + CloseHandle( hErrMsgMutex ); return; } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹î•ñ‚ðƒŠƒXƒg‚ɒljÁ‚·‚é -------------------------------- +/*----- 転送するファイル情報をリストに追加する -------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* TRANSPACKET **Base : ƒŠƒXƒg‚̐擪 +* TRANSPACKET *Pkt : 転送ファイル情報 +* TRANSPACKET **Base : リストの先頭 * * Return Value -* int ƒXƒe[ƒ^ƒX -* SUCCESS/FAIL +* int ステータス +* FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ int AddTmpTransFileList(TRANSPACKET *Pkt, TRANSPACKET **Base) @@ -215,7 +271,7 @@ int AddTmpTransFileList(TRANSPACKET *Pkt, TRANSPACKET **Base) TRANSPACKET *Prev; int Sts; - Sts = FAIL; + Sts = FFFTP_FAIL; if((Pos = malloc(sizeof(TRANSPACKET))) != NULL) { memcpy(Pos, Pkt, sizeof(TRANSPACKET)); @@ -230,19 +286,19 @@ int AddTmpTransFileList(TRANSPACKET *Pkt, TRANSPACKET **Base) Prev = Prev->Next; Prev->Next = Pos; } - Sts = SUCCESS; + Sts = FFFTP_SUCCESS; } return(Sts); } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹î•ñƒŠƒXƒg‚ðƒNƒŠƒA‚·‚é -------------------------------- +/*----- 転送するファイル情報リストをクリアする -------------------------------- * * Parameter -* TRANSPACKET **Base : ƒŠƒXƒg‚̐擪 +* TRANSPACKET **Base : リストの先頭 * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void EraseTmpTransFileList(TRANSPACKET **Base) @@ -262,15 +318,15 @@ void EraseTmpTransFileList(TRANSPACKET **Base) } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹î•ñƒŠƒXƒg‚©‚ç‚P‚‚̏î•ñ‚ðŽæ‚菜‚­ -------------------- +/*----- 転送するファイル情報リストから1つの情報を取り除く -------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* TRANSPACKET **Base : ƒŠƒXƒg‚̐擪 +* TRANSPACKET *Pkt : 転送ファイル情報 +* TRANSPACKET **Base : リストの先頭 * * Return Value -* int ƒXƒe[ƒ^ƒX -* SUCCESS/FAIL +* int ステータス +* FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) @@ -279,13 +335,13 @@ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) TRANSPACKET *Prev; int Sts; - Sts = FAIL; + Sts = FFFTP_FAIL; Pos = *Base; if(Num == 0) { *Base = Pos->Next; free(Pos); - Sts = SUCCESS; + Sts = FFFTP_SUCCESS; } else { @@ -297,7 +353,7 @@ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) { Prev->Next = Pos->Next; free(Pos); - Sts = SUCCESS; + Sts = FFFTP_SUCCESS; break; } } @@ -306,22 +362,29 @@ int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num) } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹î•ñ‚ð“]‘—ƒtƒ@ƒCƒ‹ƒŠƒXƒg‚É“o˜^‚·‚é -------------------- +/*----- 転送するファイル情報を転送ファイルリストに登録する -------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void AddTransFileList(TRANSPACKET *Pkt) { DispTransPacket(Pkt); - WaitForSingleObject(hListAccMutex, INFINITE); + // 同時接続対応 +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + WaitForMainThread = YES; + BackgrndMessageProc(); + Sleep(1); + } - if(AddTmpTransFileList(Pkt, &TransPacketBase) == SUCCESS) + if(AddTmpTransFileList(Pkt, &TransPacketBase) == FFFTP_SUCCESS) { if((strncmp(Pkt->Cmd, "RETR", 4) == 0) || (strncmp(Pkt->Cmd, "STOR", 4) == 0)) @@ -330,30 +393,42 @@ void AddTransFileList(TRANSPACKET *Pkt) PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); } } + // 同時接続対応 + if(NextTransPacketBase == NULL) + NextTransPacketBase = TransPacketBase; ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; return; } -/*----- “]‘—ƒtƒ@ƒCƒ‹î•ñ‚ð“]‘—ƒtƒ@ƒCƒ‹ƒŠƒXƒg‚ɒljÁ‚·‚é ------------------------ +/*----- 転送ファイル情報を転送ファイルリストに追加する ------------------------ * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* TRANSPACKET **Base : ƒŠƒXƒg‚̐擪 +* TRANSPACKET *Pkt : 転送ファイル情報 +* TRANSPACKET **Base : リストの先頭 * * Return Value -* ‚È‚µ +* なし * * Note -* PktŽ©‘Ì‚ðƒŠƒXƒg‚ɘAŒ‹‚·‚é +* Pkt自体をリストに連結する *----------------------------------------------------------------------------*/ void AppendTransFileList(TRANSPACKET *Pkt) { TRANSPACKET *Pos; - WaitForSingleObject(hListAccMutex, INFINITE); + // 同時接続対応 +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + WaitForMainThread = YES; + BackgrndMessageProc(); + Sleep(1); + } if(TransPacketBase == NULL) TransPacketBase = Pkt; @@ -364,6 +439,9 @@ void AppendTransFileList(TRANSPACKET *Pkt) Pos = Pos->Next; Pos->Next = Pkt; } + // 同時接続対応 + if(NextTransPacketBase == NULL) + NextTransPacketBase = TransPacketBase; while(Pkt != NULL) { @@ -379,17 +457,19 @@ void AppendTransFileList(TRANSPACKET *Pkt) } ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; return; } -/*----- “]‘—ƒtƒ@ƒCƒ‹î•ñ‚ð•\Ž¦‚·‚é -------------------------------------------- +/*----- 転送ファイル情報を表示する -------------------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void DispTransPacket(TRANSPACKET *Pkt) @@ -413,13 +493,13 @@ static void DispTransPacket(TRANSPACKET *Pkt) } -/*----- “]‘—ƒtƒ@ƒCƒ‹ƒŠƒXƒg‚ðƒNƒŠƒA‚·‚é ---------------------------------------- +/*----- 転送ファイルリストをクリアする ---------------------------------------- * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void EraseTransFileList(void) @@ -431,30 +511,46 @@ static void EraseTransFileList(void) NotDel = NULL; - WaitForSingleObject(hListAccMutex, INFINITE); + // 同時接続対応 +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + WaitForMainThread = YES; + BackgrndMessageProc(); + Sleep(1); + } New = TransPacketBase; while(New != NULL) { - /* ÅŒã‚Ì"BACKCUR"‚Í•K—v‚Ȃ̂ŏÁ‚³‚È‚¢ */ + /* 最後の"BACKCUR"は必要なので消さない */ if(strcmp(New->Cmd, "BACKCUR") == 0) { if(NotDel != NULL) - free(NotDel); + // 同時接続対応 +// free(NotDel); + strcpy(NotDel->Cmd, ""); NotDel = New; New = New->Next; - NotDel->Next = NULL; + // 同時接続対応 +// NotDel->Next = NULL; } else { Next = New->Next; - free(New); + // 同時接続対応 +// free(New); + strcpy(New->Cmd, ""); New = Next; } } TransPacketBase = NotDel; + // 同時接続対応 + NextTransPacketBase = TransPacketBase; TransFiles = 0; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); ReleaseMutex(hListAccMutex); + // 同時接続対応 + WaitForMainThread = NO; strcpy(Pkt.Cmd, "GOQUIT"); AddTransFileList(&Pkt); @@ -462,13 +558,13 @@ static void EraseTransFileList(void) } -/*----- “]‘—’†ƒ_ƒCƒAƒƒO‚ðÁ‚³‚È‚¢‚悤‚É‚·‚é‚©‚Ç‚¤‚©‚ðÝ’è -------------------- +/*----- 転送中ダイアログを消さないようにするかどうかを設定 -------------------- * * Parameter -* int Sw : “]‘—’†ƒ_ƒCƒAƒƒO‚ðÁ‚³‚È‚¢‚©‚Ç‚¤‚© (YES/NO) +* int Sw : 転送中ダイアログを消さないかどうか (YES/NO) * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void KeepTransferDialog(int Sw) @@ -478,13 +574,13 @@ void KeepTransferDialog(int Sw) } -/*----- Œ»Ý“]‘—’†‚©‚Ç‚¤‚©‚ð•Ô‚· ---------------------------------------------- +/*----- 現在転送中かどうかを返す ---------------------------------------------- * * Parameter -* ‚È‚µ +* なし * * Return Value -* int ƒXƒe[ƒ^ƒX (YES/NO=“]‘—’†‚Å‚Í‚È‚¢) +* int ステータス (YES/NO=転送中ではない) *----------------------------------------------------------------------------*/ int AskTransferNow(void) @@ -493,13 +589,13 @@ int AskTransferNow(void) } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹‚̐”‚ð•Ô‚· -------------------------------------------- +/*----- 転送するファイルの数を返す -------------------------------------------- * * Parameter -* ‚È‚µ +* なし * * Return Value -* int “]‘—‚·‚éƒtƒ@ƒCƒ‹‚̐” +* int 転送するファイルの数 *----------------------------------------------------------------------------*/ int AskTransferFileNum(void) @@ -508,13 +604,13 @@ int AskTransferFileNum(void) } -/*----- “]‘—’†ƒEƒCƒ“ƒhƒE‚ð‘O–ʂɏo‚· ------------------------------------------ +/*----- 転送中ウインドウを前面に出す ------------------------------------------ * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void GoForwardTransWindow(void) @@ -524,29 +620,33 @@ void GoForwardTransWindow(void) } -/*----- “]‘—ƒ\ƒPƒbƒg‚̃JƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠî•ñ‚ð‰Šú‰» ------------------------ +/*----- 転送ソケットのカレントディレクトリ情報を初期化 ------------------------ * * Parameter -* ‚È‚µ +* なし * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ void InitTransCurDir(void) { - strcpy(CurDir, ""); + // 同時接続対応 +// strcpy(CurDir, ""); + int i; + for(i = 0; i < MAX_DATA_CONNECTION; i++) + strcpy(CurDir[i], ""); return; } -/*----- ƒtƒ@ƒCƒ‹“]‘—ƒXƒŒƒbƒh‚̃ƒCƒ“ƒ‹[ƒv ------------------------------------ +/*----- ファイル転送スレッドのメインループ ------------------------------------ * * Parameter -* void *Dummy : Žg‚í‚È‚¢ +* void *Dummy : 使わない * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static ULONG WINAPI TransferThread(void *Dummy) @@ -556,15 +656,30 @@ static ULONG WINAPI TransferThread(void *Dummy) char Tmp[FMAX_PATH+1]; int CwdSts; int GoExit; - int Down; - int Up; +// int Down; +// int Up; + static int Down; + static int Up; int DelNotify; + int ThreadCount; + SOCKET CmdSkt; + SOCKET NewCmdSkt; + SOCKET TrnSkt; + RECT WndRect; + int i; hWndTrans = NULL; Down = NO; Up = NO; GoExit = NO; DelNotify = NO; + // 同時接続対応 + // ソケットは各転送スレッドが管理 + ThreadCount = (int)Dummy; + CmdSkt = INVALID_SOCKET; + NewCmdSkt = INVALID_SOCKET; + TrnSkt = INVALID_SOCKET; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST); while((TransPacketBase != NULL) || (WaitForSingleObject(hRunMutex, 200) == WAIT_TIMEOUT)) @@ -572,29 +687,115 @@ static ULONG WINAPI TransferThread(void *Dummy) if(fTransferThreadExit == TRUE) break; - WaitForSingleObject(hListAccMutex, INFINITE); - memset(ErrMsg, NUL, ERR_MSG_LEN+7); + if(WaitForMainThread == YES) + { + BackgrndMessageProc(); + Sleep(100); + continue; + } - Canceled = NO; +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Sleep(1); + } +// memset(ErrMsg, NUL, ERR_MSG_LEN+7); + memset(GetErrMsg(), NUL, ERR_MSG_LEN+7); - if(TransPacketBase != NULL) +// Canceled = NO; + Canceled[ThreadCount] = NO; + + while(TransPacketBase != NULL && strcmp(TransPacketBase->Cmd, "") == 0) { - ReleaseMutex(hListAccMutex); + Pos = TransPacketBase; + TransPacketBase = TransPacketBase->Next; + free(Pos); + } + NewCmdSkt = AskCmdCtrlSkt(); + if(AskReuseCmdSkt() == YES && ThreadCount == 0) + { + if(TransPacketBase && ThreadCount < AskMaxThreadCount()) + TrnSkt = AskTrnCtrlSkt(); + } + else + { + if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount()) + { + if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt) + { + ReleaseMutex(hListAccMutex); + ReConnectTrnSkt(&TrnSkt, &Canceled[ThreadCount]); + // 同時ログイン数制限に引っかかった可能性あり + // 負荷を下げるためにしばらく待機 + if(TrnSkt == INVALID_SOCKET) + { + i = 10000; + while(NewCmdSkt != CmdSkt && i > 0) + { + BackgrndMessageProc(); + Sleep(1); + i--; + } + } +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Sleep(1); + } + } + } + else + { + if(TrnSkt != INVALID_SOCKET) + { + ReleaseMutex(hListAccMutex); + SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]); + DoClose(TrnSkt); + TrnSkt = INVALID_SOCKET; +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Sleep(1); + } + } + } + } + CmdSkt = NewCmdSkt; +// if(TransPacketBase != NULL) + if(TrnSkt != INVALID_SOCKET && NextTransPacketBase != NULL) + { + Pos = NextTransPacketBase; + NextTransPacketBase = NextTransPacketBase->Next; + // ディレクトリ操作は非同期で行わない +// ReleaseMutex(hListAccMutex); if(hWndTrans == NULL) { - if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) || - (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) || - (strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) || - (strncmp(TransPacketBase->Cmd, "L-", 2) == 0) || - (strncmp(TransPacketBase->Cmd, "R-", 2) == 0)) +// if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) || +// (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) || +// (strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) || +// (strncmp(TransPacketBase->Cmd, "L-", 2) == 0) || +// (strncmp(TransPacketBase->Cmd, "R-", 2) == 0)) + if((strncmp(Pos->Cmd, "RETR", 4) == 0) || + (strncmp(Pos->Cmd, "STOR", 4) == 0) || + (strncmp(Pos->Cmd, "MKD", 3) == 0) || + (strncmp(Pos->Cmd, "L-", 2) == 0) || + (strncmp(Pos->Cmd, "R-", 2) == 0)) { hWndTrans = CreateDialog(GetFtpInst(), MAKEINTRESOURCE(transfer_dlg), HWND_DESKTOP, (DLGPROC)TransDlgProc); if(MoveToForeground == YES) SetForegroundWindow(hWndTrans); ShowWindow(hWndTrans, SW_SHOWNOACTIVATE); + GetWindowRect(hWndTrans, &WndRect); + SetWindowPos(hWndTrans, NULL, WndRect.left, WndRect.top + (WndRect.bottom - WndRect.top) * ThreadCount - (WndRect.bottom - WndRect.top) * (AskMaxThreadCount() - 1) / 2, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } } - TransPacketBase->hWndTrans = hWndTrans; +// TransPacketBase->hWndTrans = hWndTrans; + Pos->hWndTrans = hWndTrans; + Pos->ctrl_skt = TrnSkt; + Pos->ThreadCount = ThreadCount; if(hWndTrans != NULL) { @@ -606,60 +807,85 @@ static ULONG WINAPI TransferThread(void *Dummy) } if(hWndTrans != NULL) - SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase); +// SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase); + SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)Pos); - /* ƒ_ƒEƒ“ƒ[ƒh */ - if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) + /* ダウンロード */ +// if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) + if(strncmp(Pos->Cmd, "RETR", 4) == 0) { - /* •s³‚ȃpƒX‚ðŒŸo */ - if(CheckPathViolation(TransPacketBase) == NO) + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため +// ReleaseMutex(hListAccMutex); + /* 不正なパスを検出 */ +// if(CheckPathViolation(TransPacketBase) == NO) + if(CheckPathViolation(Pos) == NO) { - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ - if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == SUCCESS) + /* フルパスを使わないための処理 */ +// if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { - if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0) +// if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0) + if(strncmp(Pos->Cmd, "RETR-S", 6) == 0) { - /* ƒTƒCƒY‚Æ“ú•t‚ðŽæ“¾ */ - DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size); - DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time); - strcpy(TransPacketBase->Cmd, "RETR "); + /* サイズと日付を取得 */ +// DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size); +// DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time); +// strcpy(TransPacketBase->Cmd, "RETR "); + DoSIZE(TrnSkt, Pos->RemoteFile, &Pos->Size, &Canceled[Pos->ThreadCount]); + DoMDTM(TrnSkt, Pos->RemoteFile, &Pos->Time, &Canceled[Pos->ThreadCount]); + strcpy(Pos->Cmd, "RETR "); } Down = YES; // if(DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO) == 429) // { -// if(ReConnectTrnSkt() == SUCCESS) - DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled); +// if(ReConnectTrnSkt() == FFFTP_SUCCESS) +// DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled); + DoDownLoad(TrnSkt, Pos, NO, &Canceled[Pos->ThreadCount]); // } } } + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); } - /* ƒAƒbƒvƒ[ƒh */ - else if(strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) + /* アップロード */ +// else if(strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) + else if(strncmp(Pos->Cmd, "STOR", 4) == 0) { - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ - if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == SUCCESS) + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため +// ReleaseMutex(hListAccMutex); + /* フルパスを使わないための処理 */ +// if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; // if(DoUpLoad(AskTrnCtrlSkt(), TransPacketBase) == 429) // { -// if(ReConnectTrnSkt() == SUCCESS) - DoUpLoad(AskTrnCtrlSkt(), TransPacketBase); +// if(ReConnectTrnSkt() == FFFTP_SUCCESS) +// DoUpLoad(AskTrnCtrlSkt(), TransPacketBase); + DoUpLoad(TrnSkt, Pos); // } } + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); } - /* ƒtƒHƒ‹ƒ_ì¬iƒ[ƒJƒ‹‚Ü‚½‚̓zƒXƒgj */ - else if(strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) + /* フォルダ作成(ローカルまたはホスト) */ +// else if(strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) + else if(strncmp(Pos->Cmd, "MKD", 3) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN078, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN078, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN078, FALSE, YES); - if(strlen(TransPacketBase->RemoteFile) > 0) +// if(strlen(TransPacketBase->RemoteFile) > 0) + if(strlen(Pos->RemoteFile) > 0) { - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ + /* フルパスを使わないための処理 */ CwdSts = FTP_COMPLETE; - strcpy(Tmp, TransPacketBase->RemoteFile); - if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FAIL) +// strcpy(Tmp, TransPacketBase->RemoteFile); + strcpy(Tmp, Pos->RemoteFile); +// if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FFFTP_FAIL) + if(ProcForNonFullpath(TrnSkt, Tmp, CurDir[Pos->ThreadCount], hWndTrans, &Canceled[Pos->ThreadCount]) == FFFTP_FAIL) { ClearAll = YES; CwdSts = FTP_ERROR; @@ -668,149 +894,217 @@ static ULONG WINAPI TransferThread(void *Dummy) if(CwdSts == FTP_COMPLETE) { Up = YES; - CommandProcTrn(NULL, "MKD %s", Tmp); - /* ‚·‚łɃtƒHƒ‹ƒ_‚ª‚ ‚éê‡‚à‚ ‚é‚̂ŁA */ - /* ‚±‚±‚ł̓Gƒ‰[ƒ`ƒFƒbƒN‚Í‚µ‚È‚¢ */ +// CommandProcTrn(NULL, "MKD %s", Tmp); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "MKD %s", Tmp); + /* すでにフォルダがある場合もあるので、 */ + /* ここではエラーチェックはしない */ if(FolderAttr) - CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); +// CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp); } } - else if(strlen(TransPacketBase->LocalFile) > 0) +// else if(strlen(TransPacketBase->LocalFile) > 0) + else if(strlen(Pos->LocalFile) > 0) { Down = YES; - DoLocalMKD(TransPacketBase->LocalFile); +// DoLocalMKD(TransPacketBase->LocalFile); + DoLocalMKD(Pos->LocalFile); } + ReleaseMutex(hListAccMutex); } - /* ƒfƒBƒŒƒNƒgƒŠì¬ií‚ɃzƒXƒg‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "R-MKD", 5) == 0) + /* ディレクトリ作成(常にホスト側) */ +// else if(strncmp(TransPacketBase->Cmd, "R-MKD", 5) == 0) + else if(strncmp(Pos->Cmd, "R-MKD", 5) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN079, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN079, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN079, FALSE, YES); - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ - if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == SUCCESS) + /* フルパスを使わないための処理 */ +// if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; - CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); +// CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); if(FolderAttr) - CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile); +// CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Pos->RemoteFile); } + ReleaseMutex(hListAccMutex); } - /* ƒfƒBƒŒƒNƒgƒŠíœií‚ɃzƒXƒg‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "R-RMD", 5) == 0) + /* ディレクトリ削除(常にホスト側) */ +// else if(strncmp(TransPacketBase->Cmd, "R-RMD", 5) == 0) + else if(strncmp(Pos->Cmd, "R-RMD", 5) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN080, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN080, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN080, FALSE, YES); - DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase); +// DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase); + DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos); if((DelNotify == YES) || (DelNotify == YES_ALL)) { - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ - if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == SUCCESS) + /* フルパスを使わないための処理 */ +// if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; - CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); +// CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); } } + ReleaseMutex(hListAccMutex); } - /* ƒtƒ@ƒCƒ‹íœií‚ɃzƒXƒg‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0) + /* ファイル削除(常にホスト側) */ +// else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0) + else if(strncmp(Pos->Cmd, "R-DELE", 6) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN081, FALSE, YES); - DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase); +// DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase); + DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos); if((DelNotify == YES) || (DelNotify == YES_ALL)) { - /* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢‚½‚߂̏ˆ— */ - if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == SUCCESS) + /* フルパスを使わないための処理 */ +// if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS) + if(MakeNonFullPath(Pos, CurDir[Pos->ThreadCount], Tmp) == FFFTP_SUCCESS) { Up = YES; - CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); +// CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile); + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "%s%s", Pos->Cmd+2, Pos->RemoteFile); } } + ReleaseMutex(hListAccMutex); } - /* ƒfƒBƒŒƒNƒgƒŠì¬ií‚Ƀ[ƒJƒ‹‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0) + /* ディレクトリ作成(常にローカル側) */ +// else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0) + else if(strncmp(Pos->Cmd, "L-MKD", 5) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN082, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN082, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN082, FALSE, YES); Down = YES; - DoLocalMKD(TransPacketBase->LocalFile); +// DoLocalMKD(TransPacketBase->LocalFile); + DoLocalMKD(Pos->LocalFile); + ReleaseMutex(hListAccMutex); } - /* ƒfƒBƒŒƒNƒgƒŠíœií‚Ƀ[ƒJƒ‹‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "L-RMD", 5) == 0) + /* ディレクトリ削除(常にローカル側) */ +// else if(strncmp(TransPacketBase->Cmd, "L-RMD", 5) == 0) + else if(strncmp(Pos->Cmd, "L-RMD", 5) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN083, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN083, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN083, FALSE, YES); - DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase); +// DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase); + DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos); if((DelNotify == YES) || (DelNotify == YES_ALL)) { Down = YES; - DoLocalRMD(TransPacketBase->LocalFile); +// DoLocalRMD(TransPacketBase->LocalFile); + DoLocalRMD(Pos->LocalFile); } + ReleaseMutex(hListAccMutex); } - /* ƒtƒ@ƒCƒ‹íœií‚Ƀ[ƒJƒ‹‘¤j */ - else if(strncmp(TransPacketBase->Cmd, "L-DELE", 6) == 0) + /* ファイル削除(常にローカル側) */ +// else if(strncmp(TransPacketBase->Cmd, "L-DELE", 6) == 0) + else if(strncmp(Pos->Cmd, "L-DELE", 6) == 0) { - DispTransFileInfo(TransPacketBase, MSGJPN084, FALSE, YES); +// DispTransFileInfo(TransPacketBase, MSGJPN084, FALSE, YES); + DispTransFileInfo(Pos, MSGJPN084, FALSE, YES); - DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase); +// DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase); + DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos); if((DelNotify == YES) || (DelNotify == YES_ALL)) { Down = YES; - DoLocalDELE(TransPacketBase->LocalFile); +// DoLocalDELE(TransPacketBase->LocalFile); + DoLocalDELE(Pos->LocalFile); } + ReleaseMutex(hListAccMutex); } - /* ƒJƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠ‚ðÝ’è */ - else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0) + /* カレントディレクトリを設定 */ +// else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0) + else if(strcmp(Pos->Cmd, "SETCUR") == 0) { - if(AskShareProh() == YES) +// if(AskShareProh() == YES) + if(AskReuseCmdSkt() == NO || AskShareProh() == YES) { - if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) +// if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) + if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0) { - if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE) +// if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE) + if(CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "CWD %s", Pos->RemoteFile)/100 != FTP_COMPLETE) { DispCWDerror(hWndTrans); ClearAll = YES; } } } - strcpy(CurDir, TransPacketBase->RemoteFile); +// strcpy(CurDir, TransPacketBase->RemoteFile); + strcpy(CurDir[Pos->ThreadCount], Pos->RemoteFile); + ReleaseMutex(hListAccMutex); } - /* ƒJƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠ‚ð–ß‚· */ - else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0) + /* カレントディレクトリを戻す */ +// else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0) + else if(strcmp(Pos->Cmd, "BACKCUR") == 0) { - if(AskShareProh() == NO) +// if(AskShareProh() == NO) + if(AskReuseCmdSkt() == YES && AskShareProh() == NO) { - if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) - CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile); - strcpy(CurDir, TransPacketBase->RemoteFile); +// if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0) +// CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile); +// strcpy(CurDir, TransPacketBase->RemoteFile); + if(strcmp(CurDir[Pos->ThreadCount], Pos->RemoteFile) != 0) + CommandProcTrn(TrnSkt, NULL, &Canceled[Pos->ThreadCount], "CWD %s", Pos->RemoteFile); + strcpy(CurDir[Pos->ThreadCount], Pos->RemoteFile); } + ReleaseMutex(hListAccMutex); } - /* Ž©“®I—¹‚Ì‚½‚ß‚Ì’Ê’m */ - else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0) + /* 自動終了のための通知 */ +// else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0) + else if(strcmp(Pos->Cmd, "GOQUIT") == 0) { + ReleaseMutex(hListAccMutex); GoExit = YES; } + else + ReleaseMutex(hListAccMutex); - /*===== ‚P‚‚̏ˆ—I‚í‚è =====*/ + /*===== 1つの処理終わり =====*/ if(ForceAbort == NO) { - WaitForSingleObject(hListAccMutex, INFINITE); +// WaitForSingleObject(hListAccMutex, INFINITE); + while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT) + { + BackgrndMessageProc(); + Sleep(1); + } if(ClearAll == YES) +// EraseTransFileList(); + { + for(i = 0; i < MAX_DATA_CONNECTION; i++) + Canceled[i] = YES; EraseTransFileList(); + Pos = NULL; + } else { - if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) || - (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)) +// if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) || +// (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)) + if((strncmp(Pos->Cmd, "RETR", 4) == 0) || + (strncmp(Pos->Cmd, "STOR", 4) == 0)) { - TransFiles--; +// TransFiles--; + if(TransFiles > 0) + TransFiles--; PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0); } - Pos = TransPacketBase; - TransPacketBase = TransPacketBase->Next; - free(Pos); +// Pos = TransPacketBase; +// TransPacketBase = TransPacketBase->Next; +// free(Pos); } ClearAll = NO; ReleaseMutex(hListAccMutex); @@ -822,8 +1116,13 @@ static ULONG WINAPI TransferThread(void *Dummy) ReleaseMutex(hListAccMutex); } } + if(hWndTrans != NULL) + SendMessage(hWndTrans, WM_SET_PACKET, 0, 0); + if(Pos != NULL) + strcpy(Pos->Cmd, ""); } - else +// else + else if(TransPacketBase == NULL) { DelNotify = NO; @@ -835,57 +1134,93 @@ static ULONG WINAPI TransferThread(void *Dummy) DestroyWindow(hWndTrans); hWndTrans = NULL; - if(GoExit == YES) - { - SoundPlay(SND_TRANS); - - if(AskAutoExit() == NO) - { - if(Down == YES) - PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0); - if(Up == YES) - PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0); - } - Down = NO; - Up = NO; - } +// if(GoExit == YES) +// { +// SoundPlay(SND_TRANS); +// +// if(AskAutoExit() == NO) +// { +// if(Down == YES) +// PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0); +// if(Up == YES) +// PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0); +// } +// Down = NO; +// Up = NO; +// } } } BackgrndMessageProc(); +// Sleep(1); + Sleep(100); if(GoExit == YES) { + SoundPlay(SND_TRANS); + if(AskAutoExit() == NO) + { + if(Down == YES) + PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0); + if(Up == YES) + PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0); + } + Down = NO; + Up = NO; PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0); GoExit = NO; } } + else + { + ReleaseMutex(hListAccMutex); + if(hWndTrans != NULL) + { + DestroyWindow(hWndTrans); + hWndTrans = NULL; + } + BackgrndMessageProc(); + if(ThreadCount < AskMaxThreadCount()) + Sleep(1); + else + Sleep(100); + } + } + if(AskReuseCmdSkt() == NO || ThreadCount > 0) + { + if(TrnSkt != INVALID_SOCKET) + { + SendData(TrnSkt, "QUIT\r\n", 6, 0, &Canceled[ThreadCount]); + DoClose(TrnSkt); + } } return 0; } -/*----- ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢ƒtƒ@ƒCƒ‹ƒAƒNƒZƒX‚̏€”õ ------------------------------ +/*----- フルパスを使わないファイルアクセスの準備 ------------------------------ * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒpƒPƒbƒg -* char *Cur : ƒJƒŒƒ“ƒgƒfƒBƒŒƒNƒgƒŠ -* char *Tmp : ì‹Æ—pƒGƒŠƒA +* TRANSPACKET *Pkt : 転送パケット +* char *Cur : カレントディレクトリ +* char *Tmp : 作業用エリア * * Return Value -* int ƒXƒe[ƒ^ƒX(SUCCESS/FAIL) +* int ステータス(FFFTP_SUCCESS/FFFTP_FAIL) * * Note -* ƒtƒ‹ƒpƒX‚ðŽg‚í‚È‚¢Žž‚́A -* ‚±‚̃‚ƒWƒ…[ƒ‹“à‚Å CWD ‚ðs‚È‚¢A -* Pkt->RemoteFile ‚Ƀtƒ@ƒCƒ‹–¼‚Ì‚ÝŽc‚·BiƒpƒX–¼‚͏Á‚·j +* フルパスを使わない時は、 +* このモジュール内で CWD を行ない、 +* Pkt->RemoteFile にファイル名のみ残す。(パス名は消す) *----------------------------------------------------------------------------*/ +// 同時接続対応 static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp) { int Sts; - Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1); - if(Sts == FAIL) +// Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1); + Sts = ProcForNonFullpath(Pkt->ctrl_skt, Pkt->RemoteFile, Cur, Pkt->hWndTrans, &Canceled[Pkt->ThreadCount]); + if(Sts == FFFTP_FAIL) ClearAll = YES; return(Sts); @@ -894,19 +1229,19 @@ static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp) -/*----- ƒ_ƒEƒ“ƒ[ƒh‚ðs‚È‚¤ -------------------------------------------------- +/*----- ダウンロードを行なう -------------------------------------------------- * * Parameter -* SOCKET cSkt : ƒRƒ“ƒgƒ[ƒ‹ƒ\ƒPƒbƒg -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* int DirList : ƒfƒBƒŒƒNƒgƒŠƒŠƒXƒg‚̃_ƒEƒ“ƒ[ƒh(YES/NO) +* SOCKET cSkt : コントロールソケット +* TRANSPACKET *Pkt : 転送ファイル情報 +* int DirList : ディレクトリリストのダウンロード(YES/NO) * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード * * Note -* ‚±‚̃‚ƒWƒ…[ƒ‹‚́Aƒtƒ@ƒCƒ‹ˆê——‚̎擾‚È‚Ç‚ðs‚È‚¤Û‚ɃƒCƒ“‚̃XƒŒƒbƒh -* ‚©‚ç‚àŒÄ‚΂ê‚éBƒƒCƒ“‚̃XƒŒƒbƒh‚©‚çŒÄ‚΂ê‚鎞‚Í Pkt->hWndTrans == NULLB +* このモジュールは、ファイル一覧の取得などを行なう際にメインのスレッド +* からも呼ばれる。メインのスレッドから呼ばれる時は Pkt->hWndTrans == NULL。 *----------------------------------------------------------------------------*/ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) @@ -931,7 +1266,9 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) { if(Pkt->hWndTrans != NULL) { - AllTransSizeNow = 0; + // 同時接続対応 +// AllTransSizeNow = 0; + AllTransSizeNow[Pkt->ThreadCount] = 0; if(DirList == NO) DispTransFileInfo(Pkt, MSGJPN086, TRUE, YES); @@ -962,13 +1299,13 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork) } -/*----- ’ʏ탂[ƒh‚Ńtƒ@ƒCƒ‹‚ðƒ_ƒEƒ“ƒ[ƒh ------------------------------------ +/*----- 通常モードでファイルをダウンロード ------------------------------------ * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) @@ -990,7 +1327,9 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - if(SocksGet2ndBindReply(listen_socket, &data_socket) == FAIL) + // 同時接続対応 +// if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + if(SocksGet2ndBindReply(listen_socket, &data_socket, CancelCheckWork) == FFFTP_FAIL) { iLength = sizeof(saSockAddr1); data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength); @@ -1011,7 +1350,19 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) if(data_socket != INVALID_SOCKET) { - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); + // FTPS対応 +// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(IsSSLAttached(Pkt->ctrl_skt)) + { + if(AttachSSL(data_socket, Pkt->ctrl_skt, CancelCheckWork)) + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + else + iRetCode = 500; + } + else + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } } @@ -1037,13 +1388,13 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) } -/*----- Passiveƒ‚[ƒh‚Ńtƒ@ƒCƒ‹‚ðƒ_ƒEƒ“ƒ[ƒh --------------------------------- +/*----- Passiveモードでファイルをダウンロード --------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) @@ -1060,10 +1411,12 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV"); if(iRetCode/100 == FTP_COMPLETE) { - if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == SUCCESS) + if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) { if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET) { + // 変数が未初期化のバグ修正 + Flg = 1; if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR) ReportWSError("setsockopt", WSAGetLastError()); @@ -1073,7 +1426,19 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); + // FTPS対応 +// iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + if(IsSSLAttached(Pkt->ctrl_skt)) + { + if(AttachSSL(data_socket, Pkt->ctrl_skt, CancelCheckWork)) + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); + else + iRetCode = 500; + } + else + iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork); // data_socket = DoClose(data_socket); } else @@ -1106,20 +1471,20 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork) } -/*----- ƒ_ƒEƒ“ƒ[ƒh‚ÌŽÀs ---------------------------------------------------- +/*----- ダウンロードの実行 ---------------------------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* SOCKET dSkt : ƒf[ƒ^ƒ\ƒPƒbƒg -* int CreateMode : ƒtƒ@ƒCƒ‹ì¬ƒ‚[ƒh (CREATE_ALWAYS/OPEN_ALWAYS) +* TRANSPACKET *Pkt : 転送ファイル情報 +* SOCKET dSkt : データソケット +* int CreateMode : ファイル作成モード (CREATE_ALWAYS/OPEN_ALWAYS) * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード * * Note -* “]‘—‚ÌŒo‰ß•\Ž¦‚Í -* ƒ_ƒCƒAƒƒO‚ðo‚·(Pkt->hWndTrans!=NULL)ê‡AƒCƒ“ƒ^[ƒoƒ‹ƒ^ƒCƒ}‚ÅŒo‰ß‚ð•\Ž¦‚·‚é -* ƒ_ƒCƒAƒƒO‚ðo‚³‚È‚¢ê‡A‚±‚̃‹[ƒ`ƒ“‚©‚çDispDownloadSize()‚ðŒÄ‚Ô +* 転送の経過表示は +* ダイアログを出す(Pkt->hWndTrans!=NULL)場合、インターバルタイマで経過を表示する +* ダイアログを出さない場合、このルーチンからDispDownloadSize()を呼ぶ *----------------------------------------------------------------------------*/ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork) @@ -1149,6 +1514,12 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc /* End */ #endif + // 念のため受信バッファを無効にする +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS + int buf_size = 0; + setsockopt(dSkt, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)); +#endif + Pkt->Abort = ABORT_NONE; Sec.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -1157,28 +1528,41 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc dwFileAttributes = GetFileAttributes(Pkt->LocalFile); if (dwFileAttributes != INVALID_FILE_ATTRIBUTES && (dwFileAttributes & FILE_ATTRIBUTE_READONLY)) { - // “Ç‚ÝŽæ‚èê—p + // 読み取り専用 if (MessageBox(GetMainHwnd(), MSGJPN296, MSGJPN086, MB_YESNO) == IDYES) { - // ‘®«‚ð‰ðœ + // 属性を解除 SetFileAttributes(Pkt->LocalFile, dwFileAttributes ^ FILE_ATTRIBUTE_READONLY); } } if((iFileHandle = CreateFile(Pkt->LocalFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &Sec, CreateMode, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE) { + // UTF-8対応 + char Buf3[(BUFSIZE + 3) * 4]; + CODECONVINFO cInfo2; + int ProcessedBOM = NO; + // 4GB超対応(kaokunさん提供) + DWORD High = 0; if(CreateMode == OPEN_ALWAYS) - SetFilePointer(iFileHandle, 0, 0, FILE_END); + // 4GB超対応(kaokunさん提供) +// SetFilePointer(iFileHandle, 0, 0, FILE_END); + SetFilePointer(iFileHandle, 0, &High, FILE_END); if(Pkt->hWndTrans != NULL) { - TimeStart = time(NULL); + // 同時接続対応 +// TimeStart = time(NULL); + TimeStart[Pkt->ThreadCount] = time(NULL); SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL); } InitCodeConvInfo(&cInfo); cInfo.KanaCnv = Pkt->KanaCnv; - /*===== ƒtƒ@ƒCƒ‹‚ðŽóM‚·‚郋[ƒv =====*/ + InitCodeConvInfo(&cInfo2); + cInfo2.KanaCnv = Pkt->KanaCnv; + + /*===== ファイルを受信するループ =====*/ while((Pkt->Abort == ABORT_NONE) && (ForceAbort == NO)) { // FD_ZERO(&ReadFds); @@ -1225,7 +1609,7 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc break; } - /* Š¿ŽšƒR[ƒh•ÏŠ· */ + /* 漢字コード変換 */ if(Pkt->KanjiCode != KANJI_NOCNV) { cInfo.Str = Buf; @@ -1234,11 +1618,271 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc cInfo.BufSize = BUFSIZE+3; do { - if(Pkt->KanjiCode == KANJI_JIS) - Continue = ConvJIStoSJIS(&cInfo); - else - Continue = ConvEUCtoSJIS(&cInfo); - if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE) + // ここで全てUTF-8へ変換する + // TODO: SJIS以外も直接UTF-8へ変換 +// if(Pkt->KanjiCode == KANJI_JIS) +// Continue = ConvJIStoSJIS(&cInfo); +// else +// Continue = ConvEUCtoSJIS(&cInfo); + char Buf3[(BUFSIZE + 3) * 4]; + CODECONVINFO cInfo2; + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvSJIStoJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvJIStoSJIS(&cInfo2); + break; + case KANJI_JIS: + Continue = ConvSJIStoJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_EUC: + Continue = ConvSJIStoEUC(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8N: + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_JIS: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + Continue = ConvJIStoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_EUC: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + Continue = ConvEUCtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_UTF8N: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0) + { + cInfo.Str += 3; + cInfo.StrLen -= 3; + } + cInfo2.OutLen = 0; + switch(Pkt->KanjiCodeDesired) + { + case KANJI_UTF8BOM: + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + break; + } + Continue = YES; + ProcessedBOM = YES; + break; + } + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + } +// if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE) + if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE) Pkt->Abort = ABORT_DISKFULL; } while((Continue == YES) && (Pkt->Abort == ABORT_NONE)); @@ -1251,10 +1895,12 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc Pkt->ExistSize += iNumBytes; if(Pkt->hWndTrans != NULL) - AllTransSizeNow += iNumBytes; + // 同時接続対応 +// AllTransSizeNow += iNumBytes; + AllTransSizeNow[Pkt->ThreadCount] += iNumBytes; else { - /* “]‘—ƒ_ƒCƒAƒƒO‚ðo‚³‚È‚¢Žž‚ÌŒo‰ß•\Ž¦ */ + /* 転送ダイアログを出さない時の経過表示 */ DispDownloadSize(Pkt->ExistSize); } @@ -1262,30 +1908,208 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc ForceAbort = YES; } - /* ‘‚«Žc‚µ‚½ƒf[ƒ^‚ð‘‚«ž‚Þ */ + /* 書き残したデータを書き込む */ if(Pkt->KanjiCode != KANJI_NOCNV) { cInfo.Buf = Buf2; cInfo.BufSize = BUFSIZE+3; FlushRestData(&cInfo); - if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE) + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvJIStoSJIS(&cInfo2); + break; + case KANJI_JIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_EUC: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_JIS: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_EUC: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_UTF8N: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_UTF8BOM: + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + } +// if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE) + if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE) + Pkt->Abort = ABORT_DISKFULL; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + FlushRestData(&cInfo2); + if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE) Pkt->Abort = ABORT_DISKFULL; } - /* ƒOƒ‰ƒt•\Ž¦‚ðXV */ + /* グラフ表示を更新 */ if(Pkt->hWndTrans != NULL) { KillTimer(Pkt->hWndTrans, TIMER_DISPLAY); DispTransferStatus(Pkt->hWndTrans, YES, Pkt); - TimeStart = time(NULL) - TimeStart + 1; + // 同時接続対応 +// TimeStart = time(NULL) - TimeStart + 1; + TimeStart[Pkt->ThreadCount] = time(NULL) - TimeStart[Pkt->ThreadCount] + 1; } else { - /* “]‘—ƒ_ƒCƒAƒƒO‚ðo‚³‚È‚¢Žž‚ÌŒo‰ß•\Ž¦‚ðÁ‚· */ + /* 転送ダイアログを出さない時の経過表示を消す */ DispDownloadSize(-1); } - /* ƒtƒ@ƒCƒ‹‚̃^ƒCƒ€ƒXƒ^ƒ“ƒv‚ð‡‚í‚¹‚é */ + /* ファイルのタイムスタンプを合わせる */ if((SaveTimeStamp == YES) && ((Pkt->Time.dwLowDateTime != 0) || (Pkt->Time.dwHighDateTime != 0))) { @@ -1312,10 +2136,10 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc if(ForceAbort == NO) { - /* Abort‚ðƒzƒXƒg‚É“`‚¦‚é */ + /* Abortをホストに伝える */ if(Pkt->Abort != ABORT_NONE && iFileHandle != INVALID_HANDLE_VALUE) { - SendData(Pkt->ctrl_skt, "\xFF\xF4\xFF", 3, MSG_OOB, CancelCheckWork); /* MSG_OOB‚É’ˆÓ */ + SendData(Pkt->ctrl_skt, "\xFF\xF4\xFF", 3, MSG_OOB, CancelCheckWork); /* MSG_OOBに注意 */ SendData(Pkt->ctrl_skt, "\xF2", 1, 0, CancelCheckWork); command(Pkt->ctrl_skt, NULL, CancelCheckWork, "ABOR"); } @@ -1340,14 +2164,14 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc } -/*----- ƒ_ƒEƒ“ƒ[ƒhI—¹^’†Ž~Žž‚̃ƒbƒZ[ƒW‚ð•\Ž¦ ---------------------------- +/*----- ダウンロード終了/中止時のメッセージを表示 ---------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* int iRetCode : ‰ž“šƒR[ƒh +* TRANSPACKET *Pkt : 転送ファイル情報 +* int iRetCode : 応答コード * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) @@ -1361,8 +2185,8 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) strcpy(Fname, Pkt->RemoteFile); #if defined(HAVE_OPENVMS) - /* OpenVMS‚̏ꍇA‹óƒfƒBƒŒƒNƒgƒŠ‚ÖˆÚ“®‚·‚é‚Æ550 File not found‚É‚È‚Á‚Ä - * ƒGƒ‰[ƒ_ƒCƒAƒƒO‚âƒGƒ‰[ƒƒbƒZ[ƒW‚ªo‚é‚̂ʼn½‚à‚µ‚È‚¢ */ + /* OpenVMSの場合、空ディレクトリへ移動すると550 File not foundになって + * エラーダイアログやエラーメッセージが出るので何もしない */ if (AskHostType() == HTYPE_VMS) return; #endif @@ -1372,14 +2196,19 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) SetTaskMsg(MSGJPN097); strcpy(Fname, MSGJPN098); } - else if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) - SetTaskMsg(MSGJPN099, TimeStart, Pkt->ExistSize/TimeStart); + // 同時接続対応 +// else if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) +// SetTaskMsg(MSGJPN099, TimeStart, Pkt->ExistSize/TimeStart); + else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0)) + SetTaskMsg(MSGJPN099, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); else SetTaskMsg(MSGJPN100); if(Pkt->Abort != ABORT_USER) { - if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) + // 全て中止を選択後にダイアログが表示されるバグ対策 +// if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) + if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO) ClearAll = YES; } } @@ -1387,8 +2216,14 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0)) SetTaskMsg(MSGJPN101, Pkt->ExistSize); - else if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) - SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart); + // 同時接続対応 +// else if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) +// SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart); + else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0)) + // "0 B/S"と表示されるバグを修正 + // 原因は%dにあたる部分に64ビット値が渡されているため +// SetTaskMsg(MSGJPN102, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); + SetTaskMsg(MSGJPN102, (LONG)TimeStart[Pkt->ThreadCount], (LONG)(Pkt->ExistSize/TimeStart[Pkt->ThreadCount])); else SetTaskMsg(MSGJPN103, Pkt->ExistSize); } @@ -1397,15 +2232,15 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode) } -/*----- ƒ_ƒEƒ“ƒ[ƒh^ƒAƒbƒvƒ[ƒhƒGƒ‰[‚̃_ƒCƒAƒƒO‚ð•\Ž¦ -------------------- +/*----- ダウンロード/アップロードエラーのダイアログを表示 -------------------- * * Parameter -* int RedID : ƒ_ƒCƒAƒƒOƒ{ƒbƒNƒX‚̃Šƒ\[ƒXID -* HWND hWnd : ‘‚«ž‚Ý’†ƒ_ƒCƒAƒƒO‚̃EƒCƒ“ƒhƒE -* char *Fname : ƒtƒ@ƒCƒ‹–¼ +* int RedID : ダイアログボックスのリソースID +* HWND hWnd : 書き込み中ダイアログのウインドウ +* char *Fname : ファイル名 * * Return Value -* int ƒXƒe[ƒ^ƒX (YES=’†Ž~/NO=‘S‚Ä’†Ž~) +* int ステータス (YES=中止/NO=全て中止) *----------------------------------------------------------------------------*/ static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) @@ -1418,13 +2253,13 @@ static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname) } -/*----- ƒ_ƒEƒ“ƒ[ƒhƒGƒ‰[^ƒAƒbƒvƒ[ƒhƒGƒ‰[ƒ_ƒCƒAƒƒO‚̃R[ƒ‹ƒoƒbƒN -------- +/*----- ダウンロードエラー/アップロードエラーダイアログのコールバック -------- * * Parameter -* HWND hDlg : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* UINT message : ƒƒbƒZ[ƒW”ԍ† -* WPARAM wParam : ƒƒbƒZ[ƒW‚Ì WPARAM ˆø” -* LPARAM lParam : ƒƒbƒZ[ƒW‚Ì LPARAM ˆø” +* HWND hDlg : ウインドウハンドル +* UINT message : メッセージ番号 +* WPARAM wParam : メッセージの WPARAM 引数 +* LPARAM lParam : メッセージの LPARAM 引数 * * Return Value * BOOL TRUE/FALSE @@ -1436,7 +2271,9 @@ static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wPara { case WM_INITDIALOG : SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam); - SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg); + // 同時接続対応 +// SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg); + SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)GetErrMsg()); return(TRUE); case WM_COMMAND : @@ -1456,19 +2293,19 @@ static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wPara } -/*----- ƒ_ƒEƒ“ƒ[ƒh‚̃ŠƒWƒ…[ƒ€‚̏€”õ‚ðs‚¤ ---------------------------------- +/*----- ダウンロードのリジュームの準備を行う ---------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* iont ProcMode : ˆ—ƒ‚[ƒh(EXIST_xxx) -* LONGLONG Size : ƒ[ƒhÏ‚݂̃tƒ@ƒCƒ‹‚̃TƒCƒY -* int *Mode : ƒtƒ@ƒCƒ‹ì¬ƒ‚[ƒh (CREATE_xxxx) +* TRANSPACKET *Pkt : 転送ファイル情報 +* iont ProcMode : 処理モード(EXIST_xxx) +* LONGLONG Size : ロード済みのファイルのサイズ +* int *Mode : ファイル作成モード (CREATE_xxxx) * * Return Value -* int “]‘—‚ðs‚¤‚©‚Ç‚¤‚©(YES/NO=‚±‚̃tƒ@ƒCƒ‹‚𒆎~/NO_ALL=‘S‚Ä’†Ž~) +* int 転送を行うかどうか(YES/NO=このファイルを中止/NO_ALL=全て中止) * * Note -* Pkt->ExistSize‚̃Zƒbƒg‚ðs‚È‚¤ +* Pkt->ExistSizeのセットを行なう *----------------------------------------------------------------------------*/ static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode, int *CancelCheckWork) @@ -1488,7 +2325,7 @@ static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "REST %s", MakeNumString(Size, Tmp, FALSE)); if(iRetCode/100 < FTP_RETRY) { - /* ƒŠƒWƒ…[ƒ€ */ + /* リジューム */ if(Pkt->hWndTrans != NULL) Pkt->ExistSize = Size; *Mode = OPEN_ALWAYS; @@ -1498,7 +2335,7 @@ static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int Com = DialogBox(GetFtpInst(), MAKEINTRESOURCE(noresume_dlg), Pkt->hWndTrans, NoResumeWndProc); if(Com != YES) { - if(Com == NO_ALL) /* ‘S‚Ä’†Ž~ */ + if(Com == NO_ALL) /* 全て中止 */ ClearAll = YES; Pkt->Abort = ABORT_USER; } @@ -1508,13 +2345,13 @@ static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int } -/*----- resumeƒGƒ‰[ƒ_ƒCƒAƒƒO‚̃R[ƒ‹ƒoƒbƒN ---------------------------------- +/*----- resumeエラーダイアログのコールバック ---------------------------------- * * Parameter -* HWND hDlg : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* UINT message : ƒƒbƒZ[ƒW”ԍ† -* WPARAM wParam : ƒƒbƒZ[ƒW‚Ì WPARAM ˆø” -* LPARAM lParam : ƒƒbƒZ[ƒW‚Ì LPARAM ˆø” +* HWND hDlg : ウインドウハンドル +* UINT message : メッセージ番号 +* WPARAM wParam : メッセージの WPARAM 引数 +* LPARAM lParam : メッセージの LPARAM 引数 * * Return Value * BOOL TRUE/FALSE @@ -1549,14 +2386,14 @@ static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LP -/*----- ƒAƒbƒvƒ[ƒh‚ðs‚È‚¤ -------------------------------------------------- +/*----- アップロードを行なう -------------------------------------------------- * * Parameter -* SOCKET cSkt : ƒRƒ“ƒgƒ[ƒ‹ƒ\ƒPƒbƒg -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* SOCKET cSkt : コントロールソケット +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) @@ -1568,12 +2405,14 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) if(Pkt->Mode != EXIST_IGNORE) { - if(CheckFileReadable(Pkt->LocalFile) == SUCCESS) + if(CheckFileReadable(Pkt->LocalFile) == FFFTP_SUCCESS) { if(Pkt->Type == TYPE_I) Pkt->KanjiCode = KANJI_NOCNV; - iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "TYPE %c", Pkt->Type); + // 同時接続対応 +// iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "TYPE %c", Pkt->Type); + iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "TYPE %c", Pkt->Type); if(iRetCode/100 < FTP_RETRY) { if(Pkt->Mode == EXIST_UNIQUE) @@ -1595,9 +2434,11 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) else SetErrorMsg(Reply); - /* ‘®«•ÏX */ + /* 属性変更 */ if((Pkt->Attr != -1) && ((iRetCode/100) == FTP_COMPLETE)) - command(Pkt->ctrl_skt, Reply, &Canceled, "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile); + // 同時接続対応 +// command(Pkt->ctrl_skt, Reply, &Canceled, "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile); + command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile); } else { @@ -1618,13 +2459,13 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt) } -/*----- ’ʏ탂[ƒh‚Ńtƒ@ƒCƒ‹‚ðƒAƒbƒvƒ[ƒh ------------------------------------ +/*----- 通常モードでファイルをアップロード ------------------------------------ * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ static int UpLoadNonPassive(TRANSPACKET *Pkt) @@ -1638,7 +2479,9 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) int Resume; char Reply[ERR_MSG_LEN+7]; - if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled)) != INVALID_SOCKET) + // 同時接続対応 +// if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled)) != INVALID_SOCKET) + if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET) { SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume); if(Resume == NO) @@ -1646,10 +2489,14 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) else sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile); - iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf); + // 同時接続対応 +// iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf); + iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf); if((iRetCode/100) == FTP_PRELIM) { - if(SocksGet2ndBindReply(listen_socket, &data_socket) == FAIL) + // 同時接続対応 +// if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL) + if(SocksGet2ndBindReply(listen_socket, &data_socket, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) { iLength=sizeof(saSockAddr1); data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength); @@ -1670,7 +2517,19 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) if(data_socket != INVALID_SOCKET) { - iRetCode = UpLoadFile(Pkt, data_socket); + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); + // FTPS対応 +// iRetCode = UpLoadFile(Pkt, data_socket); + if(IsSSLAttached(Pkt->ctrl_skt)) + { + if(AttachSSL(data_socket, Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount])) + iRetCode = UpLoadFile(Pkt, data_socket); + else + iRetCode = 500; + } + else + iRetCode = UpLoadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } } @@ -1693,13 +2552,13 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt) } -/*----- Passiveƒ‚[ƒh‚Ńtƒ@ƒCƒ‹‚ðƒAƒbƒvƒ[ƒh --------------------------------- +/*----- Passiveモードでファイルをアップロード --------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ +* TRANSPACKET *Pkt : 転送ファイル情報 * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ static int UpLoadPassive(TRANSPACKET *Pkt) @@ -1713,13 +2572,19 @@ static int UpLoadPassive(TRANSPACKET *Pkt) int Resume; char Reply[ERR_MSG_LEN+7]; - iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV"); + // 同時接続対応 +// iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV"); + iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV"); if(iRetCode/100 == FTP_COMPLETE) { - if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == SUCCESS) + if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS) { - if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET) + // 同時接続対応 +// if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET) + if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET) { + // 変数が未初期化のバグ修正 + Flg = 1; if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR) ReportWSError("setsockopt", WSAGetLastError()); @@ -1729,10 +2594,24 @@ static int UpLoadPassive(TRANSPACKET *Pkt) else sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile); - iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf); + // 同時接続対応 +// iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf); + iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf); if(iRetCode/100 == FTP_PRELIM) { - iRetCode = UpLoadFile(Pkt, data_socket); + // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため + ReleaseMutex(hListAccMutex); + // FTPS対応 +// iRetCode = UpLoadFile(Pkt, data_socket); + if(IsSSLAttached(Pkt->ctrl_skt)) + { + if(AttachSSL(data_socket, Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount])) + iRetCode = UpLoadFile(Pkt, data_socket); + else + iRetCode = 500; + } + else + iRetCode = UpLoadFile(Pkt, data_socket); data_socket = DoClose(data_socket); } @@ -1766,18 +2645,18 @@ static int UpLoadPassive(TRANSPACKET *Pkt) } -/*----- ƒAƒbƒvƒ[ƒh‚ÌŽÀs ---------------------------------------------------- +/*----- アップロードの実行 ---------------------------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* SOCKET dSkt : ƒf[ƒ^ƒ\ƒPƒbƒg +* TRANSPACKET *Pkt : 転送ファイル情報 +* SOCKET dSkt : データソケット * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード * * Note -* “]‘—‚ÌŒo‰ß•\Ž¦‚́AƒCƒ“ƒ^[ƒoƒ‹ƒ^ƒCƒ}‚ÅŒo‰ß‚ð•\Ž¦‚·‚é -* “]‘—ƒ_ƒCƒAƒƒO‚ðo‚³‚È‚¢‚ŃAƒbƒvƒ[ƒh‚·‚邱‚Æ‚Í‚È‚¢ +* 転送の経過表示は、インターバルタイマで経過を表示する +* 転送ダイアログを出さないでアップロードすることはない *----------------------------------------------------------------------------*/ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) @@ -1808,6 +2687,12 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) /* End */ #endif + // 念のため送信バッファを無効にする +#ifdef DISABLE_TRANSFER_NETWORK_BUFFERS + int buf_size = 0; + setsockopt(dSkt, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)); +#endif + Pkt->Abort = ABORT_NONE; Sec.nLength = sizeof(SECURITY_ATTRIBUTES); @@ -1817,6 +2702,10 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) if((iFileHandle = CreateFile(Pkt->LocalFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, &Sec, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE) { + // UTF-8対応 + char Buf3[(BUFSIZE + 3) * 4]; + CODECONVINFO cInfo2; + int ProcessedBOM = NO; if(Pkt->hWndTrans != NULL) { Low = GetFileSize(iFileHandle, &High); @@ -1826,8 +2715,11 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) Low = (DWORD)LOW32(Pkt->ExistSize); SetFilePointer(iFileHandle, Low, &High, FILE_BEGIN); - AllTransSizeNow = 0; - TimeStart = time(NULL); + // 同時接続対応 +// AllTransSizeNow = 0; +// TimeStart = time(NULL); + AllTransSizeNow[Pkt->ThreadCount] = 0; + TimeStart[Pkt->ThreadCount] = time(NULL); SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL); } @@ -1835,7 +2727,10 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo.KanaCnv = Pkt->KanaCnv; InitTermCodeConvInfo(&tInfo); - /*===== ƒtƒ@ƒCƒ‹‚𑗐M‚·‚郋[ƒv =====*/ + InitCodeConvInfo(&cInfo2); + cInfo2.KanaCnv = Pkt->KanaCnv; + + /*===== ファイルを送信するループ =====*/ while((Pkt->Abort == ABORT_NONE) && (ForceAbort == NO) && (ReadFile(iFileHandle, Buf, BUFSIZE, &iNumBytes, NULL) == TRUE)) @@ -1843,7 +2738,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) if(iNumBytes == 0) break; - /* EOFœ‹Ž */ + /* EOF除去 */ EofPos = NULL; if((RmEOF == YES) && (Pkt->Type == TYPE_A)) { @@ -1851,7 +2746,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) iNumBytes = EofPos - Buf; } - /* Š¿ŽšƒR[ƒh•ÏŠ· */ + /* 漢字コード変換 */ if(Pkt->KanjiCode != KANJI_NOCNV) { cInfo.Str = Buf; @@ -1860,12 +2755,270 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) cInfo.BufSize = BUFSIZE+3; do { - if(Pkt->KanjiCode == KANJI_JIS) - Continue = ConvSJIStoJIS(&cInfo); - else - Continue = ConvSJIStoEUC(&cInfo); + // ここで全てUTF-8へ変換する + // TODO: SJIS以外も直接UTF-8へ変換 +// if(Pkt->KanjiCode == KANJI_JIS) +// Continue = ConvSJIStoJIS(&cInfo); +// else +// Continue = ConvSJIStoEUC(&cInfo); + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvSJIStoJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvJIStoSJIS(&cInfo2); + break; + case KANJI_JIS: + Continue = ConvSJIStoJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_EUC: + Continue = ConvSJIStoEUC(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8N: + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvSJIStoUTF8N(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_JIS: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + Continue = ConvJIStoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvJIStoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_EUC: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + Continue = ConvEUCtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: +// memcpy(Buf3, cInfo.Str, cInfo.StrLen); +// cInfo2.OutLen = cInfo.StrLen; +// Continue = NO; + // カナ変換のため + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + Continue = ConvEUCtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_UTF8N: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + Continue = YES; + ProcessedBOM = YES; + break; + } + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + case KANJI_UTF8BOM: + if(ProcessedBOM == NO) + { + if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0) + { + cInfo.Str += 3; + cInfo.StrLen -= 3; + } + cInfo2.OutLen = 0; + switch(Pkt->KanjiCode) + { + case KANJI_UTF8BOM: + memcpy(Buf3, "\xEF\xBB\xBF", 3); + cInfo2.OutLen = 3; + break; + } + Continue = YES; + ProcessedBOM = YES; + break; + } + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + Continue = ConvUTF8NtoSJIS(&cInfo); + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Str, cInfo.StrLen); + cInfo2.OutLen = cInfo.StrLen; + Continue = NO; + break; + } + break; + } - if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FAIL) +// if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) { Pkt->Abort = ABORT_ERROR; break; @@ -1875,13 +3028,17 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) } else { - if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FAIL) + // 同時接続対応 +// if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; } Pkt->ExistSize += iNumBytes; if(Pkt->hWndTrans != NULL) - AllTransSizeNow += iNumBytes; + // 同時接続対応 +// AllTransSizeNow += iNumBytes; + AllTransSizeNow[Pkt->ThreadCount] += iNumBytes; if(BackgrndMessageProc() == YES) ForceAbort = YES; @@ -1892,30 +3049,210 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) if((ForceAbort == NO) && (Pkt->Abort == ABORT_NONE)) { - /* ‘—‚èŽc‚µ‚½ƒf[ƒ^‚𑗐M */ + /* 送り残したデータを送信 */ if(Pkt->KanjiCode != KANJI_NOCNV) { cInfo.Buf = Buf2; cInfo.BufSize = BUFSIZE+3; FlushRestData(&cInfo); + switch(Pkt->KanjiCodeDesired) + { + case KANJI_SJIS: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvJIStoSJIS(&cInfo2); + break; + case KANJI_JIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_EUC: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_JIS: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_EUC: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + // カナ変換のため + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + case KANJI_UTF8BOM: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoUTF8N(&cInfo2); + break; + } + break; + case KANJI_UTF8N: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + case KANJI_UTF8BOM: + switch(Pkt->KanjiCode) + { + case KANJI_SJIS: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_JIS: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoJIS(&cInfo2); + break; + case KANJI_EUC: + cInfo2.Str = cInfo.Buf; + cInfo2.StrLen = cInfo.OutLen; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + ConvSJIStoEUC(&cInfo2); + break; + case KANJI_UTF8N: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + case KANJI_UTF8BOM: + memcpy(Buf3, cInfo.Buf, cInfo.OutLen); + cInfo2.OutLen = cInfo.OutLen; + break; + } + break; + } - if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FAIL) +// if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL) + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) + Pkt->Abort = ABORT_ERROR; + cInfo2.Buf = Buf3; + cInfo2.BufSize = (BUFSIZE + 3) * 4; + FlushRestData(&cInfo2); + if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; } tInfo.Buf = Buf2; tInfo.BufSize = BUFSIZE+3; FlushRestTermCodeConvData(&tInfo); - if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled) == FAIL) + // 同時接続対応 +// if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled) == FFFTP_FAIL) + if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL) Pkt->Abort = ABORT_ERROR; } - /* ƒOƒ‰ƒt•\Ž¦‚ðXV */ + /* グラフ表示を更新 */ if(Pkt->hWndTrans != NULL) { KillTimer(Pkt->hWndTrans, TIMER_DISPLAY); DispTransferStatus(Pkt->hWndTrans, YES, Pkt); - TimeStart = time(NULL) - TimeStart + 1; + // 同時接続対応 +// TimeStart = time(NULL) - TimeStart + 1; + TimeStart[Pkt->ThreadCount] = time(NULL) - TimeStart[Pkt->ThreadCount] + 1; } CloseHandle(iFileHandle); } @@ -1935,7 +3272,9 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) ; #endif - iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled, TmpBuf); + // 同時接続対応 +// iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled, TmpBuf); + iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled[Pkt->ThreadCount], TmpBuf); //#pragma aaa //DoPrintf("##UP REPLY : %s", Buf); @@ -1950,28 +3289,30 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt) } -/*----- ƒoƒbƒtƒ@‚Ì“à—e‚ð‰üsƒR[ƒh•ÏŠ·‚µ‚Ä‘—M -------------------------------- +/*----- バッファの内容を改行コード変換して送信 -------------------------------- * * Parameter -* TERMCODECONVINFO *tInfo : ‰üsƒR[ƒh•ÏŠ·ƒpƒPƒbƒg -* SOCKET Skt : ƒ\ƒPƒbƒg -* char *Data : ƒf[ƒ^ -* int Size : ƒf[ƒ^‚̃TƒCƒY -* int Ascii : ƒ‚[ƒh@@(TYPE_xx) +* TERMCODECONVINFO *tInfo : 改行コード変換パケット +* SOCKET Skt : ソケット +* char *Data : データ +* int Size : データのサイズ +* int Ascii : モード  (TYPE_xx) * * Return Value -* int ‰ž“šƒR[ƒh +* int 応答コード *----------------------------------------------------------------------------*/ -static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii) +// 同時接続対応 +//static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii) +static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii, int *CancelCheckWork) { char Buf3[BUFSIZE*2]; int Continue; int Ret; - Ret = SUCCESS; + Ret = FFFTP_SUCCESS; -// CR-LFˆÈŠO‚̉üsƒR[ƒh‚ð•ÏŠ·‚µ‚È‚¢ƒ‚[ƒh‚Í‚±‚±‚֒ljÁ +// CR-LF以外の改行コードを変換しないモードはここへ追加 if(Ascii == TYPE_A) { tInfo->Str = Data; @@ -1981,26 +3322,30 @@ static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, do { Continue = ConvTermCodeToCRLF(tInfo); - if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled)) == FAIL) + // 同時接続対応 +// if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled)) == FFFTP_FAIL) + if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, CancelCheckWork)) == FFFTP_FAIL) break; } while(Continue == YES); } else - Ret = SendData(Skt, Data, Size, 0, &Canceled); + // 同時接続対応 +// Ret = SendData(Skt, Data, Size, 0, &Canceled); + Ret = SendData(Skt, Data, Size, 0, CancelCheckWork); return(Ret); } -/*----- ƒAƒbƒvƒ[ƒhI—¹^’†Ž~Žž‚̃ƒbƒZ[ƒW‚ð•\Ž¦ ---------------------------- +/*----- アップロード終了/中止時のメッセージを表示 ---------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* int iRetCode : ‰ž“šƒR[ƒh +* TRANSPACKET *Pkt : 転送ファイル情報 +* int iRetCode : 応答コード * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode) @@ -2009,21 +3354,32 @@ static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode) { if((iRetCode/100) >= FTP_CONTINUE) { - if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) - SetTaskMsg(MSGJPN113, TimeStart, Pkt->ExistSize/TimeStart); + // 同時接続対応 +// if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) +// SetTaskMsg(MSGJPN113, TimeStart, Pkt->ExistSize/TimeStart); + if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0)) + SetTaskMsg(MSGJPN113, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); else SetTaskMsg(MSGJPN114); if(Pkt->Abort != ABORT_USER) { - if(DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) + // 全て中止を選択後にダイアログが表示されるバグ対策 +// if(DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) + if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO) ClearAll = YES; } } else { - if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) - SetTaskMsg(MSGJPN115, TimeStart, Pkt->ExistSize/TimeStart); + // 同時接続対応 +// if((Pkt->hWndTrans != NULL) && (TimeStart != 0)) +// SetTaskMsg(MSGJPN115, TimeStart, Pkt->ExistSize/TimeStart); + if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0)) + // "0 B/S"と表示されるバグを修正 + // 原因は%dにあたる部分に64ビット値が渡されているため +// SetTaskMsg(MSGJPN115, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]); + SetTaskMsg(MSGJPN115, (LONG)TimeStart[Pkt->ThreadCount], (LONG)(Pkt->ExistSize/TimeStart[Pkt->ThreadCount])); else SetTaskMsg(MSGJPN116); } @@ -2032,19 +3388,19 @@ static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode) } -/*----- ƒAƒbƒvƒ[ƒh‚̃ŠƒWƒ…[ƒ€‚̏€”õ‚ðs‚¤ ---------------------------------- +/*----- アップロードのリジュームの準備を行う ---------------------------------- * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* iont ProcMode : ˆ—ƒ‚[ƒh(EXIST_xxx) -* LONGLONG Size : ƒzƒXƒg‚É‚ ‚éƒtƒ@ƒCƒ‹‚̃TƒCƒY -* int *Mode : ƒŠƒWƒ…[ƒ€‚ðs‚¤‚©‚Ç‚¤‚© (YES/NO) +* TRANSPACKET *Pkt : 転送ファイル情報 +* iont ProcMode : 処理モード(EXIST_xxx) +* LONGLONG Size : ホストにあるファイルのサイズ +* int *Mode : リジュームを行うかどうか (YES/NO) * * Return Value -* int ƒXƒe[ƒ^ƒX = YES +* int ステータス = YES * * Note -* Pkt->ExistSize‚̃Zƒbƒg‚ðs‚È‚¤ +* Pkt->ExistSizeのセットを行なう *----------------------------------------------------------------------------*/ static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode) @@ -2063,13 +3419,13 @@ static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *M } -/*----- “]‘—’†ƒ_ƒCƒAƒƒOƒ{ƒbƒNƒX‚̃R[ƒ‹ƒoƒbƒN -------------------------------- +/*----- 転送中ダイアログボックスのコールバック -------------------------------- * * Parameter -* HWND hDlg : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* UINT message : ƒƒbƒZ[ƒW”ԍ† -* WPARAM wParam : ƒƒbƒZ[ƒW‚Ì WPARAM ˆø” -* LPARAM lParam : ƒƒbƒZ[ƒW‚Ì LPARAM ˆø” +* HWND hDlg : ウインドウハンドル +* UINT message : メッセージ番号 +* WPARAM wParam : メッセージの WPARAM 引数 +* LPARAM lParam : メッセージの LPARAM 引数 * * Return Value * BOOL TRUE/FALSE @@ -2080,7 +3436,10 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM RECT RectDlg; RECT RectPar; HMENU hMenu; - static TRANSPACKET *Pkt; + // 同時接続対応 +// static TRANSPACKET *Pkt; + TRANSPACKET *Pkt; + int i; switch(Msg) { @@ -2109,11 +3468,16 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM case TRANS_STOP_ALL : ClearAll = YES; - /* ‚±‚±‚É break ‚Í‚È‚¢ */ + for(i = 0; i < MAX_DATA_CONNECTION; i++) + Canceled[i] = YES; + /* ここに break はない */ case IDCANCEL : + if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + break; Pkt->Abort = ABORT_USER; - Canceled = YES; +// Canceled = YES; + Canceled[Pkt->ThreadCount] = YES; break; } break; @@ -2125,27 +3489,32 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM SetForegroundWindow(hDlg); MoveToForeground = NO; KillTimer(hDlg, TIMER_DISPLAY); + if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA))) + break; + if(Canceled[Pkt->ThreadCount] == YES) + Pkt->Abort = ABORT_USER; DispTransferStatus(hDlg, NO, Pkt); SetTimer(hDlg, TIMER_DISPLAY, DISPLAY_TIMING, NULL); } break; case WM_SET_PACKET : - Pkt = (TRANSPACKET *)lParam; +// Pkt = (TRANSPACKET *)lParam; + SetWindowLong(hDlg, GWL_USERDATA, (LONG)lParam); break; } return(FALSE); } -/*----- “]‘—ƒXƒe[ƒ^ƒX‚ð•\Ž¦ -------------------------------------------------- +/*----- 転送ステータスを表示 -------------------------------------------------- * * Parameter -* HWND hWnd : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* int End : “]‘—‚ªŠ®—¹‚µ‚½‚©‚Ç‚¤‚© (YES/NO) +* HWND hWnd : ウインドウハンドル +* int End : 転送が完了したかどうか (YES/NO) * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt) @@ -2174,11 +3543,15 @@ static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt) { if(End == NO) { - TotalLap = time(NULL) - TimeStart + 1; + // 同時接続対応 +// TotalLap = time(NULL) - TimeStart + 1; + TotalLap = time(NULL) - TimeStart[Pkt->ThreadCount] + 1; Bps = 0; if(TotalLap != 0) - Bps = AllTransSizeNow / TotalLap; + // 同時接続対応 +// Bps = AllTransSizeNow / TotalLap; + Bps = AllTransSizeNow[Pkt->ThreadCount] / TotalLap; Transed = Pkt->Size - Pkt->ExistSize; if(Pkt->Size <= 0) @@ -2225,16 +3598,16 @@ static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt) } -/*----- “]‘—‚·‚éƒtƒ@ƒCƒ‹‚̏î•ñ‚ð•\Ž¦ ------------------------------------------ +/*----- 転送するファイルの情報を表示 ------------------------------------------ * * Parameter -* TRANSPACKET *Pkt : “]‘—ƒtƒ@ƒCƒ‹î•ñ -* char *Title : ƒEƒCƒ“ƒhƒE‚̃^ƒCƒgƒ‹ -* int SkipButton : u‚±‚̃tƒ@ƒCƒ‹‚𒆎~vƒ{ƒ^ƒ“‚Ì—L–³ (TRUE/FALSE) -* int Info : ƒtƒ@ƒCƒ‹î•ñ‚ð•\Ž¦‚·‚é‚©‚Ç‚¤‚© (YES/NO) +* TRANSPACKET *Pkt : 転送ファイル情報 +* char *Title : ウインドウのタイトル +* int SkipButton : 「このファイルを中止」ボタンの有無 (TRUE/FALSE) +* int Info : ファイル情報を表示するかどうか (YES/NO) * * Return Value -* ‚È‚µ +* なし *----------------------------------------------------------------------------*/ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int Info) @@ -2263,12 +3636,19 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int else if(Pkt->Type == TYPE_A) SendDlgItemMessage(Pkt->hWndTrans, TRANS_MODE, WM_SETTEXT, 0, (LPARAM)MSGJPN120); + // UTF-8対応 if(Pkt->KanjiCode == KANJI_NOCNV) SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN121); + else if(Pkt->KanjiCode == KANJI_SJIS) + SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN305); else if(Pkt->KanjiCode == KANJI_JIS) SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN122); else if(Pkt->KanjiCode == KANJI_EUC) SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN123); + else if(Pkt->KanjiCode == KANJI_UTF8N) + SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN306); + else if(Pkt->KanjiCode == KANJI_UTF8BOM) + SendDlgItemMessage(Pkt->hWndTrans, TRANS_KANJI, WM_SETTEXT, 0, (LPARAM)MSGJPN329); } else { @@ -2282,17 +3662,17 @@ static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int } -/*----- PASVƒRƒ}ƒ“ƒh‚Ì–ß‚è’l‚©‚çƒAƒhƒŒƒX‚ƃ|[ƒg”ԍ†‚𒊏o -------------------- +/*----- PASVコマンドの戻り値からアドレスとポート番号を抽出 -------------------- * * Parameter -* char *Str : PASVƒRƒ}ƒ“ƒh‚̃Šƒvƒ‰ƒC -* char *Adrs : ƒAƒhƒŒƒX‚̃Rƒs[æ ("www.xxx.yyy.zzz") -* int *Port : ƒ|[ƒg”ԍ†‚ðƒZƒbƒg‚·‚郏[ƒN -* int Max : ƒAƒhƒŒƒX•¶Žš—ñ‚̍ő咷 +* char *Str : PASVコマンドのリプライ +* char *Adrs : アドレスのコピー先 ("www.xxx.yyy.zzz") +* int *Port : ポート番号をセットするワーク +* int Max : アドレス文字列の最大長 * * Return Value -* int ƒXƒe[ƒ^ƒX -* SUCCESS/FAIL +* int ステータス +* FFFTP_SUCCESS/FFFTP_FAIL *----------------------------------------------------------------------------*/ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) @@ -2301,25 +3681,37 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) char *Btm; int Sts; - Sts = FAIL; + Sts = FFFTP_FAIL; Pos = strchr(Str, '('); if(Pos != NULL) { Pos++; Btm = strchr(Pos, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Pos, '.'); if(Btm != NULL) { Btm++; Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Btm, '.'); if(Btm != NULL) { Btm++; Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Btm, '.'); if(Btm != NULL) { Btm++; Btm = strchr(Btm, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Btm, '.'); if(Btm != NULL) { if((Btm - Pos) <= Max) @@ -2330,11 +3722,14 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) Pos = Btm + 1; Btm = strchr(Pos, ','); + // コンマではなくドットを返すホストがあるため + if(Btm == NULL) + Btm = strchr(Pos, '.'); if(Btm != NULL) { Btm++; *Port = (atoi(Pos) * 0x100) + atoi(Btm); - Sts = SUCCESS; + Sts = FFFTP_SUCCESS; } } } @@ -2346,13 +3741,66 @@ static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max) } -/*----- Windows‚̃XƒyƒVƒƒƒ‹ƒfƒoƒCƒX‚©‚Ç‚¤‚©‚ð•Ô‚· ----------------------------- +// IPv6対応 +static int GetAdrsAndPortIPv6(char *Str, char *Adrs, int *Port, int Max, short *Family) +{ + char *Pos; + char *Btm; + int Sts; + + Sts = FFFTP_FAIL; + + Pos = strchr(Str, '|'); + if(Pos != NULL) + { + Pos++; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + switch(atoi(Pos)) + { + case 1: + *Family = AF_INET; + break; + case 2: + *Family = AF_INET6; + break; + } + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + if((Btm - Pos) <= Max) + { + if((Btm - Pos) > 0) + { + strncpy(Adrs, Pos, Btm - Pos); + *(Adrs + (Btm - Pos)) = NUL; + } + + Pos = Btm + 1; + Btm = strchr(Pos, '|'); + if(Btm != NULL) + { + Btm++; + *Port = atoi(Pos); + Sts = FFFTP_SUCCESS; + } + } + } + } + } + return(Sts); +} + + +/*----- Windowsのスペシャルデバイスかどうかを返す ----------------------------- * * Parameter -* char *Fname : ƒtƒ@ƒCƒ‹–¼ +* char *Fname : ファイル名 * * Return Value -* int ƒXƒe[ƒ^ƒX (YES/NO) +* int ステータス (YES/NO) *----------------------------------------------------------------------------*/ static int IsSpecialDevice(char *Fname) @@ -2360,20 +3808,34 @@ static int IsSpecialDevice(char *Fname) int Sts; Sts = NO; - if((_stricmp(Fname, "CON") == 0) || - (_stricmp(Fname, "PRN") == 0) || - (_stricmp(Fname, "AUX") == 0) || - (_strnicmp(Fname, "CON.", 4) == 0) || - (_strnicmp(Fname, "PRN.", 4) == 0) || - (_strnicmp(Fname, "AUX.", 4) == 0)) + // 比較が不完全なバグ修正 +// if((_stricmp(Fname, "CON") == 0) || +// (_stricmp(Fname, "PRN") == 0) || +// (_stricmp(Fname, "AUX") == 0) || +// (_strnicmp(Fname, "CON.", 4) == 0) || +// (_strnicmp(Fname, "PRN.", 4) == 0) || +// (_strnicmp(Fname, "AUX.", 4) == 0)) +// { +// Sts = YES; +// } + if(_strnicmp(Fname, "AUX", 3) == 0|| _strnicmp(Fname, "CON", 3) == 0 || _strnicmp(Fname, "NUL", 3) == 0 || _strnicmp(Fname, "PRN", 3) == 0) { - Sts = YES; + if(*(Fname + 3) == '\0' || *(Fname + 3) == '.') + Sts = YES; + } + else if(_strnicmp(Fname, "COM", 3) == 0 || _strnicmp(Fname, "LPT", 3) == 0) + { + if(isdigit(*(Fname + 3)) != 0) + { + if(*(Fname + 4) == '\0' || *(Fname + 4) == '.') + Sts = YES; + } } return(Sts); } -/*----- ƒ~ƒ‰[ƒŠƒ“ƒO‚ł̃tƒ@ƒCƒ‹íœŠm”F -------------------------------------- +/*----- ミラーリングでのファイル削除確認 -------------------------------------- * * Parameter * int Cur @@ -2408,13 +3870,13 @@ static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt) } -/*----- ƒ~ƒ‰[ƒŠƒ“ƒO‚ł̃tƒ@ƒCƒ‹íœƒ_ƒCƒAƒƒO‚̃R[ƒ‹ƒoƒbƒN ------------------ +/*----- ミラーリングでのファイル削除ダイアログのコールバック ------------------ * * Parameter -* HWND hDlg : ƒEƒCƒ“ƒhƒEƒnƒ“ƒhƒ‹ -* UINT message : ƒƒbƒZ[ƒW”ԍ† -* WPARAM wParam : ƒƒbƒZ[ƒW‚Ì WPARAM ˆø” -* LPARAM lParam : ƒƒbƒZ[ƒW‚Ì LPARAM ˆø” +* HWND hDlg : ウインドウハンドル +* UINT message : メッセージ番号 +* WPARAM wParam : メッセージの WPARAM 引数 +* LPARAM lParam : メッセージの LPARAM 引数 * * Return Value * BOOL TRUE/FALSE @@ -2473,10 +3935,14 @@ static void SetErrorMsg(char *fmt, ...) { va_list Args; - if(strlen(ErrMsg) == 0) + // 同時接続対応 +// if(strlen(ErrMsg) == 0) + if(strlen(GetErrMsg()) == 0) { va_start(Args, fmt); - wvsprintf(ErrMsg, fmt, Args); + // 同時接続対応 +// wvsprintf(ErrMsg, fmt, Args); + wvsprintf(GetErrMsg(), fmt, Args); va_end(Args); } return; @@ -2487,13 +3953,13 @@ static void SetErrorMsg(char *fmt, ...) -/*----- ƒ_ƒEƒ“ƒ[ƒhŽž‚Ì•s³‚ȃpƒX‚ðƒ`ƒFƒbƒN ---------------------------------- +/*----- ダウンロード時の不正なパスをチェック ---------------------------------- * * Parameter -* TRANSPACKET *packet : ƒ_ƒEƒ“ƒ[ƒhî•ñ +* TRANSPACKET *packet : ダウンロード情報 * * Return Value -* int YES=•s³‚ȃpƒX/NO=–â‘è‚È‚¢ƒpƒX +* int YES=不正なパス/NO=問題ないパス *----------------------------------------------------------------------------*/ int CheckPathViolation(TRANSPACKET *packet) { @@ -2518,3 +3984,39 @@ int CheckPathViolation(TRANSPACKET *packet) } +// 同時接続対応 +static char* GetErrMsg() +{ + char* r; + DWORD ThreadId; + int i; + r = NULL; + WaitForSingleObject(hErrMsgMutex, INFINITE); + ThreadId = GetCurrentThreadId(); + i = 0; + while(i < MAX_DATA_CONNECTION + 1) + { + if(ErrMsgThreadId[i] == ThreadId) + { + r = ErrMsg[i]; + break; + } + i++; + } + if(!r) + { + i = 0; + while(i < MAX_DATA_CONNECTION + 1) + { + if(ErrMsgThreadId[i] == 0) + { + ErrMsgThreadId[i] = ThreadId; + r = ErrMsg[i]; + break; + } + i++; + } + } + ReleaseMutex(hErrMsgMutex); + return r; +}