OSDN Git Service

Fix bugs of deadlock around simultaneous connection.
[ffftp/ffftp.git] / getput.c
1 /*=============================================================================\r
2 *\r
3 *                                                       ダウンロード/アップロード\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 /* このソースは一部、WS_FTP Version 93.12.05 のソースを参考にしました。 */\r
31 /* スレッドの作成/終了に関して、樋口殿作成のパッチを組み込みました。 */\r
32 \r
33 /*\r
34         一部、高速化のためのコード追加 by H.Shirouzu at 2002/10/02\r
35 */\r
36 \r
37 #define STRICT\r
38 #include <stdio.h>\r
39 #include <stdlib.h>\r
40 #include <stdarg.h>\r
41 #include <string.h>\r
42 #include <mbstring.h>\r
43 #include <time.h>\r
44 #include <winsock.h>\r
45 #include <windowsx.h>\r
46 #include <commctrl.h>\r
47 #include <process.h>\r
48 \r
49 #include "common.h"\r
50 #include "resource.h"\r
51 \r
52 #define SET_BUFFER_SIZE\r
53 \r
54 /* Add by H.Shirouzu at 2002/10/02 */\r
55 #undef BUFSIZE\r
56 #define BUFSIZE                 (32 * 1024)\r
57 #define SOCKBUF_SIZE    (256 * 1024)\r
58 /* End */\r
59 \r
60 #ifdef DISABLE_TRANSFER_NETWORK_BUFFERS\r
61 #undef BUFSIZE\r
62 #define BUFSIZE                 (64 * 1024)     // RWIN値以下で充分な大きさが望ましいと思われる。\r
63 #undef SET_BUFFER_SIZE\r
64 #endif\r
65 \r
66 #define TIMER_DISPLAY           1               /* 表示更新用タイマのID */\r
67 #define DISPLAY_TIMING          500             /* 表示更新時間 0.5秒 */\r
68 \r
69 #define ERR_MSG_LEN                     1024\r
70 \r
71 \r
72 /* 削除確認ダイアログの情報 */\r
73 typedef struct {\r
74         int Cur;\r
75         TRANSPACKET *Pkt;\r
76 } MIRRORDELETEINFO;\r
77 \r
78 \r
79 /*===== プロトタイプ =====*/\r
80 \r
81 static void DispTransPacket(TRANSPACKET *Pkt);\r
82 static void EraseTransFileList(void);\r
83 static ULONG WINAPI TransferThread(void *Dummy);\r
84 static int MakeNonFullPath(TRANSPACKET *Pkt, char *CurDir, char *Tmp);\r
85 static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork);\r
86 static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork);\r
87 static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork);\r
88 static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode);\r
89 static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname);\r
90 static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);\r
91 static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode, int *CancelCheckWork);\r
92 static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
93 static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt);\r
94 static int UpLoadNonPassive(TRANSPACKET *Pkt);\r
95 static int UpLoadPassive(TRANSPACKET *Pkt);\r
96 static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt);\r
97 // 同時接続対応\r
98 //static int TermCodeConvAndSend(TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii);\r
99 static int TermCodeConvAndSend(int ThreadCount, TERMCODECONVINFO *tInfo, SOCKET Skt, char *Data, int Size, int Ascii);\r
100 static void DispUploadFinishMsg(TRANSPACKET *Pkt, int iRetCode);\r
101 static int SetUploadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode);\r
102 static LRESULT CALLBACK TransDlgProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);\r
103 static void DispTransferStatus(HWND hWnd, int End, TRANSPACKET *Pkt);\r
104 static void DispTransFileInfo(TRANSPACKET *Pkt, char *Title, int SkipButton, int Info);\r
105 static int GetAdrsAndPort(char *Str, char *Adrs, int *Port, int Max);\r
106 static int IsSpecialDevice(char *Fname);\r
107 static int MirrorDelNotify(int Cur, int Notify, TRANSPACKET *Pkt);\r
108 static BOOL CALLBACK MirrorDeleteDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
109 static void SetErrorMsg(char *fmt, ...);\r
110 \r
111 /*===== ローカルなワーク =====*/\r
112 \r
113 // 同時接続対応\r
114 //static HANDLE hTransferThread;\r
115 static HANDLE hTransferThread[MAX_DATA_CONNECTION];\r
116 static int fTransferThreadExit = FALSE;\r
117 \r
118 static HANDLE hRunMutex;                                /* 転送スレッド実行ミューテックス */\r
119 static HANDLE hListAccMutex;                    /* 転送ファイルアクセス用ミューテックス */\r
120 \r
121 static int TransFiles = 0;                              /* 転送待ちファイル数 */\r
122 static TRANSPACKET *TransPacketBase = NULL;     /* 転送ファイルリスト */\r
123 \r
124 // 同時接続対応\r
125 //static int Canceled;          /* 中止フラグ YES/NO */\r
126 static int Canceled[MAX_DATA_CONNECTION];               /* 中止フラグ YES/NO */\r
127 static int ClearAll;            /* 全て中止フラグ YES/NO */\r
128 \r
129 static int ForceAbort;          /* 転送中止フラグ */\r
130                                                         /* このフラグはスレッドを終了させるときに使う */\r
131 \r
132 // 同時接続対応\r
133 //static LONGLONG AllTransSizeNow;      /* 今回の転送で転送したサイズ */\r
134 //static time_t TimeStart;      /* 転送開始時間 */\r
135 static LONGLONG AllTransSizeNow[MAX_DATA_CONNECTION];   /* 今回の転送で転送したサイズ */\r
136 static time_t TimeStart[MAX_DATA_CONNECTION];   /* 転送開始時間 */\r
137 \r
138 static int KeepDlg = NO;        /* 転送中ダイアログを消さないかどうか (YES/NO) */\r
139 static int MoveToForeground = NO;               /* ウインドウを前面に移動するかどうか (YES/NO) */\r
140 \r
141 static char CurDir[FMAX_PATH+1] = { "" };\r
142 static char ErrMsg[ERR_MSG_LEN+7];\r
143 \r
144 /*===== 外部参照 =====*/\r
145 \r
146 /* 設定値 */\r
147 extern int SaveTimeStamp;\r
148 extern int RmEOF;\r
149 // extern int TimeOut;\r
150 extern int FwallType;\r
151 extern int MirUpDelNotify;\r
152 extern int MirDownDelNotify;\r
153 extern int FolderAttr;\r
154 extern int FolderAttrNum;\r
155 \r
156 \r
157 /*----- ファイル転送スレッドを起動する ----------------------------------------\r
158 *\r
159 *       Parameter\r
160 *               なし\r
161 *\r
162 *       Return Value\r
163 *               なし\r
164 *----------------------------------------------------------------------------*/\r
165 \r
166 int MakeTransferThread(void)\r
167 {\r
168         DWORD dwID;\r
169         int i;\r
170 \r
171         hListAccMutex = CreateMutex( NULL, FALSE, NULL );\r
172         hRunMutex = CreateMutex( NULL, TRUE, NULL );\r
173 \r
174         ClearAll = NO;\r
175         ForceAbort = NO;\r
176 \r
177         fTransferThreadExit = FALSE;\r
178         // 同時接続対応\r
179 //      hTransferThread = (HANDLE)_beginthreadex(NULL, 0, TransferThread, 0, 0, &dwID);\r
180 //      if (hTransferThread == NULL)\r
181 //              return(FFFTP_FAIL); /* XXX */\r
182         for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
183         {\r
184                 hTransferThread[i] = (HANDLE)_beginthreadex(NULL, 0, TransferThread, (void*)i, 0, &dwID);\r
185                 if(hTransferThread[i] == NULL)\r
186                         return FFFTP_FAIL;\r
187         }\r
188 \r
189         return(FFFTP_SUCCESS);\r
190 }\r
191 \r
192 \r
193 /*----- ファイル転送スレッドを終了する ----------------------------------------\r
194 *\r
195 *       Parameter\r
196 *               なし\r
197 *\r
198 *       Return Value\r
199 *               なし\r
200 *----------------------------------------------------------------------------*/\r
201 \r
202 void CloseTransferThread(void)\r
203 {\r
204         int i;\r
205         // 同時接続対応\r
206 //      Canceled = YES;\r
207         for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
208                 Canceled[i] = YES;\r
209         ClearAll = YES;\r
210         ForceAbort = YES;\r
211 \r
212         fTransferThreadExit = TRUE;\r
213         // 同時接続対応\r
214 //      while(WaitForSingleObject(hTransferThread, 10) == WAIT_TIMEOUT)\r
215 //      {\r
216 //              BackgrndMessageProc();\r
217 //              Canceled = YES;\r
218 //      }\r
219 //      CloseHandle(hTransferThread);\r
220         for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
221         {\r
222                 while(WaitForSingleObject(hTransferThread[i], 10) == WAIT_TIMEOUT)\r
223                 {\r
224                         BackgrndMessageProc();\r
225                         Canceled[i] = YES;\r
226                 }\r
227                 CloseHandle(hTransferThread[i]);\r
228         }\r
229 \r
230         ReleaseMutex( hRunMutex );\r
231 \r
232         CloseHandle( hListAccMutex );\r
233         CloseHandle( hRunMutex );\r
234         return;\r
235 }\r
236 \r
237 \r
238 /*----- 転送するファイル情報をリストに追加する --------------------------------\r
239 *\r
240 *       Parameter\r
241 *               TRANSPACKET *Pkt : 転送ファイル情報\r
242 *               TRANSPACKET **Base : リストの先頭\r
243 *\r
244 *       Return Value\r
245 *               int ステータス\r
246 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
247 *----------------------------------------------------------------------------*/\r
248 \r
249 int AddTmpTransFileList(TRANSPACKET *Pkt, TRANSPACKET **Base)\r
250 {\r
251         TRANSPACKET *Pos;\r
252         TRANSPACKET *Prev;\r
253         int Sts;\r
254 \r
255         Sts = FFFTP_FAIL;\r
256         if((Pos = malloc(sizeof(TRANSPACKET))) != NULL)\r
257         {\r
258                 memcpy(Pos, Pkt, sizeof(TRANSPACKET));\r
259                 Pos->Next = NULL;\r
260 \r
261                 if(*Base == NULL)\r
262                         *Base = Pos;\r
263                 else\r
264                 {\r
265                         Prev = *Base;\r
266                         while(Prev->Next != NULL)\r
267                                 Prev = Prev->Next;\r
268                         Prev->Next = Pos;\r
269                 }\r
270                 Sts = FFFTP_SUCCESS;\r
271         }\r
272         return(Sts);\r
273 }\r
274 \r
275 \r
276 /*----- 転送するファイル情報リストをクリアする --------------------------------\r
277 *\r
278 *       Parameter\r
279 *               TRANSPACKET **Base : リストの先頭\r
280 *\r
281 *       Return Value\r
282 *               なし\r
283 *----------------------------------------------------------------------------*/\r
284 \r
285 void EraseTmpTransFileList(TRANSPACKET **Base)\r
286 {\r
287         TRANSPACKET *Pos;\r
288         TRANSPACKET *Next;\r
289 \r
290         Pos = *Base;\r
291         while(Pos != NULL)\r
292         {\r
293                 Next = Pos->Next;\r
294                 free(Pos);\r
295                 Pos = Next;\r
296         }\r
297         *Base = NULL;\r
298         return;\r
299 }\r
300 \r
301 \r
302 /*----- 転送するファイル情報リストから1つの情報を取り除く --------------------\r
303 *\r
304 *       Parameter\r
305 *               TRANSPACKET *Pkt : 転送ファイル情報\r
306 *               TRANSPACKET **Base : リストの先頭\r
307 *\r
308 *       Return Value\r
309 *               int ステータス\r
310 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
311 *----------------------------------------------------------------------------*/\r
312 \r
313 int RemoveTmpTransFileListItem(TRANSPACKET **Base, int Num)\r
314 {\r
315         TRANSPACKET *Pos;\r
316         TRANSPACKET *Prev;\r
317         int Sts;\r
318 \r
319         Sts = FFFTP_FAIL;\r
320         Pos = *Base;\r
321         if(Num == 0)\r
322         {\r
323                 *Base = Pos->Next;\r
324                 free(Pos);\r
325                 Sts = FFFTP_SUCCESS;\r
326         }\r
327         else\r
328         {\r
329                 while(Pos != NULL)\r
330                 {\r
331                         Prev = Pos;\r
332                         Pos = Pos->Next;\r
333                         if(--Num == 0)\r
334                         {\r
335                                 Prev->Next = Pos->Next;\r
336                                 free(Pos);\r
337                                 Sts = FFFTP_SUCCESS;\r
338                                 break;\r
339                         }\r
340                 }\r
341         }\r
342         return(Sts);\r
343 }\r
344 \r
345 \r
346 /*----- 転送するファイル情報を転送ファイルリストに登録する --------------------\r
347 *\r
348 *       Parameter\r
349 *               TRANSPACKET *Pkt : 転送ファイル情報\r
350 *\r
351 *       Return Value\r
352 *               なし\r
353 *----------------------------------------------------------------------------*/\r
354 \r
355 void AddTransFileList(TRANSPACKET *Pkt)\r
356 {\r
357         DispTransPacket(Pkt);\r
358 \r
359         // 同時接続対応\r
360 //      WaitForSingleObject(hListAccMutex, INFINITE);\r
361         while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
362         {\r
363                 BackgrndMessageProc();\r
364                 Sleep(1);\r
365         }\r
366 \r
367         if(AddTmpTransFileList(Pkt, &TransPacketBase) == FFFTP_SUCCESS)\r
368         {\r
369                 if((strncmp(Pkt->Cmd, "RETR", 4) == 0) ||\r
370                    (strncmp(Pkt->Cmd, "STOR", 4) == 0))\r
371                 {\r
372                         TransFiles++;\r
373                         PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
374                 }\r
375         }\r
376         ReleaseMutex(hListAccMutex);\r
377 \r
378         return;\r
379 }\r
380 \r
381 \r
382 /*----- 転送ファイル情報を転送ファイルリストに追加する ------------------------\r
383 *\r
384 *       Parameter\r
385 *               TRANSPACKET *Pkt : 転送ファイル情報\r
386 *               TRANSPACKET **Base : リストの先頭\r
387 *\r
388 *       Return Value\r
389 *               なし\r
390 *\r
391 *       Note\r
392 *               Pkt自体をリストに連結する\r
393 *----------------------------------------------------------------------------*/\r
394 \r
395 void AppendTransFileList(TRANSPACKET *Pkt)\r
396 {\r
397         TRANSPACKET *Pos;\r
398 \r
399         // 同時接続対応\r
400 //      WaitForSingleObject(hListAccMutex, INFINITE);\r
401         while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
402         {\r
403                 BackgrndMessageProc();\r
404                 Sleep(1);\r
405         }\r
406 \r
407         if(TransPacketBase == NULL)\r
408                 TransPacketBase = Pkt;\r
409         else\r
410         {\r
411                 Pos = TransPacketBase;\r
412                 while(Pos->Next != NULL)\r
413                         Pos = Pos->Next;\r
414                 Pos->Next = Pkt;\r
415         }\r
416 \r
417         while(Pkt != NULL)\r
418         {\r
419                 DispTransPacket(Pkt);\r
420 \r
421                 if((strncmp(Pkt->Cmd, "RETR", 4) == 0) ||\r
422                    (strncmp(Pkt->Cmd, "STOR", 4) == 0))\r
423                 {\r
424                         TransFiles++;\r
425                         PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
426                 }\r
427                 Pkt = Pkt->Next;\r
428         }\r
429 \r
430         ReleaseMutex(hListAccMutex);\r
431         return;\r
432 }\r
433 \r
434 \r
435 /*----- 転送ファイル情報を表示する --------------------------------------------\r
436 *\r
437 *       Parameter\r
438 *               TRANSPACKET *Pkt : 転送ファイル情報\r
439 *\r
440 *       Return Value\r
441 *               なし\r
442 *----------------------------------------------------------------------------*/\r
443 \r
444 static void DispTransPacket(TRANSPACKET *Pkt)\r
445 {\r
446         if((strncmp(Pkt->Cmd, "RETR", 4) == 0) || (strncmp(Pkt->Cmd, "STOR", 4) == 0))\r
447                 DoPrintf("TransList Cmd=%s : %s : %s", Pkt->Cmd, Pkt->RemoteFile, Pkt->LocalFile);\r
448         else if(strncmp(Pkt->Cmd, "R-", 2) == 0)\r
449                 DoPrintf("TransList Cmd=%s : %s", Pkt->Cmd, Pkt->RemoteFile);\r
450         else if(strncmp(Pkt->Cmd, "L-", 2) == 0)\r
451                 DoPrintf("TransList Cmd=%s : %s", Pkt->Cmd, Pkt->LocalFile);\r
452         else if(strncmp(Pkt->Cmd, "MKD", 3) == 0)\r
453         {\r
454                 if(strlen(Pkt->LocalFile) > 0)\r
455                         DoPrintf("TransList Cmd=%s : %s", Pkt->Cmd, Pkt->LocalFile);\r
456                 else\r
457                         DoPrintf("TransList Cmd=%s : %s", Pkt->Cmd, Pkt->RemoteFile);\r
458         }\r
459         else\r
460                 DoPrintf("TransList Cmd=%s", Pkt->Cmd);\r
461         return;\r
462 }\r
463 \r
464 \r
465 /*----- 転送ファイルリストをクリアする ----------------------------------------\r
466 *\r
467 *       Parameter\r
468 *               なし\r
469 *\r
470 *       Return Value\r
471 *               なし\r
472 *----------------------------------------------------------------------------*/\r
473 \r
474 static void EraseTransFileList(void)\r
475 {\r
476         TRANSPACKET *New;\r
477         TRANSPACKET *Next;\r
478         TRANSPACKET *NotDel;\r
479         TRANSPACKET Pkt;\r
480 \r
481         NotDel = NULL;\r
482 \r
483         // 同時接続対応\r
484 //      WaitForSingleObject(hListAccMutex, INFINITE);\r
485         while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
486         {\r
487                 BackgrndMessageProc();\r
488                 Sleep(1);\r
489         }\r
490         New = TransPacketBase;\r
491         while(New != NULL)\r
492         {\r
493                 /* 最後の"BACKCUR"は必要なので消さない */\r
494                 if(strcmp(New->Cmd, "BACKCUR") == 0)\r
495                 {\r
496                         if(NotDel != NULL)\r
497                                 free(NotDel);\r
498                         NotDel = New;\r
499                         New = New->Next;\r
500                         NotDel->Next = NULL;\r
501                 }\r
502                 else\r
503                 {\r
504                         Next = New->Next;\r
505                         free(New);\r
506                         New = Next;\r
507                 }\r
508         }\r
509         TransPacketBase = NotDel;\r
510         TransFiles = 0;\r
511         PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
512         ReleaseMutex(hListAccMutex);\r
513 \r
514         strcpy(Pkt.Cmd, "GOQUIT");\r
515         AddTransFileList(&Pkt);\r
516         return;\r
517 }\r
518 \r
519 \r
520 /*----- 転送中ダイアログを消さないようにするかどうかを設定 --------------------\r
521 *\r
522 *       Parameter\r
523 *               int Sw : 転送中ダイアログを消さないかどうか (YES/NO)\r
524 *\r
525 *       Return Value\r
526 *               なし\r
527 *----------------------------------------------------------------------------*/\r
528 \r
529 void KeepTransferDialog(int Sw)\r
530 {\r
531         KeepDlg = Sw;\r
532         return;\r
533 }\r
534 \r
535 \r
536 /*----- 現在転送中かどうかを返す ----------------------------------------------\r
537 *\r
538 *       Parameter\r
539 *               なし\r
540 *\r
541 *       Return Value\r
542 *               int ステータス (YES/NO=転送中ではない)\r
543 *----------------------------------------------------------------------------*/\r
544 \r
545 int AskTransferNow(void)\r
546 {\r
547         return(TransPacketBase != NULL ? YES : NO);\r
548 }\r
549 \r
550 \r
551 /*----- 転送するファイルの数を返す --------------------------------------------\r
552 *\r
553 *       Parameter\r
554 *               なし\r
555 *\r
556 *       Return Value\r
557 *               int 転送するファイルの数\r
558 *----------------------------------------------------------------------------*/\r
559 \r
560 int AskTransferFileNum(void)\r
561 {\r
562         return(TransFiles);\r
563 }\r
564 \r
565 \r
566 /*----- 転送中ウインドウを前面に出す ------------------------------------------\r
567 *\r
568 *       Parameter\r
569 *               なし\r
570 *\r
571 *       Return Value\r
572 *               なし\r
573 *----------------------------------------------------------------------------*/\r
574 \r
575 void GoForwardTransWindow(void)\r
576 {\r
577         MoveToForeground = YES;\r
578         return;\r
579 }\r
580 \r
581 \r
582 /*----- 転送ソケットのカレントディレクトリ情報を初期化 ------------------------\r
583 *\r
584 *       Parameter\r
585 *               なし\r
586 *\r
587 *       Return Value\r
588 *               なし\r
589 *----------------------------------------------------------------------------*/\r
590 \r
591 void InitTransCurDir(void)\r
592 {\r
593         strcpy(CurDir, "");\r
594         return;\r
595 }\r
596 \r
597 \r
598 /*----- ファイル転送スレッドのメインループ ------------------------------------\r
599 *\r
600 *       Parameter\r
601 *               void *Dummy : 使わない\r
602 *\r
603 *       Return Value\r
604 *               なし\r
605 *----------------------------------------------------------------------------*/\r
606 \r
607 static ULONG WINAPI TransferThread(void *Dummy)\r
608 {\r
609         TRANSPACKET *Pos;\r
610         HWND hWndTrans;\r
611         char Tmp[FMAX_PATH+1];\r
612         int CwdSts;\r
613         int GoExit;\r
614         int Down;\r
615         int Up;\r
616         int DelNotify;\r
617         int ThreadCount;\r
618         SOCKET CmdSkt;\r
619         SOCKET NewCmdSkt;\r
620         SOCKET TrnSkt;\r
621         RECT WndRect;\r
622         int i;\r
623 \r
624         hWndTrans = NULL;\r
625         Down = NO;\r
626         Up = NO;\r
627         GoExit = NO;\r
628         DelNotify = NO;\r
629         // 同時接続対応\r
630         // ソケットは各転送スレッドが管理\r
631         ThreadCount = (int)Dummy;\r
632         CmdSkt = INVALID_SOCKET;\r
633         NewCmdSkt = INVALID_SOCKET;\r
634         TrnSkt = INVALID_SOCKET;\r
635 \r
636         while((TransPacketBase != NULL) ||\r
637                   (WaitForSingleObject(hRunMutex, 200) == WAIT_TIMEOUT))\r
638         {\r
639                 if(fTransferThreadExit == TRUE)\r
640                         break;\r
641 \r
642 //              WaitForSingleObject(hListAccMutex, INFINITE);\r
643                 while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
644                 {\r
645                         BackgrndMessageProc();\r
646                         Sleep(1);\r
647                 }\r
648                 memset(ErrMsg, NUL, ERR_MSG_LEN+7);\r
649 \r
650 //              Canceled = NO;\r
651                 Canceled[ThreadCount] = NO;\r
652 \r
653                 NewCmdSkt = AskCmdCtrlSkt();\r
654                 if(TransPacketBase && NewCmdSkt != INVALID_SOCKET && ThreadCount < AskMaxThreadCount())\r
655                 {\r
656                         if(TrnSkt == INVALID_SOCKET || NewCmdSkt != CmdSkt)\r
657                         {\r
658                                 ReleaseMutex(hListAccMutex);\r
659                                 ReConnectTrnSkt(&TrnSkt);\r
660 //                              WaitForSingleObject(hListAccMutex, INFINITE);\r
661                                 while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
662                                 {\r
663                                         BackgrndMessageProc();\r
664                                         Sleep(1);\r
665                                 }\r
666                         }\r
667                 }\r
668                 else\r
669                 {\r
670                         if(TrnSkt != INVALID_SOCKET)\r
671                         {\r
672                                 ReleaseMutex(hListAccMutex);\r
673                                 DoClose(TrnSkt);\r
674                                 TrnSkt = INVALID_SOCKET;\r
675 //                              WaitForSingleObject(hListAccMutex, INFINITE);\r
676                                 while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
677                                 {\r
678                                         BackgrndMessageProc();\r
679                                         Sleep(1);\r
680                                 }\r
681                         }\r
682                 }\r
683                 CmdSkt = NewCmdSkt;\r
684 //              if(TransPacketBase != NULL)\r
685                 if(TrnSkt != INVALID_SOCKET && TransPacketBase != NULL)\r
686                 {\r
687                         Pos = TransPacketBase;\r
688                         TransPacketBase = TransPacketBase->Next;\r
689                         // ディレクトリ操作は非同期で行わない\r
690 //                      ReleaseMutex(hListAccMutex);\r
691                         if(hWndTrans == NULL)\r
692                         {\r
693 //                              if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
694 //                                 (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0) ||\r
695 //                                 (strncmp(TransPacketBase->Cmd, "MKD", 3) == 0) ||\r
696 //                                 (strncmp(TransPacketBase->Cmd, "L-", 2) == 0) ||\r
697 //                                 (strncmp(TransPacketBase->Cmd, "R-", 2) == 0))\r
698                                 if((strncmp(Pos->Cmd, "RETR", 4) == 0) ||\r
699                                    (strncmp(Pos->Cmd, "STOR", 4) == 0) ||\r
700                                    (strncmp(Pos->Cmd, "MKD", 3) == 0) ||\r
701                                    (strncmp(Pos->Cmd, "L-", 2) == 0) ||\r
702                                    (strncmp(Pos->Cmd, "R-", 2) == 0))\r
703                                 {\r
704                                         hWndTrans = CreateDialog(GetFtpInst(), MAKEINTRESOURCE(transfer_dlg), HWND_DESKTOP, (DLGPROC)TransDlgProc);\r
705                                         if(MoveToForeground == YES)\r
706                                                 SetForegroundWindow(hWndTrans);\r
707                                         ShowWindow(hWndTrans, SW_SHOWNOACTIVATE);\r
708                                         GetWindowRect(hWndTrans, &WndRect);\r
709                                         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
710                                 }\r
711                         }\r
712 //                      TransPacketBase->hWndTrans = hWndTrans;\r
713                         Pos->hWndTrans = hWndTrans;\r
714                         Pos->ctrl_skt = TrnSkt;\r
715                         Pos->ThreadCount = ThreadCount;\r
716 \r
717                         if(hWndTrans != NULL)\r
718                         {\r
719                                 if(MoveToForeground == YES)\r
720                                 {\r
721                                         SetForegroundWindow(hWndTrans);\r
722                                         MoveToForeground = NO;\r
723                                 }\r
724                         }\r
725 \r
726                         if(hWndTrans != NULL)\r
727 //                              SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)TransPacketBase);\r
728                                 SendMessage(hWndTrans, WM_SET_PACKET, 0, (LPARAM)Pos);\r
729 \r
730                         /* ダウンロード */\r
731 //                      if(strncmp(TransPacketBase->Cmd, "RETR", 4) == 0)\r
732                         if(strncmp(Pos->Cmd, "RETR", 4) == 0)\r
733                         {\r
734                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
735 //                              ReleaseMutex(hListAccMutex);\r
736                                 /* 不正なパスを検出 */\r
737 //                              if(CheckPathViolation(TransPacketBase) == NO)\r
738                                 if(CheckPathViolation(Pos) == NO)\r
739                                 {\r
740                                         /* フルパスを使わないための処理 */\r
741 //                                      if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
742                                         if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
743                                         {\r
744 //                                              if(strncmp(TransPacketBase->Cmd, "RETR-S", 6) == 0)\r
745                                                 if(strncmp(Pos->Cmd, "RETR-S", 6) == 0)\r
746                                                 {\r
747                                                         /* サイズと日付を取得 */\r
748 //                                                      DoSIZE(TransPacketBase->RemoteFile, &TransPacketBase->Size);\r
749 //                                                      DoMDTM(TransPacketBase->RemoteFile, &TransPacketBase->Time);\r
750 //                                                      strcpy(TransPacketBase->Cmd, "RETR ");\r
751                                                         DoSIZE(TrnSkt, Pos->RemoteFile, &Pos->Size);\r
752                                                         DoMDTM(TrnSkt, Pos->RemoteFile, &Pos->Time);\r
753                                                         strcpy(Pos->Cmd, "RETR ");\r
754                                                 }\r
755 \r
756                                                 Down = YES;\r
757 //                                              if(DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO) == 429)\r
758 //                                              {\r
759 //                                                      if(ReConnectTrnSkt() == FFFTP_SUCCESS)\r
760 //                                                              DoDownLoad(AskTrnCtrlSkt(), TransPacketBase, NO, &Canceled);\r
761                                                                 DoDownLoad(TrnSkt, Pos, NO, &Canceled[Pos->ThreadCount]);\r
762 //                                              }\r
763                                         }\r
764                                 }\r
765                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
766                                 ReleaseMutex(hListAccMutex);\r
767                         }\r
768                         /* アップロード */\r
769 //                      else if(strncmp(TransPacketBase->Cmd, "STOR", 4) == 0)\r
770                         else if(strncmp(Pos->Cmd, "STOR", 4) == 0)\r
771                         {\r
772                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
773 //                              ReleaseMutex(hListAccMutex);\r
774                                 /* フルパスを使わないための処理 */\r
775 //                              if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
776                                 if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
777                                 {\r
778                                         Up = YES;\r
779 //                                      if(DoUpLoad(AskTrnCtrlSkt(), TransPacketBase) == 429)\r
780 //                                      {\r
781 //                                              if(ReConnectTrnSkt() == FFFTP_SUCCESS)\r
782 //                                                      DoUpLoad(AskTrnCtrlSkt(), TransPacketBase);\r
783                                                         DoUpLoad(TrnSkt, Pos);\r
784 //                                      }\r
785                                 }\r
786                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
787                                 ReleaseMutex(hListAccMutex);\r
788                         }\r
789                         /* フォルダ作成(ローカルまたはホスト) */\r
790 //                      else if(strncmp(TransPacketBase->Cmd, "MKD", 3) == 0)\r
791                         else if(strncmp(Pos->Cmd, "MKD", 3) == 0)\r
792                         {\r
793 //                              DispTransFileInfo(TransPacketBase, MSGJPN078, FALSE, YES);\r
794                                 DispTransFileInfo(Pos, MSGJPN078, FALSE, YES);\r
795 \r
796 //                              if(strlen(TransPacketBase->RemoteFile) > 0)\r
797                                 if(strlen(Pos->RemoteFile) > 0)\r
798                                 {\r
799                                         /* フルパスを使わないための処理 */\r
800                                         CwdSts = FTP_COMPLETE;\r
801 \r
802 //                                      strcpy(Tmp, TransPacketBase->RemoteFile);\r
803                                         strcpy(Tmp, Pos->RemoteFile);\r
804 //                                      if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, 1) == FFFTP_FAIL)\r
805                                         if(ProcForNonFullpath(Tmp, CurDir, hWndTrans, (int)TrnSkt + 1) == FFFTP_FAIL)\r
806                                         {\r
807                                                 ClearAll = YES;\r
808                                                 CwdSts = FTP_ERROR;\r
809                                         }\r
810 \r
811                                         if(CwdSts == FTP_COMPLETE)\r
812                                         {\r
813                                                 Up = YES;\r
814 //                                              CommandProcTrn(NULL, "MKD %s", Tmp);\r
815                                                 CommandProcTrn(TrnSkt, NULL, "MKD %s", Tmp);\r
816                                                 /* すでにフォルダがある場合もあるので、 */\r
817                                                 /* ここではエラーチェックはしない */\r
818 \r
819                                         if(FolderAttr)\r
820 //                                              CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp);\r
821                                                 CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Tmp);\r
822                                         }\r
823                                 }\r
824 //                              else if(strlen(TransPacketBase->LocalFile) > 0)\r
825                                 else if(strlen(Pos->LocalFile) > 0)\r
826                                 {\r
827                                         Down = YES;\r
828 //                                      DoLocalMKD(TransPacketBase->LocalFile);\r
829                                         DoLocalMKD(Pos->LocalFile);\r
830                                 }\r
831                                 ReleaseMutex(hListAccMutex);\r
832                         }\r
833                         /* ディレクトリ作成(常にホスト側) */\r
834 //                      else if(strncmp(TransPacketBase->Cmd, "R-MKD", 5) == 0)\r
835                         else if(strncmp(Pos->Cmd, "R-MKD", 5) == 0)\r
836                         {\r
837 //                              DispTransFileInfo(TransPacketBase, MSGJPN079, FALSE, YES);\r
838                                 DispTransFileInfo(Pos, MSGJPN079, FALSE, YES);\r
839 \r
840                                 /* フルパスを使わないための処理 */\r
841 //                              if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
842                                 if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
843                                 {\r
844                                         Up = YES;\r
845 //                                      CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
846                                         CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
847 \r
848                                         if(FolderAttr)\r
849 //                                              CommandProcTrn(NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, TransPacketBase->RemoteFile);\r
850                                                 CommandProcTrn(TrnSkt, NULL, "%s %03d %s", AskHostChmodCmd(), FolderAttrNum, Pos->RemoteFile);\r
851                                 }\r
852                                 ReleaseMutex(hListAccMutex);\r
853                         }\r
854                         /* ディレクトリ削除(常にホスト側) */\r
855 //                      else if(strncmp(TransPacketBase->Cmd, "R-RMD", 5) == 0)\r
856                         else if(strncmp(Pos->Cmd, "R-RMD", 5) == 0)\r
857                         {\r
858 //                              DispTransFileInfo(TransPacketBase, MSGJPN080, FALSE, YES);\r
859                                 DispTransFileInfo(Pos, MSGJPN080, FALSE, YES);\r
860 \r
861 //                              DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
862                                 DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos);\r
863                                 if((DelNotify == YES) || (DelNotify == YES_ALL))\r
864                                 {\r
865                                         /* フルパスを使わないための処理 */\r
866 //                                      if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
867                                         if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
868                                         {\r
869                                                 Up = YES;\r
870 //                                              CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
871                                                 CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
872                                         }\r
873                                 }\r
874                                 ReleaseMutex(hListAccMutex);\r
875                         }\r
876                         /* ファイル削除(常にホスト側) */\r
877 //                      else if(strncmp(TransPacketBase->Cmd, "R-DELE", 6) == 0)\r
878                         else if(strncmp(Pos->Cmd, "R-DELE", 6) == 0)\r
879                         {\r
880                                 ReleaseMutex(hListAccMutex);\r
881 //                              DispTransFileInfo(TransPacketBase, MSGJPN081, FALSE, YES);\r
882                                 DispTransFileInfo(Pos, MSGJPN081, FALSE, YES);\r
883 \r
884 //                              DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, TransPacketBase);\r
885                                 DelNotify = MirrorDelNotify(WIN_REMOTE, DelNotify, Pos);\r
886                                 if((DelNotify == YES) || (DelNotify == YES_ALL))\r
887                                 {\r
888                                         /* フルパスを使わないための処理 */\r
889 //                                      if(MakeNonFullPath(TransPacketBase, CurDir, Tmp) == FFFTP_SUCCESS)\r
890                                         if(MakeNonFullPath(Pos, CurDir, Tmp) == FFFTP_SUCCESS)\r
891                                         {\r
892                                                 Up = YES;\r
893 //                                              CommandProcTrn(NULL, "%s%s", TransPacketBase->Cmd+2, TransPacketBase->RemoteFile);\r
894                                                 CommandProcTrn(TrnSkt, NULL, "%s%s", Pos->Cmd+2, Pos->RemoteFile);\r
895                                         }\r
896                                 }\r
897                         }\r
898                         /* ディレクトリ作成(常にローカル側) */\r
899 //                      else if(strncmp(TransPacketBase->Cmd, "L-MKD", 5) == 0)\r
900                         else if(strncmp(Pos->Cmd, "L-MKD", 5) == 0)\r
901                         {\r
902 //                              DispTransFileInfo(TransPacketBase, MSGJPN082, FALSE, YES);\r
903                                 DispTransFileInfo(Pos, MSGJPN082, FALSE, YES);\r
904 \r
905                                 Down = YES;\r
906 //                              DoLocalMKD(TransPacketBase->LocalFile);\r
907                                 DoLocalMKD(Pos->LocalFile);\r
908                                 ReleaseMutex(hListAccMutex);\r
909                         }\r
910                         /* ディレクトリ削除(常にローカル側) */\r
911 //                      else if(strncmp(TransPacketBase->Cmd, "L-RMD", 5) == 0)\r
912                         else if(strncmp(Pos->Cmd, "L-RMD", 5) == 0)\r
913                         {\r
914 //                              DispTransFileInfo(TransPacketBase, MSGJPN083, FALSE, YES);\r
915                                 DispTransFileInfo(Pos, MSGJPN083, FALSE, YES);\r
916 \r
917 //                              DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
918                                 DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos);\r
919                                 if((DelNotify == YES) || (DelNotify == YES_ALL))\r
920                                 {\r
921                                         Down = YES;\r
922 //                                      DoLocalRMD(TransPacketBase->LocalFile);\r
923                                         DoLocalRMD(Pos->LocalFile);\r
924                                 }\r
925                                 ReleaseMutex(hListAccMutex);\r
926                         }\r
927                         /* ファイル削除(常にローカル側) */\r
928 //                      else if(strncmp(TransPacketBase->Cmd, "L-DELE", 6) == 0)\r
929                         else if(strncmp(Pos->Cmd, "L-DELE", 6) == 0)\r
930                         {\r
931 //                              DispTransFileInfo(TransPacketBase, MSGJPN084, FALSE, YES);\r
932                                 DispTransFileInfo(Pos, MSGJPN084, FALSE, YES);\r
933 \r
934 //                              DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, TransPacketBase);\r
935                                 DelNotify = MirrorDelNotify(WIN_LOCAL, DelNotify, Pos);\r
936                                 if((DelNotify == YES) || (DelNotify == YES_ALL))\r
937                                 {\r
938                                         Down = YES;\r
939 //                                      DoLocalDELE(TransPacketBase->LocalFile);\r
940                                         DoLocalDELE(Pos->LocalFile);\r
941                                 }\r
942                                 ReleaseMutex(hListAccMutex);\r
943                         }\r
944                         /* カレントディレクトリを設定 */\r
945 //                      else if(strcmp(TransPacketBase->Cmd, "SETCUR") == 0)\r
946                         else if(strcmp(Pos->Cmd, "SETCUR") == 0)\r
947                         {\r
948                                 if(AskShareProh() == YES)\r
949                                 {\r
950 //                                      if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
951                                         if(strcmp(CurDir, Pos->RemoteFile) != 0)\r
952                                         {\r
953 //                                              if(CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile)/100 != FTP_COMPLETE)\r
954                                                 if(CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile)/100 != FTP_COMPLETE)\r
955                                                 {\r
956                                                         DispCWDerror(hWndTrans);\r
957                                                         ClearAll = YES;\r
958                                                 }\r
959                                         }\r
960                                 }\r
961 //                              strcpy(CurDir, TransPacketBase->RemoteFile);\r
962                                 strcpy(CurDir, Pos->RemoteFile);\r
963                                 ReleaseMutex(hListAccMutex);\r
964                         }\r
965                         /* カレントディレクトリを戻す */\r
966 //                      else if(strcmp(TransPacketBase->Cmd, "BACKCUR") == 0)\r
967                         else if(strcmp(Pos->Cmd, "BACKCUR") == 0)\r
968                         {\r
969                                 if(AskShareProh() == NO)\r
970                                 {\r
971 //                                      if(strcmp(CurDir, TransPacketBase->RemoteFile) != 0)\r
972 //                                              CommandProcTrn(NULL, "CWD %s", TransPacketBase->RemoteFile);\r
973 //                                      strcpy(CurDir, TransPacketBase->RemoteFile);\r
974                                         if(strcmp(CurDir, Pos->RemoteFile) != 0)\r
975                                                 CommandProcTrn(TrnSkt, NULL, "CWD %s", Pos->RemoteFile);\r
976                                         strcpy(CurDir, Pos->RemoteFile);\r
977                                 }\r
978                                 ReleaseMutex(hListAccMutex);\r
979                         }\r
980                         /* 自動終了のための通知 */\r
981 //                      else if(strcmp(TransPacketBase->Cmd, "GOQUIT") == 0)\r
982                         else if(strcmp(Pos->Cmd, "GOQUIT") == 0)\r
983                         {\r
984                                 ReleaseMutex(hListAccMutex);\r
985                                 GoExit = YES;\r
986                         }\r
987                         else\r
988                                 ReleaseMutex(hListAccMutex);\r
989 \r
990                         /*===== 1つの処理終わり =====*/\r
991 \r
992                         if(ForceAbort == NO)\r
993                         {\r
994 //                              WaitForSingleObject(hListAccMutex, INFINITE);\r
995                                 while(WaitForSingleObject(hListAccMutex, 0) == WAIT_TIMEOUT)\r
996                                 {\r
997                                         BackgrndMessageProc();\r
998                                         Sleep(1);\r
999                                 }\r
1000                                 if(ClearAll == YES)\r
1001 //                                      EraseTransFileList();\r
1002                                 {\r
1003                                         for(i = 0; i < MAX_DATA_CONNECTION; i++)\r
1004                                                 Canceled[i] = YES;\r
1005                                         EraseTransFileList();\r
1006                                 }\r
1007                                 else\r
1008                                 {\r
1009 //                                      if((strncmp(TransPacketBase->Cmd, "RETR", 4) == 0) ||\r
1010 //                                         (strncmp(TransPacketBase->Cmd, "STOR", 4) == 0))\r
1011                                         if((strncmp(Pos->Cmd, "RETR", 4) == 0) ||\r
1012                                            (strncmp(Pos->Cmd, "STOR", 4) == 0))\r
1013                                         {\r
1014 //                                              TransFiles--;\r
1015                                                 if(TransFiles > 0)\r
1016                                                         TransFiles--;\r
1017                                                 PostMessage(GetMainHwnd(), WM_CHANGE_COND, 0, 0);\r
1018                                         }\r
1019 //                                      Pos = TransPacketBase;\r
1020 //                                      TransPacketBase = TransPacketBase->Next;\r
1021 //                                      free(Pos);\r
1022                                 }\r
1023                                 ClearAll = NO;\r
1024                                 ReleaseMutex(hListAccMutex);\r
1025 \r
1026                                 if(BackgrndMessageProc() == YES)\r
1027                                 {\r
1028                                         WaitForSingleObject(hListAccMutex, INFINITE);\r
1029                                         EraseTransFileList();\r
1030                                         ReleaseMutex(hListAccMutex);\r
1031                                 }\r
1032                         }\r
1033                         if(hWndTrans != NULL)\r
1034                                 SendMessage(hWndTrans, WM_SET_PACKET, 0, 0);\r
1035                         free(Pos);\r
1036                 }\r
1037 //              else\r
1038                 else if(TransPacketBase == NULL)\r
1039                 {\r
1040                         DelNotify = NO;\r
1041 \r
1042                         ReleaseMutex(hListAccMutex);\r
1043                         if(KeepDlg == NO)\r
1044                         {\r
1045                                 if(hWndTrans != NULL)\r
1046                                 {\r
1047                                         DestroyWindow(hWndTrans);\r
1048                                         hWndTrans = NULL;\r
1049 \r
1050                                         if(GoExit == YES)\r
1051                                         {\r
1052                                                 SoundPlay(SND_TRANS);\r
1053 \r
1054                                                 if(AskAutoExit() == NO)\r
1055                                                 {\r
1056                                                         if(Down == YES)\r
1057                                                                 PostMessage(GetMainHwnd(), WM_REFRESH_LOCAL_FLG, 0, 0);\r
1058                                                         if(Up == YES)\r
1059                                                                 PostMessage(GetMainHwnd(), WM_REFRESH_REMOTE_FLG, 0, 0);\r
1060                                                 }\r
1061                                                 Down = NO;\r
1062                                                 Up = NO;\r
1063                                         }\r
1064                                 }\r
1065                         }\r
1066                         BackgrndMessageProc();\r
1067                         Sleep(1);\r
1068 \r
1069                         if(GoExit == YES)\r
1070                         {\r
1071                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_AUTO_EXIT, 0), 0);\r
1072                                 GoExit = NO;\r
1073                         }\r
1074                 }\r
1075                 else\r
1076                 {\r
1077                         ReleaseMutex(hListAccMutex);\r
1078                         if(hWndTrans != NULL)\r
1079                         {\r
1080                                 DestroyWindow(hWndTrans);\r
1081                                 hWndTrans = NULL;\r
1082                         }\r
1083                         BackgrndMessageProc();\r
1084                         Sleep(1);\r
1085                 }\r
1086         }\r
1087         if(TrnSkt != INVALID_SOCKET)\r
1088                 DoClose(TrnSkt);\r
1089         return 0;\r
1090 }\r
1091 \r
1092 \r
1093 /*----- フルパスを使わないファイルアクセスの準備 ------------------------------\r
1094 *\r
1095 *       Parameter\r
1096 *               TRANSPACKET *Pkt : 転送パケット\r
1097 *               char *Cur : カレントディレクトリ\r
1098 *               char *Tmp : 作業用エリア\r
1099 *\r
1100 *       Return Value\r
1101 *               int ステータス(FFFTP_SUCCESS/FFFTP_FAIL)\r
1102 *\r
1103 *       Note\r
1104 *               フルパスを使わない時は、\r
1105 *                       このモジュール内で CWD を行ない、\r
1106 *                       Pkt->RemoteFile にファイル名のみ残す。(パス名は消す)\r
1107 *----------------------------------------------------------------------------*/\r
1108 \r
1109 // 同時接続対応\r
1110 static int MakeNonFullPath(TRANSPACKET *Pkt, char *Cur, char *Tmp)\r
1111 {\r
1112         int Sts;\r
1113 \r
1114 //      Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, 1);\r
1115         Sts = ProcForNonFullpath(Pkt->RemoteFile, Cur, Pkt->hWndTrans, (int)Pkt->ctrl_skt + 1);\r
1116         if(Sts == FFFTP_FAIL)\r
1117                 ClearAll = YES;\r
1118 \r
1119         return(Sts);\r
1120 }\r
1121 \r
1122 \r
1123 \r
1124 \r
1125 /*----- ダウンロードを行なう --------------------------------------------------\r
1126 *\r
1127 *       Parameter\r
1128 *               SOCKET cSkt : コントロールソケット\r
1129 *               TRANSPACKET *Pkt : 転送ファイル情報\r
1130 *               int DirList : ディレクトリリストのダウンロード(YES/NO)\r
1131 *\r
1132 *       Return Value\r
1133 *               int 応答コード\r
1134 *\r
1135 *       Note\r
1136 *               このモジュールは、ファイル一覧の取得などを行なう際にメインのスレッド\r
1137 *               からも呼ばれる。メインのスレッドから呼ばれる時は Pkt->hWndTrans == NULL。\r
1138 *----------------------------------------------------------------------------*/\r
1139 \r
1140 int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork)\r
1141 {\r
1142         int iRetCode;\r
1143         char Reply[ERR_MSG_LEN+7];\r
1144 \r
1145         Pkt->ctrl_skt = cSkt;\r
1146         if(IsSpecialDevice(GetFileName(Pkt->LocalFile)) == YES)\r
1147         {\r
1148                 iRetCode = 500;\r
1149                 SetTaskMsg(MSGJPN085, GetFileName(Pkt->LocalFile));\r
1150                 DispDownloadFinishMsg(Pkt, iRetCode);\r
1151         }\r
1152         else if(Pkt->Mode != EXIST_IGNORE)\r
1153         {\r
1154                 if(Pkt->Type == TYPE_I)\r
1155                         Pkt->KanjiCode = KANJI_NOCNV;\r
1156 \r
1157                 iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "TYPE %c", Pkt->Type);\r
1158                 if(iRetCode/100 < FTP_RETRY)\r
1159                 {\r
1160                         if(Pkt->hWndTrans != NULL)\r
1161                         {\r
1162                                 // 同時接続対応\r
1163 //                              AllTransSizeNow = 0;\r
1164                                 AllTransSizeNow[Pkt->ThreadCount] = 0;\r
1165 \r
1166                                 if(DirList == NO)\r
1167                                         DispTransFileInfo(Pkt, MSGJPN086, TRUE, YES);\r
1168                                 else\r
1169                                         DispTransFileInfo(Pkt, MSGJPN087, FALSE, NO);\r
1170                         }\r
1171 \r
1172                         if(BackgrndMessageProc() == NO)\r
1173                         {\r
1174                                 if(AskPasvMode() != YES)\r
1175                                         iRetCode = DownLoadNonPassive(Pkt, CancelCheckWork);\r
1176                                 else\r
1177                                         iRetCode = DownLoadPassive(Pkt, CancelCheckWork);\r
1178                         }\r
1179                         else\r
1180                                 iRetCode = 500;\r
1181                 }\r
1182                 else\r
1183                         SetErrorMsg(Reply);\r
1184         }\r
1185         else\r
1186         {\r
1187                 DispTransFileInfo(Pkt, MSGJPN088, TRUE, YES);\r
1188                 SetTaskMsg(MSGJPN089, Pkt->RemoteFile);\r
1189                 iRetCode = 200;\r
1190         }\r
1191         return(iRetCode);\r
1192 }\r
1193 \r
1194 \r
1195 /*----- 通常モードでファイルをダウンロード ------------------------------------\r
1196 *\r
1197 *       Parameter\r
1198 *               TRANSPACKET *Pkt : 転送ファイル情報\r
1199 *\r
1200 *       Return Value\r
1201 *               int 応答コード\r
1202 *----------------------------------------------------------------------------*/\r
1203 \r
1204 static int DownLoadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork)\r
1205 {\r
1206         int iRetCode;\r
1207         int iLength;\r
1208         SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
1209         SOCKET listen_socket = INVALID_SOCKET; // data listen socket\r
1210         char Buf[1024];\r
1211         int CreateMode;\r
1212         struct sockaddr_in saSockAddr1;\r
1213         char Reply[ERR_MSG_LEN+7];\r
1214 \r
1215         if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET)\r
1216         {\r
1217                 if(SetDownloadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &CreateMode, CancelCheckWork) == YES)\r
1218                 {\r
1219                         sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile);\r
1220                         iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf);\r
1221                         if(iRetCode/100 == FTP_PRELIM)\r
1222                         {\r
1223                                 if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)\r
1224                                 {\r
1225                                         iLength = sizeof(saSockAddr1);\r
1226                                         data_socket = do_accept(listen_socket, (struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
1227 \r
1228                                         if(shutdown(listen_socket, 1) != 0)\r
1229                                                 ReportWSError("shutdown listen", WSAGetLastError());\r
1230                                         listen_socket = DoClose(listen_socket);\r
1231 \r
1232                                         if(data_socket == INVALID_SOCKET)\r
1233                                         {\r
1234                                                 SetErrorMsg(MSGJPN280);\r
1235                                                 ReportWSError("accept", WSAGetLastError());\r
1236                                                 iRetCode = 500;\r
1237                                         }\r
1238                                         else\r
1239                                                 DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
1240                                 }\r
1241 \r
1242                                 if(data_socket != INVALID_SOCKET)\r
1243                                 {\r
1244                                         // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
1245                                         ReleaseMutex(hListAccMutex);\r
1246                                         // FTPS対応\r
1247 //                                      iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1248                                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
1249                                         {\r
1250                                                 if(AttachSSL(data_socket))\r
1251                                                         iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1252                                                 else\r
1253                                                         iRetCode = FTP_ERROR;\r
1254                                         }\r
1255                                         else\r
1256                                                 iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1257 //                                      data_socket = DoClose(data_socket);\r
1258                                 }\r
1259                         }\r
1260                         else\r
1261                         {\r
1262                                 SetErrorMsg(Reply);\r
1263                                 SetTaskMsg(MSGJPN090);\r
1264                                 listen_socket = DoClose(listen_socket);\r
1265                                 iRetCode = 500;\r
1266                         }\r
1267                 }\r
1268                 else\r
1269                         iRetCode = 500;\r
1270         }\r
1271         else\r
1272         {\r
1273                 iRetCode = 500;\r
1274                 SetErrorMsg(MSGJPN279);\r
1275         }\r
1276         DispDownloadFinishMsg(Pkt, iRetCode);\r
1277 \r
1278         return(iRetCode);\r
1279 }\r
1280 \r
1281 \r
1282 /*----- Passiveモードでファイルをダウンロード ---------------------------------\r
1283 *\r
1284 *       Parameter\r
1285 *               TRANSPACKET *Pkt : 転送ファイル情報\r
1286 *\r
1287 *       Return Value\r
1288 *               int 応答コード\r
1289 *----------------------------------------------------------------------------*/\r
1290 \r
1291 static int DownLoadPassive(TRANSPACKET *Pkt, int *CancelCheckWork)\r
1292 {\r
1293         int iRetCode;\r
1294         SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
1295         char Buf[1024];\r
1296         int CreateMode;\r
1297         char Adrs[20];\r
1298         int Port;\r
1299         int Flg;\r
1300         char Reply[ERR_MSG_LEN+7];\r
1301 \r
1302         iRetCode = command(Pkt->ctrl_skt, Buf, CancelCheckWork, "PASV");\r
1303         if(iRetCode/100 == FTP_COMPLETE)\r
1304         {\r
1305                 if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
1306                 {\r
1307                         if((data_socket = connectsock(Adrs, Port, MSGJPN091, CancelCheckWork)) != INVALID_SOCKET)\r
1308                         {\r
1309                                 // 変数が未初期化のバグ修正\r
1310                                 Flg = 1;\r
1311                                 if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
1312                                         ReportWSError("setsockopt", WSAGetLastError());\r
1313 \r
1314                                 if(SetDownloadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &CreateMode, CancelCheckWork) == YES)\r
1315                                 {\r
1316                                         sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile);\r
1317                                         iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "%s", Buf);\r
1318                                         if(iRetCode/100 == FTP_PRELIM)\r
1319                                         {\r
1320                                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
1321                                                 ReleaseMutex(hListAccMutex);\r
1322                                                 // FTPS対応\r
1323 //                                              iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1324                                                 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
1325                                                 {\r
1326                                                         if(AttachSSL(data_socket))\r
1327                                                                 iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1328                                                         else\r
1329                                                                 iRetCode = FTP_ERROR;\r
1330                                                 }\r
1331                                                 else\r
1332                                                         iRetCode = DownLoadFile(Pkt, data_socket, CreateMode, CancelCheckWork);\r
1333 //                                              data_socket = DoClose(data_socket);\r
1334                                         }\r
1335                                         else\r
1336                                         {\r
1337                                                 SetErrorMsg(Reply);\r
1338                                                 SetTaskMsg(MSGJPN092);\r
1339                                                 data_socket = DoClose(data_socket);\r
1340                                                 iRetCode = 500;\r
1341                                         }\r
1342                                 }\r
1343                                 else\r
1344                                         iRetCode = 500;\r
1345                         }\r
1346                         else\r
1347                                 iRetCode = 500;\r
1348                 }\r
1349                 else\r
1350                 {\r
1351                         SetErrorMsg(MSGJPN093);\r
1352                         SetTaskMsg(MSGJPN093);\r
1353                         iRetCode = 500;\r
1354                 }\r
1355         }\r
1356         else\r
1357                 SetErrorMsg(Buf);\r
1358 \r
1359         DispDownloadFinishMsg(Pkt, iRetCode);\r
1360 \r
1361         return(iRetCode);\r
1362 }\r
1363 \r
1364 \r
1365 /*----- ダウンロードの実行 ----------------------------------------------------\r
1366 *\r
1367 *       Parameter\r
1368 *               TRANSPACKET *Pkt : 転送ファイル情報\r
1369 *               SOCKET dSkt : データソケット\r
1370 *               int CreateMode : ファイル作成モード (CREATE_ALWAYS/OPEN_ALWAYS)\r
1371 *\r
1372 *       Return Value\r
1373 *               int 応答コード\r
1374 *\r
1375 *       Note\r
1376 *               転送の経過表示は\r
1377 *                       ダイアログを出す(Pkt->hWndTrans!=NULL)場合、インターバルタイマで経過を表示する\r
1378 *                       ダイアログを出さない場合、このルーチンからDispDownloadSize()を呼ぶ\r
1379 *----------------------------------------------------------------------------*/\r
1380 \r
1381 static int DownLoadFile(TRANSPACKET *Pkt, SOCKET dSkt, int CreateMode, int *CancelCheckWork)\r
1382 {\r
1383         int iNumBytes;\r
1384         char Buf[BUFSIZE];\r
1385         char Buf2[BUFSIZE+3];\r
1386         HANDLE iFileHandle;\r
1387         SECURITY_ATTRIBUTES Sec;\r
1388         DWORD Writed;\r
1389         CODECONVINFO cInfo;\r
1390         int Continue;\r
1391 //      fd_set ReadFds;\r
1392 //      struct timeval Tout;\r
1393 //      struct timeval *ToutPtr;\r
1394         int iRetCode;\r
1395         int TimeOutErr;\r
1396         char TmpBuf[ONELINE_BUF_SIZE];\r
1397         DWORD dwFileAttributes;\r
1398 \r
1399 #ifdef SET_BUFFER_SIZE\r
1400 /* Add by H.Shirouzu at 2002/10/02 */\r
1401         int buf_size = SOCKBUF_SIZE;\r
1402         for ( ; buf_size > 0; buf_size /= 2)\r
1403                 if (setsockopt(dSkt, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size)) == 0)\r
1404                         break;\r
1405 /* End */\r
1406 #endif\r
1407 \r
1408         // 念のため受信バッファを無効にする\r
1409 #ifdef DISABLE_TRANSFER_NETWORK_BUFFERS\r
1410         int buf_size = 0;\r
1411         setsockopt(dSkt, SOL_SOCKET, SO_RCVBUF, (char *)&buf_size, sizeof(buf_size));\r
1412 #endif\r
1413 \r
1414         Pkt->Abort = ABORT_NONE;\r
1415 \r
1416         Sec.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1417         Sec.lpSecurityDescriptor = NULL;\r
1418         Sec.bInheritHandle = FALSE;\r
1419 \r
1420         dwFileAttributes = GetFileAttributes(Pkt->LocalFile);\r
1421         if (dwFileAttributes != INVALID_FILE_ATTRIBUTES && (dwFileAttributes & FILE_ATTRIBUTE_READONLY)) {\r
1422                 // 読み取り専用\r
1423                 if (MessageBox(GetMainHwnd(), MSGJPN296, MSGJPN086, MB_YESNO) == IDYES) {\r
1424                         // 属性を解除\r
1425                         SetFileAttributes(Pkt->LocalFile, dwFileAttributes ^ FILE_ATTRIBUTE_READONLY);\r
1426                 }\r
1427         }\r
1428 \r
1429         if((iFileHandle = CreateFile(Pkt->LocalFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &Sec, CreateMode, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE)\r
1430         {\r
1431                 // UTF-8対応\r
1432                 char Buf3[(BUFSIZE + 3) * 4];\r
1433                 CODECONVINFO cInfo2;\r
1434                 int ProcessedBOM = NO;\r
1435                 if(CreateMode == OPEN_ALWAYS)\r
1436                         SetFilePointer(iFileHandle, 0, 0, FILE_END);\r
1437 \r
1438                 if(Pkt->hWndTrans != NULL)\r
1439                 {\r
1440                         // 同時接続対応\r
1441 //                      TimeStart = time(NULL);\r
1442                         TimeStart[Pkt->ThreadCount] = time(NULL);\r
1443                         SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL);\r
1444                 }\r
1445 \r
1446                 InitCodeConvInfo(&cInfo);\r
1447                 cInfo.KanaCnv = Pkt->KanaCnv;\r
1448 \r
1449                 InitCodeConvInfo(&cInfo2);\r
1450                 cInfo2.KanaCnv = Pkt->KanaCnv;\r
1451 \r
1452                 /*===== ファイルを受信するループ =====*/\r
1453                 while((Pkt->Abort == ABORT_NONE) && (ForceAbort == NO))\r
1454                 {\r
1455 //                      FD_ZERO(&ReadFds);\r
1456 //                      FD_SET(dSkt, &ReadFds);\r
1457 //                      ToutPtr = NULL;\r
1458 //                      if(TimeOut != 0)\r
1459 //                      {\r
1460 //                              Tout.tv_sec = TimeOut;\r
1461 //                              Tout.tv_usec = 0;\r
1462 //                              ToutPtr = &Tout;\r
1463 //                      }\r
1464 //                      iNumBytes = select(0, &ReadFds, NULL, NULL, ToutPtr);\r
1465 //                      if(iNumBytes == SOCKET_ERROR)\r
1466 //                      {\r
1467 //                              ReportWSError("select", WSAGetLastError());\r
1468 //                              if(Pkt->Abort == ABORT_NONE)\r
1469 //                                      Pkt->Abort = ABORT_ERROR;\r
1470 //                              break;\r
1471 //                      }\r
1472 //                      else if(iNumBytes == 0)\r
1473 //                      {\r
1474 //                              SetErrorMsg(MSGJPN094);\r
1475 //                              SetTaskMsg(MSGJPN094);\r
1476 //                              Pkt->Abort = ABORT_ERROR;\r
1477 //                              break;\r
1478 //                      }\r
1479 \r
1480                         if((iNumBytes = do_recv(dSkt, Buf, BUFSIZE, 0, &TimeOutErr, CancelCheckWork)) <= 0)\r
1481                         {\r
1482                                 if(TimeOutErr == YES)\r
1483                                 {\r
1484                                         SetErrorMsg(MSGJPN094);\r
1485                                         SetTaskMsg(MSGJPN094);\r
1486                                         if(Pkt->hWndTrans != NULL)\r
1487                                                 ClearAll = YES;\r
1488                                         if(Pkt->Abort == ABORT_NONE)\r
1489                                                 Pkt->Abort = ABORT_ERROR;\r
1490                                 }\r
1491                                 else if(iNumBytes == SOCKET_ERROR)\r
1492                                 {\r
1493                                         if(Pkt->Abort == ABORT_NONE)\r
1494                                                 Pkt->Abort = ABORT_ERROR;\r
1495                                 }\r
1496                                 break;\r
1497                         }\r
1498 \r
1499                         /* 漢字コード変換 */\r
1500                         if(Pkt->KanjiCode != KANJI_NOCNV)\r
1501                         {\r
1502                                 cInfo.Str = Buf;\r
1503                                 cInfo.StrLen = iNumBytes;\r
1504                                 cInfo.Buf = Buf2;\r
1505                                 cInfo.BufSize = BUFSIZE+3;\r
1506                                 do\r
1507                                 {\r
1508                                         // ここで全てUTF-8へ変換する\r
1509                                         // TODO: SJIS以外も直接UTF-8へ変換\r
1510 //                                      if(Pkt->KanjiCode == KANJI_JIS)\r
1511 //                                              Continue = ConvJIStoSJIS(&cInfo);\r
1512 //                                      else\r
1513 //                                              Continue = ConvEUCtoSJIS(&cInfo);\r
1514                                         char Buf3[(BUFSIZE + 3) * 4];\r
1515                                         CODECONVINFO cInfo2;\r
1516                                         switch(Pkt->KanjiCode)\r
1517                                         {\r
1518                                         case KANJI_SJIS:\r
1519                                                 switch(Pkt->KanjiCodeDesired)\r
1520                                                 {\r
1521                                                 case KANJI_SJIS:\r
1522 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
1523 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
1524 //                                                      Continue = NO;\r
1525                                                         // カナ変換のため\r
1526                                                         Continue = ConvSJIStoJIS(&cInfo);\r
1527                                                         cInfo2.Str = cInfo.Buf;\r
1528                                                         cInfo2.StrLen = cInfo.OutLen;\r
1529                                                         cInfo2.Buf = Buf3;\r
1530                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1531                                                         ConvJIStoSJIS(&cInfo2);\r
1532                                                         break;\r
1533                                                 case KANJI_JIS:\r
1534                                                         Continue = ConvSJIStoJIS(&cInfo);\r
1535                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1536                                                         cInfo2.OutLen = cInfo.OutLen;\r
1537                                                         break;\r
1538                                                 case KANJI_EUC:\r
1539                                                         Continue = ConvSJIStoEUC(&cInfo);\r
1540                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1541                                                         cInfo2.OutLen = cInfo.OutLen;\r
1542                                                         break;\r
1543                                                 case KANJI_UTF8N:\r
1544                                                         if(ProcessedBOM == NO)\r
1545                                                         {\r
1546                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
1547                                                                 cInfo2.OutLen = 3;\r
1548                                                                 Continue = YES;\r
1549                                                                 ProcessedBOM = YES;\r
1550                                                                 break;\r
1551                                                         }\r
1552                                                         Continue = ConvSJIStoUTF8N(&cInfo);\r
1553                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1554                                                         cInfo2.OutLen = cInfo.OutLen;\r
1555                                                         break;\r
1556                                                 }\r
1557                                                 break;\r
1558                                         case KANJI_JIS:\r
1559                                                 switch(Pkt->KanjiCodeDesired)\r
1560                                                 {\r
1561                                                 case KANJI_SJIS:\r
1562                                                         Continue = ConvJIStoSJIS(&cInfo);\r
1563                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1564                                                         cInfo2.OutLen = cInfo.OutLen;\r
1565                                                         break;\r
1566                                                 case KANJI_JIS:\r
1567 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
1568 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
1569 //                                                      Continue = NO;\r
1570                                                         // カナ変換のため\r
1571                                                         Continue = ConvJIStoSJIS(&cInfo);\r
1572                                                         cInfo2.Str = cInfo.Buf;\r
1573                                                         cInfo2.StrLen = cInfo.OutLen;\r
1574                                                         cInfo2.Buf = Buf3;\r
1575                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1576                                                         ConvSJIStoJIS(&cInfo2);\r
1577                                                         break;\r
1578                                                 case KANJI_EUC:\r
1579                                                         Continue = ConvJIStoSJIS(&cInfo);\r
1580                                                         cInfo2.Str = cInfo.Buf;\r
1581                                                         cInfo2.StrLen = cInfo.OutLen;\r
1582                                                         cInfo2.Buf = Buf3;\r
1583                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1584                                                         ConvSJIStoEUC(&cInfo2);\r
1585                                                         break;\r
1586                                                 case KANJI_UTF8N:\r
1587                                                         if(ProcessedBOM == NO)\r
1588                                                         {\r
1589                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
1590                                                                 cInfo2.OutLen = 3;\r
1591                                                                 Continue = YES;\r
1592                                                                 ProcessedBOM = YES;\r
1593                                                                 break;\r
1594                                                         }\r
1595                                                         Continue = ConvJIStoSJIS(&cInfo);\r
1596                                                         cInfo2.Str = cInfo.Buf;\r
1597                                                         cInfo2.StrLen = cInfo.OutLen;\r
1598                                                         cInfo2.Buf = Buf3;\r
1599                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1600                                                         ConvSJIStoUTF8N(&cInfo2);\r
1601                                                         break;\r
1602                                                 }\r
1603                                                 break;\r
1604                                         case KANJI_EUC:\r
1605                                                 switch(Pkt->KanjiCodeDesired)\r
1606                                                 {\r
1607                                                 case KANJI_SJIS:\r
1608                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
1609                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1610                                                         cInfo2.OutLen = cInfo.OutLen;\r
1611                                                         break;\r
1612                                                 case KANJI_JIS:\r
1613                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
1614                                                         cInfo2.Str = cInfo.Buf;\r
1615                                                         cInfo2.StrLen = cInfo.OutLen;\r
1616                                                         cInfo2.Buf = Buf3;\r
1617                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1618                                                         ConvSJIStoJIS(&cInfo2);\r
1619                                                         break;\r
1620                                                 case KANJI_EUC:\r
1621 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
1622 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
1623 //                                                      Continue = NO;\r
1624                                                         // カナ変換のため\r
1625                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
1626                                                         cInfo2.Str = cInfo.Buf;\r
1627                                                         cInfo2.StrLen = cInfo.OutLen;\r
1628                                                         cInfo2.Buf = Buf3;\r
1629                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1630                                                         ConvSJIStoEUC(&cInfo2);\r
1631                                                         break;\r
1632                                                 case KANJI_UTF8N:\r
1633                                                         if(ProcessedBOM == NO)\r
1634                                                         {\r
1635                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
1636                                                                 cInfo2.OutLen = 3;\r
1637                                                                 Continue = YES;\r
1638                                                                 ProcessedBOM = YES;\r
1639                                                                 break;\r
1640                                                         }\r
1641                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
1642                                                         cInfo2.Str = cInfo.Buf;\r
1643                                                         cInfo2.StrLen = cInfo.OutLen;\r
1644                                                         cInfo2.Buf = Buf3;\r
1645                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1646                                                         ConvSJIStoUTF8N(&cInfo2);\r
1647                                                         break;\r
1648                                                 }\r
1649                                                 break;\r
1650                                         case KANJI_UTF8N:\r
1651                                                 if(ProcessedBOM == NO)\r
1652                                                 {\r
1653                                                         if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0)\r
1654                                                         {\r
1655                                                                 cInfo.Str += 3;\r
1656                                                                 cInfo.StrLen -= 3;\r
1657                                                         }\r
1658                                                         cInfo2.OutLen = 0;\r
1659                                                         switch(Pkt->KanjiCodeDesired)\r
1660                                                         {\r
1661                                                         case KANJI_UTF8N:\r
1662                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
1663                                                                 cInfo2.OutLen = 3;\r
1664                                                                 break;\r
1665                                                         }\r
1666                                                         Continue = YES;\r
1667                                                         ProcessedBOM = YES;\r
1668                                                         break;\r
1669                                                 }\r
1670                                                 switch(Pkt->KanjiCodeDesired)\r
1671                                                 {\r
1672                                                 case KANJI_SJIS:\r
1673                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
1674                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1675                                                         cInfo2.OutLen = cInfo.OutLen;\r
1676                                                         break;\r
1677                                                 case KANJI_JIS:\r
1678                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
1679                                                         cInfo2.Str = cInfo.Buf;\r
1680                                                         cInfo2.StrLen = cInfo.OutLen;\r
1681                                                         cInfo2.Buf = Buf3;\r
1682                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1683                                                         ConvSJIStoJIS(&cInfo2);\r
1684                                                         break;\r
1685                                                 case KANJI_EUC:\r
1686                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
1687                                                         cInfo2.Str = cInfo.Buf;\r
1688                                                         cInfo2.StrLen = cInfo.OutLen;\r
1689                                                         cInfo2.Buf = Buf3;\r
1690                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1691                                                         ConvSJIStoEUC(&cInfo2);\r
1692                                                         break;\r
1693                                                 case KANJI_UTF8N:\r
1694                                                         memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
1695                                                         cInfo2.OutLen = cInfo.StrLen;\r
1696                                                         Continue = NO;\r
1697                                                         break;\r
1698                                                 }\r
1699                                                 break;\r
1700                                         }\r
1701 //                                      if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE)\r
1702                                         if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE)\r
1703                                                 Pkt->Abort = ABORT_DISKFULL;\r
1704                                 }\r
1705                                 while((Continue == YES) && (Pkt->Abort == ABORT_NONE));\r
1706                         }\r
1707                         else\r
1708                         {\r
1709                                 if(WriteFile(iFileHandle, Buf, iNumBytes, &Writed, NULL) == FALSE)\r
1710                                         Pkt->Abort = ABORT_DISKFULL;\r
1711                         }\r
1712 \r
1713                         Pkt->ExistSize += iNumBytes;\r
1714                         if(Pkt->hWndTrans != NULL)\r
1715                                 // 同時接続対応\r
1716 //                              AllTransSizeNow += iNumBytes;\r
1717                                 AllTransSizeNow[Pkt->ThreadCount] += iNumBytes;\r
1718                         else\r
1719                         {\r
1720                                 /* 転送ダイアログを出さない時の経過表示 */\r
1721                                 DispDownloadSize(Pkt->ExistSize);\r
1722                         }\r
1723 \r
1724                         if(BackgrndMessageProc() == YES)\r
1725                                 ForceAbort = YES;\r
1726                 }\r
1727 \r
1728                 /* 書き残したデータを書き込む */\r
1729                 if(Pkt->KanjiCode != KANJI_NOCNV)\r
1730                 {\r
1731                         cInfo.Buf = Buf2;\r
1732                         cInfo.BufSize = BUFSIZE+3;\r
1733                         FlushRestData(&cInfo);\r
1734                         switch(Pkt->KanjiCode)\r
1735                         {\r
1736                         case KANJI_SJIS:\r
1737                                 switch(Pkt->KanjiCodeDesired)\r
1738                                 {\r
1739                                 case KANJI_SJIS:\r
1740                                         // カナ変換のため\r
1741                                         cInfo2.Str = cInfo.Buf;\r
1742                                         cInfo2.StrLen = cInfo.OutLen;\r
1743                                         cInfo2.Buf = Buf3;\r
1744                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1745                                         ConvJIStoSJIS(&cInfo2);\r
1746                                         break;\r
1747                                 case KANJI_JIS:\r
1748                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1749                                         cInfo2.OutLen = cInfo.OutLen;\r
1750                                         break;\r
1751                                 case KANJI_EUC:\r
1752                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1753                                         cInfo2.OutLen = cInfo.OutLen;\r
1754                                         break;\r
1755                                 case KANJI_UTF8N:\r
1756                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1757                                         cInfo2.OutLen = cInfo.OutLen;\r
1758                                         break;\r
1759                                 }\r
1760                                 break;\r
1761                         case KANJI_JIS:\r
1762                                 switch(Pkt->KanjiCodeDesired)\r
1763                                 {\r
1764                                 case KANJI_SJIS:\r
1765                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1766                                         cInfo2.OutLen = cInfo.OutLen;\r
1767                                         break;\r
1768                                 case KANJI_JIS:\r
1769                                         // カナ変換のため\r
1770                                         cInfo2.Str = cInfo.Buf;\r
1771                                         cInfo2.StrLen = cInfo.OutLen;\r
1772                                         cInfo2.Buf = Buf3;\r
1773                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1774                                         ConvSJIStoJIS(&cInfo2);\r
1775                                         break;\r
1776                                 case KANJI_EUC:\r
1777                                         cInfo2.Str = cInfo.Buf;\r
1778                                         cInfo2.StrLen = cInfo.OutLen;\r
1779                                         cInfo2.Buf = Buf3;\r
1780                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1781                                         ConvSJIStoEUC(&cInfo2);\r
1782                                         break;\r
1783                                 case KANJI_UTF8N:\r
1784                                         cInfo2.Str = cInfo.Buf;\r
1785                                         cInfo2.StrLen = cInfo.OutLen;\r
1786                                         cInfo2.Buf = Buf3;\r
1787                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1788                                         ConvSJIStoUTF8N(&cInfo2);\r
1789                                         break;\r
1790                                 }\r
1791                                 break;\r
1792                         case KANJI_EUC:\r
1793                                 switch(Pkt->KanjiCodeDesired)\r
1794                                 {\r
1795                                 case KANJI_SJIS:\r
1796                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1797                                         cInfo2.OutLen = cInfo.OutLen;\r
1798                                         break;\r
1799                                 case KANJI_JIS:\r
1800                                         cInfo2.Str = cInfo.Buf;\r
1801                                         cInfo2.StrLen = cInfo.OutLen;\r
1802                                         cInfo2.Buf = Buf3;\r
1803                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1804                                         ConvSJIStoJIS(&cInfo2);\r
1805                                         break;\r
1806                                 case KANJI_EUC:\r
1807                                         // カナ変換のため\r
1808                                         cInfo2.Str = cInfo.Buf;\r
1809                                         cInfo2.StrLen = cInfo.OutLen;\r
1810                                         cInfo2.Buf = Buf3;\r
1811                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1812                                         ConvSJIStoEUC(&cInfo2);\r
1813                                         break;\r
1814                                 case KANJI_UTF8N:\r
1815                                         cInfo2.Str = cInfo.Buf;\r
1816                                         cInfo2.StrLen = cInfo.OutLen;\r
1817                                         cInfo2.Buf = Buf3;\r
1818                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1819                                         ConvSJIStoUTF8N(&cInfo2);\r
1820                                         break;\r
1821                                 }\r
1822                                 break;\r
1823                         case KANJI_UTF8N:\r
1824                                 switch(Pkt->KanjiCodeDesired)\r
1825                                 {\r
1826                                 case KANJI_SJIS:\r
1827                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1828                                         cInfo2.OutLen = cInfo.OutLen;\r
1829                                         break;\r
1830                                 case KANJI_JIS:\r
1831                                         cInfo2.Str = cInfo.Buf;\r
1832                                         cInfo2.StrLen = cInfo.OutLen;\r
1833                                         cInfo2.Buf = Buf3;\r
1834                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1835                                         ConvSJIStoJIS(&cInfo2);\r
1836                                         break;\r
1837                                 case KANJI_EUC:\r
1838                                         cInfo2.Str = cInfo.Buf;\r
1839                                         cInfo2.StrLen = cInfo.OutLen;\r
1840                                         cInfo2.Buf = Buf3;\r
1841                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1842                                         ConvSJIStoEUC(&cInfo2);\r
1843                                         break;\r
1844                                 case KANJI_UTF8N:\r
1845                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
1846                                         cInfo2.OutLen = cInfo.OutLen;\r
1847                                         break;\r
1848                                 }\r
1849                                 break;\r
1850                         }\r
1851 //                      if(WriteFile(iFileHandle, Buf2, cInfo.OutLen, &Writed, NULL) == FALSE)\r
1852                         if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE)\r
1853                                 Pkt->Abort = ABORT_DISKFULL;\r
1854                         cInfo2.Buf = Buf3;\r
1855                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
1856                         FlushRestData(&cInfo2);\r
1857                         if(WriteFile(iFileHandle, Buf3, cInfo2.OutLen, &Writed, NULL) == FALSE)\r
1858                                 Pkt->Abort = ABORT_DISKFULL;\r
1859                 }\r
1860 \r
1861                 /* グラフ表示を更新 */\r
1862                 if(Pkt->hWndTrans != NULL)\r
1863                 {\r
1864                         KillTimer(Pkt->hWndTrans, TIMER_DISPLAY);\r
1865                         DispTransferStatus(Pkt->hWndTrans, YES, Pkt);\r
1866                         // 同時接続対応\r
1867 //                      TimeStart = time(NULL) - TimeStart + 1;\r
1868                         TimeStart[Pkt->ThreadCount] = time(NULL) - TimeStart[Pkt->ThreadCount] + 1;\r
1869                 }\r
1870                 else\r
1871                 {\r
1872                         /* 転送ダイアログを出さない時の経過表示を消す */\r
1873                         DispDownloadSize(-1);\r
1874                 }\r
1875 \r
1876                 /* ファイルのタイムスタンプを合わせる */\r
1877                 if((SaveTimeStamp == YES) &&\r
1878                    ((Pkt->Time.dwLowDateTime != 0) || (Pkt->Time.dwHighDateTime != 0)))\r
1879                 {\r
1880                         SetFileTime(iFileHandle, &Pkt->Time, &Pkt->Time, &Pkt->Time);\r
1881                 }\r
1882 \r
1883                 CloseHandle(iFileHandle);\r
1884 \r
1885                 if(iNumBytes == SOCKET_ERROR)\r
1886                         ReportWSError("recv",WSAGetLastError());\r
1887         }\r
1888         else\r
1889         {\r
1890                 SetErrorMsg(MSGJPN095, Pkt->LocalFile);\r
1891                 SetTaskMsg(MSGJPN095, Pkt->LocalFile);\r
1892                 Pkt->Abort = ABORT_ERROR;\r
1893         }\r
1894 \r
1895 \r
1896         if(shutdown(dSkt, 1) != 0)\r
1897                 ReportWSError("shutdown", WSAGetLastError());\r
1898 \r
1899         DoClose(dSkt);\r
1900 \r
1901         if(ForceAbort == NO)\r
1902         {\r
1903                 /* Abortをホストに伝える */\r
1904                 if(Pkt->Abort != ABORT_NONE && iFileHandle != INVALID_HANDLE_VALUE)\r
1905                 {\r
1906                         SendData(Pkt->ctrl_skt, "\xFF\xF4\xFF", 3, MSG_OOB, CancelCheckWork);   /* MSG_OOBに注意 */\r
1907                         SendData(Pkt->ctrl_skt, "\xF2", 1, 0, CancelCheckWork);\r
1908                         command(Pkt->ctrl_skt, NULL, CancelCheckWork, "ABOR");\r
1909                 }\r
1910         }\r
1911 \r
1912         iRetCode = ReadReplyMessage(Pkt->ctrl_skt, Buf, 1024, CancelCheckWork, TmpBuf);\r
1913 \r
1914 //#pragma aaa\r
1915 //DoPrintf("##DOWN REPLY : %s", Buf);\r
1916 \r
1917         if(Pkt->Abort == ABORT_DISKFULL)\r
1918         {\r
1919                 SetErrorMsg(MSGJPN096);\r
1920                 SetTaskMsg(MSGJPN096);\r
1921         }\r
1922         if(iRetCode >= FTP_RETRY)\r
1923                 SetErrorMsg(Buf);\r
1924         if(Pkt->Abort != ABORT_NONE)\r
1925                 iRetCode = 500;\r
1926 \r
1927         return(iRetCode);\r
1928 }\r
1929 \r
1930 \r
1931 /*----- ダウンロード終了/中止時のメッセージを表示 ----------------------------\r
1932 *\r
1933 *       Parameter\r
1934 *               TRANSPACKET *Pkt : 転送ファイル情報\r
1935 *               int iRetCode : 応答コード\r
1936 *\r
1937 *       Return Value\r
1938 *               なし\r
1939 *----------------------------------------------------------------------------*/\r
1940 \r
1941 static void DispDownloadFinishMsg(TRANSPACKET *Pkt, int iRetCode)\r
1942 {\r
1943         char Fname[FMAX_PATH+1];\r
1944 \r
1945         if(ForceAbort == NO)\r
1946         {\r
1947                 if((iRetCode/100) >= FTP_CONTINUE)\r
1948                 {\r
1949                         strcpy(Fname, Pkt->RemoteFile);\r
1950 \r
1951 #if defined(HAVE_OPENVMS)\r
1952                         /* OpenVMSの場合、空ディレクトリへ移動すると550 File not foundになって\r
1953                          * エラーダイアログやエラーメッセージが出るので何もしない */\r
1954                         if (AskHostType() == HTYPE_VMS)\r
1955                                 return;\r
1956 #endif\r
1957 \r
1958                         if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0))\r
1959                         {\r
1960                                 SetTaskMsg(MSGJPN097);\r
1961                                 strcpy(Fname, MSGJPN098);\r
1962                         }\r
1963                         // 同時接続対応\r
1964 //                      else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
1965 //                              SetTaskMsg(MSGJPN099, TimeStart, Pkt->ExistSize/TimeStart);\r
1966                         else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
1967                                 SetTaskMsg(MSGJPN099, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
1968                         else\r
1969                                 SetTaskMsg(MSGJPN100);\r
1970 \r
1971                         if(Pkt->Abort != ABORT_USER)\r
1972                         {\r
1973                                 // 全て中止を選択後にダイアログが表示されるバグ対策\r
1974 //                              if(DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO)\r
1975                                 if(Canceled[Pkt->ThreadCount] == NO && ClearAll == NO && DispUpDownErrDialog(downerr_dlg, Pkt->hWndTrans, Fname) == NO)\r
1976                                         ClearAll = YES;\r
1977                         }\r
1978                 }\r
1979                 else\r
1980                 {\r
1981                         if((strncmp(Pkt->Cmd, "NLST", 4) == 0) || (strncmp(Pkt->Cmd, "LIST", 4) == 0))\r
1982                                 SetTaskMsg(MSGJPN101, Pkt->ExistSize);\r
1983                         // 同時接続対応\r
1984 //                      else if((Pkt->hWndTrans != NULL) && (TimeStart != 0))\r
1985 //                              SetTaskMsg(MSGJPN102, TimeStart, Pkt->ExistSize/TimeStart);\r
1986                         else if((Pkt->hWndTrans != NULL) && (TimeStart[Pkt->ThreadCount] != 0))\r
1987                                 SetTaskMsg(MSGJPN102, TimeStart[Pkt->ThreadCount], Pkt->ExistSize/TimeStart[Pkt->ThreadCount]);\r
1988                         else\r
1989                                 SetTaskMsg(MSGJPN103, Pkt->ExistSize);\r
1990                 }\r
1991         }\r
1992         return;\r
1993 }\r
1994 \r
1995 \r
1996 /*----- ダウンロード/アップロードエラーのダイアログを表示 --------------------\r
1997 *\r
1998 *       Parameter\r
1999 *               int RedID : ダイアログボックスのリソースID\r
2000 *               HWND hWnd : 書き込み中ダイアログのウインドウ\r
2001 *               char *Fname : ファイル名\r
2002 *\r
2003 *       Return Value\r
2004 *               int ステータス (YES=中止/NO=全て中止)\r
2005 *----------------------------------------------------------------------------*/\r
2006 \r
2007 static int DispUpDownErrDialog(int ResID, HWND hWnd, char *Fname)\r
2008 {\r
2009         if(hWnd == NULL)\r
2010                 hWnd = GetMainHwnd();\r
2011 \r
2012         SoundPlay(SND_ERROR);\r
2013         return(DialogBoxParam(GetFtpInst(), MAKEINTRESOURCE(ResID), hWnd, UpDownErrorDialogProc, (LPARAM)Fname));\r
2014 }\r
2015 \r
2016 \r
2017 /*----- ダウンロードエラー/アップロードエラーダイアログのコールバック --------\r
2018 *\r
2019 *       Parameter\r
2020 *               HWND hDlg : ウインドウハンドル\r
2021 *               UINT message : メッセージ番号\r
2022 *               WPARAM wParam : メッセージの WPARAM 引数\r
2023 *               LPARAM lParam : メッセージの LPARAM 引数\r
2024 *\r
2025 *       Return Value\r
2026 *               BOOL TRUE/FALSE\r
2027 *----------------------------------------------------------------------------*/\r
2028 \r
2029 static BOOL CALLBACK UpDownErrorDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
2030 {\r
2031         switch (message)\r
2032         {\r
2033                 case WM_INITDIALOG :\r
2034                         SendDlgItemMessage(hDlg, UPDOWN_ERR_FNAME, WM_SETTEXT, 0, (LPARAM)lParam);\r
2035                         SendDlgItemMessage(hDlg, UPDOWN_ERR_MSG, WM_SETTEXT, 0, (LPARAM)ErrMsg);\r
2036                         return(TRUE);\r
2037 \r
2038                 case WM_COMMAND :\r
2039                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
2040                         {\r
2041                                 case IDOK :\r
2042                                         EndDialog(hDlg, YES);\r
2043                                         break;\r
2044 \r
2045                                 case IDCANCEL :\r
2046                                         EndDialog(hDlg, NO);\r
2047                                         break;\r
2048                         }\r
2049                         return(TRUE);\r
2050         }\r
2051     return(FALSE);\r
2052 }\r
2053 \r
2054 \r
2055 /*----- ダウンロードのリジュームの準備を行う ----------------------------------\r
2056 *\r
2057 *       Parameter\r
2058 *               TRANSPACKET *Pkt : 転送ファイル情報\r
2059 *               iont ProcMode : 処理モード(EXIST_xxx)\r
2060 *               LONGLONG Size : ロード済みのファイルのサイズ\r
2061 *               int *Mode : ファイル作成モード (CREATE_xxxx)\r
2062 *\r
2063 *       Return Value\r
2064 *               int 転送を行うかどうか(YES/NO=このファイルを中止/NO_ALL=全て中止)\r
2065 *\r
2066 *       Note\r
2067 *               Pkt->ExistSizeのセットを行なう\r
2068 *----------------------------------------------------------------------------*/\r
2069 \r
2070 static int SetDownloadResume(TRANSPACKET *Pkt, int ProcMode, LONGLONG Size, int *Mode, int *CancelCheckWork)\r
2071 {\r
2072         int iRetCode;\r
2073         int Com;\r
2074         char Reply[ERR_MSG_LEN+7];\r
2075         char Tmp[40];\r
2076 \r
2077         Com = YES;\r
2078 \r
2079         Pkt->ExistSize = 0;\r
2080         *Mode = CREATE_ALWAYS;\r
2081 \r
2082         if(ProcMode == EXIST_RESUME)\r
2083         {\r
2084                 iRetCode = command(Pkt->ctrl_skt, Reply, CancelCheckWork, "REST %s", MakeNumString(Size, Tmp, FALSE));\r
2085                 if(iRetCode/100 < FTP_RETRY)\r
2086                 {\r
2087                         /* リジューム */\r
2088                         if(Pkt->hWndTrans != NULL)\r
2089                                 Pkt->ExistSize = Size;\r
2090                         *Mode = OPEN_ALWAYS;\r
2091                 }\r
2092                 else\r
2093                 {\r
2094                         Com = DialogBox(GetFtpInst(), MAKEINTRESOURCE(noresume_dlg), Pkt->hWndTrans, NoResumeWndProc);\r
2095                         if(Com != YES)\r
2096                         {\r
2097                                 if(Com == NO_ALL)               /* 全て中止 */\r
2098                                         ClearAll = YES;\r
2099                                 Pkt->Abort = ABORT_USER;\r
2100                         }\r
2101                 }\r
2102         }\r
2103         return(Com);\r
2104 }\r
2105 \r
2106 \r
2107 /*----- resumeエラーダイアログのコールバック ----------------------------------\r
2108 *\r
2109 *       Parameter\r
2110 *               HWND hDlg : ウインドウハンドル\r
2111 *               UINT message : メッセージ番号\r
2112 *               WPARAM wParam : メッセージの WPARAM 引数\r
2113 *               LPARAM lParam : メッセージの LPARAM 引数\r
2114 *\r
2115 *       Return Value\r
2116 *               BOOL TRUE/FALSE\r
2117 *----------------------------------------------------------------------------*/\r
2118 \r
2119 static BOOL CALLBACK NoResumeWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
2120 {\r
2121         switch (iMessage)\r
2122         {\r
2123                 case WM_INITDIALOG :\r
2124                         return(TRUE);\r
2125 \r
2126                 case WM_COMMAND :\r
2127                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
2128                         {\r
2129                                 case IDOK :\r
2130                                         EndDialog(hDlg, YES);\r
2131                                         break;\r
2132 \r
2133                                 case IDCANCEL :\r
2134                                         EndDialog(hDlg, NO);\r
2135                                         break;\r
2136 \r
2137                                 case RESUME_CANCEL_ALL :\r
2138                                         EndDialog(hDlg, NO_ALL);\r
2139                                         break;\r
2140                         }\r
2141             return(TRUE);\r
2142         }\r
2143         return(FALSE);\r
2144 }\r
2145 \r
2146 \r
2147 \r
2148 /*----- アップロードを行なう --------------------------------------------------\r
2149 *\r
2150 *       Parameter\r
2151 *               SOCKET cSkt : コントロールソケット\r
2152 *               TRANSPACKET *Pkt : 転送ファイル情報\r
2153 *\r
2154 *       Return Value\r
2155 *               int 応答コード\r
2156 *----------------------------------------------------------------------------*/\r
2157 \r
2158 static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt)\r
2159 {\r
2160         int iRetCode;\r
2161         char Reply[ERR_MSG_LEN+7];\r
2162 \r
2163         Pkt->ctrl_skt = cSkt;\r
2164 \r
2165         if(Pkt->Mode != EXIST_IGNORE)\r
2166         {\r
2167                 if(CheckFileReadable(Pkt->LocalFile) == FFFTP_SUCCESS)\r
2168                 {\r
2169                         if(Pkt->Type == TYPE_I)\r
2170                                 Pkt->KanjiCode = KANJI_NOCNV;\r
2171 \r
2172                         // 同時接続対応\r
2173 //                      iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "TYPE %c", Pkt->Type);\r
2174                         iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "TYPE %c", Pkt->Type);\r
2175                         if(iRetCode/100 < FTP_RETRY)\r
2176                         {\r
2177                                 if(Pkt->Mode == EXIST_UNIQUE)\r
2178                                         strcpy(Pkt->Cmd, "STOU ");\r
2179 \r
2180                                 if(Pkt->hWndTrans != NULL)\r
2181                                         DispTransFileInfo(Pkt, MSGJPN104, TRUE, YES);\r
2182 \r
2183                                 if(BackgrndMessageProc() == NO)\r
2184                                 {\r
2185                                         if(AskPasvMode() != YES)\r
2186                                                 iRetCode = UpLoadNonPassive(Pkt);\r
2187                                         else\r
2188                                                 iRetCode = UpLoadPassive(Pkt);\r
2189                                 }\r
2190                                 else\r
2191                                         iRetCode = 500;\r
2192                         }\r
2193                         else\r
2194                                 SetErrorMsg(Reply);\r
2195 \r
2196                         /* 属性変更 */\r
2197                         if((Pkt->Attr != -1) && ((iRetCode/100) == FTP_COMPLETE))\r
2198                                 // 同時接続対応\r
2199 //                              command(Pkt->ctrl_skt, Reply, &Canceled, "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile);\r
2200                                 command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s %03X %s", AskHostChmodCmd(), Pkt->Attr, Pkt->RemoteFile);\r
2201                 }\r
2202                 else\r
2203                 {\r
2204                         SetErrorMsg(MSGJPN105, Pkt->LocalFile);\r
2205                         SetTaskMsg(MSGJPN105, Pkt->LocalFile);\r
2206                         iRetCode = 500;\r
2207                         Pkt->Abort = ABORT_ERROR;\r
2208                         DispUploadFinishMsg(Pkt, iRetCode);\r
2209                 }\r
2210         }\r
2211         else\r
2212         {\r
2213                 DispTransFileInfo(Pkt, MSGJPN106, TRUE, YES);\r
2214                 SetTaskMsg(MSGJPN107, Pkt->LocalFile);\r
2215                 iRetCode = 200;\r
2216         }\r
2217         return(iRetCode);\r
2218 }\r
2219 \r
2220 \r
2221 /*----- 通常モードでファイルをアップロード ------------------------------------\r
2222 *\r
2223 *       Parameter\r
2224 *               TRANSPACKET *Pkt : 転送ファイル情報\r
2225 *\r
2226 *       Return Value\r
2227 *               int 応答コード\r
2228 *----------------------------------------------------------------------------*/\r
2229 \r
2230 static int UpLoadNonPassive(TRANSPACKET *Pkt)\r
2231 {\r
2232         int iRetCode;\r
2233         int iLength;\r
2234         SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
2235         SOCKET listen_socket = INVALID_SOCKET; // data listen socket\r
2236         char Buf[1024];\r
2237         struct sockaddr_in saSockAddr1;\r
2238         int Resume;\r
2239         char Reply[ERR_MSG_LEN+7];\r
2240 \r
2241         // 同時接続対応\r
2242 //      if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled)) != INVALID_SOCKET)\r
2243         if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET)\r
2244         {\r
2245                 SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume);\r
2246                 if(Resume == NO)\r
2247                         sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile);\r
2248                 else\r
2249                         sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile);\r
2250 \r
2251                 // 同時接続対応\r
2252 //              iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
2253                 iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf);\r
2254                 if((iRetCode/100) == FTP_PRELIM)\r
2255                 {\r
2256                         if(SocksGet2ndBindReply(listen_socket, &data_socket) == FFFTP_FAIL)\r
2257                         {\r
2258                                 iLength=sizeof(saSockAddr1);\r
2259                                 data_socket = do_accept(listen_socket,(struct sockaddr *)&saSockAddr1, (int *)&iLength);\r
2260 \r
2261                                 if(shutdown(listen_socket, 1) != 0)\r
2262                                         ReportWSError("shutdown listen", WSAGetLastError());\r
2263                                 listen_socket = DoClose(listen_socket);\r
2264 \r
2265                                 if(data_socket == INVALID_SOCKET)\r
2266                                 {\r
2267                                         SetErrorMsg(MSGJPN280);\r
2268                                         ReportWSError("accept", WSAGetLastError());\r
2269                                         iRetCode = 500;\r
2270                                 }\r
2271                                 else\r
2272                                         DoPrintf("Skt=%u : accept from %s port %u", data_socket, inet_ntoa(saSockAddr1.sin_addr), ntohs(saSockAddr1.sin_port));\r
2273                         }\r
2274 \r
2275                         if(data_socket != INVALID_SOCKET)\r
2276                         {\r
2277                                 // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
2278                                 ReleaseMutex(hListAccMutex);\r
2279                                 // FTPS対応\r
2280 //                              iRetCode = UpLoadFile(Pkt, data_socket);\r
2281                                 if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
2282                                 {\r
2283                                         if(AttachSSL(data_socket))\r
2284                                                 iRetCode = UpLoadFile(Pkt, data_socket);\r
2285                                         else\r
2286                                                 iRetCode = FTP_ERROR;\r
2287                                 }\r
2288                                 else\r
2289                                         iRetCode = UpLoadFile(Pkt, data_socket);\r
2290                                 data_socket = DoClose(data_socket);\r
2291                         }\r
2292                 }\r
2293                 else\r
2294                 {\r
2295                         SetErrorMsg(Reply);\r
2296                         SetTaskMsg(MSGJPN108);\r
2297                         listen_socket = DoClose(listen_socket);\r
2298                         iRetCode = 500;\r
2299                 }\r
2300         }\r
2301         else\r
2302         {\r
2303                 SetErrorMsg(MSGJPN279);\r
2304                 iRetCode = 500;\r
2305         }\r
2306         DispUploadFinishMsg(Pkt, iRetCode);\r
2307 \r
2308         return(iRetCode);\r
2309 }\r
2310 \r
2311 \r
2312 /*----- Passiveモードでファイルをアップロード ---------------------------------\r
2313 *\r
2314 *       Parameter\r
2315 *               TRANSPACKET *Pkt : 転送ファイル情報\r
2316 *\r
2317 *       Return Value\r
2318 *               int 応答コード\r
2319 *----------------------------------------------------------------------------*/\r
2320 \r
2321 static int UpLoadPassive(TRANSPACKET *Pkt)\r
2322 {\r
2323         int iRetCode;\r
2324         SOCKET data_socket = INVALID_SOCKET;   // data channel socket\r
2325         char Buf[1024];\r
2326         char Adrs[20];\r
2327         int Port;\r
2328         int Flg;\r
2329         int Resume;\r
2330         char Reply[ERR_MSG_LEN+7];\r
2331 \r
2332         // 同時接続対応\r
2333 //      iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled, "PASV");\r
2334         iRetCode = command(Pkt->ctrl_skt, Buf, &Canceled[Pkt->ThreadCount], "PASV");\r
2335         if(iRetCode/100 == FTP_COMPLETE)\r
2336         {\r
2337                 if(GetAdrsAndPort(Buf, Adrs, &Port, 19) == FFFTP_SUCCESS)\r
2338                 {\r
2339                         // 同時接続対応\r
2340 //                      if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled)) != INVALID_SOCKET)\r
2341                         if((data_socket = connectsock(Adrs, Port, MSGJPN109, &Canceled[Pkt->ThreadCount])) != INVALID_SOCKET)\r
2342                         {\r
2343                                 // 変数が未初期化のバグ修正\r
2344                                 Flg = 1;\r
2345                                 if(setsockopt(data_socket, IPPROTO_TCP, TCP_NODELAY, (LPSTR)&Flg, sizeof(Flg)) == SOCKET_ERROR)\r
2346                                         ReportWSError("setsockopt", WSAGetLastError());\r
2347 \r
2348                                 SetUploadResume(Pkt, Pkt->Mode, Pkt->ExistSize, &Resume);\r
2349                                 if(Resume == NO)\r
2350                                         sprintf(Buf, "%s%s", Pkt->Cmd, Pkt->RemoteFile);\r
2351                                 else\r
2352                                         sprintf(Buf, "%s%s", "APPE ", Pkt->RemoteFile);\r
2353 \r
2354                                 // 同時接続対応\r
2355 //                              iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled, "%s", Buf);\r
2356                                 iRetCode = command(Pkt->ctrl_skt, Reply, &Canceled[Pkt->ThreadCount], "%s", Buf);\r
2357                                 if(iRetCode/100 == FTP_PRELIM)\r
2358                                 {\r
2359                                         // 一部TYPE、STOR(RETR)、PORT(PASV)を並列に処理できないホストがあるため\r
2360                                         ReleaseMutex(hListAccMutex);\r
2361                                         // FTPS対応\r
2362 //                                      iRetCode = UpLoadFile(Pkt, data_socket);\r
2363                                         if(AskCryptMode() == CRYPT_FTPES || AskCryptMode() == CRYPT_FTPIS)\r
2364                                         {\r
2365                                                 if(AttachSSL(data_socket))\r
2366                                                         iRetCode = UpLoadFile(Pkt, data_socket);\r
2367                                                 else\r
2368                                                         iRetCode = FTP_ERROR;\r
2369                                         }\r
2370                                         else\r
2371                                                 iRetCode = UpLoadFile(Pkt, data_socket);\r
2372 \r
2373                                         data_socket = DoClose(data_socket);\r
2374                                 }\r
2375                                 else\r
2376                                 {\r
2377                                         SetErrorMsg(Reply);\r
2378                                         SetTaskMsg(MSGJPN110);\r
2379                                         data_socket = DoClose(data_socket);\r
2380                                         iRetCode = 500;\r
2381                                 }\r
2382                         }\r
2383                         else\r
2384                         {\r
2385                                 SetErrorMsg(MSGJPN281);\r
2386                                 iRetCode = 500;\r
2387                         }\r
2388                 }\r
2389                 else\r
2390                 {\r
2391                         SetErrorMsg(Buf);\r
2392                         SetTaskMsg(MSGJPN111);\r
2393                         iRetCode = 500;\r
2394                 }\r
2395         }\r
2396         else\r
2397                 SetErrorMsg(Buf);\r
2398 \r
2399         DispUploadFinishMsg(Pkt, iRetCode);\r
2400 \r
2401         return(iRetCode);\r
2402 }\r
2403 \r
2404 \r
2405 /*----- アップロードの実行 ----------------------------------------------------\r
2406 *\r
2407 *       Parameter\r
2408 *               TRANSPACKET *Pkt : 転送ファイル情報\r
2409 *               SOCKET dSkt : データソケット\r
2410 *\r
2411 *       Return Value\r
2412 *               int 応答コード\r
2413 *\r
2414 *       Note\r
2415 *               転送の経過表示は、インターバルタイマで経過を表示する\r
2416 *               転送ダイアログを出さないでアップロードすることはない\r
2417 *----------------------------------------------------------------------------*/\r
2418 \r
2419 static int UpLoadFile(TRANSPACKET *Pkt, SOCKET dSkt)\r
2420 {\r
2421         DWORD iNumBytes;\r
2422         HANDLE iFileHandle;\r
2423         SECURITY_ATTRIBUTES Sec;\r
2424         char Buf[BUFSIZE];\r
2425         char Buf2[BUFSIZE+3];\r
2426         CODECONVINFO cInfo;\r
2427         TERMCODECONVINFO tInfo;\r
2428         int Continue;\r
2429         char *EofPos;\r
2430         int iRetCode;\r
2431 #if 0\r
2432         int TimeOutErr;\r
2433 #endif\r
2434         char TmpBuf[ONELINE_BUF_SIZE];\r
2435         DWORD Low;\r
2436         DWORD High;\r
2437 \r
2438 #ifdef SET_BUFFER_SIZE\r
2439 /* Add by H.Shirouzu at 2002/10/02 */\r
2440         int buf_size = SOCKBUF_SIZE;\r
2441         for ( ; buf_size > 0; buf_size /= 2)\r
2442                 if (setsockopt(dSkt, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size)) == 0)\r
2443                         break;\r
2444 /* End */\r
2445 #endif\r
2446 \r
2447         // 念のため送信バッファを無効にする\r
2448 #ifdef DISABLE_TRANSFER_NETWORK_BUFFERS\r
2449         int buf_size = 0;\r
2450         setsockopt(dSkt, SOL_SOCKET, SO_SNDBUF, (char *)&buf_size, sizeof(buf_size));\r
2451 #endif\r
2452 \r
2453         Pkt->Abort = ABORT_NONE;\r
2454 \r
2455         Sec.nLength = sizeof(SECURITY_ATTRIBUTES);\r
2456         Sec.lpSecurityDescriptor = NULL;\r
2457         Sec.bInheritHandle = FALSE;\r
2458 \r
2459         if((iFileHandle = CreateFile(Pkt->LocalFile, GENERIC_READ,\r
2460                 FILE_SHARE_READ|FILE_SHARE_WRITE, &Sec, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
2461         {\r
2462                 // UTF-8対応\r
2463                 char Buf3[(BUFSIZE + 3) * 4];\r
2464                 CODECONVINFO cInfo2;\r
2465                 int ProcessedBOM = NO;\r
2466                 if(Pkt->hWndTrans != NULL)\r
2467                 {\r
2468                         Low = GetFileSize(iFileHandle, &High);\r
2469                         Pkt->Size = MakeLongLong(High, Low);\r
2470 \r
2471                         High = (DWORD)HIGH32(Pkt->ExistSize);\r
2472                         Low = (DWORD)LOW32(Pkt->ExistSize);\r
2473                         SetFilePointer(iFileHandle, Low, &High, FILE_BEGIN);\r
2474 \r
2475                         // 同時接続対応\r
2476 //                      AllTransSizeNow = 0;\r
2477 //                      TimeStart = time(NULL);\r
2478                         AllTransSizeNow[Pkt->ThreadCount] = 0;\r
2479                         TimeStart[Pkt->ThreadCount] = time(NULL);\r
2480                         SetTimer(Pkt->hWndTrans, TIMER_DISPLAY, DISPLAY_TIMING, NULL);\r
2481                 }\r
2482 \r
2483                 InitCodeConvInfo(&cInfo);\r
2484                 cInfo.KanaCnv = Pkt->KanaCnv;\r
2485                 InitTermCodeConvInfo(&tInfo);\r
2486 \r
2487                 InitCodeConvInfo(&cInfo2);\r
2488                 cInfo2.KanaCnv = Pkt->KanaCnv;\r
2489 \r
2490                 /*===== ファイルを送信するループ =====*/\r
2491                 while((Pkt->Abort == ABORT_NONE) &&\r
2492                           (ForceAbort == NO) &&\r
2493                           (ReadFile(iFileHandle, Buf, BUFSIZE, &iNumBytes, NULL) == TRUE))\r
2494                 {\r
2495                         if(iNumBytes == 0)\r
2496                                 break;\r
2497 \r
2498                         /* EOF除去 */\r
2499                         EofPos = NULL;\r
2500                         if((RmEOF == YES) && (Pkt->Type == TYPE_A))\r
2501                         {\r
2502                                 if((EofPos = memchr(Buf, 0x1A, iNumBytes)) != NULL)\r
2503                                         iNumBytes = EofPos - Buf;\r
2504                         }\r
2505 \r
2506                         /* 漢字コード変換 */\r
2507                         if(Pkt->KanjiCode != KANJI_NOCNV)\r
2508                         {\r
2509                                 cInfo.Str = Buf;\r
2510                                 cInfo.StrLen = iNumBytes;\r
2511                                 cInfo.Buf = Buf2;\r
2512                                 cInfo.BufSize = BUFSIZE+3;\r
2513                                 do\r
2514                                 {\r
2515                                         // ここで全てUTF-8へ変換する\r
2516                                         // TODO: SJIS以外も直接UTF-8へ変換\r
2517 //                                      if(Pkt->KanjiCode == KANJI_JIS)\r
2518 //                                              Continue = ConvSJIStoJIS(&cInfo);\r
2519 //                                      else\r
2520 //                                              Continue = ConvSJIStoEUC(&cInfo);\r
2521                                         switch(Pkt->KanjiCodeDesired)\r
2522                                         {\r
2523                                         case KANJI_SJIS:\r
2524                                                 switch(Pkt->KanjiCode)\r
2525                                                 {\r
2526                                                 case KANJI_SJIS:\r
2527 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
2528 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
2529 //                                                      Continue = NO;\r
2530                                                         // カナ変換のため\r
2531                                                         Continue = ConvSJIStoJIS(&cInfo);\r
2532                                                         cInfo2.Str = cInfo.Buf;\r
2533                                                         cInfo2.StrLen = cInfo.OutLen;\r
2534                                                         cInfo2.Buf = Buf3;\r
2535                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2536                                                         ConvJIStoSJIS(&cInfo2);\r
2537                                                         break;\r
2538                                                 case KANJI_JIS:\r
2539                                                         Continue = ConvSJIStoJIS(&cInfo);\r
2540                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2541                                                         cInfo2.OutLen = cInfo.OutLen;\r
2542                                                         break;\r
2543                                                 case KANJI_EUC:\r
2544                                                         Continue = ConvSJIStoEUC(&cInfo);\r
2545                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2546                                                         cInfo2.OutLen = cInfo.OutLen;\r
2547                                                         break;\r
2548                                                 case KANJI_UTF8N:\r
2549                                                         if(ProcessedBOM == NO)\r
2550                                                         {\r
2551                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
2552                                                                 cInfo2.OutLen = 3;\r
2553                                                                 Continue = YES;\r
2554                                                                 ProcessedBOM = YES;\r
2555                                                                 break;\r
2556                                                         }\r
2557                                                         Continue = ConvSJIStoUTF8N(&cInfo);\r
2558                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2559                                                         cInfo2.OutLen = cInfo.OutLen;\r
2560                                                         break;\r
2561                                                 }\r
2562                                                 break;\r
2563                                         case KANJI_JIS:\r
2564                                                 switch(Pkt->KanjiCode)\r
2565                                                 {\r
2566                                                 case KANJI_SJIS:\r
2567                                                         Continue = ConvJIStoSJIS(&cInfo);\r
2568                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2569                                                         cInfo2.OutLen = cInfo.OutLen;\r
2570                                                         break;\r
2571                                                 case KANJI_JIS:\r
2572 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
2573 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
2574 //                                                      Continue = NO;\r
2575                                                         // カナ変換のため\r
2576                                                         Continue = ConvJIStoSJIS(&cInfo);\r
2577                                                         cInfo2.Str = cInfo.Buf;\r
2578                                                         cInfo2.StrLen = cInfo.OutLen;\r
2579                                                         cInfo2.Buf = Buf3;\r
2580                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2581                                                         ConvSJIStoJIS(&cInfo2);\r
2582                                                         break;\r
2583                                                 case KANJI_EUC:\r
2584                                                         Continue = ConvJIStoSJIS(&cInfo);\r
2585                                                         cInfo2.Str = cInfo.Buf;\r
2586                                                         cInfo2.StrLen = cInfo.OutLen;\r
2587                                                         cInfo2.Buf = Buf3;\r
2588                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2589                                                         ConvSJIStoEUC(&cInfo2);\r
2590                                                         break;\r
2591                                                 case KANJI_UTF8N:\r
2592                                                         if(ProcessedBOM == NO)\r
2593                                                         {\r
2594                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
2595                                                                 cInfo2.OutLen = 3;\r
2596                                                                 Continue = YES;\r
2597                                                                 ProcessedBOM = YES;\r
2598                                                                 break;\r
2599                                                         }\r
2600                                                         Continue = ConvJIStoSJIS(&cInfo);\r
2601                                                         cInfo2.Str = cInfo.Buf;\r
2602                                                         cInfo2.StrLen = cInfo.OutLen;\r
2603                                                         cInfo2.Buf = Buf3;\r
2604                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2605                                                         ConvSJIStoUTF8N(&cInfo2);\r
2606                                                         break;\r
2607                                                 }\r
2608                                                 break;\r
2609                                         case KANJI_EUC:\r
2610                                                 switch(Pkt->KanjiCode)\r
2611                                                 {\r
2612                                                 case KANJI_SJIS:\r
2613                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
2614                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2615                                                         cInfo2.OutLen = cInfo.OutLen;\r
2616                                                         break;\r
2617                                                 case KANJI_JIS:\r
2618                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
2619                                                         cInfo2.Str = cInfo.Buf;\r
2620                                                         cInfo2.StrLen = cInfo.OutLen;\r
2621                                                         cInfo2.Buf = Buf3;\r
2622                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2623                                                         ConvSJIStoJIS(&cInfo2);\r
2624                                                         break;\r
2625                                                 case KANJI_EUC:\r
2626 //                                                      memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
2627 //                                                      cInfo2.OutLen = cInfo.StrLen;\r
2628 //                                                      Continue = NO;\r
2629                                                         // カナ変換のため\r
2630                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
2631                                                         cInfo2.Str = cInfo.Buf;\r
2632                                                         cInfo2.StrLen = cInfo.OutLen;\r
2633                                                         cInfo2.Buf = Buf3;\r
2634                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2635                                                         ConvSJIStoEUC(&cInfo2);\r
2636                                                         break;\r
2637                                                 case KANJI_UTF8N:\r
2638                                                         if(ProcessedBOM == NO)\r
2639                                                         {\r
2640                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
2641                                                                 cInfo2.OutLen = 3;\r
2642                                                                 Continue = YES;\r
2643                                                                 ProcessedBOM = YES;\r
2644                                                                 break;\r
2645                                                         }\r
2646                                                         Continue = ConvEUCtoSJIS(&cInfo);\r
2647                                                         cInfo2.Str = cInfo.Buf;\r
2648                                                         cInfo2.StrLen = cInfo.OutLen;\r
2649                                                         cInfo2.Buf = Buf3;\r
2650                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2651                                                         ConvSJIStoUTF8N(&cInfo2);\r
2652                                                         break;\r
2653                                                 }\r
2654                                                 break;\r
2655                                         case KANJI_UTF8N:\r
2656                                                 if(ProcessedBOM == NO)\r
2657                                                 {\r
2658                                                         if(memcmp(Buf, "\xEF\xBB\xBF", 3) == 0)\r
2659                                                         {\r
2660                                                                 cInfo.Str += 3;\r
2661                                                                 cInfo.StrLen -= 3;\r
2662                                                         }\r
2663                                                         cInfo2.OutLen = 0;\r
2664                                                         switch(Pkt->KanjiCode)\r
2665                                                         {\r
2666                                                         case KANJI_UTF8N:\r
2667                                                                 memcpy(Buf3, "\xEF\xBB\xBF", 3);\r
2668                                                                 cInfo2.OutLen = 3;\r
2669                                                                 break;\r
2670                                                         }\r
2671                                                         Continue = YES;\r
2672                                                         ProcessedBOM = YES;\r
2673                                                         break;\r
2674                                                 }\r
2675                                                 switch(Pkt->KanjiCode)\r
2676                                                 {\r
2677                                                 case KANJI_SJIS:\r
2678                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
2679                                                         memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2680                                                         cInfo2.OutLen = cInfo.OutLen;\r
2681                                                         break;\r
2682                                                 case KANJI_JIS:\r
2683                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
2684                                                         cInfo2.Str = cInfo.Buf;\r
2685                                                         cInfo2.StrLen = cInfo.OutLen;\r
2686                                                         cInfo2.Buf = Buf3;\r
2687                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2688                                                         ConvSJIStoJIS(&cInfo2);\r
2689                                                         break;\r
2690                                                 case KANJI_EUC:\r
2691                                                         Continue = ConvUTF8NtoSJIS(&cInfo);\r
2692                                                         cInfo2.Str = cInfo.Buf;\r
2693                                                         cInfo2.StrLen = cInfo.OutLen;\r
2694                                                         cInfo2.Buf = Buf3;\r
2695                                                         cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2696                                                         ConvSJIStoEUC(&cInfo2);\r
2697                                                         break;\r
2698                                                 case KANJI_UTF8N:\r
2699                                                         memcpy(Buf3, cInfo.Str, cInfo.StrLen);\r
2700                                                         cInfo2.OutLen = cInfo.StrLen;\r
2701                                                         Continue = NO;\r
2702                                                         break;\r
2703                                                 }\r
2704                                                 break;\r
2705                                         }\r
2706 \r
2707 //                                      if(TermCodeConvAndSend(&tInfo, dSkt, Buf2, cInfo.OutLen, Pkt->Type) == FFFTP_FAIL)\r
2708                                         if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf3, cInfo2.OutLen, Pkt->Type) == FFFTP_FAIL)\r
2709                                         {\r
2710                                                 Pkt->Abort = ABORT_ERROR;\r
2711                                                         break;\r
2712                                         }\r
2713                                 }\r
2714                                 while(Continue == YES);\r
2715                         }\r
2716                         else\r
2717                         {\r
2718                                 // 同時接続対応\r
2719 //                              if(TermCodeConvAndSend(&tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL)\r
2720                                 if(TermCodeConvAndSend(Pkt->ThreadCount, &tInfo, dSkt, Buf, iNumBytes, Pkt->Type) == FFFTP_FAIL)\r
2721                                         Pkt->Abort = ABORT_ERROR;\r
2722                         }\r
2723 \r
2724                         Pkt->ExistSize += iNumBytes;\r
2725                         if(Pkt->hWndTrans != NULL)\r
2726                                 // 同時接続対応\r
2727 //                              AllTransSizeNow += iNumBytes;\r
2728                                 AllTransSizeNow[Pkt->ThreadCount] += iNumBytes;\r
2729 \r
2730                         if(BackgrndMessageProc() == YES)\r
2731                                 ForceAbort = YES;\r
2732 \r
2733                         if(EofPos != NULL)\r
2734                                 break;\r
2735                 }\r
2736 \r
2737                 if((ForceAbort == NO) && (Pkt->Abort == ABORT_NONE))\r
2738                 {\r
2739                         /* 送り残したデータを送信 */\r
2740                         if(Pkt->KanjiCode != KANJI_NOCNV)\r
2741                         {\r
2742                                 cInfo.Buf = Buf2;\r
2743                                 cInfo.BufSize = BUFSIZE+3;\r
2744                                 FlushRestData(&cInfo);\r
2745                                 switch(Pkt->KanjiCodeDesired)\r
2746                                 {\r
2747                                 case KANJI_SJIS:\r
2748                                         switch(Pkt->KanjiCode)\r
2749                                         {\r
2750                                         case KANJI_SJIS:\r
2751                                                 // カナ変換のため\r
2752                                                 cInfo2.Str = cInfo.Buf;\r
2753                                                 cInfo2.StrLen = cInfo.OutLen;\r
2754                                                 cInfo2.Buf = Buf3;\r
2755                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2756                                                 ConvJIStoSJIS(&cInfo2);\r
2757                                                 break;\r
2758                                         case KANJI_JIS:\r
2759                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2760                                                 cInfo2.OutLen = cInfo.OutLen;\r
2761                                                 break;\r
2762                                         case KANJI_EUC:\r
2763                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2764                                                 cInfo2.OutLen = cInfo.OutLen;\r
2765                                                 break;\r
2766                                         case KANJI_UTF8N:\r
2767                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2768                                                 cInfo2.OutLen = cInfo.OutLen;\r
2769                                                 break;\r
2770                                         }\r
2771                                         break;\r
2772                                 case KANJI_JIS:\r
2773                                         switch(Pkt->KanjiCode)\r
2774                                         {\r
2775                                         case KANJI_SJIS:\r
2776                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2777                                                 cInfo2.OutLen = cInfo.OutLen;\r
2778                                                 break;\r
2779                                         case KANJI_JIS:\r
2780                                                 // カナ変換のため\r
2781                                                 cInfo2.Str = cInfo.Buf;\r
2782                                                 cInfo2.StrLen = cInfo.OutLen;\r
2783                                                 cInfo2.Buf = Buf3;\r
2784                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2785                                                 ConvSJIStoJIS(&cInfo2);\r
2786                                                 break;\r
2787                                         case KANJI_EUC:\r
2788                                                 cInfo2.Str = cInfo.Buf;\r
2789                                                 cInfo2.StrLen = cInfo.OutLen;\r
2790                                                 cInfo2.Buf = Buf3;\r
2791                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2792                                                 ConvSJIStoEUC(&cInfo2);\r
2793                                                 break;\r
2794                                         case KANJI_UTF8N:\r
2795                                                 cInfo2.Str = cInfo.Buf;\r
2796                                                 cInfo2.StrLen = cInfo.OutLen;\r
2797                                                 cInfo2.Buf = Buf3;\r
2798                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2799                                                 ConvSJIStoUTF8N(&cInfo2);\r
2800                                                 break;\r
2801                                         }\r
2802                                         break;\r
2803                                 case KANJI_EUC:\r
2804                                         switch(Pkt->KanjiCode)\r
2805                                         {\r
2806                                         case KANJI_SJIS:\r
2807                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2808                                                 cInfo2.OutLen = cInfo.OutLen;\r
2809                                                 break;\r
2810                                         case KANJI_JIS:\r
2811                                                 cInfo2.Str = cInfo.Buf;\r
2812                                                 cInfo2.StrLen = cInfo.OutLen;\r
2813                                                 cInfo2.Buf = Buf3;\r
2814                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2815                                                 ConvSJIStoJIS(&cInfo2);\r
2816                                                 break;\r
2817                                         case KANJI_EUC:\r
2818                                                 // カナ変換のため\r
2819                                                 cInfo2.Str = cInfo.Buf;\r
2820                                                 cInfo2.StrLen = cInfo.OutLen;\r
2821                                                 cInfo2.Buf = Buf3;\r
2822                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2823                                                 ConvSJIStoEUC(&cInfo2);\r
2824                                                 break;\r
2825                                         case KANJI_UTF8N:\r
2826                                                 cInfo2.Str = cInfo.Buf;\r
2827                                                 cInfo2.StrLen = cInfo.OutLen;\r
2828                                                 cInfo2.Buf = Buf3;\r
2829                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2830                                                 ConvSJIStoUTF8N(&cInfo2);\r
2831                                                 break;\r
2832                                         }\r
2833                                         break;\r
2834                                 case KANJI_UTF8N:\r
2835                                         switch(Pkt->KanjiCode)\r
2836                                         {\r
2837                                         case KANJI_SJIS:\r
2838                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2839                                                 cInfo2.OutLen = cInfo.OutLen;\r
2840                                                 break;\r
2841                                         case KANJI_JIS:\r
2842                                                 cInfo2.Str = cInfo.Buf;\r
2843                                                 cInfo2.StrLen = cInfo.OutLen;\r
2844                                                 cInfo2.Buf = Buf3;\r
2845                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2846                                                 ConvSJIStoJIS(&cInfo2);\r
2847                                                 break;\r
2848                                         case KANJI_EUC:\r
2849                                                 cInfo2.Str = cInfo.Buf;\r
2850                                                 cInfo2.StrLen = cInfo.OutLen;\r
2851                                                 cInfo2.Buf = Buf3;\r
2852                                                 cInfo2.BufSize = (BUFSIZE + 3) * 4;\r
2853                                                 ConvSJIStoEUC(&cInfo2);\r
2854                                                 break;\r
2855                                         case KANJI_UTF8N:\r
2856                                                 memcpy(Buf3, cInfo.Buf, cInfo.OutLen);\r
2857                                                 cInfo2.OutLen = cInfo.OutLen;\r
2858                                                 break;\r
2859                                         }\r
2860                                         break;\r
2861