OSDN Git Service

Fix bugs of playing sound.
[ffftp/ffftp.git] / getput.c
index 9573c3e..1c287b6 100644 (file)
--- a/getput.c
+++ b/getput.c
@@ -94,7 +94,9 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt);
 static int UpLoadNonPassive(TRANSPACKET *Pkt);\r
 static int UpLoadPassive(TRANSPACKET *Pkt);\r
 static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt);\r
-static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii);\r
+// 同時接続対応\r
+//static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii);\r
+static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii);\r
 static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode);\r
 static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode);\r
 static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);\r
@@ -108,7 +110,9 @@ static void SetErrorMsg(char *fmt, ...);
 \r
 /*===== ローカルなワーク =====*/\r
 \r
-static HANDLE hTransferThread;\r
+// 同時接続対応\r
+//static HANDLE hTransferThread;\r
+static HANDLE hTransferThread[MAX_DATA_CONNECTION];\r
 static int fTransferThreadExit = FALSE;\r
 \r
 static HANDLE hRunMutex;                               /* 転送スレッド実行ミューテックス */\r
@@ -116,15 +120,22 @@ static HANDLE hListAccMutex;                      /* 転送ファイルアクセス用ミューテ
 \r
 static int TransFiles = 0;                             /* 転送待ちファイル数 */\r
 static TRANSPACKET *TransPacketBase = NULL;    /* 転送ファイルリスト */\r
+// 同時接続対応\r
+static TRANSPACKET *NextTransPacketBase = NULL;\r
 \r
-static int Canceled;           /* 中止フラグ YES/NO */\r
+// 同時接続対応\r
+//static int Canceled;         /* 中止フラグ YES/NO */\r
+static int Canceled[MAX_DATA_CONNECTION];              /* 中止フラグ YES/NO */\r
 static int ClearAll;           /* 全て中止フラグ YES/NO */\r
 \r
 static int ForceAbort;         /* 転送中止フラグ */\r
                                                        /* このフラグはスレッドを終了させるときに使う */\r
 \r
-static LONGLONG AllTransSizeNow;       /* 今回の転送で転送したサイズ */\r
-static time_t TimeStart;       /* 転送開始時間 */\r
+// 同時接続対応\r
+//static LONGLONG AllTransSizeNow;     /* 今回の転送で転送したサイズ */\r
+//static time_t TimeStart;     /* 転送開始時間 */\r
+static LONGLONG AllTransSizeNow[MAX_DATA_CONNECTION];  /* 今回の転送で転送したサイズ */\r
+static time_t TimeStart[MAX_DATA_CONNECTION];  /* 転送開始時間 */\r
 \r
 static int KeepDlg = NO;       /* 転送中ダイアログを消さないかどうか (YES/NO) */\r
 static int MoveToForeground = NO;              /* ウインドウを前面に移動するかどうか (YES/NO) */\r
@@ -157,6 +168,7 @@ extern int FolderAttrNum;
 int MakeTransferThread(void)\r
 {\r
        DWORD dwID;\r
+       int i;\r
 \r
        hListAccMutex = CreateMutex( NULL, FALSE, NULL );\r
        hRunMutex = CreateMutex( NULL, TRUE, NULL );\r
@@ -165,9 +177,16 @@ int MakeTransferThread(void)
        ForceAbort = NO;\r
 \r
        fTransferThreadExit = FALSE;\r
-       hTransferThread = (HANDLE)_beginthreadex(NULL, 0, TransferThread, 0, 0, &dwID);\r
-       if (hTransferThread == NULL)\r
-               return(FFFTP_FAIL); /* XXX */\r
+       // 同時接続対応\r
+//     hTransferThread = (HANDLE)_beginthreadex(NULL, 0, TransferThread, 0, 0, &dwID);\r
+//     if (hTransferThread == NULL)\r
+//             return(FFFTP_FAIL); /* XXX */\r
+       for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
+       {\r
+               hTransferThread[i] = (HANDLE)_beginthreadex(NULL, 0, TransferThread, (void*)i, 0, &dwID);\r
+               if(hTransferThread[i] == NULL)\r
+                       return FFFTP_FAIL;\r
+       }\r
 \r
        return(FFFTP_SUCCESS);\r
 }\r
@@ -184,17 +203,31 @@ int MakeTransferThread(void)
 \r
 void CloseTransferThread(void)\r
 {\r
-       Canceled = YES;\r
+       int i;\r
+       // 同時接続対応\r
+//     Canceled = YES;\r
+       for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
+               Canceled[i] = YES;\r
        ClearAll = YES;\r
        ForceAbort = YES;\r
 \r
        fTransferThreadExit = TRUE;\r
-       while(WaitForSingleObject(hTransferThread, 10) == WAIT_TIMEOUT)\r
+       // 同時接続対応\r
+//     while(WaitForSingleObject(hTransferThread, 10) == WAIT_TIMEOUT)\r
+//     {\r
+//             BackgrndMessageProc();\r
+//             Canceled = YES;\r
+//     }\r
+//     CloseHandle(hTransferThread);\r
+       for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
        {\r
-               BackgrndMessageProc();\r
-               Canceled = YES;\r
+               while(WaitForSingleObject(hTransferThread[i], 10) == WAIT_TIMEOUT)\r
+               {\r
+                       BackgrndMessageProc();\r
+                       Canceled[i] = YES;\r
+               }\r
+               CloseHandle(hTransferThread[i]);\r
        }\r
-       CloseHandle(hTransferThread);\r
 \r
        ReleaseMutex( hRunMutex );\r
 \r
@@ -325,7 +358,13 @@ void AddTransFileList(TRANSPACKET *Pkt)
 {\r
        DispTransPacket(Pkt);\r
 \r
-       WaitForSingleObject(hListAccMutex, INFINITE);\r
+       // 同時接続対応\r
+//     WaitForSingleObject(hListAccMutex, INFINITE);\r
+       while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+       {\r
+               BackgrndMessageProc();\r
+               Sleep(1);\r
+       }\r
 \r
        if(AddTmpTransFileList(Pkt, &TransPacketBase) == FFFTP_SUCCESS)\r
        {\r
@@ -336,6 +375,9 @@ void AddTransFileList(TRANSPACKET *Pkt)
                        PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
                }\r
        }\r
+       // 同時接続対応\r
+       if(NextTransPacketBase == NULL)\r
+               NextTransPacketBase = TransPacketBase;\r
        ReleaseMutex(hListAccMutex);\r
 \r
        return;\r
@@ -359,7 +401,13 @@ void AppendTransFileList(TRANSPACKET *Pkt)
 {\r
        TRANSPACKET *Pos;\r
 \r
-       WaitForSingleObject(hListAccMutex, INFINITE);\r
+       // 同時接続対応\r
+//     WaitForSingleObject(hListAccMutex, INFINITE);\r
+       while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+       {\r
+               BackgrndMessageProc();\r
+               Sleep(1);\r
+       }\r
 \r
        if(TransPacketBase == NULL)\r
                TransPacketBase = Pkt;\r
@@ -370,6 +418,9 @@ void AppendTransFileList(TRANSPACKET *Pkt)
                        Pos = Pos->Next;\r
                Pos->Next = Pkt;\r
        }\r
+       // 同時接続対応\r
+       if(NextTransPacketBase == NULL)\r
+               NextTransPacketBase = TransPacketBase;\r
 \r
        while(Pkt != NULL)\r
        {\r
@@ -437,7 +488,13 @@ static void EraseTransFileList(void)
 \r
        NotDel = NULL;\r
 \r
-       WaitForSingleObject(hListAccMutex, INFINITE);\r
+       // 同時接続対応\r
+//     WaitForSingleObject(hListAccMutex, INFINITE);\r
+       while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+       {\r
+               BackgrndMessageProc();\r
+               Sleep(1);\r
+       }\r
        New = TransPacketBase;\r
        while(New != NULL)\r
        {\r
@@ -445,19 +502,26 @@ static void EraseTransFileList(void)
                if(strcmp(New->Cmd, "BACKCUR") == 0)\r
                {\r
                        if(NotDel != NULL)\r
-                               free(NotDel);\r
+                               // 同時接続対応\r
+//                             free(NotDel);\r
+                               strcpy(NotDel->Cmd, "");\r
                        NotDel = New;\r
                        New = New->Next;\r
-                       NotDel->Next = NULL;\r
+                       // 同時接続対応\r
+//                     NotDel->Next = NULL;\r
                }\r
                else\r
                {\r
                        Next = New->Next;\r
-                       free(New);\r
+                       // 同時接続対応\r
+//                     free(New);\r
+                       strcpy(New->Cmd, "");\r
                        New = Next;\r
                }\r
        }\r
        TransPacketBase = NotDel;\r
+       // 同時接続対応\r
+       NextTransPacketBase = TransPacketBase;\r
        TransFiles = 0;\r
        PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
        ReleaseMutex(hListAccMutex);\r
@@ -562,15 +626,29 @@ static ULONG WINAPI TransferThread(void *Dummy)
        char Tmp[FMAX_PATH+1];\r
        int CwdSts;\r
        int GoExit;\r
-       int Down;\r
-       int Up;\r
+//     int Down;\r
+//     int Up;\r
+       static int Down;\r
+       static int Up;\r
        int DelNotify;\r
+       int ThreadCount;\r
+       SOCKET CmdSkt;\r
+       SOCKET NewCmdSkt;\r
+       SOCKET TrnSkt;\r
+       RECT WndRect;\r
+       int i;\r
 \r
        hWndTrans = NULL;\r
        Down = NO;\r
        Up = NO;\r
        GoExit = NO;\r
        DelNotify = NO;\r
+       // 同時接続対応\r
+       // ソケットは各転送スレッドが管理\r
+       ThreadCount = (int)Dummy;\r
+       CmdSkt = INVALID_SOCKET;\r
+       NewCmdSkt = INVALID_SOCKET;\r
+       TrnSkt = INVALID_SOCKET;\r
 \r
        while((TransPacketBase != NULL) ||\r
                  (WaitForSingleObject(hRunMutex, 200) == WAIT_TIMEOUT))\r
@@ -578,29 +656,86 @@ static ULONG WINAPI TransferThread(void *Dummy)
                if(fTransferThreadExit == TRUE)\r
                        break;\r
 \r
-               WaitForSingleObject(hListAccMutex, INFINITE);\r
+//             WaitForSingleObject(hListAccMutex, INFINITE);\r
+               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+               {\r
+                       BackgrndMessageProc();\r
+                       Sleep(1);\r
+               }\r
                memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
 \r
-               Canceled = NO;\r
+//             Canceled = NO;\r
+               Canceled[ThreadCount] = NO;\r
 \r
-               if(TransPacketBase != NULL)\r
+               while(TransPacketBase != NULL && strcmp(TransPacketBase->Cmd, "") == 0)\r
                {\r
-                       ReleaseMutex(hListAccMutex);\r
+                       Pos = TransPacketBase;\r
+                       TransPacketBase = TransPacketBase->Next;\r
+                       free(Pos);\r
+               }\r
+               NewCmdSkt = AskCmdCtrlSkt();\r
+               if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
+               {\r
+                       if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
+                       {\r
+                               ReleaseMutex(hListAccMutex);\r
+                               ReConnectTrnSkt(&TrnSkt);\r
+//                             WaitForSingleObject(hListAccMutex, INFINITE);\r
+                               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+                               {\r
+                                       BackgrndMessageProc();\r
+                                       Sleep(1);\r
+                               }\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if(TrnSkt != INVALID_SOCKET)\r
+                       {\r
+                               ReleaseMutex(hListAccMutex);\r
+                               DoClose(TrnSkt);\r
+                               TrnSkt = INVALID_SOCKET;\r
+//                             WaitForSingleObject(hListAccMutex, INFINITE);\r
+                               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+                               {\r
+                                       BackgrndMessageProc();\r
+                                       Sleep(1);\r
+                               }\r
+                       }\r
+               }\r
+               CmdSkt = NewCmdSkt;\r
+//             if(TransPacketBase != NULL)\r
+               if(TrnSkt != INVALID_SOCKET && NextTransPacketBase != NULL)\r
+               {\r
+                       Pos = NextTransPacketBase;\r
+                       NextTransPacketBase = NextTransPacketBase->Next;\r
+                       // ディレクトリ操作は非同期で行わない\r
+//                     ReleaseMutex(hListAccMutex);\r
                        if(hWndTrans == NULL)\r
                        {\r
-                               if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
-                                  (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) ||\r
-                                  (strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) ||\r
-                                  (strncmp(TransPacketBase->Cmd, "L-", 2) == 0) ||\r
-                                  (strncmp(TransPacketBase->Cmd, "R-", 2) == 0))\r
+//                             if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
+//                                (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) ||\r
+//                                (strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) ||\r
+//                                (strncmp(TransPacketBase->Cmd, "L-", 2) == 0) ||\r
+//                                (strncmp(TransPacketBase->Cmd, "R-", 2) == 0))\r
+                               if((strncmp(Pos->Cmd, "RETR", 4) == 0) ||\r
+                                  (strncmp(Pos->Cmd, "STOR", 4) == 0) ||\r
+                                  (strncmp(Pos->Cmd, "MKD", 3) == 0) ||\r
+                                  (strncmp(Pos->Cmd, "L-", 2) == 0) ||\r
+                                  (strncmp(Pos->Cmd, "R-", 2) == 0))\r
                                {\r
                                        hWndTrans = CreateDialog(GetFtpInst(), MAKEINTRESOURCE(transfer_dlg), HWND_DESKTOP, (DLGPROC)TransDlgProc);\r
                                        if(MoveToForeground == YES)\r
                                                SetForegroundWindow(hWndTrans);\r
                                        ShowWindow(hWndTrans, SW_SHOWNOACTIVATE);\r
+                                       GetWindowRect(hWndTrans, &WndRect);\r
+                                       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);\r
                                }\r
                        }\r
-                       TransPacketBase->hWndTrans = hWndTrans;\r
+//                     TransPacketBase->hWndTrans = hWndTrans;\r
+                       Pos->hWndTrans = hWndTrans;\r
+                       Pos->ctrl_skt = TrnSkt;\r
+                       Pos->ThreadCount = ThreadCount;\r
 \r
                        if(hWndTrans != NULL)\r
                        {\r
@@ -612,60 +747,85 @@ static ULONG WINAPI TransferThread(void *Dummy)
                        }\r
 \r
                        if(hWndTrans != NULL)\r
-                               SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase);\r
+//                             SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase);\r
+                               SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)Pos);\r
 \r
                        /* ダウンロード */\r
-                       if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0)\r
+//                     if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0)\r
+                       if(strncmp(Pos->Cmd, "RETR", 4) == 0)\r
                        {\r
+                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+//                             ReleaseMutex(hListAccMutex);\r
                                /* 不正なパスを検出 */\r
-                               if(CheckPathViolation(TransPacketBase) == NO)\r
+//                             if(CheckPathViolation(TransPacketBase) == NO)\r
+                               if(CheckPathViolation(Pos) == NO)\r
                                {\r
                                        /* フルパスを使わないための処理 */\r
-                                       if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+//                                     if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+                                       if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
                                        {\r
-                                               if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0)\r
+//                                             if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0)\r
+                                               if(strncmp(Pos->Cmd, "RETR-S", 6) == 0)\r
                                                {\r
                                                        /* サイズと日付を取得 */\r
-                                                       DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size);\r
-                                                       DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time);\r
-                                                       strcpy(TransPacketBase->Cmd, "RETR ");\r
+//                                                     DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size);\r
+//                                                     DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time);\r
+//                                                     strcpy(TransPacketBase->Cmd, "RETR ");\r
+                                                       DoSIZE(TrnSkt, Pos->RemoteFile, &Pos->Size);\r
+                                                       DoMDTM(TrnSkt, Pos->RemoteFile, &Pos->Time);\r
+                                                       strcpy(Pos->Cmd, "RETR ");\r
                                                }\r
 \r
                                                Down = YES;\r
 //                                             if(DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO) == 429)\r
 //                                             {\r
 //                                                     if(ReConnectTrnSkt() == FFFTP_SUCCESS)\r
-                                                               DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled);\r
+//                                                             DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled);\r
+                                                               DoDownLoad(TrnSkt, Pos, NO, &Canceled[Pos->ThreadCount]);\r
 //                                             }\r
                                        }\r
                                }\r
+                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* アップロード */\r
-                       else if(strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)\r
+                       else if(strncmp(Pos->Cmd, "STOR", 4) == 0)\r
                        {\r
+                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+//                             ReleaseMutex(hListAccMutex);\r
                                /* フルパスを使わないための処理 */\r
-                               if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+//                             if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+                               if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
                                {\r
                                        Up = YES;\r
 //                                     if(DoUpLoad(AskTrnCtrlSkt(), TransPacketBase) == 429)\r
 //                                     {\r
 //                                             if(ReConnectTrnSkt() == FFFTP_SUCCESS)\r
-                                                       DoUpLoad(AskTrnCtrlSkt(), TransPacketBase);\r
+//                                                     DoUpLoad(AskTrnCtrlSkt(), TransPacketBase);\r
+                                                       DoUpLoad(TrnSkt, Pos);\r
 //                                     }\r
                                }\r
+                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* フォルダ作成(ローカルまたはホスト) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "MKD", 3) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "MKD", 3) == 0)\r
+                       else if(strncmp(Pos->Cmd, "MKD", 3) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN078, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN078, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN078, FALSE, YES);\r
 \r
-                               if(strlen(TransPacketBase->RemoteFile) > 0)\r
+//                             if(strlen(TransPacketBase->RemoteFile) > 0)\r
+                               if(strlen(Pos->RemoteFile) > 0)\r
                                {\r
                                        /* フルパスを使わないための処理 */\r
                                        CwdSts = FTP_COMPLETE;\r
 \r
-                                       strcpy(Tmp, TransPacketBase->RemoteFile);\r
-                                       if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FFFTP_FAIL)\r
+//                                     strcpy(Tmp, TransPacketBase->RemoteFile);\r
+                                       strcpy(Tmp, Pos->RemoteFile);\r
+//                                     if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FFFTP_FAIL)\r
+                                       if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, (int)TrnSkt + 1) == FFFTP_FAIL)\r
                                        {\r
                                                ClearAll = YES;\r
                                                CwdSts = FTP_ERROR;\r
@@ -674,149 +834,215 @@ static ULONG WINAPI TransferThread(void *Dummy)
                                        if(CwdSts == FTP_COMPLETE)\r
                                        {\r
                                                Up = YES;\r
-                                               CommandProcTrn(NULL, "MKD %s", Tmp);\r
+//                                             CommandProcTrn(NULL, "MKD %s", Tmp);\r
+                                               CommandProcTrn(TrnSkt, NULL, "MKD %s", Tmp);\r
                                                /* すでにフォルダがある場合もあるので、 */\r
                                                /* ここではエラーチェックはしない */\r
 \r
                                        if(FolderAttr)\r
-                                               CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp);\r
+//                                             CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp);\r
+                                               CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp);\r
                                        }\r
                                }\r
-                               else if(strlen(TransPacketBase->LocalFile) > 0)\r
+//                             else if(strlen(TransPacketBase->LocalFile) > 0)\r
+                               else if(strlen(Pos->LocalFile) > 0)\r
                                {\r
                                        Down = YES;\r
-                                       DoLocalMKD(TransPacketBase->LocalFile);\r
+//                                     DoLocalMKD(TransPacketBase->LocalFile);\r
+                                       DoLocalMKD(Pos->LocalFile);\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* ディレクトリ作成(常にホスト側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "R-MKD", 5) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "R-MKD", 5) == 0)\r
+                       else if(strncmp(Pos->Cmd, "R-MKD", 5) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN079, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN079, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN079, FALSE, YES);\r
 \r
                                /* フルパスを使わないための処理 */\r
-                               if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+//                             if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+                               if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
                                {\r
                                        Up = YES;\r
-                                       CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+//                                     CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+                                       CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
 \r
                                        if(FolderAttr)\r
-                                               CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile);\r
+//                                             CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile);\r
+                                               CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Pos->RemoteFile);\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* ディレクトリ削除(常にホスト側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "R-RMD", 5) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "R-RMD", 5) == 0)\r
+                       else if(strncmp(Pos->Cmd, "R-RMD", 5) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN080, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN080, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN080, FALSE, YES);\r
 \r
-                               DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
+//                             DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
+                               DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos);\r
                                if((DelNotify == YES) || (DelNotify == YES_ALL))\r
                                {\r
                                        /* フルパスを使わないための処理 */\r
-                                       if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+//                                     if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+                                       if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
                                        {\r
                                                Up = YES;\r
-                                               CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+//                                             CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+                                               CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
                                        }\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* ファイル削除(常にホスト側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0)\r
+                       else if(strncmp(Pos->Cmd, "R-DELE", 6) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES);\r
+                               ReleaseMutex(hListAccMutex);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN081, FALSE, YES);\r
 \r
-                               DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
+//                             DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
+                               DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos);\r
                                if((DelNotify == YES) || (DelNotify == YES_ALL))\r
                                {\r
                                        /* フルパスを使わないための処理 */\r
-                                       if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+//                                     if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
+                                       if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
                                        {\r
                                                Up = YES;\r
-                                               CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+//                                             CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
+                                               CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
                                        }\r
                                }\r
                        }\r
                        /* ディレクトリ作成(常にローカル側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0)\r
+                       else if(strncmp(Pos->Cmd, "L-MKD", 5) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN082, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN082, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN082, FALSE, YES);\r
 \r
                                Down = YES;\r
-                               DoLocalMKD(TransPacketBase->LocalFile);\r
+//                             DoLocalMKD(TransPacketBase->LocalFile);\r
+                               DoLocalMKD(Pos->LocalFile);\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* ディレクトリ削除(常にローカル側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "L-RMD", 5) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "L-RMD", 5) == 0)\r
+                       else if(strncmp(Pos->Cmd, "L-RMD", 5) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN083, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN083, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN083, FALSE, YES);\r
 \r
-                               DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
+//                             DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
+                               DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos);\r
                                if((DelNotify == YES) || (DelNotify == YES_ALL))\r
                                {\r
                                        Down = YES;\r
-                                       DoLocalRMD(TransPacketBase->LocalFile);\r
+//                                     DoLocalRMD(TransPacketBase->LocalFile);\r
+                                       DoLocalRMD(Pos->LocalFile);\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* ファイル削除(常にローカル側) */\r
-                       else if(strncmp(TransPacketBase->Cmd, "L-DELE", 6) == 0)\r
+//                     else if(strncmp(TransPacketBase->Cmd, "L-DELE", 6) == 0)\r
+                       else if(strncmp(Pos->Cmd, "L-DELE", 6) == 0)\r
                        {\r
-                               DispTransFileInfo(TransPacketBase, MSGJPN084, FALSE, YES);\r
+//                             DispTransFileInfo(TransPacketBase, MSGJPN084, FALSE, YES);\r
+                               DispTransFileInfo(Pos, MSGJPN084, FALSE, YES);\r
 \r
-                               DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
+//                             DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
+                               DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos);\r
                                if((DelNotify == YES) || (DelNotify == YES_ALL))\r
                                {\r
                                        Down = YES;\r
-                                       DoLocalDELE(TransPacketBase->LocalFile);\r
+//                                     DoLocalDELE(TransPacketBase->LocalFile);\r
+                                       DoLocalDELE(Pos->LocalFile);\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* カレントディレクトリを設定 */\r
-                       else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0)\r
+//                     else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0)\r
+                       else if(strcmp(Pos->Cmd, "SETCUR") == 0)\r
                        {\r
                                if(AskShareProh() == YES)\r
                                {\r
-                                       if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
+//                                     if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
+                                       if(strcmp(CurDir, Pos->RemoteFile) != 0)\r
                                        {\r
-                                               if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE)\r
+//                                             if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE)\r
+                                               if(CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile)/100 != FTP_COMPLETE)\r
                                                {\r
                                                        DispCWDerror(hWndTrans);\r
                                                        ClearAll = YES;\r
                                                }\r
                                        }\r
                                }\r
-                               strcpy(CurDir, TransPacketBase->RemoteFile);\r
+//                             strcpy(CurDir, TransPacketBase->RemoteFile);\r
+                               strcpy(CurDir, Pos->RemoteFile);\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* カレントディレクトリを戻す */\r
-                       else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0)\r
+//                     else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0)\r
+                       else if(strcmp(Pos->Cmd, "BACKCUR") == 0)\r
                        {\r
                                if(AskShareProh() == NO)\r
                                {\r
-                                       if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
-                                               CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile);\r
-                                       strcpy(CurDir, TransPacketBase->RemoteFile);\r
+//                                     if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
+//                                             CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile);\r
+//                                     strcpy(CurDir, TransPacketBase->RemoteFile);\r
+                                       if(strcmp(CurDir, Pos->RemoteFile) != 0)\r
+                                               CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile);\r
+                                       strcpy(CurDir, Pos->RemoteFile);\r
                                }\r
+                               ReleaseMutex(hListAccMutex);\r
                        }\r
                        /* 自動終了のための通知 */\r
-                       else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0)\r
+//                     else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0)\r
+                       else if(strcmp(Pos->Cmd, "GOQUIT") == 0)\r
                        {\r
+                               ReleaseMutex(hListAccMutex);\r
                                GoExit = YES;\r
                        }\r
+                       else\r
+                               ReleaseMutex(hListAccMutex);\r
 \r
                        /*===== 1つの処理終わり =====*/\r
 \r
                        if(ForceAbort == NO)\r
                        {\r
-                               WaitForSingleObject(hListAccMutex, INFINITE);\r
+//                             WaitForSingleObject(hListAccMutex, INFINITE);\r
+                               while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
+                               {\r
+                                       BackgrndMessageProc();\r
+                                       Sleep(1);\r
+                               }\r
                                if(ClearAll == YES)\r
+//                                     EraseTransFileList();\r
+                               {\r
+                                       for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
+                                               Canceled[i] = YES;\r
                                        EraseTransFileList();\r
+                                       Pos = NULL;\r
+                               }\r
                                else\r
                                {\r
-                                       if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
-                                          (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0))\r
+//                                     if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
+//                                        (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0))\r
+                                       if((strncmp(Pos->Cmd, "RETR", 4) == 0) ||\r
+                                          (strncmp(Pos->Cmd, "STOR", 4) == 0))\r
                                        {\r
-                                               TransFiles--;\r
+//                                             TransFiles--;\r
+                                               if(TransFiles > 0)\r
+                                                       TransFiles--;\r
                                                PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
                                        }\r
-                                       Pos = TransPacketBase;\r
-                                       TransPacketBase = TransPacketBase->Next;\r
-                                       free(Pos);\r
+//                                     Pos = TransPacketBase;\r
+//                                     TransPacketBase = TransPacketBase->Next;\r
+//                                     free(Pos);\r
                                }\r
                                ClearAll = NO;\r
                                ReleaseMutex(hListAccMutex);\r
@@ -828,8 +1054,13 @@ static ULONG WINAPI TransferThread(void *Dummy)
                                        ReleaseMutex(hListAccMutex);\r
                                }\r
                        }\r
+                       if(hWndTrans != NULL)\r
+                               SendMessage(hWndTrans, WM_SET_PACKET, 0, 0);\r
+                       if(Pos != NULL)\r
+                               strcpy(Pos->Cmd, "");\r
                }\r
-               else\r
+//             else\r
+               else if(TransPacketBase == NULL)\r
                {\r
                        DelNotify = NO;\r
 \r
@@ -841,31 +1072,55 @@ static ULONG WINAPI TransferThread(void *Dummy)
                                        DestroyWindow(hWndTrans);\r
                                        hWndTrans = NULL;\r
 \r
-                                       if(GoExit == YES)\r
-                                       {\r
-                                               SoundPlay(SND_TRANS);\r
-\r
-                                               if(AskAutoExit() == NO)\r
-                                               {\r
-                                                       if(Down == YES)\r
-                                                               PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0);\r
-                                                       if(Up == YES)\r
-                                                               PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0);\r
-                                               }\r
-                                               Down = NO;\r
-                                               Up = NO;\r
-                                       }\r
+//                                     if(GoExit == YES)\r
+//                                     {\r
+//                                             SoundPlay(SND_TRANS);\r
+//\r
+//                                             if(AskAutoExit() == NO)\r
+//                                             {\r
+//                                                     if(Down == YES)\r
+//                                                             PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0);\r
+//                                                     if(Up == YES)\r
+//                                                             PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0);\r
+//                                             }\r
+//                                             Down = NO;\r
+//                                             Up = NO;\r
+//                                     }\r
                                }\r
                        }\r
                        BackgrndMessageProc();\r
+                       Sleep(1);\r
 \r
                        if(GoExit == YES)\r
                        {\r
+                               SoundPlay(SND_TRANS);\r
+                               if(AskAutoExit() == NO)\r
+                               {\r
+                                       if(Down == YES)\r
+                                               PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0);\r
+                                       if(Up == YES)\r
+                                               PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0);\r
+                               }\r
+                               Down = NO;\r
+                               Up = NO;\r
                                PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0);\r
                                GoExit = NO;\r
                        }\r
                }\r
+               else\r
+               {\r
+                       ReleaseMutex(hListAccMutex);\r
+                       if(hWndTrans != NULL)\r
+                       {\r
+                               DestroyWindow(hWndTrans);\r
+                               hWndTrans = NULL;\r
+                       }\r
+                       BackgrndMessageProc();\r
+                       Sleep(1);\r
+               }\r
        }\r
+       if(TrnSkt != INVALID_SOCKET)\r
+               DoClose(TrnSkt);\r
        return 0;\r
 }\r
 \r
@@ -886,11 +1141,13 @@ static ULONG WINAPI TransferThread(void *Dummy)
 *                      Pkt->RemoteFile にファイル名のみ残す。(パス名は消す)\r
 *----------------------------------------------------------------------------*/\r
 \r
+// 同時接続対応\r
 static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp)\r
 {\r
        int Sts;\r
 \r
-       Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1);\r
+//     Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1);\r
+       Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, (int)Pkt->ctrl_skt + 1);\r
        if(Sts == FFFTP_FAIL)\r
                ClearAll = YES;\r
 \r
@@ -937,7 +1194,9 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork)
                {\r
                        if(Pkt->hWndTrans != NULL)\r
                        {\r
-                               AllTransSizeNow = 0;\r
+                               // 同時接続対応\r
+//                             AllTransSizeNow = 0;\r
+                               AllTransSizeNow[Pkt->ThreadCount] = 0;\r
 \r
                                if(DirList == NO)\r
                                        DispTransFileInfo(Pkt, MSGJPN086, TRUE, YES);\r
@@ -1017,6 +1276,8 @@ static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
 \r
                                if(data_socket != INVALID_SOCKET)\r
                                {\r
+                                       // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                                       ReleaseMutex(hListAccMutex);\r
                                        // FTPS対応\r
 //                                     iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
                                        if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
@@ -1091,6 +1352,8 @@ static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork)
                                        iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf);\r
                                        if(iRetCode/100 == FTP_PRELIM)\r
                                        {\r
+                                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                                               ReleaseMutex(hListAccMutex);\r
                                                // FTPS対応\r
 //                                             iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
                                                if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
@@ -1209,7 +1472,9 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc
 \r
                if(Pkt->hWndTrans != NULL)\r
                {\r
-                       TimeStart = time(NULL);\r
+                       // 同時接続対応\r
+//                     TimeStart = time(NULL);\r
+                       TimeStart[Pkt->ThreadCount] = time(NULL);\r
                        SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL);\r
                }\r
 \r
@@ -1482,7 +1747,9 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc
 \r
                        Pkt->ExistSize += iNumBytes;\r
                        if(Pkt->hWndTrans != NULL)\r
-                               AllTransSizeNow += iNumBytes;\r
+                               // 同時接続対応\r
+//                             AllTransSizeNow += iNumBytes;\r
+                               AllTransSizeNow[Pkt->ThreadCount] += iNumBytes;\r
                        else\r
                        {\r
                                /* 転送ダイアログを出さない時の経過表示 */\r
@@ -1631,7 +1898,9 @@ static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *Canc
                {\r
                        KillTimer(Pkt->hWndTrans, TIMER_DISPLAY);\r
                        DispTransferStatus(Pkt->hWndTrans, YES, Pkt);\r
-                       TimeStart = time(NULL) - TimeStart + 1;\r
+                       // 同時接続対応\r
+//                     TimeStart = time(NULL) - TimeStart + 1;\r
+                       TimeStart[Pkt->ThreadCount] = time(NULL) - TimeStart[Pkt->ThreadCount] + 1;\r
                }\r
                else\r
                {\r
@@ -1726,14 +1995,19 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode)
                                SetTaskMsg(MSGJPN097);\r
                                strcpy(Fname, MSGJPN098);\r
                        }\r
-                       else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
-                               SetTaskMsg(MSGJPN099, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       // 同時接続対応\r
+//                     else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
+//                             SetTaskMsg(MSGJPN099, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
+                               SetTaskMsg(MSGJPN099, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
                        else\r
                                SetTaskMsg(MSGJPN100);\r
 \r
                        if(Pkt->Abort != ABORT_USER)\r
                        {\r
-                               if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO)\r
+                               // 全て中止を選択後にダイアログが表示されるバグ対策\r
+//                             if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO)\r
+                               if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO)\r
                                        ClearAll = YES;\r
                        }\r
                }\r
@@ -1741,8 +2015,11 @@ static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode)
                {\r
                        if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0))\r
                                SetTaskMsg(MSGJPN101, Pkt->ExistSize);\r
-                       else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
-                               SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       // 同時接続対応\r
+//                     else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
+//                             SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
+                               SetTaskMsg(MSGJPN102, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
                        else\r
                                SetTaskMsg(MSGJPN103, Pkt->ExistSize);\r
                }\r
@@ -1927,7 +2204,9 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt)
                        if(Pkt->Type == TYPE_I)\r
                                Pkt->KanjiCode = KANJI_NOCNV;\r
 \r
-                       iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "TYPE %c", Pkt->Type);\r
+                       // 同時接続対応\r
+//                     iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "TYPE %c", Pkt->Type);\r
+                       iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "TYPE %c", Pkt->Type);\r
                        if(iRetCode/100 < FTP_RETRY)\r
                        {\r
                                if(Pkt->Mode == EXIST_UNIQUE)\r
@@ -1951,7 +2230,9 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt)
 \r
                        /* 属性変更 */\r
                        if((Pkt->Attr != -1) && ((iRetCode/100) == FTP_COMPLETE))\r
-                               command(Pkt->ctrl_skt, Reply, &Canceled, "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile);\r
+                               // 同時接続対応\r
+//                             command(Pkt->ctrl_skt, Reply, &Canceled, "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile);\r
+                               command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile);\r
                }\r
                else\r
                {\r
@@ -1992,7 +2273,9 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
        int Resume;\r
        char Reply[ERR_MSG_LEN+7];\r
 \r
-       if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled)) != INVALID_SOCKET)\r
+       // 同時接続対応\r
+//     if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled)) != INVALID_SOCKET)\r
+       if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET)\r
        {\r
                SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume);\r
                if(Resume == NO)\r
@@ -2000,7 +2283,9 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
                else\r
                        sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile);\r
 \r
-               iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
+               // 同時接続対応\r
+//             iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
+               iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf);\r
                if((iRetCode/100) == FTP_PRELIM)\r
                {\r
                        if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)\r
@@ -2024,6 +2309,8 @@ static int UpLoadNonPassive(TRANSPACKET *Pkt)
 \r
                        if(data_socket != INVALID_SOCKET)\r
                        {\r
+                               // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                               ReleaseMutex(hListAccMutex);\r
                                // FTPS対応\r
 //                             iRetCode = UpLoadFile(Pkt, data_socket);\r
                                if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
@@ -2077,12 +2364,16 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
        int Resume;\r
        char Reply[ERR_MSG_LEN+7];\r
 \r
-       iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV");\r
+       // 同時接続対応\r
+//     iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV");\r
+       iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");\r
        if(iRetCode/100 == FTP_COMPLETE)\r
        {\r
                if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
                {\r
-                       if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET)\r
+                       // 同時接続対応\r
+//                     if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET)\r
+                       if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET)\r
                        {\r
                                // 変数が未初期化のバグ修正\r
                                Flg = 1;\r
@@ -2095,9 +2386,13 @@ static int UpLoadPassive(TRANSPACKET *Pkt)
                                else\r
                                        sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile);\r
 \r
-                               iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
+                               // 同時接続対応\r
+//                             iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
+                               iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf);\r
                                if(iRetCode/100 == FTP_PRELIM)\r
                                {\r
+                                       // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
+                                       ReleaseMutex(hListAccMutex);\r
                                        // FTPS対応\r
 //                                     iRetCode = UpLoadFile(Pkt, data_socket);\r
                                        if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
@@ -2212,8 +2507,11 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                        Low = (DWORD)LOW32(Pkt->ExistSize);\r
                        SetFilePointer(iFileHandle, Low, &High, FILE_BEGIN);\r
 \r
-                       AllTransSizeNow = 0;\r
-                       TimeStart = time(NULL);\r
+                       // 同時接続対応\r
+//                     AllTransSizeNow = 0;\r
+//                     TimeStart = time(NULL);\r
+                       AllTransSizeNow[Pkt->ThreadCount] = 0;\r
+                       TimeStart[Pkt->ThreadCount] = time(NULL);\r
                        SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL);\r
                }\r
 \r
@@ -2442,7 +2740,7 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                                        }\r
 \r
 //                                     if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL)\r
-                                       if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
+                                       if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
                                        {\r
                                                Pkt->Abort = ABORT_ERROR;\r
                                                        break;\r
@@ -2452,13 +2750,17 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                        }\r
                        else\r
                        {\r
-                               if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL)\r
+                               // 同時接続対応\r
+//                             if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL)\r
+                               if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL)\r
                                        Pkt->Abort = ABORT_ERROR;\r
                        }\r
 \r
                        Pkt->ExistSize += iNumBytes;\r
                        if(Pkt->hWndTrans != NULL)\r
-                               AllTransSizeNow += iNumBytes;\r
+                               // 同時接続対応\r
+//                             AllTransSizeNow += iNumBytes;\r
+                               AllTransSizeNow[Pkt->ThreadCount] += iNumBytes;\r
 \r
                        if(BackgrndMessageProc() == YES)\r
                                ForceAbort = YES;\r
@@ -2594,19 +2896,21 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                                }\r
 \r
 //                             if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL)\r
-                               if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
+                               if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
                                        Pkt->Abort = ABORT_ERROR;\r
                                cInfo2.Buf = Buf3;\r
                                cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
                                FlushRestData(&cInfo2);\r
-                               if(TermCodeConvAndSend(&tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
+                               if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
                                        Pkt->Abort = ABORT_ERROR;\r
                        }\r
 \r
                        tInfo.Buf = Buf2;\r
                        tInfo.BufSize = BUFSIZE+3;\r
                        FlushRestTermCodeConvData(&tInfo);\r
-                       if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled) == FFFTP_FAIL)\r
+                       // 同時接続対応\r
+//                     if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled) == FFFTP_FAIL)\r
+                       if(SendData(dSkt, Buf2, tInfo.OutLen, 0, &Canceled[Pkt->ThreadCount]) == FFFTP_FAIL)\r
                                Pkt->Abort = ABORT_ERROR;\r
                }\r
 \r
@@ -2615,7 +2919,9 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                {\r
                        KillTimer(Pkt->hWndTrans, TIMER_DISPLAY);\r
                        DispTransferStatus(Pkt->hWndTrans, YES, Pkt);\r
-                       TimeStart = time(NULL) - TimeStart + 1;\r
+                       // 同時接続対応\r
+//                     TimeStart = time(NULL) - TimeStart + 1;\r
+                       TimeStart[Pkt->ThreadCount] = time(NULL) - TimeStart[Pkt->ThreadCount] + 1;\r
                }\r
                CloseHandle(iFileHandle);\r
        }\r
@@ -2635,7 +2941,9 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
                ;\r
 #endif\r
 \r
-       iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled, TmpBuf);\r
+       // 同時接続対応\r
+//     iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled, TmpBuf);\r
+       iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, &Canceled[Pkt->ThreadCount], TmpBuf);\r
 \r
 //#pragma aaa\r
 //DoPrintf("##UP REPLY : %s", Buf);\r
@@ -2663,7 +2971,9 @@ static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)
 *              int 応答コード\r
 *----------------------------------------------------------------------------*/\r
 \r
-static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii)\r
+// 同時接続対応\r
+//static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii)\r
+static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii)\r
 {\r
        char Buf3[BUFSIZE*2];\r
        int Continue;\r
@@ -2681,13 +2991,17 @@ static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data,
                do\r
                {\r
                        Continue = ConvTermCodeToCRLF(tInfo);\r
-                       if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled)) == FFFTP_FAIL)\r
+                       // 同時接続対応\r
+//                     if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled)) == FFFTP_FAIL)\r
+                       if((Ret = SendData(Skt, Buf3, tInfo->OutLen, 0, &Canceled[ThreadCount])) == FFFTP_FAIL)\r
                                break;\r
                }\r
                while(Continue == YES);\r
        }\r
        else\r
-               Ret = SendData(Skt, Data, Size, 0, &Canceled);\r
+               // 同時接続対応\r
+//             Ret = SendData(Skt, Data, Size, 0, &Canceled);\r
+               Ret = SendData(Skt, Data, Size, 0, &Canceled[ThreadCount]);\r
 \r
        return(Ret);\r
 }\r
@@ -2709,21 +3023,32 @@ static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode)
        {\r
                if((iRetCode/100) >= FTP_CONTINUE)\r
                {\r
-                       if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
-                               SetTaskMsg(MSGJPN113, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       // 同時接続対応\r
+//                     if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
+//                             SetTaskMsg(MSGJPN113, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
+                               SetTaskMsg(MSGJPN113, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
                        else\r
                                SetTaskMsg(MSGJPN114);\r
 \r
                        if(Pkt->Abort != ABORT_USER)\r
                        {\r
-                               if(DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO)\r
+                               // 全て中止を選択後にダイアログが表示されるバグ対策\r
+//                             if(DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO)\r
+                               if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(uperr_dlg, Pkt->hWndTrans, Pkt->LocalFile) == NO)\r
                                        ClearAll = YES;\r
                        }\r
                }\r
                else\r
                {\r
-                       if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
-                               SetTaskMsg(MSGJPN115, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       // 同時接続対応\r
+//                     if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
+//                             SetTaskMsg(MSGJPN115, TimeStart, Pkt->ExistSize/TimeStart);\r
+                       if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
+                               // "0 B/S"と表示されるバグを修正\r
+                               // 原因は%dにあたる部分に64ビット値が渡されているため\r
+//                             SetTaskMsg(MSGJPN115, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
+                               SetTaskMsg(MSGJPN115, (LONG)TimeStart[Pkt->ThreadCount], (LONG)(Pkt->ExistSize/TimeStart[Pkt->ThreadCount]));\r
                        else\r
                                SetTaskMsg(MSGJPN116);\r
                }\r
@@ -2780,7 +3105,10 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM
        RECT RectDlg;\r
        RECT RectPar;\r
        HMENU hMenu;\r
-       static TRANSPACKET *Pkt;\r
+       // 同時接続対応\r
+//     static TRANSPACKET *Pkt;\r
+       TRANSPACKET *Pkt;\r
+       int i;\r
 \r
        switch(Msg)\r
        {\r
@@ -2809,11 +3137,16 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM
 \r
                                case TRANS_STOP_ALL :\r
                                        ClearAll = YES;\r
+                                       for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
+                                               Canceled[i] = YES;\r
                                        /* ここに break はない */\r
 \r
                                case IDCANCEL :\r
+                                       if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA)))\r
+                                               break;\r
                                        Pkt->Abort = ABORT_USER;\r
-                                       Canceled = YES;\r
+//                                     Canceled = YES;\r
+                                       Canceled[Pkt->ThreadCount] = YES;\r
                                        break;\r
                        }\r
                        break;\r
@@ -2825,13 +3158,18 @@ static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM
                                        SetForegroundWindow(hDlg);\r
                                MoveToForeground = NO;\r
                                KillTimer(hDlg, TIMER_DISPLAY);\r
+                               if(!(Pkt = (TRANSPACKET*)GetWindowLong(hDlg, GWL_USERDATA)))\r
+                                       break;\r
+                               if(Canceled[Pkt->ThreadCount] == YES)\r
+                                       Pkt->Abort = ABORT_USER;\r
                                DispTransferStatus(hDlg, NO, Pkt);\r
                                SetTimer(hDlg, TIMER_DISPLAY, DISPLAY_TIMING, NULL);\r
                        }\r
                        break;\r
 \r
                case WM_SET_PACKET :\r
-                       Pkt = (TRANSPACKET *)lParam;\r
+//                     Pkt = (TRANSPACKET *)lParam;\r
+                       SetWindowLong(hDlg, GWL_USERDATA, (LONG)lParam);\r
                        break;\r
        }\r
        return(FALSE);\r
@@ -2874,11 +3212,15 @@ static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt)
                {\r
                        if(End == NO)\r
                        {\r
-                               TotalLap = time(NULL) - TimeStart + 1;\r
+                               // 同時接続対応\r
+//                             TotalLap = time(NULL) - TimeStart + 1;\r
+                               TotalLap = time(NULL) - TimeStart[Pkt->ThreadCount] + 1;\r
 \r
                                Bps = 0;\r
                                if(TotalLap != 0)\r
-                                       Bps = AllTransSizeNow / TotalLap;\r
+                                       // 同時接続対応\r
+//                                     Bps = AllTransSizeNow / TotalLap;\r
+                                       Bps = AllTransSizeNow[Pkt->ThreadCount] / TotalLap;\r
                                Transed = Pkt->Size - Pkt->ExistSize;\r
 \r
                                if(Pkt->Size <= 0)\r