OSDN Git Service

Fix bugs of simultaneous connection.
[ffftp/ffftp.git] / filelist.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 // UTF-8対応\r
31 //#define _WIN32_WINNT  0x400\r
32 \r
33 #define STRICT\r
34 // IPv6対応\r
35 #include <winsock2.h>\r
36 #include <windows.h>\r
37 #include <stdio.h>\r
38 #include <stdlib.h>\r
39 #include <string.h>\r
40 #include <ctype.h>\r
41 #include <time.h>\r
42 #include <mbstring.h>\r
43 #include <malloc.h>\r
44 #include <windowsx.h>\r
45 #include <commctrl.h>\r
46 #include <sys/types.h>\r
47 #include <sys/stat.h>\r
48 #include <direct.h>\r
49 \r
50 #include "common.h"\r
51 #include "resource.h"\r
52 \r
53 #include <htmlhelp.h>\r
54 #include "helpid.h"\r
55 \r
56 #include <shlobj.h>\r
57 #include "OleDragDrop.h"\r
58 #include "common.h"\r
59 \r
60 // UTF-8対応\r
61 #undef __MBSWRAPPER_H__\r
62 #include "mbswrapper.h"\r
63 \r
64 #define BUF_SIZE                256\r
65 #define CF_CNT 2\r
66 #define WM_DRAGDROP             (WM_APP + 100)\r
67 #define WM_GETDATA              (WM_APP + 101)\r
68 #define WM_DRAGOVER             (WM_APP + 102)\r
69 \r
70 \r
71 /*===== ファイルリストのリスト用ストラクチャ =====*/\r
72 \r
73 typedef struct {\r
74         FILELIST *Top;                  /* ファイルリストの先頭 */\r
75         int Files;                              /* ファイルの数 */\r
76 } FLISTANCHOR;\r
77 \r
78 /*===== プロトタイプ =====*/\r
79 \r
80 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
81 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
82 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
83 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win);\r
84 static void EraseDispFileList(FLISTANCHOR *Anchor);\r
85 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor);\r
86 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist);\r
87 // 64ビット対応\r
88 //static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
89 static INT_PTR CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
90 static void DispListList(FILELIST *Pos, char *Title);\r
91 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
92 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
93 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List);\r
94 static int GetListOneLine(char *Buf, int Max, FILE *Fd);\r
95 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir);\r
96 static void MakeLocalTree(char *Path, FILELIST **Base);\r
97 static void AddFileList(FILELIST *Pkt, FILELIST **Base);\r
98 static int AnalizeFileInfo(char *Str);\r
99 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day);\r
100 static int CheckHHMMformat(char *Str);\r
101 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3);\r
102 static int CheckYYYYMMDDformat(char *Str, char Sym);\r
103 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist);\r
104 static int FindField(char *Str, char *Buf, int Num, int ToLast);\r
105 // MLSD対応\r
106 static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast);\r
107 static void GetMonth(char *Str, WORD *Month, WORD *Day);\r
108 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
109 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute);\r
110 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
111 static int CheckSpecialDirName(char *Fname);\r
112 static int AskFilterStr(char *Fname, int Type);\r
113 // 64ビット対応\r
114 //static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
115 static INT_PTR CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
116 static int atoi_n(const char *Str, int Len);\r
117 \r
118 /*===== 外部参照 =====*/\r
119 \r
120 extern int SepaWidth;\r
121 extern int RemoteWidth;\r
122 extern int ListHeight;\r
123 extern char FilterStr[FILTER_EXT_LEN+1];\r
124 extern HWND hHelpWin;\r
125 \r
126 /* 設定値 */\r
127 extern int LocalWidth;\r
128 extern int LocalTabWidth[4];\r
129 extern int RemoteTabWidth[6];\r
130 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
131 extern HFONT ListFont;\r
132 extern int ListType;\r
133 extern int FindMode;\r
134 extern int DotFile;\r
135 extern int DispIgnoreHide;\r
136 extern int DispDrives;\r
137 extern int MoveMode;\r
138 \r
139 /*===== ローカルなワーク =====*/\r
140 \r
141 static HWND hWndListLocal = NULL;\r
142 static HWND hWndListRemote = NULL;\r
143 \r
144 static WNDPROC LocalProcPtr;\r
145 static WNDPROC RemoteProcPtr;\r
146 \r
147 static HIMAGELIST ListImg = NULL;\r
148 \r
149 static char FindStr[40+1] = { "*" };            /* 検索文字列 */\r
150 static int IgnoreNew = NO;\r
151 static int IgnoreOld = NO;\r
152 static int IgnoreExist = NO;\r
153 \r
154 static int Dragging = NO;\r
155 \r
156 static int StratusMode;                 /* 0=ファイル, 1=ディレクトリ, 2=リンク */\r
157 \r
158 \r
159 // リモートファイルリスト (2007.9.3 yutaka)\r
160 static FILELIST *remoteFileListBase;\r
161 static FILELIST *remoteFileListBaseNoExpand;\r
162 static char remoteFileDir[FMAX_PATH + 1];\r
163 \r
164 \r
165 /*----- ファイルリストウインドウを作成する ------------------------------------\r
166 *\r
167 *       Parameter\r
168 *               HWND hWnd : 親ウインドウのウインドウハンドル\r
169 *               HINSTANCE hInst : インスタンスハンドル\r
170 *\r
171 *       Return Value\r
172 *               int ステータス\r
173 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
174 *----------------------------------------------------------------------------*/\r
175 \r
176 int MakeListWin(HWND hWnd, HINSTANCE hInst)\r
177 {\r
178         int Sts;\r
179         LV_COLUMN LvCol;\r
180         long Tmp;\r
181 \r
182         /*===== ローカル側のリストビュー =====*/\r
183 \r
184         hWndListLocal = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
185                         WC_LISTVIEWA, NULL,\r
186                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
187                         0, TOOLWIN_HEIGHT*2, LocalWidth, ListHeight,\r
188                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
189 \r
190         if(hWndListLocal != NULL)\r
191         {\r
192                 // 64ビット対応\r
193 //              LocalProcPtr = (WNDPROC)SetWindowLong(hWndListLocal, GWL_WNDPROC, (LONG)LocalWndProc);\r
194                 LocalProcPtr = (WNDPROC)SetWindowLongPtr(hWndListLocal, GWLP_WNDPROC, (LONG_PTR)LocalWndProc);\r
195 \r
196             Tmp = SendMessage(hWndListLocal, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
197             Tmp |= LVS_EX_FULLROWSELECT;\r
198             SendMessage(hWndListLocal, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
199 \r
200                 if(ListFont != NULL)\r
201                         SendMessage(hWndListLocal, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
202 \r
203                 ListImg = ImageList_LoadBitmap(hInst, MAKEINTRESOURCE(dirattr_bmp), 16, 9, RGB(255,0,0));\r
204                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
205                 ShowWindow(hWndListLocal, SW_SHOW);\r
206 \r
207                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
208                 LvCol.cx = LocalTabWidth[0];\r
209                 LvCol.pszText = MSGJPN038;\r
210                 LvCol.iSubItem = 0;\r
211                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
212 \r
213                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
214                 LvCol.cx = LocalTabWidth[1];\r
215                 LvCol.pszText = MSGJPN039;\r
216                 LvCol.iSubItem = 1;\r
217                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
218 \r
219                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
220                 LvCol.fmt = LVCFMT_RIGHT;\r
221                 LvCol.cx = LocalTabWidth[2];\r
222                 LvCol.pszText = MSGJPN040;\r
223                 LvCol.iSubItem = 2;\r
224                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
225 \r
226                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
227                 LvCol.cx = LocalTabWidth[3];\r
228                 LvCol.pszText = MSGJPN041;\r
229                 LvCol.iSubItem = 3;\r
230                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
231         }\r
232 \r
233         /*===== ホスト側のリストビュー =====*/\r
234 \r
235         hWndListRemote = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
236                         WC_LISTVIEWA, NULL,\r
237                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
238                         LocalWidth + SepaWidth, TOOLWIN_HEIGHT*2, RemoteWidth, ListHeight,\r
239                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
240 \r
241         if(hWndListRemote != NULL)\r
242         {\r
243                 // 64ビット対応\r
244 //              RemoteProcPtr = (WNDPROC)SetWindowLong(hWndListRemote, GWL_WNDPROC, (LONG)RemoteWndProc);\r
245                 RemoteProcPtr = (WNDPROC)SetWindowLongPtr(hWndListRemote, GWLP_WNDPROC, (LONG_PTR)RemoteWndProc);\r
246 \r
247             Tmp = SendMessage(hWndListRemote, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
248             Tmp |= LVS_EX_FULLROWSELECT;\r
249             SendMessage(hWndListRemote, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
250 \r
251                 if(ListFont != NULL)\r
252                         SendMessage(hWndListRemote, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
253 \r
254                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
255                 ShowWindow(hWndListRemote, SW_SHOW);\r
256 \r
257                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
258                 LvCol.cx = RemoteTabWidth[0];\r
259                 LvCol.pszText = MSGJPN042;\r
260                 LvCol.iSubItem = 0;\r
261                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
262 \r
263                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
264                 LvCol.cx = RemoteTabWidth[1];\r
265                 LvCol.pszText = MSGJPN043;\r
266                 LvCol.iSubItem = 1;\r
267                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
268 \r
269                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
270                 LvCol.fmt = LVCFMT_RIGHT;\r
271                 LvCol.cx = RemoteTabWidth[2];\r
272                 LvCol.pszText = MSGJPN044;\r
273                 LvCol.iSubItem = 2;\r
274                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
275 \r
276                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
277                 LvCol.cx = RemoteTabWidth[3];\r
278                 LvCol.pszText = MSGJPN045;\r
279                 LvCol.iSubItem = 3;\r
280                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
281 \r
282                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
283                 LvCol.cx = RemoteTabWidth[4];\r
284                 LvCol.pszText = MSGJPN046;\r
285                 LvCol.iSubItem = 4;\r
286                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 4, (LPARAM)&LvCol);\r
287 \r
288                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
289                 LvCol.cx = RemoteTabWidth[5];\r
290                 LvCol.pszText = MSGJPN047;\r
291                 LvCol.iSubItem = 5;\r
292                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 5, (LPARAM)&LvCol);\r
293         }\r
294 \r
295         Sts = FFFTP_SUCCESS;\r
296         if((hWndListLocal == NULL) ||\r
297            (hWndListRemote == NULL))\r
298         {\r
299                 Sts = FFFTP_FAIL;\r
300         }\r
301         return(Sts);\r
302 }\r
303 \r
304 \r
305 /*----- ファイルリストウインドウを削除 ----------------------------------------\r
306 *\r
307 *       Parameter\r
308 *               なし\r
309 *\r
310 *       Return Value\r
311 *               なし\r
312 *----------------------------------------------------------------------------*/\r
313 \r
314 void DeleteListWin(void)\r
315 {\r
316 //      if(ListImg != NULL)\r
317 //              ImageList_Destroy(ListImg);\r
318         if(hWndListLocal != NULL)\r
319                 DestroyWindow(hWndListLocal);\r
320         if(hWndListRemote != NULL)\r
321                 DestroyWindow(hWndListRemote);\r
322         return;\r
323 }\r
324 \r
325 \r
326 /*----- ローカル側のファイルリストのウインドウハンドルを返す ------------------\r
327 *\r
328 *       Parameter\r
329 *               なし\r
330 *\r
331 *       Return Value\r
332 *               HWND ウインドウハンドル\r
333 *----------------------------------------------------------------------------*/\r
334 \r
335 HWND GetLocalHwnd(void)\r
336 {\r
337         return(hWndListLocal);\r
338 }\r
339 \r
340 \r
341 /*----- ホスト側のファイルリストのウインドウハンドルを返す --------------------\r
342 *\r
343 *       Parameter\r
344 *               なし\r
345 *\r
346 *       Return Value\r
347 *               HWND ウインドウハンドル\r
348 *----------------------------------------------------------------------------*/\r
349 \r
350 HWND GetRemoteHwnd(void)\r
351 {\r
352         return(hWndListRemote);\r
353 }\r
354 \r
355 \r
356 /*----- ローカル側のファイルリストウインドウのメッセージ処理 ------------------\r
357 *\r
358 *       Parameter\r
359 *               HWND hWnd : ウインドウハンドル\r
360 *               UINT message  : メッセージ番号\r
361 *               WPARAM wParam : メッセージの WPARAM 引数\r
362 *               LPARAM lParam : メッセージの LPARAM 引数\r
363 *\r
364 *       Return Value\r
365 *               メッセージに対応する戻り値\r
366 *----------------------------------------------------------------------------*/\r
367 \r
368 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
369 {\r
370         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
371 }\r
372 \r
373 \r
374 /*----- ホスト側のファイルリストウインドウのメッセージ処理 --------------------\r
375 *\r
376 *       Parameter\r
377 *               HWND hWnd : ウインドウハンドル\r
378 *               UINT message  : メッセージ番号\r
379 *               WPARAM wParam : メッセージの WPARAM 引数\r
380 *               LPARAM lParam : メッセージの LPARAM 引数\r
381 *\r
382 *       Return Value\r
383 *               メッセージに対応する戻り値\r
384 *----------------------------------------------------------------------------*/\r
385 \r
386 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
387 {\r
388         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
389 }\r
390 \r
391 \r
392 // ダイアログプロシージャ\r
393 static BOOL CALLBACK doOleDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)\r
394 {\r
395 #define TIMER_ID     (100)      // 作成するタイマの識別ID\r
396 #define TIMER_ELAPSE (100)       // WM_TIMERの発生間隔\r
397         MSG message;\r
398 \r
399         switch( msg ){\r
400         case WM_INITDIALOG:  // ダイアログボックスが作成されたとき\r
401                 SetTimer( hDlg, TIMER_ID, 0, NULL);\r
402                 return TRUE;\r
403 \r
404         case WM_TIMER:\r
405                 ShowWindow(hDlg, SW_HIDE);  // ダイアログは隠す\r
406 \r
407                 if (wp != TIMER_ID)\r
408                         break;\r
409 \r
410                 if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {\r
411                                 TranslateMessage(&message);\r
412                                 DispatchMessage(&message);\r
413 \r
414                 } else {\r
415                         if (AskTransferNow() == NO) {\r
416                                 EndDialog( hDlg, 0 );\r
417                                 return TRUE;\r
418                         }\r
419                 }\r
420 \r
421                 SetTimer( hDlg, TIMER_ID, TIMER_ELAPSE, NULL );\r
422                 return TRUE;\r
423 \r
424         case WM_COMMAND:     // ダイアログボックス内の何かが選択されたとき\r
425                 switch( LOWORD( wp ) ){\r
426 //              case IDOK:       // 「OK」ボタンが選択された\r
427                 case IDCANCEL:   // 「キャンセル」ボタンが選択された\r
428                         // ダイアログボックスを消す\r
429                         EndDialog( hDlg, 0 );\r
430                         break;\r
431                 }\r
432                 return TRUE;\r
433         }\r
434 \r
435         return FALSE;  // DefWindowProc()ではなく、FALSEを返すこと!\r
436 #undef TIMER_ID     \r
437 #undef TIMER_ELAPSE \r
438 }\r
439 \r
440 \r
441 static void doTransferRemoteFile(void)\r
442 {\r
443         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
444         int CancelFlg = NO;\r
445         char LocDir[FMAX_PATH+1];\r
446         char TmpDir[FMAX_PATH+1];\r
447         char buf[32];\r
448         int i;\r
449         DWORD pid;\r
450 \r
451         // すでにリモートから転送済みなら何もしない。(2007.9.3 yutaka)\r
452         if (remoteFileListBase != NULL)\r
453                 return;\r
454 \r
455         FileListBase = NULL;\r
456         MakeSelectedFileList(WIN_REMOTE, YES, NO, &FileListBase, &CancelFlg);\r
457         FileListBaseNoExpand = NULL;\r
458         MakeSelectedFileList(WIN_REMOTE, NO, NO, &FileListBaseNoExpand, &CancelFlg);\r
459 \r
460         // set temporary folder\r
461         AskLocalCurDir(LocDir, FMAX_PATH);\r
462 \r
463         // アプリを多重起動してもコンフリクトしないように、テンポラリフォルダ名にプロセスID\r
464         // を付加する。(2007.9.13 yutaka)\r
465         GetTempPath(sizeof(TmpDir), TmpDir);\r
466         pid = GetCurrentProcessId();\r
467         _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ffftp%d", pid);\r
468         strncat_s(TmpDir, sizeof(TmpDir), buf, _TRUNCATE);\r
469         _mkdir(TmpDir);\r
470 #if 0\r
471         if (TmpDir[strlen(TmpDir) - 1] == '\\') {\r
472                 TmpDir[strlen(TmpDir) - 1] = '\0';\r
473         }\r
474 #endif\r
475 \r
476         // 既存のファイルを削除する\r
477         for (pf = FileListBase ; pf ; pf = pf->Next) {\r
478                 char fn[FMAX_PATH+1];\r
479 \r
480                 strncpy_s(fn, sizeof(fn), TmpDir, _TRUNCATE);\r
481                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
482                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
483 \r
484                 remove(fn);\r
485         }\r
486 \r
487         // ダウンロード先をテンポラリに設定\r
488         SetLocalDirHist(TmpDir);\r
489 \r
490         // FFFTPにダウンロード要求を出し、ダウンロードの完了を待つ。\r
491         PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
492 \r
493         for (i = 0 ; i < 10 ; i++) {\r
494                 MSG msg;\r
495 \r
496                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\r
497                         TranslateMessage(&msg);\r
498                         DispatchMessage(&msg);\r
499 \r
500                 } else {\r
501                         // 転送スレッドが動き出したら抜ける。\r
502                         if (AskTransferNow() == YES)\r
503                                 break;\r
504                 }\r
505 \r
506                 Sleep(10);\r
507         }\r
508 \r
509         // OLE D&D中にメインウィンドウをユーザに操作させると、おかしくなるので、\r
510         // 隠しモーダルダイアログを作る。\r
511         // (2007.9.11 yutaka)\r
512         DialogBox(GetFtpInst(), MAKEINTRESOURCE(IDD_OLEDRAG), GetMainHwnd(), (DLGPROC)doOleDlgProc);\r
513 \r
514         // ダウンロード先を元に戻す\r
515         SetLocalDirHist(LocDir);\r
516         SetCurrentDirAsDirHist();\r
517 \r
518         remoteFileListBase = FileListBase;  // あとでフリーすること\r
519         remoteFileListBaseNoExpand = FileListBaseNoExpand;  // あとでフリーすること\r
520         strncpy_s(remoteFileDir, sizeof(remoteFileDir), TmpDir, _TRUNCATE);\r
521 \r
522 #if 0\r
523         // add temporary list\r
524         if (remoteFileListBase != NULL) {\r
525                 FILELIST *pf = remoteFileListBase;\r
526                 char fn[FMAX_PATH + 1];\r
527                 while (pf) {\r
528                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
529                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
530                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
531                         AddTempFileList(fn);\r
532                         pf = pf->Next;\r
533                 }\r
534         }\r
535 #endif\r
536 }\r
537 \r
538 \r
539 int isDirectory(char *fn)\r
540 {\r
541         struct _stat buf;\r
542 \r
543         if (_stat(fn, &buf) == 0) {\r
544                 if (buf.st_mode & _S_IFDIR) { // is directory\r
545                         return 1;\r
546                 }\r
547         }\r
548         return 0;\r
549 }\r
550 \r
551 // テンポラリのファイルおよびフォルダを削除する。\r
552 void doDeleteRemoteFile(void)\r
553 {\r
554         if (remoteFileListBase != NULL) {\r
555 #if 0\r
556                 int dirs = 0;\r
557                 int i, count;\r
558                 FILELIST *pf = remoteFileListBase;\r
559                 char fn[FMAX_PATH + 1];\r
560                 while (pf) {\r
561                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
562                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
563                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
564                         if (isDirectory(fn)) {\r
565                                 dirs++;\r
566                         } else {\r
567                                 remove(fn);\r
568                         }\r
569                         pf = pf->Next;\r
570                 }\r
571 \r
572                 count = 0;\r
573                 for (i = 0 ; i < 1000 ; i++) {\r
574                         pf = remoteFileListBase;\r
575                         while (pf) {\r
576                                 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
577                                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
578                                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
579                                 if (isDirectory(fn)) {\r
580                                         if (_rmdir(fn) == 0) { // ディレクトリを消せたらカウントアップ\r
581                                                 count++;\r
582                                                 if (count >= dirs)  // すべて消せたら終わり\r
583                                                         goto skip;\r
584                                         }\r
585                                 }\r
586                                 pf = pf->Next;\r
587                         }\r
588                 }\r
589 skip:\r
590                 _rmdir(remoteFileDir);  // 自分で作ったディレクトリも消す\r
591 #else\r
592                 SHFILEOPSTRUCT FileOp = { NULL, FO_DELETE, remoteFileDir, NULL, \r
593                         FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI, \r
594                         FALSE, NULL, NULL };    \r
595                 SHFileOperation(&FileOp);\r
596 #endif\r
597 \r
598                 DeleteFileList(&remoteFileListBase);\r
599                 remoteFileListBase = NULL;\r
600         }\r
601 \r
602         if (remoteFileListBaseNoExpand != NULL) {\r
603                 DeleteFileList(&remoteFileListBaseNoExpand);\r
604                 remoteFileListBaseNoExpand = NULL;\r
605         }\r
606 }\r
607 \r
608 \r
609 // yutaka\r
610 // cf. http://www.nakka.com/lib/\r
611 /* ドロップファイルの作成 */\r
612 static HDROP APIPRIVATE CreateDropFileMem(char **FileName,int cnt,BOOL fWide)\r
613 {\r
614         HDROP hDrop;\r
615         LPDROPFILES lpDropFile;\r
616         wchar_t wbuf[BUF_SIZE];\r
617         int flen = 0;\r
618         int i;\r
619         \r
620         if(fWide == TRUE){\r
621                 /* ワイドキャラ */\r
622                 for(i = 0;i < cnt;i++){\r
623                         // UTF-8対応\r
624 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
625 //                      flen += (wcslen(wbuf) + 1) * sizeof(wchar_t);\r
626                         flen += sizeof(wchar_t) * MtoW(NULL, 0, FileName[i], -1);\r
627                 }\r
628                 flen++;\r
629         }else{\r
630                 /* マルチバイト */\r
631                 for(i = 0;i < cnt;i++){\r
632                         // UTF-8対応\r
633 //                      flen += lstrlen(FileName[i]) + 1;\r
634                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
635                         flen += sizeof(char) * WtoA(NULL, 0, wbuf, -1);\r
636                 }\r
637         }\r
638 \r
639         hDrop = (HDROP)GlobalAlloc(GHND,sizeof(DROPFILES) + flen + 1);\r
640         if (hDrop == NULL){\r
641                 return NULL;\r
642         }\r
643 \r
644         lpDropFile = (LPDROPFILES) GlobalLock(hDrop);\r
645         lpDropFile->pFiles = sizeof(DROPFILES);         /* ファイル名のリストまでのオフセット */\r
646         lpDropFile->pt.x = 0;\r
647         lpDropFile->pt.y = 0;\r
648         lpDropFile->fNC = FALSE;\r
649         lpDropFile->fWide = fWide;                                      /* ワイドキャラの場合は TRUE */\r
650 \r
651         /* 構造体の後ろにファイル名のリストをコピーする。(ファイル名\0ファイル名\0ファイル名\0\0) */\r
652         if(fWide == TRUE){\r
653                 /* ワイドキャラ */\r
654                 wchar_t *buf;\r
655 \r
656                 buf = (wchar_t *)(&lpDropFile[1]);\r
657                 for(i = 0;i < cnt;i++){\r
658                         // UTF-8対応\r
659 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
660 //                      wcscpy(buf,wbuf);\r
661 //                      buf += wcslen(wbuf) + 1;\r
662                         buf += MtoW(buf, BUF_SIZE, FileName[i], -1);\r
663                 }\r
664         }else{\r
665                 /* マルチバイト */\r
666                 char *buf;\r
667 \r
668                 buf = (char *)(&lpDropFile[1]);\r
669                 for(i = 0;i < cnt;i++){\r
670                         // UTF-8対応\r
671 //                      lstrcpy(buf,FileName[i]);\r
672 //                      buf += lstrlen(FileName[i]) + 1;\r
673                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
674                         buf += WtoA(buf, BUF_SIZE, wbuf, -1);\r
675                 }\r
676         }\r
677 \r
678         GlobalUnlock(hDrop);\r
679         return(hDrop);\r
680 }\r
681 \r
682 \r
683 // OLE D&Dを開始する \r
684 // (2007.8.30 yutaka)\r
685 static void doDragDrop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
686 {\r
687         UINT cf[CF_CNT];\r
688         POINT pt;\r
689         int ret;\r
690 \r
691         // テンポラリをきれいにする (2007.9.3 yutaka)\r
692         doDeleteRemoteFile();\r
693 \r
694         /* ドラッグ&ドロップの開始 */\r
695         cf[0] = CF_HDROP;\r
696         cf[1] = CF_HDROP;       /* ファイル */\r
697         if((ret = OLE_IDropSource_Start(hWnd,WM_GETDATA, WM_DRAGOVER, cf,1,DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK)) == DROPEFFECT_MOVE){\r
698         }\r
699 \r
700         // ドロップ先のアプリに WM_LBUTTONUP を飛ばす。\r
701         GetCursorPos(&pt);\r
702         ScreenToClient(hWnd, &pt);\r
703         PostMessage(hWnd,WM_LBUTTONUP,0,MAKELPARAM(pt.x,pt.y));\r
704 }\r
705 \r
706 \r
707 \r
708 /*----- ファイル一覧ウインドウの共通メッセージ処理 ----------------------------\r
709 *\r
710 *       Parameter\r
711 *               HWND hWnd : ウインドウハンドル\r
712 *               UINT message  : メッセージ番号\r
713 *               WPARAM wParam : メッセージの WPARAM 引数\r
714 *               LPARAM lParam : メッセージの LPARAM 引数\r
715 *\r
716 *       Return Value\r
717 *               メッセージに対応する戻り値\r
718 *----------------------------------------------------------------------------*/\r
719 \r
720 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
721 {\r
722         POINT Point;\r
723         HWND hWndPnt;\r
724         HWND hWndParent;\r
725         static HCURSOR hCsrDrg;\r
726         static HCURSOR hCsrNoDrg;\r
727         static POINT DragPoint;\r
728         static HWND hWndDragStart;\r
729         static int RemoteDropFileIndex = -1;\r
730         int Win;\r
731         HWND hWndDst;\r
732         WNDPROC ProcPtr;\r
733         HWND hWndHistEdit;\r
734 \r
735         Win = WIN_LOCAL;\r
736         hWndDst = hWndListRemote;\r
737         ProcPtr = LocalProcPtr;\r
738         hWndHistEdit = GetLocalHistEditHwnd();\r
739         if(hWnd == hWndListRemote)\r
740         {\r
741                 Win = WIN_REMOTE;\r
742                 hWndDst = hWndListLocal;\r
743                 ProcPtr = RemoteProcPtr;\r
744                 hWndHistEdit = GetRemoteHistEditHwnd();\r
745         }\r
746 \r
747         switch (message)\r
748         {\r
749         case WM_SYSKEYDOWN:\r
750                         if (wParam == 'D') {    // Alt+D\r
751                                 SetFocus(hWndHistEdit);\r
752                                 break;\r
753                         }\r
754                         EraseListViewTips();\r
755                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
756 \r
757         case WM_KEYDOWN:\r
758                         if(wParam == 0x09)\r
759                         {\r
760                                 SetFocus(hWndDst);\r
761                                 break;\r
762                         }\r
763                         EraseListViewTips();\r
764                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
765 \r
766                 case WM_SETFOCUS :\r
767                         SetFocusHwnd(hWnd);\r
768                         MakeButtonsFocus();\r
769                         DispCurrentWindow(Win);\r
770                         DispSelectedSpace();\r
771                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
772 \r
773                 case WM_KILLFOCUS :\r
774                         EraseListViewTips();\r
775                         MakeButtonsFocus();\r
776                         DispCurrentWindow(-1);\r
777                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
778 \r
779                 case WM_DROPFILES :\r
780                         // ドラッグ中は処理しない。ドラッグ後にWM_LBUTTONDOWNが飛んでくるため、そこで処理する。\r
781                         if (Dragging == YES) \r
782                                 return (FALSE);\r
783 \r
784                         if(hWnd == hWndListRemote)\r
785                         {\r
786                                 if(AskConnecting() == YES)\r
787                                         UpLoadDragProc(wParam);\r
788                         }\r
789                         else if(hWnd == hWndListLocal)\r
790                         {\r
791                                 ChangeDirDropFileProc(wParam);\r
792                         }\r
793                         break;\r
794 \r
795                 case WM_LBUTTONDOWN :\r
796                         EraseListViewTips();\r
797                         SetFocus(hWnd);\r
798                         DragPoint.x = LOWORD(lParam);\r
799                         DragPoint.y = HIWORD(lParam);\r
800                         hWndDragStart = hWnd;\r
801                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
802                         break;\r
803 \r
804                 case WM_LBUTTONUP :\r
805                         if(Dragging == YES)\r
806                         {\r
807                                 Dragging = NO;\r
808                                 ReleaseCapture();\r
809                                 hCsrDrg = LoadCursor(NULL, IDC_ARROW);\r
810                                 SetCursor(hCsrDrg);\r
811 \r
812                                 Point.x = (long)(short)LOWORD(lParam);\r
813                                 Point.y = (long)(short)HIWORD(lParam);\r
814                                 ClientToScreen(hWnd, &Point);\r
815                                 hWndPnt = WindowFromPoint(Point);\r
816                                 if(hWndPnt == hWndDst)  // local <-> remote \r
817                                 {\r
818                                         if(hWndPnt == hWndListRemote) {\r
819                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_UPLOAD, 0), 0);\r
820                                         } else if(hWndPnt == hWndListLocal) {\r
821                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
822                                         }\r
823                                 } else { // 同一ウィンドウ内の場合 (yutaka)\r
824                                         if (hWndDragStart == hWndListRemote && hWndPnt == hWndListRemote) {\r
825                                                 // remote <-> remoteの場合は、サーバでのファイルの移動を行う。(2007.9.5 yutaka)\r
826                                                 if (RemoteDropFileIndex != -1) {\r
827                                                         ListView_SetItemState(hWnd, RemoteDropFileIndex, 0, LVIS_DROPHILITED);\r
828                                                         MoveRemoteFileProc(RemoteDropFileIndex);\r
829                                                 }\r
830 \r
831                                         }\r
832 \r
833                                 }\r
834                         }\r
835                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
836 \r
837                 case WM_DRAGDROP:  \r
838                         // OLE D&Dを開始する (yutaka)\r
839                         doDragDrop(hWnd, message, wParam, lParam);\r
840                         return (TRUE);\r
841                         break;\r
842  \r
843                 case WM_GETDATA:  // ファイルのパスをD&D先のアプリへ返す (yutaka)\r
844                         switch(wParam)\r
845                         {\r
846                         case CF_HDROP:          /* ファイル */\r
847                                 {\r
848                                         OSVERSIONINFO os_info;\r
849                                         BOOL NTFlag = FALSE;\r
850                                         char **FileNameList;\r
851                                         int filelen;\r
852                                         int i, j, filenum = 0;\r
853  \r
854                                         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
855                                         int CancelFlg = NO;\r
856                                         char LocDir[FMAX_PATH+1];\r
857                                         char *PathDir;\r
858  \r
859                                         // 変数が未初期化のバグ修正\r
860                                         FileListBaseNoExpand = NULL;\r
861                                         // ローカル側で選ばれているファイルをFileListBaseに登録\r
862                                         if (hWndDragStart == hWndListLocal) {\r
863                                                 AskLocalCurDir(LocDir, FMAX_PATH);\r
864                                                 PathDir = LocDir;\r
865  \r
866                                                 FileListBase = NULL;\r
867                                                 // ローカル側からアプリケーションにD&Dできないバグ修正\r
868 //                                              MakeSelectedFileList(WIN_LOCAL, YES, NO, &FileListBase, &CancelFlg);                    \r
869                                                 MakeSelectedFileList(WIN_LOCAL, NO, NO, &FileListBase, &CancelFlg);                     \r
870                                                 FileListBaseNoExpand = FileListBase;\r
871  \r
872                                         } else if (hWndDragStart == hWndListRemote) {\r
873                                                 GetCursorPos(&Point);\r
874                                                 hWndPnt = WindowFromPoint(Point);\r
875                                                 hWndParent = GetParent(hWndPnt);\r
876                                                 if (hWndPnt == hWndListRemote || hWndPnt == hWndListLocal ||\r
877                                                         hWndParent == hWndListRemote || hWndParent == hWndListLocal) {\r
878                                                         FileListBase = NULL;\r
879  \r
880                                                 } else {\r
881                                                         // 選択されているリモートファイルのリストアップ\r
882                                                         // このタイミングでリモートからローカルの一時フォルダへダウンロードする\r
883                                                         // (2007.8.31 yutaka)\r
884                                                         doTransferRemoteFile();\r
885                                                         PathDir = remoteFileDir;\r
886                                                         FileListBase = remoteFileListBase;\r
887                                                         FileListBaseNoExpand = remoteFileListBaseNoExpand;\r
888                                                 }\r
889  \r
890                                         } \r
891  \r
892                                         pf = FileListBaseNoExpand;\r
893                                         for (filenum = 0; pf ; filenum++) {\r
894                                                 pf = pf->Next;\r
895                                         }\r
896                                         // ファイルが未選択の場合は何もしない。(yutaka)\r
897                                         if (filenum <= 0) {\r
898                                                 *((HANDLE *)lParam) = NULL;\r
899                                                 return (FALSE);\r
900                                         }\r
901                                         \r
902                                         /* ファイル名の配列を作成する */\r
903                                         // TODO: GlobalAllocが返すのはメモリポインタではなくハンドルだが実際は同じ値\r
904                                         FileNameList = (char **)GlobalAlloc(GPTR,sizeof(char *) * filenum);\r
905                                         if(FileNameList == NULL){\r
906                                                 abort();\r
907                                         }\r
908                                         pf = FileListBaseNoExpand;\r
909                                         for (j = 0; pf ; j++) {\r
910                                                 filelen = strlen(PathDir) + 1 + strlen(pf->File) + 1;\r
911                                                 FileNameList[j] = (char *)GlobalAlloc(GPTR, filelen);\r
912                                                 strncpy_s(FileNameList[j], filelen, PathDir, _TRUNCATE);\r
913                                                 strncat_s(FileNameList[j], filelen, "\\", _TRUNCATE);\r
914                                                 strncat_s(FileNameList[j], filelen, pf->File, _TRUNCATE);\r
915                                                 pf = pf->Next;\r
916 #if 0\r
917                                                 if (FileListBase->Node == NODE_DIR) { \r
918                                                         // フォルダを掴んだ場合はそれ以降展開しない\r
919                                                         filenum = 1;\r
920                                                         break;\r
921                                                 }\r
922 #endif\r
923                                         }\r
924                                         \r
925                                         os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
926                                         GetVersionEx(&os_info);\r
927                                         if(os_info.dwPlatformId == VER_PLATFORM_WIN32_NT){\r
928                                                 NTFlag = TRUE;\r
929                                         }\r
930  \r
931                                         /* ドロップファイルリストの作成 */\r
932                                         /* NTの場合はUNICODEになるようにする */\r
933                                         *((HANDLE *)lParam) = CreateDropFileMem(FileNameList, filenum, NTFlag);\r
934  \r
935                                         /* ファイル名の配列を解放する */\r
936                                         for (i = 0; i < filenum ; i++) {\r
937                                                 GlobalFree(FileNameList[i]);\r
938                                         }\r
939                                         GlobalFree(FileNameList);\r
940  \r
941                                         if (hWndDragStart == hWndListLocal) {\r
942                                                 DeleteFileList(&FileListBase);\r
943                                         } else {\r
944                                                 // あとでファイル削除してフリーする\r
945                                         }\r
946  \r
947                                         return (TRUE);\r
948                                 }\r
949                                 break;\r
950  \r
951                         default:\r
952                                 *((HANDLE *)lParam) = NULL;\r
953                                 break;\r
954                         }\r
955  \r
956                         break;\r
957 \r
958                 case WM_DRAGOVER:\r
959                         {\r
960                                 LVHITTESTINFO hi;\r
961                                 int Node, index;\r
962                                 static int prev_index = -1;\r
963 \r
964                                 // 同一ウィンドウ内でのD&Dはリモート側のみ\r
965                                 if (Win != WIN_REMOTE)\r
966                                         break;\r
967 \r
968                                 if(MoveMode == MOVE_DISABLE)\r
969                                         break;\r
970 \r
971                                 memset(&hi, 0, sizeof(hi));\r
972 \r
973                                 GetCursorPos(&Point);\r
974                                 hWndPnt = WindowFromPoint(Point);\r
975                                 ScreenToClient(hWnd, &Point);\r
976 \r
977                                 hi.pt = Point;\r
978 \r
979                                 // 以前の選択を消す\r
980                                 ListView_SetItemState(hWnd, prev_index, 0, LVIS_DROPHILITED);\r
981                                 RemoteDropFileIndex = -1;\r
982 \r
983                                 if ((hWndPnt == hWndListRemote) && (ListView_HitTest(hWnd, &hi) != -1)) {\r
984                                         if (hi.flags == LVHT_ONITEMLABEL) { // The position is over a list-view item's text.\r
985                                         \r
986                                                 index = hi.iItem;\r
987                                                 prev_index = index;\r
988                                                 Node = GetNodeType(Win, index);\r
989                                                 if (Node == NODE_DIR) {\r
990                                                         ListView_SetItemState(hWnd, index, LVIS_DROPHILITED, LVIS_DROPHILITED);\r
991                                                         RemoteDropFileIndex = index;\r
992                                                 }\r
993                                         }\r
994                                 } \r
995 \r
996                         }\r
997                         break;\r
998 \r
999                 case WM_RBUTTONDOWN :\r
1000                         /* ここでファイルを選ぶ */\r
1001                         CallWindowProc(ProcPtr, hWnd, message, wParam, lParam);\r
1002 \r
1003                         EraseListViewTips();\r
1004                         SetFocus(hWnd);\r
1005                         if(hWnd == hWndListRemote)\r
1006                                 RemoteRbuttonMenu(0);\r
1007                         else if(hWnd == hWndListLocal)\r
1008                                 LocalRbuttonMenu(0);\r
1009                         break;\r
1010 \r
1011                 case WM_LBUTTONDBLCLK :\r
1012                         DoubleClickProc(Win, NO, -1);\r
1013                         break;\r
1014 \r
1015                 case WM_MOUSEMOVE :\r
1016                         if(wParam == MK_LBUTTON)\r
1017                         {\r
1018                                 if((Dragging == NO) && \r
1019                                    (hWnd == hWndDragStart) &&\r
1020                                    (AskConnecting() == YES) &&\r
1021                                    (SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0) > 0) &&\r
1022                                    ((abs((short)LOWORD(lParam) - DragPoint.x) > 5) ||\r
1023                                         (abs((short)HIWORD(lParam) - DragPoint.y) > 5)))\r
1024                                 {\r
1025                                         SetCapture(hWnd);\r
1026                                         Dragging = YES;\r
1027                                         hCsrDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(drag_csr));\r
1028                                         hCsrNoDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(nodrop_csr));\r
1029                                         SetCursor(hCsrDrg);\r
1030                                 }\r
1031                                 else if(Dragging == YES)\r
1032                                 {\r
1033                                         Point.x = (long)(short)LOWORD(lParam);\r
1034                                         Point.y = (long)(short)HIWORD(lParam);\r
1035                                         ClientToScreen(hWnd, &Point);\r
1036                                         hWndPnt = WindowFromPoint(Point);\r
1037                                         if((hWndPnt == hWndListRemote) || (hWndPnt == hWndListLocal))\r
1038                                                 SetCursor(hCsrDrg);\r
1039                                         else {\r
1040                                                 // マウスポインタの×表示をやめる (yutaka)\r
1041 #if 0\r
1042                                                 SetCursor(hCsrNoDrg);\r
1043 #endif\r
1044                                         }\r
1045 \r
1046                                         // OLE D&Dの開始を指示する\r
1047                                         PostMessage(hWnd, WM_DRAGDROP, MAKEWPARAM(wParam, lParam), 0);\r
1048 \r
1049                                 }\r
1050                                 else\r
1051                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1052                         }\r
1053                         else\r
1054                         {\r
1055                                 CheckTipsDisplay(hWnd, lParam);\r
1056                                 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1057                         }\r
1058                         break;\r
1059 \r
1060                 case WM_MOUSEWHEEL :\r
1061                         if(Dragging == NO)\r
1062                         {\r
1063                 short zDelta = (short)HIWORD(wParam);\r
1064 \r
1065                                 EraseListViewTips();\r
1066                                 Point.x = (short)LOWORD(lParam);\r
1067                                 Point.y = (short)HIWORD(lParam);\r
1068                                 hWndPnt = WindowFromPoint(Point);\r
1069 \r
1070                                 if((wParam & MAKEWPARAM(MK_SHIFT, 0)) && \r
1071                                    ((hWndPnt == hWndListRemote) ||\r
1072                                         (hWndPnt == hWndListLocal) || \r
1073                                         (hWndPnt == GetTaskWnd())))\r
1074                                 {\r
1075                                         PostMessage(hWndPnt, WM_VSCROLL, zDelta > 0 ? MAKEWPARAM(SB_PAGEUP, 0) : MAKEWPARAM(SB_PAGEDOWN, 0), 0);\r
1076 //                                      PostMessage(hWndPnt, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0);\r
1077                                 }\r
1078                                 else if(hWndPnt == hWnd)\r
1079                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1080                                 else if((hWndPnt == hWndDst) || (hWndPnt == GetTaskWnd()))\r
1081                                         PostMessage(hWndPnt, message, wParam, lParam);\r
1082                         }\r
1083                         break;\r
1084 \r
1085                 default :\r
1086                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1087         }\r
1088     return(0L);\r
1089 }\r
1090 \r
1091 \r
1092 /*----- ファイルリストのタブ幅を取得する --------------------------------------\r
1093 *\r
1094 *       Parameter\r
1095 *               なし\r
1096 *\r
1097 *       Return Value\r
1098 *               なし\r
1099 *----------------------------------------------------------------------------*/\r
1100 \r
1101 void GetListTabWidth(void)\r
1102 {\r
1103         LV_COLUMN LvCol;\r
1104         int i;\r
1105 \r
1106         for(i = 0; i <= 3; i++)\r
1107         {\r
1108                 LvCol.mask = LVCF_WIDTH;\r
1109                 if(SendMessage(hWndListLocal, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1110                         LocalTabWidth[i] = LvCol.cx;\r
1111         }\r
1112 \r
1113         for(i = 0; i <= 5; i++)\r
1114         {\r
1115                 LvCol.mask = LVCF_WIDTH;\r
1116                 if(SendMessage(hWndListRemote, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1117                         RemoteTabWidth[i] = LvCol.cx;\r
1118         }\r
1119         return;\r
1120 }\r
1121 \r
1122 \r
1123 /*----- ファイル一覧方法にしたがってリストビューを設定する --------------------\r
1124 *\r
1125 *       Parameter\r
1126 *               なし\r
1127 *\r
1128 *       Return Value\r
1129 *               なし\r
1130 *----------------------------------------------------------------------------*/\r
1131 \r
1132 void SetListViewType(void)\r
1133 {\r
1134         // 64ビット対応\r
1135 //      long lStyle;\r
1136         LONG_PTR lStyle;\r
1137 \r
1138         switch(ListType)\r
1139         {\r
1140                 case LVS_LIST :\r
1141                         // 64ビット対応\r
1142 //                      lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1143                         lStyle = GetWindowLongPtr(GetLocalHwnd(), GWL_STYLE);\r
1144                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1145                         lStyle |= LVS_LIST;\r
1146                         // 64ビット対応\r
1147 //                      SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1148                         SetWindowLongPtr(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1149 \r
1150                         // 64ビット対応\r
1151 //                      lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1152                         lStyle = GetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE);\r
1153                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1154                         lStyle |= LVS_LIST;\r
1155                         // 64ビット対応\r
1156 //                      SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1157                         SetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1158                         break;\r
1159 \r
1160                 default :\r
1161                         // 64ビット対応\r
1162 //                      lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1163                         lStyle = GetWindowLongPtr(GetLocalHwnd(), GWL_STYLE);\r
1164                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1165                         lStyle |= LVS_REPORT;\r
1166                         // 64ビット対応\r
1167 //                      SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1168                         SetWindowLongPtr(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1169 \r
1170                         // 64ビット対応\r
1171 //                      lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1172                         lStyle = GetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE);\r
1173                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1174                         lStyle |= LVS_REPORT;\r
1175                         // 64ビット対応\r
1176 //                      SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1177                         SetWindowLongPtr(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1178                         break;\r
1179         }\r
1180         return;\r
1181 }\r
1182 \r
1183 \r
1184 /*----- ホスト側のファイル一覧ウインドウにファイル名をセット ------------------\r
1185 *\r
1186 *       Parameter\r
1187 *               int Mode : キャッシュモード (CACHE_xxx)\r
1188 *\r
1189 *       Return Value\r
1190 *               なし\r
1191 *----------------------------------------------------------------------------*/\r
1192 \r
1193 void GetRemoteDirForWnd(int Mode, int *CancelCheckWork)\r
1194 {\r
1195         FILE *fd;\r
1196         LONGLONG Size;\r
1197         char Str[FMAX_PATH+1];\r
1198         char Buf[FMAX_PATH+1];\r
1199         FILETIME Time;\r
1200         int Attr;\r
1201         int Type;\r
1202         int ListType;\r
1203         int Num;\r
1204         FLISTANCHOR Anchor;\r
1205         char Owner[OWNER_NAME_LEN+1];\r
1206         int Link;\r
1207         int InfoExist;\r
1208 \r
1209 //#pragma aaa\r
1210 //DoPrintf("===== GetRemoteDirForWnd");\r
1211 \r
1212         Anchor.Top = NULL;\r
1213         Anchor.Files = 0;\r
1214 \r
1215         if(AskConnecting() == YES)\r
1216         {\r
1217 //              SetCursor(LoadCursor(NULL, IDC_WAIT));\r
1218                 DisableUserOpe();\r
1219 \r
1220                 AskRemoteCurDir(Buf, FMAX_PATH);\r
1221                 SetRemoteDirHist(Buf);\r
1222 \r
1223                 Type = FTP_COMPLETE;\r
1224                 if(Mode != CACHE_LASTREAD)\r
1225                 {\r
1226 \r
1227                         if((Num = AskCached(Buf)) == -1)\r
1228                         {\r
1229                                 Num = AskFreeCache();\r
1230                                 Mode = CACHE_REFRESH;\r
1231                         }\r
1232 \r
1233                         if(Mode == CACHE_REFRESH)\r
1234                         {\r
1235                                 if((Type = DoDirListCmdSkt("", "", Num, CancelCheckWork)) == FTP_COMPLETE)\r
1236                                         SetCache(Num, Buf);\r
1237                                 else\r
1238                                         ClearCache(Num);\r
1239                         }\r
1240                 }\r
1241                 else\r
1242                         Num = AskCurrentFileListNum();\r
1243 \r
1244                 if(Type == FTP_COMPLETE)\r
1245                 {\r
1246                         SetCurrentFileListNum(Num);\r
1247                         MakeCacheFileName(Num, Buf);\r
1248                         if((fd = fopen(Buf, "rb"))!=NULL)\r
1249                         {\r
1250                                 ListType = LIST_UNKNOWN;\r
1251 \r
1252                                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
1253                                 {\r
1254                                         if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
1255                                         {\r
1256                                                 if((Type = ResolvFileInfo(Str, ListType, Buf, &Size, &Time, &Attr, Owner, &Link, &InfoExist)) != NODE_NONE)\r
1257                                                 {\r
1258                                                         if(AskFilterStr(Buf, Type) == YES)\r
1259                                                         {\r
1260                                                                 if((DotFile == YES) || (Buf[0] != '.'))\r
1261                                                                 {\r
1262                                                                         AddDispFileList(&Anchor, Buf, &Time, Size, Attr, Type, Link, Owner, InfoExist, WIN_REMOTE);\r
1263                                                                 }\r
1264                                                         }\r
1265                                                 }\r
1266                                         }\r
1267                                 }\r
1268                                 fclose(fd);\r
1269 \r
1270                                 DispFileList2View(GetRemoteHwnd(), &Anchor);\r
1271                                 EraseDispFileList(&Anchor);\r
1272 \r
1273                                 // 先頭のアイテムを選択\r
1274                                 ListView_SetItemState(GetRemoteHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1275                         }\r
1276                         else\r
1277                         {\r
1278                                 SetTaskMsg(MSGJPN048);\r
1279                                 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1280                         }\r
1281                 }\r
1282                 else\r
1283                 {\r
1284 #if defined(HAVE_OPENVMS)\r
1285                         /* OpenVMSの場合空ディレクトリ移動の時に出るので、メッセージだけ出さない\r
1286                          * ようにする(VIEWはクリアして良い) */\r
1287                         if (AskHostType() != HTYPE_VMS)\r
1288 #endif\r
1289                         SetTaskMsg(MSGJPN049);\r
1290                         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1291                 }\r
1292 \r
1293 //              SetCursor(LoadCursor(NULL, IDC_ARROW));\r
1294                 EnableUserOpe();\r
1295 \r
1296         }\r
1297 \r
1298 //#pragma aaa\r
1299 //DoPrintf("===== GetRemoteDirForWnd Done");\r
1300 \r
1301         return;\r
1302 }\r
1303 \r
1304 \r
1305 /*----- ローカル側のファイル一覧ウインドウにファイル名をセット ----------------\r
1306 *\r
1307 *       Parameter\r
1308 *               なし\r
1309 *\r
1310 *       Return Value\r
1311 *               なし\r
1312 *----------------------------------------------------------------------------*/\r
1313 \r
1314 void GetLocalDirForWnd(void)\r
1315 {\r
1316         HANDLE fHnd;\r
1317         WIN32_FIND_DATA Find;\r
1318         char Scan[FMAX_PATH+1];\r
1319         char *Pos;\r
1320         char Buf[10];\r
1321         FILETIME Time;\r
1322         FLISTANCHOR Anchor;\r
1323         DWORD NoDrives;\r
1324         int Tmp;\r
1325 \r
1326         Anchor.Top = NULL;\r
1327         Anchor.Files = 0;\r
1328 \r
1329         DoLocalPWD(Scan);\r
1330         SetLocalDirHist(Scan);\r
1331         DispLocalFreeSpace(Scan);\r
1332 \r
1333         /* ディレクトリ/ファイル */\r
1334 \r
1335         SetYenTail(Scan);\r
1336         strcat(Scan, "*");\r
1337         if((fHnd = FindFirstFileAttr(Scan, &Find, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
1338         {\r
1339                 do\r
1340                 {\r
1341                         if((strcmp(Find.cFileName, ".") != 0) &&\r
1342                            (strcmp(Find.cFileName, "..") != 0))\r
1343                         {\r
1344                                 if((DotFile == YES) || (Find.cFileName[0] != '.'))\r
1345                                 {\r
1346                                         if(Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r
1347                                                 AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_DIR, NO, "", FINFO_ALL, WIN_LOCAL);\r
1348                                         else\r
1349                                         {\r
1350                                                 if(AskFilterStr(Find.cFileName, NODE_FILE) == YES)\r
1351                                                 {\r
1352                                                         AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_FILE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1353                                                 }\r
1354                                         }\r
1355                                 }\r
1356                         }\r
1357                 }\r
1358                 while(FindNextFileAttr(fHnd, &Find, DispIgnoreHide) == TRUE);\r
1359                 FindClose(fHnd);\r
1360         }\r
1361 \r
1362         /* ドライブ */\r
1363         if(DispDrives)\r
1364         {\r
1365                 GetLogicalDriveStrings(FMAX_PATH, Scan);\r
1366                 NoDrives = LoadHideDriveListRegistory();\r
1367 \r
1368                 Pos = Scan;\r
1369                 while(*Pos != NUL)\r
1370                 {\r
1371                         Tmp = toupper(*Pos) - 'A';\r
1372                         if((NoDrives & (0x00000001 << Tmp)) == 0)\r
1373                         {\r
1374                                 sprintf(Buf, "%s", Pos);\r
1375                                 memset(&Time, 0, sizeof(FILETIME));\r
1376                                 AddDispFileList(&Anchor, Buf, &Time, 0, 0, NODE_DRIVE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1377                         }\r
1378                         Pos = strchr(Pos, NUL) + 1;\r
1379                 }\r
1380         }\r
1381 \r
1382         DispFileList2View(GetLocalHwnd(), &Anchor);\r
1383         EraseDispFileList(&Anchor);\r
1384 \r
1385         // 先頭のアイテムを選択\r
1386         ListView_SetItemState(GetLocalHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1387 \r
1388         return;\r
1389 }\r
1390 \r
1391 \r
1392 /*----- ファイル情報をファイル一覧用リストに登録する --------------------------\r
1393 *\r
1394 *       Parameter\r
1395 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1396 *               char *Name : ファイル名\r
1397 *               FILETIME *Time : 日付\r
1398 *               LONGLONG Size : サイズ\r
1399 *               int Attr : 属性\r
1400 *               int Type : タイプ (NODE_xxxx)\r
1401 *               int Link : リンクかどうか (YES/NO)\r
1402 *               char *Owner : オーナ名\r
1403 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1404 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1405 *\r
1406 *       Return Value\r
1407 *               なし\r
1408 *----------------------------------------------------------------------------*/\r
1409 \r
1410 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win)\r
1411 {\r
1412         int i;\r
1413         FILELIST *Pos;\r
1414         FILELIST *Prev;\r
1415         FILELIST *New;\r
1416         int FileSort;\r
1417         int DirSort;\r
1418         int Sort;\r
1419         LONGLONG Cmp;\r
1420 \r
1421         FileSort = AskSortType(ITEM_LFILE);\r
1422         DirSort = AskSortType(ITEM_LDIR);\r
1423         if(Win == WIN_REMOTE)\r
1424         {\r
1425                 FileSort = AskSortType(ITEM_RFILE);\r
1426                 DirSort = AskSortType(ITEM_RDIR);\r
1427         }\r
1428 \r
1429         Pos = Anchor->Top;\r
1430         for(i = 0; i < Anchor->Files; i++)\r
1431         {\r
1432                 if((Type == NODE_DIR) && (Pos->Node == NODE_FILE))\r
1433                         break;\r
1434                 if((Type == NODE_FILE) && (Pos->Node == NODE_DRIVE))\r
1435                         break;\r
1436 \r
1437                 if(Type == Pos->Node)\r
1438                 {\r
1439                         if(Type == NODE_DIR)\r
1440                                 Sort = DirSort;\r
1441                         else\r
1442                                 Sort = FileSort;\r
1443 \r
1444                         if((Sort & SORT_GET_ORD) == SORT_ASCENT)\r
1445                         {\r
1446                                 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1447                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) < 0)) ||\r
1448                                    (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1449                                         ((Cmp = Size - Pos->Size) < 0)) ||\r
1450                                    (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1451                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) < 0)))\r
1452                                 {\r
1453                                         break;\r
1454                                 }\r
1455 \r
1456                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1457                                 {\r
1458                                         if(_mbsicmp(Name, Pos->File) < 0)\r
1459                                                 break;\r
1460                                 }\r
1461                         }\r
1462                         else\r
1463                         {\r
1464                                 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1465                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) > 0)) ||\r
1466                                    (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1467                                         ((Cmp = Size - Pos->Size) > 0)) ||\r
1468                                    (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1469                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) > 0)))\r
1470                                 {\r
1471                                         break;\r
1472                                 }\r
1473 \r
1474                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1475                                 {\r
1476                                         if(_mbsicmp(Name, Pos->File) > 0)\r
1477                                                 break;\r
1478                                 }\r
1479                         }\r
1480                 }\r
1481                 Prev = Pos;\r
1482                 Pos = Pos->Next;\r
1483         }\r
1484 \r
1485         if((New = malloc(sizeof(FILELIST))) != NULL)\r
1486         {\r
1487                 strcpy(New->File, Name);\r
1488                 New->Node = Type;\r
1489                 New->Link = Link;\r
1490                 New->Size = Size;\r
1491                 New->Attr = Attr;\r
1492                 New->Time = *Time;\r
1493                 strcpy(New->Owner, Owner);\r
1494                 New->InfoExist = InfoExist;\r
1495 \r
1496                 if(Pos == Anchor->Top)\r
1497                 {\r
1498                         New->Next = Anchor->Top;\r
1499                         Anchor->Top = New;\r
1500                 }\r
1501                 else\r
1502                 {\r
1503                         New->Next = Prev->Next;\r
1504                         Prev->Next = New;\r
1505                 }\r
1506                 Anchor->Files += 1;\r
1507         }\r
1508         return;\r
1509 }\r
1510 \r
1511 \r
1512 /*----- ファイル一覧用リストをクリアする --------------------------------------\r
1513 *\r
1514 *       Parameter\r
1515 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1516 *\r
1517 *       Return Value\r
1518 *               なし\r
1519 *----------------------------------------------------------------------------*/\r
1520 \r
1521 static void EraseDispFileList(FLISTANCHOR *Anchor)\r
1522 {\r
1523         FILELIST *Pos;\r
1524         FILELIST *Next;\r
1525         int i;\r
1526 \r
1527         Pos = Anchor->Top;\r
1528         for(i = 0; i < Anchor->Files; i++)\r
1529         {\r
1530                 Next = Pos->Next;\r
1531                 free(Pos);\r
1532                 Pos = Next;\r
1533         }\r
1534         Anchor->Files = 0;\r
1535         Anchor->Top = NULL;\r
1536         return;\r
1537 }\r
1538 \r
1539 \r
1540 /*----- ファイル一覧用リストの内容をファイル一覧ウインドウにセット ------------\r
1541 *\r
1542 *       Parameter\r
1543 *               HWND hWnd : ウインドウハンドル\r
1544 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1545 *\r
1546 *       Return Value\r
1547 *               なし\r
1548 *----------------------------------------------------------------------------*/\r
1549 \r
1550 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor)\r
1551 {\r
1552         int i;\r
1553         FILELIST *Pos;\r
1554 \r
1555         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)FALSE, 0);\r
1556         SendMessage(hWnd, LVM_DELETEALLITEMS, 0, 0);\r
1557 \r
1558         Pos = Anchor->Top;\r
1559         for(i = 0; i < Anchor->Files; i++)\r
1560         {\r
1561                 AddListView(hWnd, -1, Pos->File, Pos->Node, Pos->Size, &Pos->Time, Pos->Attr, Pos->Owner, Pos->Link, Pos->InfoExist);\r
1562                 Pos = Pos->Next;\r
1563         }\r
1564 \r
1565         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)TRUE, 0);\r
1566         UpdateWindow(hWnd);\r
1567 \r
1568         DispSelectedSpace();\r
1569         return;\r
1570 }\r
1571 \r
1572 \r
1573 /*----- ファイル一覧ウインドウ(リストビュー)に追加 --------------------------\r
1574 *\r
1575 *       Parameter\r
1576 *               HWND hWnd : ウインドウハンドル\r
1577 *               int Pos : 挿入位置\r
1578 *               char *Name : 名前\r
1579 *               int Type : タイプ (NIDE_xxxx)\r
1580 *               LONGLONG Size : サイズ\r
1581 *               FILETIME *Time : 日付\r
1582 *               int Attr : 属性\r
1583 *               char Owner : オーナ名\r
1584 *               int Link : リンクかどうか\r
1585 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1586 *\r
1587 *       Return Value\r
1588 *               なし\r
1589 *----------------------------------------------------------------------------*/\r
1590 \r
1591 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist)\r
1592 {\r
1593         LV_ITEM LvItem;\r
1594         char Tmp[20];\r
1595 \r
1596         if(Pos == -1)\r
1597                 Pos = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);\r
1598 \r
1599         /* アイコン/ファイル名 */\r
1600         LvItem.mask = LVIF_TEXT | LVIF_IMAGE;\r
1601         LvItem.iItem = Pos;\r
1602         LvItem.iSubItem = 0;\r
1603         LvItem.pszText = Name;\r
1604         if((Type == NODE_FILE) && (AskTransferTypeAssoc(Name, TYPE_X) == TYPE_I))\r
1605                 Type = 3;\r
1606         if(Link == NO)\r
1607                 LvItem.iImage = Type;\r
1608         else\r
1609                 LvItem.iImage = 4;\r
1610         LvItem.iItem = SendMessage(hWnd, LVM_INSERTITEM, 0, (LPARAM)&LvItem);\r
1611 \r
1612         /* 日付/時刻 */\r
1613         FileTime2TimeString(Time, Tmp, DISPFORM_LEGACY, InfoExist);\r
1614         LvItem.mask = LVIF_TEXT;\r
1615         LvItem.iItem = Pos;\r
1616         LvItem.iSubItem = 1;\r
1617         LvItem.pszText = Tmp;\r
1618         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1619 \r
1620         /* サイズ */\r
1621         if(Type == NODE_DIR)\r
1622                 strcpy(Tmp, "<DIR>");\r
1623         else if(Type == NODE_DRIVE)\r
1624                 strcpy(Tmp, "<DRIVE>");\r
1625         else if(Size >= 0)\r
1626                 MakeNumString(Size, Tmp, TRUE);\r
1627         else\r
1628                 strcpy(Tmp, "");\r
1629         LvItem.mask = LVIF_TEXT;\r
1630         LvItem.iItem = Pos;\r
1631         LvItem.iSubItem = 2;\r
1632         LvItem.pszText = Tmp;\r
1633         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1634 \r
1635         /* 拡張子 */\r
1636         LvItem.mask = LVIF_TEXT;\r
1637         LvItem.iItem = Pos;\r
1638         LvItem.iSubItem = 3;\r
1639         LvItem.pszText = GetFileExt(Name);\r
1640         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1641 \r
1642         if(hWnd == GetRemoteHwnd())\r
1643         {\r
1644                 /* 属性 */\r
1645                 strcpy(Tmp, "");\r
1646                 if(InfoExist & FINFO_ATTR)\r
1647                         AttrValue2String(Attr, Tmp);\r
1648                 LvItem.mask = LVIF_TEXT;\r
1649                 LvItem.iItem = Pos;\r
1650                 LvItem.iSubItem = 4;\r
1651                 LvItem.pszText = Tmp;\r
1652                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1653 \r
1654                 /* オーナ名 */\r
1655                 LvItem.mask = LVIF_TEXT;\r
1656                 LvItem.iItem = Pos;\r
1657                 LvItem.iSubItem = 5;\r
1658                 LvItem.pszText = Owner;\r
1659                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1660         }\r
1661         return;\r
1662 }\r
1663 \r
1664 \r
1665 /*----- ファイル名一覧ウインドウをソートし直す --------------------------------\r
1666 *\r
1667 *       Parameter\r
1668 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1669 *\r
1670 *       Return Value\r
1671 *               なし\r
1672 *----------------------------------------------------------------------------*/\r
1673 \r
1674 void ReSortDispList(int Win, int *CancelCheckWork)\r
1675 {\r
1676         if(Win == WIN_REMOTE)\r
1677                 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);\r
1678         else\r
1679                 GetLocalDirForWnd();\r
1680         return;\r
1681 }\r
1682 \r
1683 \r
1684 /*----- ファイル一覧ウインドウのファイルを選択する ----------------------------\r
1685 *\r
1686 *       Parameter\r
1687 *               HWND hWnd : ウインドウハンドル\r
1688 *               int Type : 選択方法 (SELECT_xxx)\r
1689 *\r
1690 *       Return Value\r
1691 *               なし\r
1692 *----------------------------------------------------------------------------*/\r
1693 \r
1694 void SelectFileInList(HWND hWnd, int Type)\r
1695 {\r
1696         int Win;\r
1697         int WinDst;\r
1698         int i;\r
1699         int Num;\r
1700         char RegExp[FMAX_PATH+1];\r
1701         char Name[FMAX_PATH+1];\r
1702         LV_ITEM LvItem;\r
1703         int CsrPos;\r
1704         FILETIME Time1;\r
1705         FILETIME Time2;\r
1706         int Find;\r
1707 \r
1708         Win = WIN_LOCAL;\r
1709         WinDst = WIN_REMOTE;\r
1710         if(hWnd == GetRemoteHwnd())\r
1711         {\r
1712                 Win = WIN_REMOTE;\r
1713                 WinDst = WIN_LOCAL;\r
1714         }\r
1715 \r
1716         Num = GetItemCount(Win);\r
1717         switch(Type)\r
1718         {\r
1719                 case SELECT_ALL :\r
1720                         LvItem.state = 0;\r
1721                         if(GetSelectedCount(Win) <= 1)\r
1722                                 LvItem.state = LVIS_SELECTED;\r
1723                         for(i = 0; i < Num; i++)\r
1724                         {\r
1725                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1726                                 {\r
1727                                         LvItem.mask = LVIF_STATE;\r
1728                                         LvItem.iItem = i;\r
1729                                         LvItem.stateMask = LVIS_SELECTED;\r
1730                                         LvItem.iSubItem = 0;\r
1731                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1732                                 }\r
1733                         }\r
1734                         break;\r
1735 \r
1736                 case SELECT_REGEXP :\r
1737                         if(((Win == WIN_LOCAL) &&\r
1738                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_local_dlg), hWnd, SelectDialogCallBack) == YES)) ||\r
1739                            ((Win == WIN_REMOTE) &&\r
1740                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_remote_dlg), hWnd, SelectDialogCallBack) == YES)))\r
1741                         {\r
1742                                 strcpy(RegExp, FindStr);\r
1743 //                              if(FindMode == 0)\r
1744 //                                      WildCard2RegExp(RegExp);\r
1745 \r
1746                                 _mbslwr(RegExp);\r
1747                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
1748                                 {\r
1749                                         CsrPos = -1;\r
1750                                         for(i = 0; i < Num; i++)\r
1751                                         {\r
1752                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1753                                                 Find = FindNameNode(WinDst, Name);\r
1754 \r
1755                                                 _mbslwr(Name);\r
1756                                                 LvItem.state = 0;\r
1757                                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1758                                                 {\r
1759                                                         if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1760                                                            ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1761                                                         {\r
1762                                                                 LvItem.state = LVIS_SELECTED;\r
1763 \r
1764                                                                 if(Find >= 0)\r
1765                                                                 {\r
1766                                                                         if(IgnoreExist == YES)\r
1767                                                                                 LvItem.state = 0;\r
1768 \r
1769                                                                         if((LvItem.state != 0) && (IgnoreNew == YES))\r
1770                                                                         {\r
1771                                                                                 GetNodeTime(Win, i, &Time1);\r
1772                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1773                                                                                 if(CompareFileTime(&Time1, &Time2) > 0)\r
1774                                                                                         LvItem.state = 0;\r
1775                                                                         }\r
1776 \r
1777                                                                         if((LvItem.state != 0) && (IgnoreOld == YES))\r
1778                                                                         {\r
1779                                                                                 GetNodeTime(Win, i, &Time1);\r
1780                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1781                                                                                 if(CompareFileTime(&Time1, &Time2) < 0)\r
1782                                                                                         LvItem.state = 0;\r
1783                                                                         }\r
1784                                                                 }\r
1785                                                         }\r
1786                                                 }\r
1787 \r
1788                                                 if((LvItem.state != 0) && (CsrPos == -1))\r
1789                                                         CsrPos = i;\r
1790 \r
1791                                                 LvItem.mask = LVIF_STATE;\r
1792                                                 LvItem.iItem = i;\r
1793                                                 LvItem.stateMask = LVIS_SELECTED;\r
1794                                                 LvItem.iSubItem = 0;\r
1795                                                 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1796                                         }\r
1797                                         if(CsrPos != -1)\r
1798                                         {\r
1799                                                 LvItem.mask = LVIF_STATE;\r
1800                                                 LvItem.iItem = CsrPos;\r
1801                                                 LvItem.state = LVIS_FOCUSED;\r
1802                                                 LvItem.stateMask = LVIS_FOCUSED;\r
1803                                                 LvItem.iSubItem = 0;\r
1804                                                 SendMessage(hWnd, LVM_SETITEMSTATE, CsrPos, (LPARAM)&LvItem);\r
1805                                                 SendMessage(hWnd, LVM_ENSUREVISIBLE, CsrPos, (LPARAM)TRUE);\r
1806                                         }\r
1807                                 }\r
1808                         }\r
1809                         break;\r
1810         }\r
1811         return;\r
1812 }\r
1813 \r
1814 \r
1815 /*----- 選択ダイアログのコールバック ------------------------------------------\r
1816 *\r
1817 *       Parameter\r
1818 *               HWND hDlg : ウインドウハンドル\r
1819 *               UINT message : メッセージ番号\r
1820 *               WPARAM wParam : メッセージの WPARAM 引数\r
1821 *               LPARAM lParam : メッセージの LPARAM 引数\r
1822 *\r
1823 *       Return Value\r
1824 *               BOOL TRUE/FALSE\r
1825 *----------------------------------------------------------------------------*/\r
1826 \r
1827 // 64ビット対応\r
1828 //static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
1829 static INT_PTR CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
1830 {\r
1831         switch (iMessage)\r
1832         {\r
1833                 case WM_INITDIALOG :\r
1834                         SendDlgItemMessage(hDlg, SEL_FNAME, EM_LIMITTEXT, 40, 0);\r
1835                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_SETTEXT, 0, (LPARAM)FindStr);\r
1836                         SendDlgItemMessage(hDlg, SEL_REGEXP, BM_SETCHECK, FindMode, 0);\r
1837                         SendDlgItemMessage(hDlg, SEL_NOOLD, BM_SETCHECK, IgnoreOld, 0);\r
1838                         SendDlgItemMessage(hDlg, SEL_NONEW, BM_SETCHECK, IgnoreNew, 0);\r
1839                         SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_SETCHECK, IgnoreExist, 0);\r
1840                         return(TRUE);\r
1841 \r
1842                 case WM_COMMAND :\r
1843                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
1844                         {\r
1845                                 case IDOK :\r
1846                                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_GETTEXT, 40+1, (LPARAM)FindStr);\r
1847                                         FindMode = SendDlgItemMessage(hDlg, SEL_REGEXP, BM_GETCHECK, 0, 0);\r
1848                                         IgnoreOld = SendDlgItemMessage(hDlg, SEL_NOOLD, BM_GETCHECK, 0, 0);\r
1849                                         IgnoreNew = SendDlgItemMessage(hDlg, SEL_NONEW, BM_GETCHECK, 0, 0);\r
1850                                         IgnoreExist = SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_GETCHECK, 0, 0);\r
1851                                         EndDialog(hDlg, YES);\r
1852                                         break;\r
1853 \r
1854                                 case IDCANCEL :\r
1855                                         EndDialog(hDlg, NO);\r
1856                                         break;\r
1857 \r
1858                                 case IDHELP :\r
1859                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000061);\r
1860                                         break;\r
1861                         }\r
1862             return(TRUE);\r
1863         }\r
1864         return(FALSE);\r
1865 }\r
1866 \r
1867 \r
1868 /*----- ファイル一覧ウインドウのファイルを検索する ----------------------------\r
1869 *\r
1870 *       Parameter\r
1871 *               HWND hWnd : ウインドウハンドル\r
1872 *               int Type : 検索方法 (FIND_xxx)\r
1873 *\r
1874 *       Return Value\r
1875 *               なし\r
1876 *----------------------------------------------------------------------------*/\r
1877 \r
1878 void FindFileInList(HWND hWnd, int Type)\r
1879 {\r
1880         int Win;\r
1881         int i;\r
1882         int Num;\r
1883         static char RegExp[FMAX_PATH+1] = { "" };\r
1884         char Name[FMAX_PATH+1];\r
1885         LV_ITEM LvItem;\r
1886         char *Title;\r
1887 \r
1888         Win = WIN_LOCAL;\r
1889         Title = MSGJPN050;\r
1890         if(hWnd == GetRemoteHwnd())\r
1891         {\r
1892                 Win = WIN_REMOTE;\r
1893                 Title = MSGJPN051;\r
1894         }\r
1895 \r
1896         Num = GetItemCount(Win);\r
1897         switch(Type)\r
1898         {\r
1899                 case FIND_FIRST :\r
1900                         if(InputDialogBox(find_dlg, hWnd, Title, FindStr, 40+1, &FindMode, IDH_HELP_TOPIC_0000001) == YES)\r
1901                         {\r
1902                                 strcpy(RegExp, FindStr);\r
1903 //                              if(FindMode == 0)\r
1904 //                                      WildCard2RegExp(RegExp);\r
1905 \r
1906                                 _mbslwr(RegExp);\r
1907                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
1908                                 {\r
1909                                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
1910                                         {\r
1911                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1912                                                 _mbslwr(Name);\r
1913 \r
1914                                                 LvItem.state = 0;\r
1915                                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1916                                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1917                                                 {\r
1918                                                         LvItem.mask = LVIF_STATE;\r
1919                                                         LvItem.iItem = i;\r
1920                                                         LvItem.state = LVIS_FOCUSED;\r
1921                                                         LvItem.stateMask = LVIS_FOCUSED;\r
1922                                                         LvItem.iSubItem = 0;\r
1923                                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1924                                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
1925                                                         break;\r
1926                                                 }\r
1927                                         }\r
1928                                 }\r
1929                         }\r
1930                         break;\r
1931 \r
1932                 case FIND_NEXT :\r
1933                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
1934                         {\r
1935                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1936                                 _mbslwr(Name);\r
1937 \r
1938                                 LvItem.state = 0;\r
1939                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1940                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1941                                 {\r
1942                                         LvItem.mask = LVIF_STATE;\r
1943                                         LvItem.iItem = i;\r
1944                                         LvItem.state = LVIS_FOCUSED;\r
1945                                         LvItem.stateMask = LVIS_FOCUSED;\r
1946                                         LvItem.iSubItem = 0;\r
1947                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1948                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
1949                                         break;\r
1950                                 }\r
1951                         }\r
1952                         break;\r
1953         }\r
1954         return;\r
1955 }\r
1956 \r
1957 \r
1958 #if 0\r
1959 /*----- ワイルドカードを正規表現に変換する ------------------------------------\r
1960 *\r
1961 *       Parameter\r
1962 *               char *Str : 文字列\r
1963 *\r
1964 *       Return Value\r
1965 *               なし\r
1966 *----------------------------------------------------------------------------*/\r
1967 \r
1968 void WildCard2RegExp(char *Str)\r
1969 {\r
1970         char Tmp[FMAX_PATH+1];\r
1971         char *Org;\r
1972         char *Pos;\r
1973         UINT Ch;\r
1974 \r
1975         Org = Str;\r
1976         Pos = Tmp;\r
1977 \r
1978         *Pos++ = '^';\r
1979         *Pos++ = '(';\r
1980         while(*Str != NUL)\r
1981         {\r
1982                 if(Pos >= Tmp + FMAX_PATH - 3)\r
1983                         break;\r
1984 \r
1985                 Ch = _mbsnextc(Str);\r
1986                 Str = _mbsinc(Str);\r
1987 \r
1988                 if(Ch <= 0x7F)\r
1989                 {\r
1990                         if(strchr("[]()^$.+", Ch) != NULL)\r
1991                         {\r
1992                                 *Pos++ = '\\';\r
1993                                 *Pos++ = Ch;\r
1994                         }\r
1995                         else if(Ch == '*')\r
1996                         {\r
1997                                 *Pos++ = '.';\r
1998                                 *Pos++ = '*';\r
1999                         }\r
2000                         else if(Ch == '?')\r
2001                                 *Pos++ = '.';\r
2002                         else if(Ch == '|')\r
2003                         {\r
2004                                 *Pos++ = '|';\r
2005                         }\r
2006                         else\r
2007                                 *Pos++ = Ch;\r
2008                 }\r
2009                 else\r
2010                 {\r
2011                         _mbsnset(Pos, Ch, 1);\r
2012                         Pos = _mbsinc(Pos);\r
2013                 }\r
2014         }\r
2015         *Pos++ = ')';\r
2016         *Pos++ = '$';\r
2017         *Pos = NUL;\r
2018         strcpy(Org, Tmp);\r
2019 \r
2020         return;\r
2021 }\r
2022 #endif\r
2023 \r
2024 \r
2025 /*----- カーソル位置のアイテム番号を返す --------------------------------------\r
2026 *\r
2027 *       Parameter\r
2028 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2029 *\r
2030 *       Return Value\r
2031 *               int アイテム番号\r
2032 *----------------------------------------------------------------------------*/\r
2033 \r
2034 int GetCurrentItem(int Win)\r
2035 {\r
2036         HWND hWnd;\r
2037         int Ret;\r
2038 \r
2039         hWnd = GetLocalHwnd();\r
2040         if(Win == WIN_REMOTE)\r
2041                 hWnd = GetRemoteHwnd();\r
2042 \r
2043         if((Ret = SendMessage(hWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0))) == -1)\r
2044                 Ret = 0;\r
2045 \r
2046         return(Ret);\r
2047 }\r
2048 \r
2049 \r
2050 /*----- アイテム数を返す ------------------------------------------------------\r
2051 *\r
2052 *       Parameter\r
2053 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2054 *\r
2055 *       Return Value\r
2056 *               int アイテム数\r
2057 *----------------------------------------------------------------------------*/\r
2058 \r
2059 int GetItemCount(int Win)\r
2060 {\r
2061         HWND hWnd;\r
2062 \r
2063         hWnd = GetLocalHwnd();\r
2064         if(Win == WIN_REMOTE)\r
2065                 hWnd = GetRemoteHwnd();\r
2066 \r
2067         return(SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0));\r
2068 }\r
2069 \r
2070 \r
2071 /*----- 選択されているアイテム数を返す ----------------------------------------\r
2072 *\r
2073 *       Parameter\r
2074 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2075 *\r
2076 *       Return Value\r
2077 *               int 選択されているアイテム数\r
2078 *----------------------------------------------------------------------------*/\r
2079 \r
2080 int GetSelectedCount(int Win)\r
2081 {\r
2082         HWND hWnd;\r
2083 \r
2084         hWnd = GetLocalHwnd();\r
2085         if(Win == WIN_REMOTE)\r
2086                 hWnd = GetRemoteHwnd();\r
2087 \r
2088         return(SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0));\r
2089 }\r
2090 \r
2091 \r
2092 /*----- 選択されている最初のアイテム番号を返す --------------------------------\r
2093 *\r
2094 *       Parameter\r
2095 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2096 *               int All : 選ばれていないものを含める\r
2097 *\r
2098 *       Return Value\r
2099 *               int アイテム番号\r
2100 *                       -1 = 選択されていない\r
2101 *----------------------------------------------------------------------------*/\r
2102 \r
2103 int GetFirstSelected(int Win, int All)\r
2104 {\r
2105         HWND hWnd;\r
2106         int Ope;\r
2107 \r
2108         hWnd = GetLocalHwnd();\r
2109         if(Win == WIN_REMOTE)\r
2110                 hWnd = GetRemoteHwnd();\r
2111 \r
2112         Ope = LVNI_SELECTED;\r
2113         if(All == YES)\r
2114                 Ope = LVNI_ALL;\r
2115 \r
2116         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)MAKELPARAM(Ope, 0)));\r
2117 }\r
2118 \r
2119 \r
2120 /*----- 選択されている次のアイテム番号を返す ----------------------------------\r
2121 *\r
2122 *       Parameter\r
2123 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2124 *               int Pos : 今のアイテム番号\r
2125 *               int All : 選ばれていないものも含める\r
2126 *\r
2127 *       Return Value\r
2128 *               int アイテム番号\r
2129 *                       -1 = 選択されていない\r
2130 *----------------------------------------------------------------------------*/\r
2131 \r
2132 int GetNextSelected(int Win, int Pos, int All)\r
2133 {\r
2134         HWND hWnd;\r
2135         int Ope;\r
2136 \r
2137         hWnd = GetLocalHwnd();\r
2138         if(Win == WIN_REMOTE)\r
2139                 hWnd = GetRemoteHwnd();\r
2140 \r
2141         Ope = LVNI_SELECTED;\r
2142         if(All == YES)\r
2143                 Ope = LVNI_ALL;\r
2144 \r
2145         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)Pos, (LPARAM)MAKELPARAM(Ope, 0)));\r
2146 }\r
2147 \r
2148 \r
2149 /*----- 指定された名前のアイテムを探す ----------------------------------------\r
2150 *\r
2151 *       Parameter\r
2152 *               int Win : ウインドウ番号 (WIN_xxx)\r
2153 *               char *Name : 名前\r
2154 *\r
2155 *       Return Value\r
2156 *               int アイテム番号\r
2157 *                       -1=見つからなかった\r
2158 *----------------------------------------------------------------------------*/\r
2159 \r
2160 int FindNameNode(int Win, char *Name)\r
2161 {\r
2162         LV_FINDINFO FindInfo;\r
2163         HWND hWnd;\r
2164 \r
2165         hWnd = GetLocalHwnd();\r
2166         if(Win == WIN_REMOTE)\r
2167                 hWnd = GetRemoteHwnd();\r
2168 \r
2169         FindInfo.flags = LVFI_STRING;\r
2170         FindInfo.psz = Name;\r
2171         return(SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)&FindInfo));\r
2172 }\r
2173 \r
2174 \r
2175 /*----- 指定位置のアイテムの名前を返す ----------------------------------------\r
2176 *\r
2177 *       Parameter\r
2178 *               int Win : ウインドウ番号 (WIN_xxx)\r
2179 *               int Pos : 位置\r
2180 *               char *Buf : 名前を返すバッファ\r
2181 *               int Max : バッファのサイズ\r
2182 *\r
2183 *       Return Value\r
2184 *               なし\r
2185 *----------------------------------------------------------------------------*/\r
2186 \r
2187 void GetNodeName(int Win, int Pos, char *Buf, int Max)\r
2188 {\r
2189         HWND hWnd;\r
2190         LV_ITEM LvItem;\r
2191 \r
2192         hWnd = GetLocalHwnd();\r
2193         if(Win == WIN_REMOTE)\r
2194                 hWnd = GetRemoteHwnd();\r
2195 \r
2196         LvItem.mask = LVIF_TEXT;\r
2197         LvItem.iItem = Pos;\r
2198         LvItem.iSubItem = 0;\r
2199         LvItem.pszText = Buf;\r
2200         LvItem.cchTextMax = Max;\r
2201         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2202         return;\r
2203 }\r
2204 \r
2205 \r
2206 /*----- 指定位置のアイテムの日付を返す ----------------------------------------\r
2207 *\r
2208 *       Parameter\r
2209 *               int Win : ウインドウ番号 (WIN_xxx)\r
2210 *               int Pos : 位置\r
2211 *               FILETIME *Buf : 日付を返すバッファ\r
2212 *\r
2213 *       Return Value\r
2214 *               int ステータス\r
2215 *                       YES/NO=日付情報がなかった\r
2216 *----------------------------------------------------------------------------*/\r
2217 \r
2218 int GetNodeTime(int Win, int Pos, FILETIME *Buf)\r
2219 {\r
2220         HWND hWnd;\r
2221         LV_ITEM LvItem;\r
2222         char Tmp[20];\r
2223         int Ret;\r
2224 \r
2225         hWnd = GetLocalHwnd();\r
2226         if(Win == WIN_REMOTE)\r
2227                 hWnd = GetRemoteHwnd();\r
2228 \r
2229         LvItem.mask = LVIF_TEXT;\r
2230         LvItem.iItem = Pos;\r
2231         LvItem.iSubItem = 1;\r
2232         LvItem.pszText = Tmp;\r
2233         LvItem.cchTextMax = 20;\r
2234         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2235         Ret = TimeString2FileTime(Tmp, Buf);\r
2236         return(Ret);\r
2237 }\r
2238 \r
2239 \r
2240 /*----- 指定位置のアイテムのサイズを返す --------------------------------------\r
2241 *\r
2242 *       Parameter\r
2243 *               int Win : ウインドウ番号 (WIN_xxx)\r
2244 *               int Pos : 位置\r
2245 *               int *Buf : サイズを返すワーク\r
2246 *\r
2247 *       Return Value\r
2248 *               int ステータス\r
2249 *                       YES/NO=サイズ情報がなかった\r
2250 *----------------------------------------------------------------------------*/\r
2251 \r
2252 int GetNodeSize(int Win, int Pos, LONGLONG *Buf)\r
2253 {\r
2254         HWND hWnd;\r
2255         LV_ITEM LvItem;\r
2256         char Tmp[40];\r
2257         int Ret;\r
2258 \r
2259         hWnd = GetLocalHwnd();\r
2260         if(Win == WIN_REMOTE)\r
2261                 hWnd = GetRemoteHwnd();\r
2262 \r
2263         LvItem.mask = LVIF_TEXT;\r
2264         LvItem.iItem = Pos;\r
2265         LvItem.iSubItem = 2;\r
2266         LvItem.pszText = Tmp;\r
2267         LvItem.cchTextMax = 20;\r
2268         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2269         *Buf = -1;\r
2270         Ret = NO;\r
2271         if(strlen(Tmp) > 0)\r
2272         {\r
2273                 RemoveComma(Tmp);\r
2274                 *Buf = _atoi64(Tmp);\r
2275                 Ret = YES;\r
2276         }\r
2277         return(Ret);\r
2278 }\r
2279 \r
2280 \r
2281 /*----- 指定位置のアイテムの属性を返す ----------------------------------------\r
2282 *\r
2283 *       Parameter\r
2284 *               int Win : ウインドウ番号 (WIN_xxx)\r
2285 *               int Pos : 位置\r
2286 *               int *Buf : 属性を返すワーク\r
2287 *\r
2288 *       Return Value\r
2289 *               int ステータス\r
2290 *                       YES/NO=サイズ情報がなかった\r
2291 *----------------------------------------------------------------------------*/\r
2292 \r
2293 int GetNodeAttr(int Win, int Pos, int *Buf)\r
2294 {\r
2295         LV_ITEM LvItem;\r
2296         char Tmp[20];\r
2297         int Ret;\r
2298 \r
2299         *Buf = 0;\r
2300         Ret = NO;\r
2301         if(Win == WIN_REMOTE)\r
2302         {\r
2303                 LvItem.mask = LVIF_TEXT;\r
2304                 LvItem.iItem = Pos;\r
2305                 LvItem.iSubItem = 4;\r
2306                 LvItem.pszText = Tmp;\r
2307                 LvItem.cchTextMax = 20;\r
2308                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2309                 if(strlen(Tmp) > 0)\r
2310                 {\r
2311                         *Buf = AttrString2Value(Tmp);\r
2312                         Ret = YES;\r
2313                 }\r
2314         }\r
2315         return(Ret);\r
2316 }\r
2317 \r
2318 \r
2319 /*----- 指定位置のアイテムのタイプを返す --------------------------------------\r
2320 *\r
2321 *       Parameter\r
2322 *               int Win : ウインドウ番号 (WIN_xxx)\r
2323 *               int Pos : 位置\r
2324 *\r
2325 *       Return Value\r
2326 *               int タイプ (NODE_xxx)\r
2327 *----------------------------------------------------------------------------*/\r
2328 \r
2329 int GetNodeType(int Win, int Pos)\r
2330 {\r
2331         char Tmp[20];\r
2332         LV_ITEM LvItem;\r
2333         int Ret;\r
2334         HWND hWnd;\r
2335 \r
2336         hWnd = GetLocalHwnd();\r
2337         if(Win == WIN_REMOTE)\r
2338                 hWnd = GetRemoteHwnd();\r
2339 \r
2340         LvItem.mask = LVIF_TEXT;\r
2341         LvItem.iItem = Pos;\r
2342         LvItem.iSubItem = 2;\r
2343         LvItem.pszText = Tmp;\r
2344         LvItem.cchTextMax = 20;\r
2345         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2346 \r
2347         if(strcmp(Tmp, "<DIR>") == 0)\r
2348                 Ret = NODE_DIR;\r
2349         else if(strcmp(Tmp, "<DRIVE>") == 0)\r
2350                 Ret = NODE_DRIVE;\r
2351         else\r
2352                 Ret = NODE_FILE;\r
2353 \r
2354         return(Ret);\r
2355 }\r
2356 \r
2357 \r
2358 /*----- 指定位置のアイテムのオーナ名を返す ------------------------------------\r
2359 *\r
2360 *       Parameter\r
2361 *               int Win : ウインドウ番号 (WIN_xxx)\r
2362 *               int Pos : 位置\r
2363 *               char *Buf : オーナ名を返すバッファ\r
2364 *               int Max : バッファのサイズ\r
2365 *\r
2366 *       Return Value\r
2367 *               なし\r
2368 *----------------------------------------------------------------------------*/\r
2369 \r
2370 void GetNodeOwner(int Win, int Pos, char *Buf, int Max)\r
2371 {\r
2372         LV_ITEM LvItem;\r
2373 \r
2374         strcpy(Buf, "");\r
2375         if(Win == WIN_REMOTE)\r
2376         {\r
2377                 LvItem.mask = LVIF_TEXT;\r
2378                 LvItem.iItem = Pos;\r
2379                 LvItem.iSubItem = 5;\r
2380                 LvItem.pszText = Buf;\r
2381                 LvItem.cchTextMax = Max;\r
2382                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2383         }\r
2384         return;\r
2385 }\r
2386 \r
2387 \r
2388 /*----- ホスト側のファイル一覧ウインドウをクリア ------------------------------\r
2389 *\r
2390 *       Parameter\r
2391 *               なし\r
2392 *\r
2393 *       Return Value\r
2394 *               なし\r
2395 *----------------------------------------------------------------------------*/\r
2396 \r
2397 void EraseRemoteDirForWnd(void)\r
2398 {\r
2399         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
2400         SendMessage(GetRemoteHistHwnd(), CB_RESETCONTENT, 0, 0);\r
2401         return;\r
2402 }\r
2403 \r
2404 \r
2405 /*----- 選択されているファイルの総サイズを返す --------------------------------\r
2406 *\r
2407 *       Parameter\r
2408 *               int Win : ウインドウ番号 (WIN_xxx)\r
2409 *\r
2410 *       Return Value\r
2411 *               double サイズ\r
2412 *----------------------------------------------------------------------------*/\r
2413 \r
2414 double GetSelectedTotalSize(int Win)\r
2415 {\r
2416         double Ret;\r
2417         LONGLONG Size;\r
2418         int Pos;\r
2419 \r
2420         Ret = 0;\r
2421         if(GetSelectedCount(Win) > 0)\r
2422         {\r
2423                 Pos = GetFirstSelected(Win, NO);\r
2424                 while(Pos != -1)\r
2425                 {\r
2426                         GetNodeSize(Win, Pos, &Size);\r
2427                         if(Size >= 0)\r
2428                                 Ret += Size;\r
2429                         Pos = GetNextSelected(Win, Pos, NO);\r
2430                 }\r
2431         }\r
2432         return(Ret);\r
2433 }\r
2434 \r
2435 \r
2436 \r
2437 /*===================================================================\r
2438 \r
2439 ===================================================================*/\r
2440 \r
2441 \r
2442 \r
2443 /*----- ファイル一覧で選ばれているファイルをリストに登録する ------------------\r
2444 *\r
2445 *       Parameter\r
2446 *               int Win : ウインドウ番号 (WIN_xxx)\r
2447 *               int Expand : サブディレクトリを展開する (YES/NO)\r
2448 *               int All : 選ばれていないものもすべて登録する (YES/NO)\r
2449 *               FILELIST **Base : ファイルリストの先頭\r
2450 *\r
2451 *       Return Value\r
2452 *               なし\r
2453 *----------------------------------------------------------------------------*/\r
2454 \r
2455 void MakeSelectedFileList(int Win, int Expand, int All, FILELIST **Base, int *CancelCheckWork)\r
2456 {\r
2457         int Pos;\r
2458         char Name[FMAX_PATH+1];\r
2459         char Cur[FMAX_PATH+1];\r
2460         FILELIST Pkt;\r
2461         int Node;\r
2462         DWORD Attr;\r
2463         int Ignore;\r
2464 \r
2465         if((All == YES) || (GetSelectedCount(Win) > 0))\r
2466         {\r
2467                 /*===== カレントディレクトリのファイル =====*/\r
2468 \r
2469                 Pos = GetFirstSelected(Win, All);\r
2470                 while(Pos != -1)\r
2471                 {\r
2472                         Node = GetNodeType(Win, Pos);\r
2473                         if((Node == NODE_FILE) ||\r
2474                            ((Expand == NO) && (Node == NODE_DIR)))\r
2475                         {\r
2476                                 Pkt.InfoExist = 0;\r
2477                                 GetNodeName(Win, Pos, Pkt.File, FMAX_PATH);\r
2478                                 if(GetNodeSize(Win, Pos, &Pkt.Size) == YES)\r
2479                                         Pkt.InfoExist |= FINFO_SIZE;\r
2480                                 if(GetNodeAttr(Win, Pos, &Pkt.Attr) == YES)\r
2481                                         Pkt.InfoExist |= FINFO_ATTR;\r
2482                                 if(GetNodeTime(Win, Pos, &Pkt.Time) == YES)\r
2483                                         Pkt.InfoExist |= (FINFO_TIME | FINFO_DATE);\r
2484                                 Pkt.Node = Node;\r
2485 \r
2486                                 Ignore = NO;\r
2487                                 if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2488                                 {\r
2489                                         AskLocalCurDir(Cur, FMAX_PATH);\r
2490                                         SetYenTail(Cur);\r
2491                                         strcat(Cur, Pkt.File);\r
2492                                         Attr = GetFileAttributes(Cur);\r
2493                                         if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2494                                                 Ignore = YES;\r
2495                                 }\r
2496 \r
2497                                 if(Ignore == NO)\r
2498                                         AddFileList(&Pkt, Base);\r
2499                         }\r
2500                         Pos = GetNextSelected(Win, Pos, All);\r
2501                 }\r
2502 \r
2503                 if(Expand == YES)\r
2504                 {\r
2505                         /*===== ディレクトリツリー =====*/\r
2506 \r
2507                         Pos = GetFirstSelected(Win, All);\r
2508                         while(Pos != -1)\r
2509                         {\r
2510                                 if(GetNodeType(Win, Pos) == NODE_DIR)\r
2511                                 {\r
2512                                         GetNodeName(Win, Pos, Name, FMAX_PATH);\r
2513                                         strcpy(Pkt.File, Name);\r
2514                                         ReplaceAll(Pkt.File, '\\', '/');\r
2515 //8/26\r
2516 \r
2517                                         Ignore = NO;\r
2518                                         if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2519                                         {\r
2520                                                 AskLocalCurDir(Cur, FMAX_PATH);\r
2521                                                 SetYenTail(Cur);\r
2522                                                 strcat(Cur, Pkt.File);\r
2523                                                 ReplaceAll(Cur, '/', '\\');\r
2524                                                 Attr = GetFileAttributes(Cur);\r
2525                                                 if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2526                                                         Ignore = YES;\r
2527                                         }\r
2528 \r
2529                                         if(Ignore == NO)\r
2530                                         {\r
2531                                                 Pkt.Node = NODE_DIR;\r
2532                                                 Pkt.Attr = 0;\r
2533                                                 Pkt.Size = 0;\r
2534                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2535                                                 AddFileList(&Pkt, Base);\r
2536 \r
2537                                                 if(Win == WIN_LOCAL)\r
2538                                                         MakeLocalTree(Name, Base);\r
2539                                                 else\r
2540                                                 {\r
2541                                                         AskRemoteCurDir(Cur, FMAX_PATH);\r
2542 \r
2543                                                         if((AskListCmdMode() == NO) &&\r
2544                                                            (AskUseNLST_R() == YES))\r
2545                                                                 MakeRemoteTree1(Name, Cur, Base, CancelCheckWork);\r
2546                                                         else\r
2547                                                                 MakeRemoteTree2(Name, Cur, Base, CancelCheckWork);\r
2548 \r
2549 //DispListList(*Base, "LIST");\r
2550 \r
2551                                                 }\r
2552                                         }\r
2553                                 }\r
2554                                 Pos = GetNextSelected(Win, Pos, All);\r
2555                         }\r
2556                 }\r
2557         }\r
2558         return;\r
2559 }\r
2560 \r
2561 \r
2562 /* デバッグ用 */\r
2563 /* ファイルリストの内容を表示 */\r
2564 static void DispListList(FILELIST *Pos, char *Title)\r
2565 {\r
2566         DoPrintf("############ %s ############", Title);\r
2567         while(Pos != NULL)\r
2568         {\r
2569                 DoPrintf("%d %s", Pos->Node, Pos->File);\r
2570                 Pos = Pos->Next;\r
2571         }\r
2572         DoPrintf("############ END ############");\r
2573         return;\r
2574 }\r
2575 \r
2576 \r
2577 /*----- Drag&Dropされたファイルをリストに登録する -----------------------------\r
2578 *\r
2579 *       Parameter\r
2580 *               WPARAM wParam : ドロップされたファイルの情報\r
2581 *               char *Cur : カレントディレクトリを返すバッファ\r
2582 *               FILELIST **Base : ファイルリストの先頭\r
2583 *\r
2584 *       Return Value\r
2585 *               なし\r
2586 *----------------------------------------------------------------------------*/\r
2587 \r
2588 void MakeDroppedFileList(WPARAM wParam, char *Cur, FILELIST **Base)\r
2589 {\r
2590         int Max;\r
2591         int i;\r
2592         char Name[FMAX_PATH+1];\r
2593         char Tmp[FMAX_PATH+1];\r
2594         FILELIST Pkt;\r
2595         HANDLE fHnd;\r
2596         WIN32_FIND_DATA Find;\r
2597 \r
2598         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2599 \r
2600         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2601         GetUpperDir(Cur);\r
2602 \r
2603         for(i = 0; i < Max; i++)\r
2604         {\r
2605                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2606 \r
2607                 if((GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY) == 0)\r
2608                 {\r
2609                         Pkt.Node = NODE_FILE;\r
2610                         strcpy(Pkt.File, GetFileName(Name));\r
2611 \r
2612                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2613                         if((fHnd = FindFirstFile(Name, &Find)) != INVALID_HANDLE_VALUE)\r
2614                         {\r
2615                                 FindClose(fHnd);\r
2616                                 Pkt.Time = Find.ftLastWriteTime;\r
2617                         }\r
2618                         AddFileList(&Pkt, Base);\r
2619                 }\r
2620         }\r
2621 \r
2622         GetCurrentDirectory(FMAX_PATH, Tmp);\r
2623         SetCurrentDirectory(Cur);\r
2624         for(i = 0; i < Max; i++)\r
2625         {\r
2626                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2627 \r
2628                 if(GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY)\r
2629                 {\r
2630                         Pkt.Node = NODE_DIR;\r
2631                         strcpy(Pkt.File, GetFileName(Name));\r
2632                         AddFileList(&Pkt, Base);\r
2633 \r
2634                         MakeLocalTree(Pkt.File, Base);\r
2635                 }\r
2636         }\r
2637         SetCurrentDirectory(Tmp);\r
2638 \r
2639         DragFinish((HDROP)wParam);\r
2640 \r
2641         return;\r
2642 }\r
2643 \r
2644 \r
2645 /*----- Drag&Dropされたファイルがあるフォルダを取得する -----------------------\r
2646 *\r
2647 *       Parameter\r
2648 *               WPARAM wParam : ドロップされたファイルの情報\r
2649 *               char *Cur : カレントディレクトリを返すバッファ\r
2650 *\r
2651 *       Return Value\r
2652 *               なし\r
2653 *----------------------------------------------------------------------------*/\r
2654 \r
2655 void MakeDroppedDir(WPARAM wParam, char *Cur)\r
2656 {\r
2657         int Max;\r
2658 \r
2659         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2660         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2661         GetUpperDir(Cur);\r
2662         DragFinish((HDROP)wParam);\r
2663 \r
2664         return;\r
2665 }\r
2666 \r
2667 \r
2668 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(1)-------\r
2669 *\r
2670 *       Parameter\r
2671 *               char *Path : パス名\r
2672 *               char *Cur : カレントディレクトリ\r
2673 *               FILELIST **Base : ファイルリストの先頭\r
2674 *\r
2675 *       Return Value\r
2676 *               なし\r
2677 *\r
2678 *       Note\r
2679 *               NLST -alLR を使う\r
2680 *----------------------------------------------------------------------------*/\r
2681 \r
2682 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2683 {\r
2684         int Sts;\r
2685 \r
2686         if(DoCWD(Path, NO, NO, NO) == FTP_COMPLETE)\r
2687         {\r
2688                 /* サブフォルダも含めたリストを取得 */\r
2689                 Sts = DoDirListCmdSkt("R", "", 999, CancelCheckWork);   /* NLST -alLR*/\r
2690                 DoCWD(Cur, NO, NO, NO);\r
2691 \r
2692                 if(Sts == FTP_COMPLETE)\r
2693                         AddRemoteTreeToFileList(999, Path, RDIR_NLST, Base);\r
2694         }\r
2695         return;\r
2696 }\r
2697 \r
2698 \r
2699 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(2)-------\r
2700 *\r
2701 *       Parameter\r
2702 *               char *Path : パス名\r
2703 *               char *Cur : カレントディレクトリ\r
2704 *               FILELIST **Base : ファイルリストの先頭\r
2705 *\r
2706 *       Return Value\r
2707 *               なし\r
2708 *\r
2709 *       Note\r
2710 *               各フォルダに移動してリストを取得\r
2711 *----------------------------------------------------------------------------*/\r
2712 \r
2713 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2714 {\r
2715         int Sts;\r
2716         FILELIST *CurList;\r
2717         FILELIST *Pos;\r
2718         FILELIST Pkt;\r
2719 \r
2720         /* VAX VMS は CWD xxx/yyy という指定ができないので */\r
2721         /* CWD xxx, Cwd yyy と複数に分ける                                       */\r
2722         if(AskHostType() != HTYPE_VMS)\r
2723                 Sts = DoCWD(Path, NO, NO, NO);\r
2724         else\r
2725         {\r
2726 #if defined(HAVE_OPENVMS)\r
2727                 /* OpenVMSの場合、ディレクトリ移動時は"HOGE.DIR;1"を"HOGE"にする */\r
2728                 ReformVMSDirName(Path, TRUE);\r
2729 #endif\r
2730                 Sts = DoCWDStepByStep(Path, Cur);\r
2731         }\r
2732 \r
2733         if(Sts == FTP_COMPLETE)\r
2734         {\r
2735                 Sts = DoDirListCmdSkt("", "", 999, CancelCheckWork);            /* NLST -alL*/\r
2736                 DoCWD(Cur, NO, NO, NO);\r
2737 \r
2738                 if(Sts == FTP_COMPLETE)\r
2739                 {\r
2740                         CurList = NULL;\r
2741                         AddRemoteTreeToFileList(999, Path, RDIR_CWD, &CurList);\r
2742                         CopyTmpListToFileList(Base, CurList);\r
2743 \r
2744                         Pos = CurList;\r
2745                         while(Pos != NULL)\r
2746                         {\r
2747                                 if(Pos->Node == NODE_DIR)\r
2748                                 {\r
2749                                         /* まずディレクトリ名をセット */\r
2750                                         strcpy(Pkt.File, Pos->File);\r
2751                                         Pkt.Node = NODE_DIR;\r
2752                                         Pkt.Size = 0;\r
2753                                         Pkt.Attr = 0;\r
2754                                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2755                                         AddFileList(&Pkt, Base);\r
2756 \r
2757                                         /* そのディレクトリの中を検索 */\r
2758                                         MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork);\r
2759                                 }\r
2760                                 Pos = Pos->Next;\r
2761                         }\r
2762                         DeleteFileList(&CurList);\r
2763                 }\r
2764         }\r
2765         return;\r
2766 }\r
2767 \r
2768 \r
2769 /*----- ファイルリストの内容を別のファイルリストにコピー ----------------------\r
2770 *\r
2771 *       Parameter\r
2772 *               FILELIST **Base : コピー先\r
2773 *               FILELIST *List : コピー元\r
2774 *\r
2775 *       Return Value\r
2776 *               なし\r
2777 *\r
2778 *       Note\r
2779 *               コピーするのはファイルの情報だけ\r
2780 *               ディレクトリの情報はコピーしない\r
2781 *----------------------------------------------------------------------------*/\r
2782 \r
2783 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List)\r
2784 {\r
2785         while(List != NULL)\r
2786         {\r
2787                 if(List->Node == NODE_FILE)\r
2788                         AddFileList(List, Base);\r
2789 \r
2790                 List = List->Next;\r
2791         }\r
2792         return;\r
2793 }\r
2794 \r
2795 \r
2796 /*----- ホスト側のファイル情報をファイルリストに登録 --------------------------\r
2797 *\r
2798 *       Parameter\r
2799 *               int Num : テンポラリファイルのファイル名番号 (_ffftp.???)\r
2800 *               char *Path : パス名\r
2801 *               int IncDir : 再帰検索の方法 (RDIR_xxx)\r
2802 *               FILELIST **Base : ファイルリストの先頭\r
2803 *\r
2804 *       Return Value\r
2805 *               なし\r
2806 *----------------------------------------------------------------------------*/\r
2807 \r
2808 void AddRemoteTreeToFileList(int Num, char *Path, int IncDir, FILELIST **Base)\r
2809 {\r
2810         char Str[FMAX_PATH+1];\r
2811         char Dir[FMAX_PATH+1];\r
2812         char Name[FMAX_PATH+1];\r
2813         LONGLONG Size;\r
2814         FILETIME Time;\r
2815         int Attr;\r
2816         FILELIST Pkt;\r
2817         FILE *fd;\r
2818         int Node;\r
2819         int ListType;\r
2820         char Owner[OWNER_NAME_LEN+1];\r
2821         int Link;\r
2822         int InfoExist;\r
2823 \r
2824         MakeCacheFileName(Num, Str);\r
2825         if((fd = fopen(Str, "rb")) != NULL)\r
2826         {\r
2827                 strcpy(Dir, Path);\r
2828 \r
2829                 ListType = LIST_UNKNOWN;\r
2830 \r
2831                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
2832                 {\r
2833                         if((ListType = AnalizeFileInfo(Str)) == LIST_UNKNOWN)\r
2834                         {\r
2835                                 if(MakeDirPath(Str, ListType, Path, Dir) == FFFTP_SUCCESS)\r
2836                                 {\r
2837                                         if(IncDir == RDIR_NLST)\r
2838                                         {\r
2839                                                 strcpy(Pkt.File, Dir);\r
2840                                                 Pkt.Node = NODE_DIR;\r
2841                                                 Pkt.Size = 0;\r
2842                                                 Pkt.Attr = 0;\r
2843                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2844                                                 AddFileList(&Pkt, Base);\r
2845                                         }\r
2846                                 }\r
2847                         }\r
2848                         else\r
2849                         {\r
2850                                 Node = ResolvFileInfo(Str, ListType, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
2851 \r
2852                                 if(AskFilterStr(Name, Node) == YES)\r
2853                                 {\r
2854                                         if((Node == NODE_FILE) ||\r
2855                                            ((IncDir == RDIR_CWD) && (Node == NODE_DIR)))\r
2856                                         {\r
2857                                                 strcpy(Pkt.File, Dir);\r
2858                                                 if(strlen(Pkt.File) > 0)\r
2859                                                         SetSlashTail(Pkt.File);\r
2860                                                 strcat(Pkt.File, Name);\r
2861                                                 Pkt.Node = Node;\r
2862                                                 Pkt.Link = Link;\r
2863                                                 Pkt.Size = Size;\r
2864                                                 Pkt.Attr = Attr;\r
2865                                                 Pkt.Time = Time;\r
2866                                                 Pkt.InfoExist = InfoExist;\r
2867                                                 AddFileList(&Pkt, Base);\r
2868                                         }\r
2869                                 }\r
2870                         }\r
2871                 }\r
2872                 fclose(fd);\r
2873         }\r
2874         return;\r
2875 }\r
2876 \r
2877 \r
2878 /*----- ファイル一覧情報の1行を取得 ------------------------------------------\r
2879 *\r
2880 *       Parameter\r
2881 *               char *Buf : 1行の情報をセットするバッファ\r
2882 *               int Max : 最大文字数\r
2883 *               FILE *Fd : ストリーム\r
2884 *\r
2885 *       Return Value\r
2886 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2887 *\r
2888 *       Note\r
2889 *               VAX VMS以外の時は fgets(Buf, Max, Fd) と同じ\r
2890 *               Vax VMSの時は、複数行のファイル情報を1行にまとめる\r
2891 *----------------------------------------------------------------------------*/\r
2892 \r
2893 static int GetListOneLine(char *Buf, int Max, FILE *Fd)\r
2894 {\r
2895         char Tmp[FMAX_PATH+1];\r
2896         int Sts;\r
2897 \r
2898         Sts = FFFTP_FAIL;\r
2899         while((Sts == FFFTP_FAIL) && (fgets(Buf, Max, Fd) != NULL))\r
2900         {\r
2901                 Sts = FFFTP_SUCCESS;\r
2902                 RemoveReturnCode(Buf);\r
2903                 ReplaceAll(Buf, '\x08', ' ');\r
2904 \r
2905                 /* VAX VMSではファイル情報が複数行にわかれている     */\r
2906                 /* それを1行にまとめる                                                               */\r
2907                 if(AskHostType() == HTYPE_VMS)\r
2908                 {\r
2909                         if(strchr(Buf, ';') == NULL)    /* ファイル名以外の行 */\r
2910                                 Sts = FFFTP_FAIL;\r
2911                         else\r
2912                         {\r
2913                                 Max -= strlen(Buf);\r
2914                                 while(strchr(Buf, ')') == NULL)\r
2915                                 {\r
2916                                         if(fgets(Tmp, FMAX_PATH, Fd) != NULL)\r
2917                                         {\r
2918                                                 RemoveReturnCode(Tmp);\r
2919                                                 ReplaceAll(Buf, '\x08', ' ');\r
2920                                                 if((int)strlen(Tmp) > Max)\r
2921                                                         Tmp[Max] = NUL;\r
2922                                                 Max -= strlen(Tmp);\r
2923                                                 strcat(Buf, Tmp);\r
2924                                         }\r
2925                                         else\r
2926                                                 break;\r
2927                                 }\r
2928                         }\r
2929                 }\r
2930         }\r
2931 \r
2932 //      DoPrintf("List : %s", Buf);\r
2933 \r
2934         return(Sts);\r
2935 }\r
2936 \r
2937 \r
2938 /*----- サブディレクトリ情報の解析 --------------------------------------------\r
2939 *\r
2940 *       Parameter\r
2941 *               char *Str : ファイル情報(1行)\r
2942 *               int ListType : リストのタイプ\r
2943 *               char *Path : 先頭からのパス名\r
2944 *               char *Dir : ディレクトリ名\r
2945 *\r
2946 *       Return Value\r
2947 *               int ステータス\r
2948 *                       FFFTP_SUCCESS/FFFTP_FAIL=ディレクトリ情報でない\r
2949 *----------------------------------------------------------------------------*/\r
2950 \r
2951 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir)\r
2952 {\r
2953         int Sts;\r
2954 \r
2955         Sts = FFFTP_FAIL;\r
2956         switch(ListType)\r
2957         {\r
2958                 case LIST_ACOS :\r
2959                 case LIST_ACOS_4 :\r
2960                         break;\r
2961 \r
2962                 default:\r
2963                         if(*(Str + strlen(Str) - 1) == ':')             /* 最後が : ならサブディレクトリ */\r
2964                         {\r
2965                                 if(strcmp(Str, ".:") != 0)\r
2966                                 {\r
2967                                         if((strncmp(Str, "./", 2) == 0) ||\r
2968                                            (strncmp(Str, ".\\", 2) == 0))\r
2969                                         {\r
2970                                                 Str += 2;\r
2971                                         }\r
2972 \r
2973                                         if(strlen(Str) > 1)\r
2974                                         {\r
2975                                                 strcpy(Dir, Path);\r
2976                                                 SetSlashTail(Dir);\r
2977                                                 strcat(Dir, Str);\r
2978                                                 *(Dir + strlen(Dir) - 1) = NUL;\r
2979 \r
2980                                                 ChangeFnameRemote2Local(Dir, FMAX_PATH);\r
2981 \r
2982                                                 ReplaceAll(Dir, '\\', '/');\r
2983                                         }\r
2984                                 }\r
2985                                 Sts = FFFTP_SUCCESS;\r
2986                         }\r
2987                         break;\r
2988         }\r
2989         return(Sts);\r
2990 }\r
2991 \r
2992 \r
2993 /*----- ローカル側のサブディレクトリ以下のファイルをリストに登録する ----------\r
2994 *\r
2995 *       Parameter\r
2996 *               char *Path : パス名\r
2997 *               FILELIST **Base : ファイルリストの先頭\r
2998 *\r
2999 *       Return Value\r
3000 *               なし\r
3001 *----------------------------------------------------------------------------*/\r
3002 \r
3003 static void MakeLocalTree(char *Path, FILELIST **Base)\r
3004 {\r
3005         char Src[FMAX_PATH+1];\r
3006         HANDLE fHnd;\r
3007         WIN32_FIND_DATA FindBuf;\r
3008         FILELIST Pkt;\r
3009         SYSTEMTIME TmpStime;\r
3010 \r
3011         strcpy(Src, Path);\r
3012         SetYenTail(Src);\r
3013         strcat(Src, "*");\r
3014         ReplaceAll(Src, '/', '\\');\r
3015 \r
3016         if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
3017         {\r
3018                 do\r
3019                 {\r
3020                         if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)\r
3021                         {\r
3022                                 if(AskFilterStr(FindBuf.cFileName, NODE_FILE) == YES)\r
3023                                 {\r
3024                                         strcpy(Pkt.File, Path);\r
3025                                         SetSlashTail(Pkt.File);\r
3026                                         strcat(Pkt.File, FindBuf.cFileName);\r
3027                                         ReplaceAll(Pkt.File, '\\', '/');\r
3028                                         Pkt.Node = NODE_FILE;\r
3029                                         Pkt.Size = MakeLongLong(FindBuf.nFileSizeHigh, FindBuf.nFileSizeLow);\r
3030                                         Pkt.Attr = 0;\r
3031                                         Pkt.Time = FindBuf.ftLastWriteTime;\r
3032                                         FileTimeToSystemTime(&Pkt.Time, &TmpStime);\r
3033                                         TmpStime.wSecond = 0;\r
3034                                         TmpStime.wMilliseconds = 0;\r
3035                                         SystemTimeToFileTime(&TmpStime, &Pkt.Time);\r
3036                                         AddFileList(&Pkt, Base);\r
3037                                 }\r
3038                         }\r
3039                 }\r
3040                 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);\r
3041                 FindClose(fHnd);\r
3042         }\r
3043 \r
3044         if((fHnd = FindFirstFileAttr(Src, &FindBuf, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
3045         {\r
3046                 do\r
3047                 {\r
3048                         if((FindBuf.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&\r
3049                            (strcmp(FindBuf.cFileName, ".") != 0) &&\r
3050                            (strcmp(FindBuf.cFileName, "..") != 0))\r
3051                         {\r
3052                                 strcpy(Src, Path);\r
3053                                 SetYenTail(Src);\r
3054                                 strcat(Src, FindBuf.cFileName);\r
3055                                 strcpy(Pkt.File, Src);\r
3056                                 ReplaceAll(Pkt.File, '\\', '/');\r
3057                                 Pkt.Node = NODE_DIR;\r
3058                                 Pkt.Size = 0;\r
3059                                 Pkt.Attr = 0;\r
3060                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
3061                                 AddFileList(&Pkt, Base);\r
3062 \r
3063                                 MakeLocalTree(Src, Base);\r
3064                         }\r
3065                 }\r
3066                 while(FindNextFileAttr(fHnd, &FindBuf, DispIgnoreHide) == TRUE);\r
3067                 FindClose(fHnd);\r
3068         }\r
3069         return;\r
3070 }\r
3071 \r
3072 \r
3073 /*----- ファイルリストに情報を登録する ----------------------------------------\r
3074 *\r
3075 *       Parameter\r
3076 *               FILELIST *Pkt : 登録するファイル情報\r
3077 *               FILELIST **Base : ファイルリストの先頭\r
3078 *\r
3079 *       Return Value\r
3080 *               なし\r
3081 *----------------------------------------------------------------------------*/\r
3082 \r
3083 static void AddFileList(FILELIST *Pkt, FILELIST **Base)\r
3084 {\r
3085         FILELIST *Pos;\r
3086         FILELIST *Prev;\r
3087 \r
3088         DoPrintf("FileList : NODE=%d : %s", Pkt->Node, Pkt->File);\r
3089 \r
3090         /* リストの重複を取り除く */\r
3091         Pos = *Base;\r
3092         while(Pos != NULL)\r
3093         {\r
3094                 if(strcmp(Pkt->File, Pos->File) == 0)\r
3095                 {\r
3096                         DoPrintf(" --> Duplicate!!");\r
3097                         break;\r
3098                 }\r
3099                 Prev = Pos;\r
3100                 Pos = Pos->Next;\r
3101         }\r
3102 \r
3103         if(Pos == NULL)         /* 重複していないので登録する */\r
3104         {\r
3105                 if((Pos = malloc(sizeof(FILELIST))) != NULL)\r
3106                 {\r
3107                         memcpy(Pos, Pkt, sizeof(FILELIST));\r
3108                         Pos->Next = NULL;\r
3109 \r
3110                         if(*Base == NULL)\r
3111                                 *Base = Pos;\r
3112                         else\r
3113                                 Prev->Next = Pos;\r
3114                 }\r
3115         }\r
3116         return;\r
3117 }\r
3118 \r
3119 \r
3120 /*----- ファイルリストをクリアする --------------------------------------------\r
3121 *\r
3122 *       Parameter\r
3123 *               FILELIST **Base : ファイルリストの先頭\r
3124 *\r
3125 *       Return Value\r
3126 *               なし\r
3127 *----------------------------------------------------------------------------*/\r
3128 \r
3129 void DeleteFileList(FILELIST **Base)\r
3130 {\r
3131         FILELIST *New;\r
3132         FILELIST *Next;\r
3133 \r
3134         New = *Base;\r
3135         while(New != NULL)\r
3136         {\r
3137                 Next = New->Next;\r
3138                 free(New);\r
3139                 New = Next;\r
3140         }\r
3141         *Base = NULL;\r
3142         return;\r
3143 }\r
3144 \r
3145 \r
3146 /*----- ファイルリストに指定のファイルがあるかチェック ------------------------\r
3147 *\r
3148 *       Parameter\r
3149 *               char *Fname : ファイル名\r
3150 *               FILELIST *Base : ファイルリストの先頭\r
3151 *               int Caps : 大文字/小文字の区別モード (COMP_xxx)\r
3152 *\r
3153 *       Return Value\r
3154 *               FILELIST *見つかったファイルリストのデータ\r
3155 *                       NULL=見つからない\r
3156 *----------------------------------------------------------------------------*/\r
3157 \r
3158 FILELIST *SearchFileList(char *Fname, FILELIST *Base, int Caps)\r
3159 {\r
3160         char Tmp[FMAX_PATH+1];\r
3161 \r
3162         while(Base != NULL)\r
3163         {\r
3164                 if(Caps == COMP_STRICT)\r
3165                 {\r
3166                         if(_mbscmp(Fname, Base->File) == 0)\r
3167                                 break;\r
3168                 }\r
3169                 else\r
3170                 {\r
3171                         if(_mbsicmp(Fname, Base->File) == 0)\r
3172                         {\r
3173                                 if(Caps == COMP_IGNORE)\r
3174                                         break;\r
3175                                 else\r
3176                                 {\r
3177                                         strcpy(Tmp, Base->File);\r
3178                                         _mbslwr(Tmp);\r
3179                                         if(_mbscmp(Tmp, Base->File) == 0)\r
3180                                                 break;\r
3181                                 }\r
3182                         }\r
3183                 }\r
3184                 Base = Base->Next;\r
3185         }\r
3186         return(Base);\r
3187 }\r
3188 \r
3189 \r
3190 /*----- ファイル情報からリストタイプを求める ----------------------------------\r
3191 *\r
3192 *       Parameter\r
3193 *               char *Str : ファイル情報(1行)\r
3194 *\r
3195 *       Return Value\r
3196 *               int リストタイプ (LIST_xxx)\r
3197 *----------------------------------------------------------------------------*/\r
3198 \r
3199 static int AnalizeFileInfo(char *Str)\r
3200 {\r
3201         int Ret;\r
3202         char Tmp[FMAX_PATH+1];\r
3203         int Add1;\r
3204         int TmpInt;\r
3205         int Flag1;\r
3206         WORD Month;\r
3207         WORD Day;\r
3208 \r
3209 //DoPrintf("LIST : %s", Str);\r
3210 \r
3211         Ret = LIST_UNKNOWN;\r
3212         Flag1 = AskHostType();\r
3213         if(Flag1 == HTYPE_ACOS)\r
3214                 Ret = LIST_ACOS;\r
3215         else if(Flag1 == HTYPE_ACOS_4)\r
3216                 Ret = LIST_ACOS_4;\r
3217         else if(Flag1 == HTYPE_VMS)\r
3218                 Ret = LIST_VMS;\r
3219         else if(Flag1 == HTYPE_IRMX)\r
3220                 Ret = LIST_IRMX;\r
3221         else if(Flag1 == HTYPE_STRATUS)\r
3222                 Ret = LIST_STRATUS;\r
3223         else if(Flag1 == HTYPE_AGILENT)\r
3224                 Ret = LIST_AGILENT;\r
3225         else if(Flag1 == HTYPE_SHIBASOKU)\r
3226                 Ret = LIST_SHIBASOKU;\r
3227         else\r
3228         {\r
3229                 /* 以下のフォーマットをチェック */\r
3230                 /* LIST_UNIX_10, LIST_UNIX_20, LIST_UNIX_12, LIST_UNIX_22, LIST_UNIX_50, LIST_UNIX_60 */\r
3231                 /* MELCOM80 */\r
3232 \r
3233                 if(FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS)\r
3234                 {\r
3235                         /* MELCOM80は "d rwxrwxrwx" のようにスペースが空いている */\r
3236                         Flag1 = NO;\r
3237                         if((strlen(Tmp) == 1) && (strchr("-dDlL", Tmp[0]) != NULL))\r
3238                         {\r
3239                                 if(FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS)\r
3240                                 {\r
3241                                         if((strlen(Tmp) == 9) ||\r
3242                                            ((strlen(Tmp) > 9) && (IsDigit(Tmp[9]) != 0)))\r
3243                                         {\r
3244                                                 memmove(Str+1, Str+2, strlen(Str+2)+1);\r
3245                                                 FindField(Str, Tmp, 0, NO);\r
3246                                                 Flag1 = YES;\r
3247                                         }\r
3248                                 }\r
3249                         }\r
3250 \r
3251                         if(strlen(Tmp) >= 10)\r
3252                         {\r
3253                                 Add1 = 0;\r
3254                                 if((strlen(Tmp) > 10) && (IsDigit(Tmp[10]) != 0))\r
3255                                 {\r
3256                                         /* こういう時 */\r
3257                                         /*   drwxr-xr-x1234  owner group  1024  Nov 6 14:21 Linux/    */\r
3258                                         Add1 = -1;\r
3259                                 }\r
3260 \r
3261 ////////////\r
3262 // LIST_UNIX_60 support\r
3263                                 if(FindField(Str, Tmp, 7+Add1, NO) == FFFTP_SUCCESS)\r
3264                                 {\r
3265                                         GetMonth(Tmp, &Month, &Day);\r
3266                                         if(Month != 0)\r
3267                                         {\r
3268                                                 Ret = CheckUnixType(Str, Tmp, Add1, 2, Day);\r
3269                                         }\r
3270                                 }\r
3271 ///////////\r
3272 \r
3273 ////////////\r
3274 // LIST_UNIX_12 support\r
3275                                 if((Ret == LIST_UNKNOWN) &&\r
3276                                    (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))\r
3277                                 {\r
3278                                         GetMonth(Tmp, &Month, &Day);\r
3279                                         if(Month != 0)\r
3280                                         {\r
3281                                                 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);\r
3282                                         }\r
3283                                 }\r
3284 //////////////////\r
3285 \r
3286 ////////////\r
3287 // LIST_UNIX_70 support\r
3288                                 if((Ret == LIST_UNKNOWN) &&\r
3289                                    (FindField(Str, Tmp, 6+Add1, NO) == FFFTP_SUCCESS))\r
3290                                 {\r
3291                                         GetMonth(Tmp, &Month, &Day);\r
3292                                         if(Month != 0)\r
3293                                         {\r
3294                                                 Ret = CheckUnixType(Str, Tmp, Add1, 1, Day);\r
3295                                         }\r
3296                                 }\r
3297 ///////////\r
3298 \r
3299                                 if((Ret == LIST_UNKNOWN) &&\r
3300                                    (FindField(Str, Tmp, 5+Add1, NO) == FFFTP_SUCCESS))\r
3301                                 {\r
3302                                         GetMonth(Tmp, &Month, &Day);\r
3303                                         if(Month != 0)\r
3304                                         {\r
3305                                                 Ret = CheckUnixType(Str, Tmp, Add1, 0, Day);\r
3306                                         }\r
3307                                 }\r
3308 \r
3309                                 if((Ret == LIST_UNKNOWN) &&\r
3310                                    (FindField(Str, Tmp, 4+Add1, NO) == FFFTP_SUCCESS))\r
3311                                 {\r
3312                                         GetMonth(Tmp, &Month, &Day);\r
3313                                         if(Month != 0)\r
3314                                         {\r
3315                                                 Ret = CheckUnixType(Str, Tmp, Add1, -1, Day);\r
3316                                         }\r
3317                                 }\r
3318 \r
3319                                 if((Ret == LIST_UNKNOWN) &&\r
3320                                    (FindField(Str, Tmp, 3+Add1, NO) == FFFTP_SUCCESS))\r
3321                                 {\r
3322                                         GetMonth(Tmp, &Month, &Day);\r
3323                                         if(Month != 0)\r
3324                                         {\r
3325                                                 Ret = CheckUnixType(Str, Tmp, Add1, -2, Day);\r
3326                                         }\r
3327                                 }\r
3328 \r
3329                                 if((Ret != LIST_UNKNOWN) && (Flag1 == YES))\r
3330                                         Ret |= LIST_MELCOM;\r
3331                         }\r
3332                 }\r
3333 \r
3334                 /* 以下のフォーマットをチェック */\r
3335                 /* LIST_AS400 */\r
3336 \r
3337                 if(Ret == LIST_UNKNOWN)\r
3338                 {\r
3339                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3340                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3341                         {\r
3342                                 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3343                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3344                                 {\r
3345                                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3346                                            (IsDigit(Tmp[0]) != 0))\r
3347                                         {\r
3348                                                 if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)\r
3349                                                 {\r
3350                                                         Ret = LIST_AS400;\r
3351                                                 }\r
3352                                         }\r
3353                                 }\r
3354                         }\r
3355                 }\r
3356 \r
3357                 /* 以下のフォーマットをチェック */\r
3358                 /* LIST_M1800 */\r
3359 \r
3360                 if(Ret == LIST_UNKNOWN)\r
3361                 {\r
3362                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3363                            (CheckYYMMDDformat(Tmp, '*', NO) != 0))\r
3364                         {\r
3365                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3366                                    ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))\r
3367                                 {\r
3368                                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3369                                            ((IsDigit(Tmp[0]) != 0) || (StrAllSameChar(Tmp, '*') == YES)))\r
3370                                         {\r
3371                                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3372                                                    (strlen(Tmp) == 4))\r
3373                                                 {\r
3374                                                         if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3375                                                         {\r
3376                                                                 Ret = LIST_M1800;\r
3377                                                         }\r
3378                                                 }\r
3379                                         }\r
3380                                 }\r
3381                         }\r
3382                 }\r
3383 \r
3384                 /* 以下のフォーマットをチェック */\r
3385                 /* LIST_GP6000 */\r
3386 \r
3387                 if(Ret == LIST_UNKNOWN)\r
3388                 {\r
3389                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3390                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3391                         {\r
3392                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3393                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3394                                 {\r
3395                                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3396                                            (IsDigit(Tmp[0]) != 0))\r
3397                                         {\r
3398                                                 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3399                                                 {\r
3400                                                         Ret = LIST_GP6000;\r
3401                                                 }\r
3402                                         }\r
3403                                 }\r
3404                         }\r
3405                 }\r
3406 \r
3407                 /* 以下のフォーマットをチェック */\r
3408                 /* LIST_DOS_1, LIST_DOS_2 */\r
3409 \r
3410                 if(Ret == LIST_UNKNOWN)\r
3411                 {\r
3412                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3413                            (CheckHHMMformat(Tmp) == YES))\r
3414                         {\r
3415                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3416                                    ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3417                                 {\r
3418                                         if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3419                                         {\r
3420                                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3421                                                    (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3422                                                 {\r
3423                                                         TmpInt = atoi(Tmp);\r
3424                                                         if((TmpInt >= 1) && (TmpInt <= 12))\r
3425                                                                 Ret = LIST_DOS_2;\r
3426                                                         else\r
3427                                                                 Ret = LIST_DOS_1;\r
3428                                                 }\r
3429                                         }\r
3430                                 }\r
3431                         }\r
3432                 }\r
3433 \r
3434                 /* 以下のフォーマットをチェック */\r
3435                 /* LIST_DOS_3 */\r
3436 \r
3437                 if(Ret == LIST_UNKNOWN)\r
3438                 {\r
3439                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3440                            (CheckHHMMformat(Tmp) == YES))\r
3441                         {\r
3442                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3443                                    ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3444                                 {\r
3445                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3446                                            (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3447                                         {\r
3448                                                 Ret = LIST_DOS_3;\r
3449                                         }\r
3450                                 }\r
3451                         }\r
3452                 }\r
3453 \r
3454                 /* 以下のフォーマットをチェック */\r
3455                 /* LIST_DOS_4 */\r
3456 \r
3457                 if(Ret == LIST_UNKNOWN)\r
3458                 {\r
3459                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3460                            (CheckYYYYMMDDformat(Tmp, NUL) == YES))\r
3461                         {\r
3462                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3463                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3464                                 {\r
3465                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3466                                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3467                                         {\r
3468                                                 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3469                                                 {\r
3470                                                         Ret = LIST_DOS_4;\r
3471                                                 }\r
3472                                         }\r
3473                                 }\r
3474                         }\r
3475                 }\r
3476 \r
3477                 /* 以下のフォーマットをチェック */\r
3478                 /* LIST_CHAMELEON */\r
3479 \r
3480                 if(Ret == LIST_UNKNOWN)\r
3481                 {\r
3482                         if(FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS)\r
3483                         {\r
3484                                 GetMonth(Tmp, &Month, &Day);\r
3485                                 if((Month != 0) && (Day == 0))\r
3486                                 {\r
3487                                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3488                                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3489                                         {\r
3490                                                 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3491                                                    (CheckHHMMformat(Tmp) == YES))\r
3492                                                 {\r
3493                                                         Ret = LIST_CHAMELEON;\r
3494                                                 }\r
3495                                         }\r
3496                                 }\r
3497                         }\r
3498                 }\r
3499 \r
3500                 /* 以下のフォーマットをチェック */\r
3501                 /* LIST_OS2 */\r
3502 \r
3503                 if(Ret == LIST_UNKNOWN)\r
3504                 {\r
3505                         if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3506                            (CheckHHMMformat(Tmp) == YES))\r
3507                         {\r
3508                                 if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3509                                    (IsDigit(Tmp[0]) != 0))\r
3510                                 {\r
3511                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3512                                            (CheckYYMMDDformat(Tmp, NUL, YES) != 0))\r
3513                                         {\r
3514                                                 if(FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS)\r
3515                                                 {\r
3516                                                         Ret = LIST_OS2;\r
3517                                                 }\r
3518                                         }\r
3519                                 }\r
3520                         }\r
3521                 }\r
3522 \r
3523                 /* 以下のフォーマットをチェック */\r
3524                 /* LIST_OS7 */\r
3525 \r
3526                 if(Ret == LIST_UNKNOWN)\r
3527                 {\r
3528                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3529                            (strlen(Tmp) == 10))\r
3530                         {\r
3531                                 if((FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS) &&\r
3532                                    (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3533                                 {\r
3534                                         if((FindField(Str, Tmp, 4, NO) == FFFTP_SUCCESS) &&\r
3535                                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3536                                         {\r
3537                                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3538                                                    (IsDigit(Tmp[0]) != 0))\r
3539                                                 {\r
3540                                                         if(FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS)\r
3541                                                         {\r
3542                                                                 Ret = LIST_OS7_2;\r
3543                                                         }\r
3544                                                 }\r
3545                                         }\r
3546                                 }\r
3547                                 else if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3548                                                 (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3549                                 {\r
3550                                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3551                                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3552                                         {\r
3553                                                 if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3554                                                 {\r
3555                                                         Ret = LIST_OS7_1;\r
3556                                                 }\r
3557                                         }\r
3558                                 }\r
3559                         }\r
3560                 }\r
3561 \r
3562                 /* 以下のフォーマットをチェック */\r
3563                 /* LIST_ALLIED */\r
3564 \r
3565                 if(Ret == LIST_UNKNOWN)\r
3566                 {\r
3567                         if((FindField(Str, Tmp, 0, NO) == FFFTP_SUCCESS) &&\r
3568                            ((Tmp[0] == '<') || (IsDigit(Tmp[0]) != 0)))\r
3569                         {\r
3570                                 if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3571                                    (CheckHHMMformat(Tmp) == YES))\r
3572                                 {\r
3573                                         if(FindField(Str, Tmp, 3, NO) == FFFTP_SUCCESS)\r
3574                                         {\r
3575                                                 GetMonth(Tmp, &Month, &Day);\r
3576                                                 if(Month != 0)\r
3577                                                 {\r
3578                                                         if((FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS) &&\r
3579                                                            (IsDigit(Tmp[0]) != 0))\r
3580                                                         {\r
3581                                                                 Ret = LIST_ALLIED;\r
3582                                                         }\r
3583                                                 }\r
3584                                         }\r
3585                                 }\r
3586                         }\r
3587                 }\r
3588 \r
3589                 /* 以下のフォーマットをチェック */\r
3590                 /* LIST_OS9 */\r
3591 \r
3592                 if(Ret == LIST_UNKNOWN)\r
3593                 {\r
3594                         if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) &&\r
3595                            (CheckYYMMDDformat(Tmp, NUL, NO) != 0))\r
3596                         {\r
3597                                 if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3598                                    (IsDigit(Tmp[0]) != 0) && (strlen(Tmp) == 4))\r
3599                                 {\r
3600                                         if((FindField(Str, Tmp, 5, NO) == FFFTP_SUCCESS) &&\r
3601                                            (IsDigit(Tmp[0]) != 0))\r
3602                                         {\r
3603                                                 if(FindField(Str, Tmp, 6, NO) == FFFTP_SUCCESS)\r
3604                                                 {\r
3605                                                         Ret = LIST_OS9;\r
3606                                                 }\r
3607                                         }\r
3608                                 }\r
3609                         }\r
3610                 }\r
3611 \r
3612                 /* 以下のフォーマットをチェック */\r
3613                 /* LIST_IBM */\r
3614 \r
3615                 if(Ret == LIST_UNKNOWN)\r
3616                 {\r
3617                         if((FindField(Str, Tmp, 2, NO) == FFFTP_SUCCESS) &&\r
3618                            (CheckYYYYMMDDformat(Tmp, NUL) == YES))\r
3619                         {\r
3620                                 if((FindField(Str, Tmp, 1, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))\r
3621                                 {\r
3622                                         if((FindField(Str, Tmp, 7, NO) == FFFTP_SUCCESS) && IsDigit(Tmp[0]))\r
3623                                         {\r
3624                                                 if(FindField(Str, Tmp, 9, NO) == FFFTP_SUCCESS)\r
3625                                                 {\r
3626                                                         Ret = LIST_IBM;\r
3627                                                 }\r
3628                                         }\r
3629                                 }\r
3630                         }\r
3631                 }\r
3632 \r
3633                 // MLSD対応\r
3634                 if(Ret == LIST_UNKNOWN)\r
3635                 {\r
3636                         if(FindField2(Str, Tmp, ';', 1, NO) == FFFTP_SUCCESS && FindField2(Str, Tmp, '=', 1, NO) == FFFTP_SUCCESS)\r
3637                         {\r
3638                                 Ret = LIST_MLSD;\r
3639                         }\r
3640                 }\r
3641         }\r
3642 \r
3643 DoPrintf("ListType=%d", Ret);\r
3644 \r
3645         return(Ret);\r
3646 }\r
3647 \r
3648 \r
3649 /*----- UNIX系リストタイプのチェックを行なう ----------------------------------\r
3650 *\r
3651 *       Parameter\r
3652 *               char *Str : ファイル情報(1行)\r
3653 *               char *Tmp : 一時ワーク\r
3654 *               int Add1 : 加算パラメータ1\r
3655 *               int Add2 : 加算パラメータ2\r
3656 *               int Day : 日 (0=ここで取得する)\r
3657 *\r
3658 *       Return Value\r
3659 *               int リストタイプ (LIST_xxx)\r
3660 *----------------------------------------------------------------------------*/\r
3661 \r
3662 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day)\r
3663 {\r
3664         int Ret;\r
3665         int Add3;\r
3666         WORD Hour;\r
3667         WORD Minute;\r
3668         int Flag;\r
3669 \r
3670         Flag = 0;\r
3671         Ret = LIST_UNKNOWN;\r
3672 \r
3673 //DayによってAdd3を変える\r
3674 \r
3675         Add3 = 0;\r
3676         if(Day != 0)\r
3677                 Add3 = -1;\r
3678 \r
3679         // unix系チェック\r
3680         if((Day != 0) ||\r
3681            ((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3682                 ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31))))\r
3683         {\r
3684                 if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3685                    ((atoi(Tmp) >= 1900) || (GetHourAndMinute(Tmp, &Hour, &Minute) == FFFTP_SUCCESS)))\r
3686                 {\r
3687                         if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)\r
3688                         {\r
3689                                 Flag = 1;\r
3690                         }\r
3691                 }\r
3692         }\r
3693 \r
3694         // 中国語Solaris専用\r
3695         if(Flag == 0)\r
3696         {\r
3697            if((FindField(Str, Tmp, 7+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3698                   ((atoi(Tmp) >= 1) && (atoi(Tmp) <= 31)))\r
3699                 {\r
3700                         if((FindField(Str, Tmp, 5+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3701                            (atoi(Tmp) >= 1900))\r
3702                         {\r
3703                                 if((FindField(Str, Tmp, 6+Add1+Add2+Add3, NO) == FFFTP_SUCCESS) &&\r
3704                                    (((atoi(Tmp) >= 1) && (atoi(Tmp) <= 9) && \r
3705                                          ((unsigned char)Tmp[1] == 0xD4) &&\r
3706                                          ((unsigned char)Tmp[2] == 0xC2)) ||\r
3707                                     ((atoi(Tmp) >= 10) && (atoi(Tmp) <= 12) && \r
3708                                          ((unsigned char)Tmp[2] == 0xD4) && \r
3709                                          ((unsigned char)Tmp[3] == 0xC2))))\r
3710                                 {\r
3711                                         if(FindField(Str, Tmp, 8+Add1+Add2+Add3, NO) == FFFTP_SUCCESS)\r
3712                                         {\r
3713                                                 Flag = 2;\r
3714                                         }\r
3715                                 }\r
3716                         }\r
3717                 }\r
3718         }\r
3719 \r
3720         if(Flag != 0)\r
3721         {\r
3722                 if(Add2 == 2)\r
3723                 {\r
3724                         Ret = LIST_UNIX_60;\r
3725                         if(Flag == 2)\r
3726                                 Ret = LIST_UNIX_64;\r
3727                         if(Day != 0)\r
3728                                 Ret = LIST_UNIX_61;\r
3729 \r
3730                         if(Add1 == -1)\r
3731                         {\r
3732                                 Ret = LIST_UNIX_62;\r
3733                                 if(Flag == 2)\r
3734                                         Ret = LIST_UNIX_65;\r
3735                                 if(Day != 0)\r
3736                                         Ret = LIST_UNIX_63;\r
3737                         }\r
3738                 }\r
3739                 else if(Add2 == 1)\r
3740                 {\r
3741                         Ret = LIST_UNIX_70;\r
3742                         if(Flag == 2)\r
3743                                 Ret = LIST_UNIX_74;\r
3744                         if(Day != 0)\r
3745                                 Ret = LIST_UNIX_71;\r
3746 \r
3747                         if(Add1 == -1)\r
3748                         {\r
3749                                 Ret = LIST_UNIX_72;\r
3750                                 if(Flag == 2)\r
3751                                         Ret = LIST_UNIX_75;\r
3752                                 if(Day != 0)\r
3753                                         Ret = LIST_UNIX_73;\r
3754                         }\r
3755                 }\r
3756                 else if(Add2 == 0)\r
3757                 {\r
3758                         Ret = LIST_UNIX_10;\r
3759                         if(Flag == 2)\r
3760                                 Ret = LIST_UNIX_14;\r
3761                         if(Day != 0)\r
3762                                 Ret = LIST_UNIX_11;\r
3763 \r
3764                         if(Add1 == -1)\r
3765                         {\r
3766                                 Ret = LIST_UNIX_12;\r
3767                                 if(Flag == 2)\r
3768                                         Ret = LIST_UNIX_15;\r
3769                                 if(Day != 0)\r
3770                                         Ret = LIST_UNIX_13;\r
3771                         }\r
3772                 }\r
3773                 else if(Add2 == -1)\r
3774                 {\r
3775                         Ret = LIST_UNIX_20;\r
3776                         if(Flag == 2)\r
3777                                 Ret = LIST_UNIX_24;\r
3778                         if(Day != 0)\r
3779                                 Ret = LIST_UNIX_21;\r
3780 \r
3781                         if(Add1 == -1)\r
3782                         {\r
3783                                 Ret = LIST_UNIX_22;\r
3784                                 if(Flag == 2)\r
3785                                         Ret = LIST_UNIX_25;\r
3786                                 if(Day != 0)\r
3787                                         Ret = LIST_UNIX_23;\r
3788                         }\r
3789                 }\r
3790                 else\r
3791                 {\r
3792                         Ret = LIST_UNIX_50;\r
3793                         if(Flag == 2)\r
3794                                 Ret = LIST_UNIX_54;\r
3795                         if(Day != 0)\r
3796                                 Ret = LIST_UNIX_51;\r
3797                 }\r
3798         }\r
3799         return(Ret);\r
3800 }\r
3801 \r
3802 \r
3803 /*----- HH:MM 形式の文字列かどうかをチェック ----------------------------------\r
3804 *\r
3805 *       Parameter\r
3806 *               char *Str : 文字列\r
3807 *\r
3808 *       Return Value\r
3809 *               int ステータス (YES/NO)\r
3810 *\r
3811 *       Note\r
3812 *               区切り文字は何でもよい\r
3813 *               時分でなくてもよい\r
3814 *               後ろに余分な文字が付いていてもよい\r
3815 *----------------------------------------------------------------------------*/\r
3816 \r
3817 static int CheckHHMMformat(char *Str)\r
3818 {\r
3819         int Ret;\r
3820 \r
3821         Ret = NO;\r
3822         if((strlen(Str) >= 3) &&\r
3823            (IsDigit(Str[0]) != 0))\r
3824         {\r
3825                 if((Str = strchr(Str, ':')) != NULL)\r
3826                 {\r
3827                         if(IsDigit(*(Str+1)) != 0)\r
3828                                 Ret = YES;\r
3829                 }\r
3830         }\r
3831         return(Ret);\r
3832 }\r
3833 \r
3834 \r
3835 /*----- YY/MM/DD 形式の文字列かどうかをチェック -------------------------------\r
3836 *\r
3837 *       Parameter\r
3838 *               char *Str : 文字列\r
3839 *               char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)\r
3840 *               int Dig3 : 3桁の年を許可\r
3841 *\r
3842 *       Return Value\r
3843 *               int ステータス\r
3844 *                       0 = 該当しない\r
3845 *                       1 = ??/??/??, ??/??/???\r
3846 *                       2 = ???/??/??\r
3847 *\r
3848 *       Note\r
3849 *               区切り文字は何でもよい\r
3850 *               年月日でなくてもよい\r
3851 *----------------------------------------------------------------------------*/\r
3852 \r
3853 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3)\r
3854 {\r
3855         int Ret;\r
3856 \r
3857         Ret = 0;\r
3858         if((strlen(Str) == 8) &&\r
3859            (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
3860            (IsDigit(Str[2]) == 0) &&\r
3861            (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&\r
3862            (IsDigit(Str[5]) == 0) &&\r
3863            (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0))\r
3864         {\r
3865                 Ret = 1; \r
3866         }\r
3867         if(Dig3 == YES)\r
3868         {\r
3869                 if((strlen(Str) == 9) &&\r
3870                    (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) && (IsDigitSym(Str[2], Sym) != 0) &&\r
3871                    (IsDigit(Str[3]) == 0) &&\r
3872                    (IsDigitSym(Str[4], Sym) != 0) && (IsDigitSym(Str[5], Sym) != 0) &&\r
3873                    (IsDigit(Str[6]) == 0) &&\r
3874                    (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))\r
3875                 {\r
3876                         Ret = 2; \r
3877                 }\r
3878                 else if((strlen(Str) == 9) &&\r
3879                                 (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
3880                                 (IsDigit(Str[2]) == 0) &&\r
3881                                 (IsDigitSym(Str[3], Sym) != 0) && (IsDigitSym(Str[4], Sym) != 0) &&\r
3882                                 (IsDigit(Str[5]) == 0) &&\r
3883                                 (IsDigitSym(Str[6], Sym) != 0) && (IsDigitSym(Str[7], Sym) != 0) && (IsDigitSym(Str[8], Sym) != 0))\r
3884                 {\r
3885                         Ret = 1; \r
3886                 }\r
3887         }\r
3888         return(Ret);\r
3889 }\r
3890 \r
3891 \r
3892 /*----- YYYY/MM/DD 形式の文字列かどうかをチェック -----------------------------\r
3893 *\r
3894 *       Parameter\r
3895 *               char *Str : 文字列\r
3896 *               char Sym : 数字の代わりに使える記号 (NUL=数字以外使えない)\r
3897 *\r
3898 *       Return Value\r
3899 *               int ステータス (YES/NO)\r
3900 *\r
3901 *       Note\r
3902 *               区切り文字は何でもよい\r
3903 *               年月日でなくてもよい\r
3904 *----------------------------------------------------------------------------*/\r
3905 \r
3906 static int CheckYYYYMMDDformat(char *Str, char Sym)\r
3907 {\r
3908         int Ret;\r
3909 \r
3910         Ret = NO;\r
3911         if((strlen(Str) == 10) &&\r
3912            (IsDigitSym(Str[0], Sym) != 0) && (IsDigitSym(Str[1], Sym) != 0) &&\r
3913            (IsDigitSym(Str[2], Sym) != 0) && (IsDigitSym(Str[3], Sym) != 0) &&\r
3914            (IsDigit(Str[4]) == 0) &&\r
3915            (IsDigitSym(Str[5], Sym) != 0) && (IsDigitSym(Str[6], Sym) != 0) &&\r
3916            (IsDigit(Str[7]) == 0) &&\r
3917            (IsDigitSym(Str[8], Sym) != 0) && (IsDigitSym(Str[9], Sym) != 0))\r
3918         {\r
3919                 Ret = YES; \r
3920         }\r
3921         return(Ret);\r
3922 }\r
3923 \r
3924 \r
3925 /*----- ファイル情報からファイル名、サイズなどを取り出す ----------------------\r
3926 *\r
3927 *       Parameter\r
3928 *               char *Str : ファイル情報(1行)\r
3929 *               int ListType : リストのタイプ\r
3930 *               char *Name : ファイル名のコピー先\r
3931 *               LONGLONG *Size : サイズのコピー先\r
3932 *               FILETIME *Time : 日付のコピー先\r
3933 *               int *Attr : 属性のコピー先\r
3934 *               char *Owner : オーナ名\r
3935 *               int *Link : リンクかどうか (YES/NO)\r
3936 *               int *InfoExist : 時刻の情報があったかどうか (YES/NO)\r
3937 *\r
3938 *       Return Value\r
3939 *               int 種類 (NODE_xxxx)\r
3940 *----------------------------------------------------------------------------*/\r
3941 \r
3942 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist)\r
3943 {\r
3944         SYSTEMTIME sTime;\r
3945         SYSTEMTIME sTimeNow;\r
3946         char Buf[FMAX_PATH+1];\r
3947         char *Pos;\r
3948         char Flag;\r
3949         int Ret;\r
3950         int offs;\r
3951         int offs2;\r
3952         int offs3;\r
3953         int OrgListType;\r
3954         int err;\r
3955         int Flag2;\r
3956 \r
3957         static const int DosPos[3][4] = { { 1, 0, 2, 3 }, { 1, 0, 2, 3 }, { 3, 2, 1, 0 } };\r
3958         static const int DosDate[3][3][2] = { { {0, 0}, {3, 4}, {6, 7} }, { {6, 7}, {0, 0}, {3, 4} }, { {6, 7}, {0, 0}, {3, 4} } };\r
3959         static const int DosLongFname[3] = { YES, YES, NO };\r
3960 \r
3961         /* まずクリアしておく */\r
3962         Ret = NODE_NONE;\r
3963         *Size = -1;\r
3964         *Attr = 0;\r
3965         *Link = NO;\r
3966         memset(Owner, NUL, OWNER_NAME_LEN+1);\r
3967         Time->dwLowDateTime = 0;\r
3968         Time->dwHighDateTime = 0;\r
3969         *InfoExist = 0;\r
3970         offs = 0;\r
3971         offs2 = 0;\r
3972         offs3 = 0;\r
3973 \r
3974         OrgListType = ListType;\r
3975         ListType &= LIST_MASKFLG;\r
3976         switch(ListType)\r
3977         {\r
3978                 case LIST_DOS_1 :\r
3979                 case LIST_DOS_2 :\r
3980                 case LIST_DOS_3 :\r
3981                         if(ListType == LIST_DOS_1)\r
3982                                 offs = 0;\r
3983                         else if(ListType == LIST_DOS_2)\r
3984                                 offs = 1;\r
3985                         else\r
3986                                 offs = 2;\r
3987 \r
3988                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
3989 \r
3990                         /* 時刻 */\r
3991                         FindField(Str, Buf, DosPos[offs][0], NO);\r
3992                         if((Pos = strchr(Buf, ':')) != NULL)\r
3993                         {\r
3994                                 *InfoExist |= FINFO_TIME;\r
3995                                 sTime.wHour = atoi(Buf);\r
3996                                 sTime.wMinute = atoi(Pos+1);\r
3997                                 sTime.wSecond = 0;\r
3998                                 sTime.wMilliseconds = 0;\r
3999 \r
4000                                 if(strlen(Pos) >= 4)\r
4001                                 {\r
4002                                         if(tolower(Pos[3]) == 'a')\r
4003                                         {\r
4004                                                 if(sTime.wHour == 12)\r
4005                                                         sTime.wHour = 0;\r
4006                                         }\r
4007                                         else if(tolower(Pos[3]) == 'p')\r
4008                                         {\r
4009                                                 if(sTime.wHour != 12)\r
4010                                                         sTime.wHour += 12;\r
4011                                         }\r
4012                                 }\r
4013                         }\r
4014 \r
4015                         /* 日付 */\r
4016                         FindField(Str, Buf, DosPos[offs][1], NO);\r
4017                         if((offs2 = CheckYYMMDDformat(Buf, NUL, YES)) == 0)\r
4018                                 break;\r
4019                         offs2--;\r
4020                         sTime.wYear = Assume1900or2000(atoi(Buf + DosDate[offs][0][offs2]));\r
4021                         sTime.wMonth = atoi(Buf + DosDate[offs][1][offs2]);\r
4022                         sTime.wDay = atoi(Buf + DosDate[offs][2][offs2]);\r
4023                         SystemTimeToFileTime(&sTime, Time);\r
4024                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4025 \r
4026                         /* サイズ */\r
4027                         FindField(Str, Buf, DosPos[offs][2], NO);\r
4028                         *Size = _atoi64(Buf);\r
4029 \r
4030                         /* 名前 */\r
4031                         if(FindField(Str, Fname, DosPos[offs][3], DosLongFname[offs]) == FFFTP_SUCCESS)\r
4032                         {\r
4033                                 Ret = NODE_FILE;\r
4034                                 if(Buf[0] == '<')\r
4035                                         Ret = NODE_DIR;\r
4036                         }\r
4037                         break;\r
4038 \r
4039                 case LIST_DOS_4 :\r
4040                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4041 \r
4042                         /* 日付 */\r
4043                         FindField(Str, Buf, 0, NO);\r
4044                         sTime.wYear = atoi(Buf);\r
4045                         sTime.wMonth = atoi(Buf+5);\r
4046                         sTime.wDay = atoi(Buf+8);\r
4047 \r
4048                         /* 時刻 */\r
4049                         *InfoExist |= FINFO_TIME;\r
4050                         FindField(Str, Buf, 1, NO);\r
4051                         sTime.wHour = atoi(Buf);\r
4052                         sTime.wMinute = atoi(Buf+3);\r
4053                         sTime.wSecond = 0;                              // atoi(Buf+6);\r
4054                         sTime.wMilliseconds = 0;\r
4055                         SystemTimeToFileTime(&sTime, Time);\r
4056                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4057 \r
4058                         /* サイズ */\r
4059                         FindField(Str, Buf, 2, NO);\r
4060                         *Size = _atoi64(Buf);\r
4061 \r
4062                         /* 名前 */\r
4063                         if(FindField(Str, Fname, 3, YES) == FFFTP_SUCCESS)\r
4064                         {\r
4065                                 Ret = NODE_FILE;\r
4066                                 if(Buf[0] == '<')\r
4067                                         Ret = NODE_DIR;\r
4068                         }\r
4069                         break;\r
4070 \r
4071                 case LIST_OS2 :\r
4072                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
4073 \r
4074                         /* 時刻 */\r
4075                         FindField(Str, Buf, 3, NO);\r
4076                         if((Pos = strchr(Buf, ':')) != NULL)\r
4077                         {\r
4078                                 *InfoExist |= FINFO_TIME;\r
4079                                 sTime.wHour = atoi(Buf);\r
4080                                 sTime.wMinute = atoi(Pos+1);\r
4081                                 sTime.wSecond = 0;\r
4082                                 sTime.wMilliseconds = 0;\r
4083                         }\r
4084 \r
4085                         /* 日付 */\r
4086                         FindField(Str, Buf, 2, NO);\r
4087                         sTime.wYear = Assume1900or2000(atoi(Buf+6));\r
4088                         sTime.wMonth = atoi(Buf+0);\r
4089                         sTime.wDay = atoi(Buf+3);\r
4090                         SystemTimeToFileTime(&sTime, Time);\r
4091                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4092 \r
4093                         /* サイズ */\r
4094                         FindField(Str, Buf, 0, NO);\r
4095                         *Size = _atoi64(Buf);\r
4096 \r
4097                         /* 名前 */\r
4098                         if(FindField(Str, Fname, 4, YES) == FFFTP_SUCCESS)\r
4099                         {\r
4100                                 FindField(Str, Buf, 1, NO);\r
4101                                 Ret = NODE_FILE;\r
4102                                 if(strstr(Buf, "DIR") != NULL)\r
4103                                         Ret = NODE_DIR;\r
4104                         }\r
4105                         break;\r
4106 \r
4107                 case LIST_CHAMELEON :\r
4108                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4109 \r
4110                         /* 属性 */\r
4111                         FindField(Str, Buf, 6, NO);\r
4112                         strcat(Buf, "------");\r
4113                         *Attr = AttrString2Value(Buf+1);\r
4114 \r
4115                         /* 日付 */\r
4116                         FindField(Str, Buf, 2, NO);\r
4117                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);      /* wDayは常に0 */\r
4118                         FindField(Str, Buf, 3, NO);\r
4119                         sTime.wDay = atoi(Buf);\r
4120                         FindField(Str, Buf, 4, NO);\r
4121                         sTime.wYear = atoi(Buf);\r
4122 \r
4123                         /* 時刻 */\r
4124                         FindField(Str, Buf, 5, NO);\r
4125                         sTime.wHour = atoi(Buf);\r
4126                         sTime.wMinute = atoi(Buf+3);\r
4127                         sTime.wSecond = 0;\r
4128                         sTime.wMilliseconds = 0;\r
4129                         SystemTimeToFileTime(&sTime, Time);\r
4130                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4131 \r
4132                         /* サイズ */\r
4133                         FindField(Str, Buf, 1, NO);\r
4134                         *Size = _atoi64(Buf);\r
4135 \r
4136                         /* 名前 */\r
4137                         if(FindField(Str, Fname, 0, NO) == FFFTP_SUCCESS)\r
4138                         {\r
4139                                 Ret = NODE_FILE;\r
4140                                 if(Buf[0] == '<')\r
4141                                         Ret = NODE_DIR;\r
4142                         }\r
4143                         break;\r
4144 \r
4145                 case LIST_AS400 :\r
4146                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4147 \r
4148                         /* オーナ名 */\r
4149                         FindField(Str, Buf, 0, NO);\r
4150                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4151 \r
4152                         /* 時刻 */\r
4153                         FindField(Str, Buf, 3, NO);\r
4154                         sTime.wHour = atoi(Buf);\r
4155                         sTime.wMinute = atoi(Buf+3);\r
4156                         sTime.wSecond = 0;\r
4157                         sTime.wMilliseconds = 0;\r
4158 \r
4159                         /* 日付 */\r
4160                         FindField(Str, Buf, 2, NO);\r
4161                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4162                         sTime.wMonth = atoi(Buf + 3);\r
4163                         sTime.wDay = atoi(Buf + 6);\r
4164                         SystemTimeToFileTime(&sTime, Time);\r
4165                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4166 \r
4167                         /* サイズ */\r
4168                         FindField(Str, Buf, 1, NO);\r
4169                         *Size = _atoi64(Buf);\r
4170 \r
4171                         /* 名前 */\r
4172                         if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)\r
4173                         {\r
4174                                 Ret = NODE_FILE;\r
4175                                 if((Pos = strchr(Fname, '/')) != NULL)\r
4176                                 {\r
4177                                         Ret = NODE_DIR;\r
4178                                         *Pos = NUL;\r
4179                                 }\r
4180                         }\r
4181                         break;\r
4182 \r
4183                 case LIST_M1800 :\r
4184                         *InfoExist |= FINFO_ATTR;\r
4185 \r
4186                         /* 属性 */\r
4187                         FindField(Str, Buf, 0, NO);\r
4188                         strcat(Buf, "------");\r
4189                         *Attr = AttrString2Value(Buf+1);\r
4190 \r
4191                         /* 日付 */\r
4192                         Time->dwLowDateTime = 0;\r
4193                         Time->dwHighDateTime = 0;\r
4194                         FindField(Str, Buf, 5, NO);\r
4195                         if(Buf[0] != '*')\r
4196                         {\r
4197                                 *InfoExist |= FINFO_DATE;\r
4198                                 sTime.wHour = 0;\r
4199                                 sTime.wMinute = 0;\r
4200                                 sTime.wSecond = 0;\r
4201                                 sTime.wMilliseconds = 0;\r
4202 \r
4203                                 sTime.wYear = Assume1900or2000(atoi(Buf));\r
4204                                 sTime.wMonth = atoi(Buf + 3);\r
4205                                 sTime.wDay = atoi(Buf + 6);\r
4206                                 SystemTimeToFileTime(&sTime, Time);\r
4207                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4208                         }\r
4209 \r
4210                         /* 名前 */\r
4211                         if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)\r
4212                         {\r
4213                                 RemoveTailingSpaces(Fname);\r
4214                                 Ret = NODE_FILE;\r
4215                                 if((Pos = strchr(Fname, '/')) != NULL)\r
4216                                 {\r
4217                                         Ret = NODE_DIR;\r
4218                                         *Pos = NUL;\r
4219                                 }\r
4220                         }\r
4221                         break;\r
4222 \r
4223                 case LIST_GP6000 :\r
4224                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4225 \r
4226                         /* オーナ名 */\r
4227                         FindField(Str, Buf, 3, NO);\r
4228                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4229 \r
4230                         /* 時刻 */\r
4231                         FindField(Str, Buf, 2, NO);\r
4232                         sTime.wHour = atoi(Buf);\r
4233                         sTime.wMinute = atoi(Buf+3);\r
4234                         sTime.wSecond = 0;\r
4235                         sTime.wMilliseconds = 0;\r
4236 \r
4237                         /* 日付 */\r
4238                         FindField(Str, Buf, 1, NO);\r
4239                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4240                         sTime.wMonth = atoi(Buf + 3);\r
4241                         sTime.wDay = atoi(Buf + 6);\r
4242                         SystemTimeToFileTime(&sTime, Time);\r
4243                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4244 \r
4245                         /* サイズ */\r
4246                         FindField(Str, Buf, 5, NO);\r
4247                         *Size = _atoi64(Buf);\r
4248 \r
4249                         /* 属性 */\r
4250                         FindField(Str, Buf, 0, NO);\r
4251                         *Attr = AttrString2Value(Buf+1);\r
4252 \r
4253                         /* 名前 */\r
4254                         if(FindField(Str, Fname, 6, YES) == FFFTP_SUCCESS)\r
4255                         {\r
4256                                 Ret = NODE_FILE;\r
4257                                 if(strchr("dl", Buf[0]) != NULL)\r
4258                                         Ret = NODE_DIR;\r
4259                         }\r
4260                         break;\r
4261 \r
4262                 case LIST_ACOS :\r
4263                 case LIST_ACOS_4 :\r
4264                         /* 名前 */\r
4265                         FindField(Str, Fname, 0, NO);\r
4266                         Ret = NODE_FILE;\r
4267                         break;\r
4268 \r
4269                 case LIST_VMS :\r
4270                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4271 \r
4272                         /* サイズ */\r
4273                         FindField(Str, Buf, 1, NO);\r
4274                         *Size = _atoi64(Buf) * BLOCK_SIZE;\r
4275 \r
4276                         /* 時刻/日付 */\r
4277                         FindField(Str, Buf, 2, NO);\r
4278                         GetVMSdate(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay);\r
4279 \r
4280                         FindField(Str, Buf, 3, NO);\r
4281                         GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute);\r
4282 \r
4283                         sTime.wSecond = 0;\r
4284                         sTime.wMilliseconds = 0;\r
4285                         SystemTimeToFileTime(&sTime, Time);\r
4286                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4287 \r
4288                         /* 名前 */\r
4289                         FindField(Str, Fname, 0, NO);\r
4290 \r
4291                         Ret = NODE_FILE;\r
4292                         if((Pos = strchr(Fname, '.')) != NULL)\r
4293                         {\r
4294                                 if(_strnicmp(Pos, ".DIR;", 5) == 0)\r
4295                                 {\r
4296                                         /* OpenVMSの場合、ファイル/ディレクトリ削除時には".DIR;?"までないと\r
4297                                          * 削除できないので、ここではつぶさない */\r
4298 #if !defined(HAVE_OPENVMS)\r
4299                                         *Pos = NUL;\r
4300 #endif\r
4301                                         Ret = NODE_DIR;\r
4302                                 }\r
4303                         }\r
4304                         break;\r
4305 \r
4306                 case LIST_OS7_2 :\r
4307                         *InfoExist |= FINFO_SIZE;\r
4308                         offs = 2;\r
4309 \r
4310                         /* サイズ */\r
4311                         FindField(Str, Buf, 2, NO);\r
4312                         *Size = _atoi64(Buf);\r
4313                         /* ここにbreakはない */\r
4314 \r
4315                 case LIST_OS7_1 :\r
4316                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_ATTR);\r
4317 \r
4318                         /* 日付 */\r
4319                         FindField(Str, Buf, 1+offs, NO);\r
4320                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4321                         sTime.wMonth = atoi(Buf + 3);\r
4322                         sTime.wDay = atoi(Buf + 6);\r
4323 \r
4324                         /* 時刻 */\r
4325                         FindField(Str, Buf, 2+offs, NO);\r
4326                         sTime.wHour = atoi(Buf);\r
4327                         sTime.wMinute = atoi(Buf+3);\r
4328                         sTime.wSecond = 0;\r
4329                         sTime.wMilliseconds = 0;\r
4330                         SystemTimeToFileTime(&sTime, Time);\r
4331                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4332 \r
4333                         /* 属性 */\r
4334                         FindField(Str, Buf, 0, NO);\r
4335                         *Attr = AttrString2Value(Buf+1);\r
4336 \r
4337                         /* 名前 */\r
4338                         if(FindField(Str, Fname, 3+offs, YES) == FFFTP_SUCCESS)\r
4339                         {\r
4340                                 RemoveTailingSpaces(Fname);\r
4341                                 Ret = NODE_FILE;\r
4342                                 if(strchr("dl", Buf[0]) != NULL)\r
4343                                         Ret = NODE_DIR;\r
4344                         }\r
4345                         break;\r
4346 \r
4347                 case LIST_STRATUS :\r
4348                         if(FindField(Str, Buf, 0, NO) != FFFTP_SUCCESS)\r
4349                                 break;\r
4350                         if(_strnicmp(Buf, "Files:", 6) == 0)\r
4351                                 StratusMode = 0;\r
4352                         else if(_strnicmp(Buf, "Dirs:", 5) == 0)\r
4353                                 StratusMode = 1;\r
4354                         else if(_strnicmp(Buf, "Links:", 6) == 0)\r
4355                                 StratusMode = 2;\r
4356                         else\r
4357                         {\r
4358                                 if(StratusMode == 0)\r
4359                                         offs = 1;\r
4360                                 else if(StratusMode == 1)\r
4361                                         offs = 0;\r
4362                                 else\r
4363                                         break;\r
4364 \r
4365                                 *InfoExist |= (FINFO_TIME | FINFO_DATE);\r
4366 \r
4367                                 /* 日付 */\r
4368                                 if(FindField(Str, Buf, 2+offs, NO) != FFFTP_SUCCESS)\r
4369                                         break;\r
4370                                 sTime.wYear = Assume1900or2000(atoi(Buf));\r
4371                                 sTime.wMonth = atoi(Buf + 3);\r
4372                                 sTime.wDay = atoi(Buf + 6);\r
4373 \r
4374                                 /* 時刻 */\r
4375                                 if(FindField(Str, Buf, 3+offs, NO) != FFFTP_SUCCESS)\r
4376                                         break;\r
4377                                 sTime.wHour = atoi(Buf);\r
4378                                 sTime.wMinute = atoi(Buf+3);\r
4379                                 sTime.wSecond = 0;\r
4380                                 sTime.wMilliseconds = 0;\r
4381                                 SystemTimeToFileTime(&sTime, Time);\r
4382                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4383 \r
4384                                 /* 名前 */\r
4385                                 if(FindField(Str, Fname, 4+offs, YES) != FFFTP_SUCCESS)\r
4386                                         break;\r
4387 \r
4388                                 if(StratusMode == 0)\r
4389                                 {\r
4390                                         *InfoExist |= FINFO_SIZE;\r
4391 \r
4392                                         /* サイズ */\r
4393                                         if(FindField(Str, Buf, 1, NO) != FFFTP_SUCCESS)\r
4394                                                 break;\r
4395                                         *Size = _atoi64(Buf) * 4096;\r
4396 \r
4397                                         /* 種類(オーナ名のフィールドにいれる) */\r
4398                                         if(FindField(Str, Buf, 2, NO) != FFFTP_SUCCESS)\r
4399                                                 break;\r
4400                                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4401 \r
4402                                         Ret = NODE_FILE;\r
4403                                 }\r
4404                                 else\r
4405                                         Ret = NODE_DIR;\r
4406                         }\r
4407                         break;\r
4408 \r
4409                 case LIST_IRMX :\r
4410                         *InfoExist |= (FINFO_DATE | FINFO_SIZE);\r
4411 \r
4412                         /* 日付 */\r
4413                         for(offs = 11; offs > 7; offs--)\r
4414                         {\r
4415                                 if((err = FindField(Str, Buf, offs, NO)) == FFFTP_SUCCESS)\r
4416                                         break;\r
4417                         }\r
4418                         if(err != FFFTP_SUCCESS)\r
4419                                 break;\r
4420                         if(IsDigit(*Buf) == 0)\r
4421                                 break;\r
4422                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4423                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4424                                 break;\r
4425                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
4426                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4427                                 break;\r
4428                         if(IsDigit(*Buf) == 0)\r
4429                                 break;\r
4430                         sTime.wDay = atoi(Buf);\r
4431                         sTime.wHour = 0;\r
4432                         sTime.wMinute = 0;\r
4433                         sTime.wSecond = 0;\r
4434                         sTime.wMilliseconds = 0;\r
4435                         SystemTimeToFileTime(&sTime, Time);\r
4436                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4437 \r
4438                         /* オーナ名 */\r
4439                         if(FindField(Str, Buf, --offs, NO) != FFFTP_SUCCESS)\r
4440                                 break;\r
4441                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4442 \r
4443                         /* サイズ */\r
4444                         do\r
4445                         {\r
4446                                 if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4447                                         break;\r
4448                         }\r
4449                         while(IsDigit(*Buf) == 0);\r
4450                         --offs;\r
4451                         if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4452                                 break;\r
4453                         RemoveComma(Buf);\r
4454                         *Size = _atoi64(Buf);\r
4455                         if((err = FindField(Str, Buf, --offs, NO)) != FFFTP_SUCCESS)\r
4456                                 break;\r
4457                         if(IsDigit(*Buf) == 0)\r
4458                                 break;\r
4459                         /* 名前 */\r
4460                         if(FindField(Str, Fname, 0, NO) != FFFTP_SUCCESS)\r
4461                                 break;\r
4462                         /* 種類 */\r
4463                         if(offs == 0)\r
4464                                 Ret = NODE_FILE;\r
4465                         else\r
4466                         {\r
4467                                 if((FindField(Str, Buf, 1, NO) == FFFTP_SUCCESS) &&\r
4468                                    (strcmp(Buf, "DR") == 0))\r
4469                                         Ret = NODE_DIR;\r
4470                                 else\r
4471                                         Ret = NODE_FILE;\r
4472                         }\r
4473                         break;\r
4474 \r
4475                 case LIST_ALLIED :\r
4476                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4477 \r
4478                         /* 日付 */\r
4479                         FindField(Str, Buf, 3, NO);\r
4480                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);      /* wDayは常に0 */\r
4481                         FindField(Str, Buf, 4, NO);\r
4482                         sTime.wDay = atoi(Buf);\r
4483                         FindField(Str, Buf, 6, NO);\r
4484                         sTime.wYear = atoi(Buf);\r
4485 \r
4486                         /* 時刻 */\r
4487                         FindField(Str, Buf, 5, NO);\r
4488                         sTime.wHour = atoi(Buf);\r
4489                         sTime.wMinute = atoi(Buf+3);\r
4490                         sTime.wSecond = 0;\r
4491                         sTime.wMilliseconds = 0;\r
4492                         SystemTimeToFileTime(&sTime, Time);\r
4493                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4494 \r
4495                         /* サイズ */\r
4496                         FindField(Str, Buf, 0, NO);\r
4497                         *Size = _atoi64(Buf);\r
4498 \r
4499                         /* 名前 */\r
4500                         if(FindField(Str, Fname, 1, NO) == FFFTP_SUCCESS)\r
4501                         {\r
4502                                 Ret = NODE_FILE;\r
4503                                 if(Buf[0] == '<')\r
4504                                         Ret = NODE_DIR;\r
4505                         }\r
4506                         break;\r
4507 \r
4508                 case LIST_OS9 :\r
4509                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4510 \r
4511                         /* 日付 */\r
4512                         FindField(Str, Buf, 1, NO);\r
4513                         sTime.wYear = Assume1900or2000(atoi(Buf));\r
4514                         sTime.wMonth = atoi(Buf + 3);\r
4515                         sTime.wDay = atoi(Buf + 6);\r
4516                         SystemTimeToFileTime(&sTime, Time);\r
4517                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4518 \r
4519                         /* 時刻 */\r
4520                         FindField(Str, Buf, 2, NO);\r
4521                         sTime.wHour = atoi_n(Buf, 2);\r
4522                         sTime.wMinute = atoi(Buf+2);\r
4523                         sTime.wSecond = 0;\r
4524                         sTime.wMilliseconds = 0;\r
4525                         SystemTimeToFileTime(&sTime, Time);\r
4526                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4527 \r
4528                         /* サイズ */\r
4529                         FindField(Str, Buf, 5, NO);\r
4530                         *Size = _atoi64(Buf);\r
4531 \r
4532                         /* オーナ名 */\r
4533                         FindField(Str, Buf, 0, NO);\r
4534                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4535 \r
4536                         /* オーナ名 */\r
4537                         FindField(Str, Buf, 3, NO);\r
4538 \r
4539                         /* 名前 */\r
4540                         if(FindField(Str, Fname, 6, NO) == FFFTP_SUCCESS)\r
4541                         {\r
4542                                 if((Buf[0] == 'd') || (Buf[0] == 'D'))\r
4543                                         Ret = NODE_DIR;\r
4544                                 else\r
4545                                         Ret = NODE_FILE;\r
4546                         }\r
4547                         break;\r
4548 \r
4549                 case LIST_IBM :\r
4550                         *InfoExist |= FINFO_DATE;\r
4551 \r
4552 \r
4553                         /* 日付 */\r
4554                         FindField(Str, Buf, 2, NO);\r
4555                         sTime.wYear = atoi(Buf);\r
4556                         sTime.wMonth = atoi(Buf + 5);\r
4557                         sTime.wDay = atoi(Buf + 8);\r
4558                         sTime.wHour = 0;\r
4559                         sTime.wMinute = 0;\r
4560                         sTime.wSecond = 0;\r
4561                         sTime.wMilliseconds = 0;\r
4562                         SystemTimeToFileTime(&sTime, Time);\r
4563                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4564 \r
4565                         /* 名前 */\r
4566                         FindField(Str, Buf, 8, NO);\r
4567                         if(FindField(Str, Fname, 9, NO) == FFFTP_SUCCESS)\r
4568                         {\r
4569                                 if(strcmp(Buf, "PO") == 0)\r
4570                                         Ret = NODE_DIR;\r
4571                                 else if(strcmp(Buf, "PS") == 0)\r
4572                                         Ret = NODE_FILE;\r
4573                         }\r
4574                         break;\r
4575 \r
4576                 case LIST_AGILENT :\r
4577                         *InfoExist |= (FINFO_SIZE | FINFO_ATTR);\r
4578 \r
4579                         /* オーナ名 */\r
4580                         FindField(Str, Buf, 2, NO);\r
4581                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4582 \r
4583                         /* サイズ */\r
4584                         FindField(Str, Buf, 4, NO);\r
4585                         *Size = _atoi64(Buf);\r
4586 \r
4587                         /* 属性 */\r
4588                         FindField(Str, Buf, 0, NO);\r
4589                         *Attr = AttrString2Value(Buf+1);\r
4590 \r
4591                         /* 名前 */\r
4592                         if(FindField(Str, Fname, 5, YES) == FFFTP_SUCCESS)\r
4593                         {\r
4594                                 Ret = NODE_FILE;\r
4595                                 if(strchr("dl", Buf[0]) != NULL)\r
4596                                         Ret = NODE_DIR;\r
4597                         }\r
4598                         break;\r
4599 \r
4600                 case LIST_SHIBASOKU :\r
4601                         *InfoExist |= (FINFO_TIME | FINFO_DATE | FINFO_SIZE);\r
4602 \r
4603                         /* サイズ */\r
4604                         FindField(Str, Buf, 0, NO);\r
4605                         if(IsDigit(Buf[0]))\r
4606                         {\r
4607                                 *Size = _atoi64(Buf);\r
4608 \r
4609                                 /* 日付 */\r
4610                                 FindField(Str, Buf, 1, NO);\r
4611                                 Buf[3] = '\0';\r
4612                                 GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
4613                                 sTime.wDay = atoi(Buf+4);\r
4614                                 sTime.wYear = atoi(Buf+7);\r
4615 \r
4616                                 /* 時刻 */\r
4617                                 FindField(Str, Buf, 2, NO);\r
4618                                 sTime.wHour = atoi(Buf);\r
4619                                 sTime.wMinute = atoi(Buf+3);\r
4620                                 sTime.wSecond = 0;\r
4621                                 sTime.wMilliseconds = 0;\r
4622                                 SystemTimeToFileTime(&sTime, Time);\r
4623                                 SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4624 \r
4625                                 /* 名前 */\r
4626                                 FindField(Str, Fname, 3, NO);\r
4627 \r
4628                                 /* 種類 */\r
4629                                 Ret = NODE_FILE;\r
4630                                 if(FindField(Str, Buf, 4, NO) == FFFTP_SUCCESS)\r
4631                                 {\r
4632                                         if(strcmp(Buf, "<DIR>") == 0)\r
4633                                                 Ret = NODE_DIR;\r
4634                                 }\r
4635                         }\r
4636                         break;\r
4637 \r
4638                 case LIST_UNIX_10 :\r
4639                 case LIST_UNIX_11 :\r
4640                 case LIST_UNIX_12 :\r
4641                 case LIST_UNIX_13 :\r
4642                 case LIST_UNIX_14 :\r
4643                 case LIST_UNIX_15 :\r
4644                 case LIST_UNIX_20 :\r
4645                 case LIST_UNIX_21 :\r
4646                 case LIST_UNIX_22 :\r
4647                 case LIST_UNIX_23 :\r
4648                 case LIST_UNIX_24 :\r
4649                 case LIST_UNIX_25 :\r
4650                 case LIST_UNIX_50 :\r
4651                 case LIST_UNIX_51 :\r
4652                 case LIST_UNIX_54 :\r
4653                 case LIST_UNIX_60 :\r
4654                 case LIST_UNIX_61 :\r
4655                 case LIST_UNIX_62 :\r
4656                 case LIST_UNIX_63 :\r
4657                 case LIST_UNIX_64 :\r
4658                 case LIST_UNIX_65 :\r
4659                 case LIST_UNIX_70 :\r
4660                 case LIST_UNIX_71 :\r
4661                 case LIST_UNIX_72 :\r
4662                 case LIST_UNIX_73 :\r
4663                 case LIST_UNIX_74 :\r
4664                 case LIST_UNIX_75 :\r
4665 // MELCOMはビットフラグになっている\r
4666 //              case LIST_MELCOM :\r
4667                 default:\r
4668                         /* offsはサイズの位置, offs=0はカラム4 */\r
4669                         offs = 0;\r
4670                         if((ListType == LIST_UNIX_12) ||\r
4671                            (ListType == LIST_UNIX_13) ||\r
4672                            (ListType == LIST_UNIX_15) ||\r
4673                            (ListType == LIST_UNIX_20) ||\r
4674                            (ListType == LIST_UNIX_21) ||\r
4675                            (ListType == LIST_UNIX_24))\r
4676                                 offs = -1;\r
4677 \r
4678                         if((ListType == LIST_UNIX_22) ||\r
4679                            (ListType == LIST_UNIX_23) ||\r
4680                            (ListType == LIST_UNIX_25) ||\r
4681                            (ListType == LIST_UNIX_50) ||\r
4682                            (ListType == LIST_UNIX_51) ||\r
4683                            (ListType == LIST_UNIX_54))\r
4684                                 offs = -2;\r
4685 \r
4686                         if((ListType == LIST_UNIX_60) ||\r
4687                            (ListType == LIST_UNIX_61) ||\r
4688                            (ListType == LIST_UNIX_64))\r
4689                                 offs = 2;\r
4690 \r
4691                         if((ListType == LIST_UNIX_62) ||\r
4692                            (ListType == LIST_UNIX_63) ||\r
4693                            (ListType == LIST_UNIX_65) ||\r
4694                            (ListType == LIST_UNIX_70) ||\r
4695                            (ListType == LIST_UNIX_71) ||\r
4696                            (ListType == LIST_UNIX_74))\r
4697                                 offs = 1;\r
4698 \r
4699                         /* offs2は時間(もしくは年)の位置 */\r
4700                         offs2 = 0;\r
4701                         if((ListType == LIST_UNIX_11) ||\r
4702                            (ListType == LIST_UNIX_13) ||\r
4703                            (ListType == LIST_UNIX_21) ||\r
4704                            (ListType == LIST_UNIX_23) ||\r
4705                            (ListType == LIST_UNIX_51) ||\r
4706                            (ListType == LIST_UNIX_61) ||\r
4707                            (ListType == LIST_UNIX_63) ||\r
4708                            (ListType == LIST_UNIX_71) ||\r
4709                            (ListType == LIST_UNIX_73))\r
4710                                 offs2 = -1;\r
4711 \r
4712                         /* offs3はオーナ名の位置 */\r
4713                         offs3 = 0;\r
4714                         if((ListType == LIST_UNIX_12) ||\r
4715                            (ListType == LIST_UNIX_13) ||\r
4716                            (ListType == LIST_UNIX_15) ||\r
4717                            (ListType == LIST_UNIX_22) ||\r
4718                            (ListType == LIST_UNIX_23) ||\r
4719                            (ListType == LIST_UNIX_25) ||\r
4720                            (ListType == LIST_UNIX_50) ||\r
4721                            (ListType == LIST_UNIX_51) ||\r
4722                            (ListType == LIST_UNIX_62) ||\r
4723                            (ListType == LIST_UNIX_63) ||\r
4724                            (ListType == LIST_UNIX_65) ||\r
4725                            (ListType == LIST_UNIX_72) ||\r
4726                            (ListType == LIST_UNIX_73) ||\r
4727                            (ListType == LIST_UNIX_75))\r
4728                                 offs3 = -1;\r
4729 \r
4730                         Flag2 = 0;\r
4731                         if((ListType == LIST_UNIX_14) ||\r
4732                            (ListType == LIST_UNIX_15) ||\r
4733                            (ListType == LIST_UNIX_24) ||\r
4734                            (ListType == LIST_UNIX_25) ||\r
4735                            (ListType == LIST_UNIX_54) ||\r
4736                            (ListType == LIST_UNIX_64) ||\r
4737                            (ListType == LIST_UNIX_65) ||\r
4738                            (ListType == LIST_UNIX_74) ||\r
4739                            (ListType == LIST_UNIX_75))\r
4740                                 Flag2 = 1;\r
4741 \r
4742                         *InfoExist |= (FINFO_DATE | FINFO_SIZE | FINFO_ATTR);\r
4743 \r
4744                         /* 属性 */\r
4745                         FindField(Str, Buf, 0, NO);\r
4746                         *Attr = AttrString2Value(Buf+1);\r
4747 \r
4748                         /* オーナ名 */\r
4749                         FindField(Str, Buf, 2+offs3, NO);\r
4750                         strncpy(Owner, Buf, OWNER_NAME_LEN);\r
4751 \r
4752                         /* サイズ */\r
4753                         FindField(Str, Buf, 4+offs, NO);\r
4754                         Pos = Buf;\r
4755                         if((*Pos != NUL) && (IsDigit(*Pos) == 0))\r
4756                         {\r
4757                                 Pos = strchr(Pos, NUL) - 1;\r
4758                                 for(; Pos > Buf; Pos--)\r
4759                                 {\r
4760                                         if(IsDigit(*Pos) == 0)\r
4761                                         {\r
4762                                                 Pos++;\r
4763                                                 break;\r
4764                                         }\r
4765                                 }\r
4766                         }\r
4767                         *Size = _atoi64(Pos);\r
4768 \r
4769                         if(Flag2 == 0)\r
4770                         {\r
4771                                 /* 時刻/日付 */\r
4772                                 GetLocalTime(&sTime);\r
4773                                 memcpy(&sTimeNow, &sTime, sizeof(SYSTEMTIME));\r
4774                                 sTime.wSecond = 0;\r
4775                                 sTime.wMilliseconds = 0;\r
4776 \r
4777                                 FindField(Str, Buf, 5+offs, NO);\r
4778                                 /* 日付が yy/mm/dd の場合に対応 */\r
4779                                 if(GetYearMonthDay(Buf, &sTime.wYear, &sTime.wMonth, &sTime.wDay) == FFFTP_SUCCESS)\r
4780                                 {\r
4781                                         sTime.wYear = Assume1900or2000(sTime.wYear);\r
4782 \r
4783                                         FindField(Str, Buf, 7+offs+offs2, NO);\r
4784                                         if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_SUCCESS)\r
4785                                                 *InfoExist |= FINFO_TIME;\r
4786                                 }\r
4787                                 else\r
4788                                 {\r
4789                                         GetMonth(Buf, &sTime.wMonth, &sTime.wDay);\r
4790                                         if(offs2 == 0)\r
4791                                         {\r
4792                                                 FindField(Str, Buf, 6+offs, NO);\r
4793                                                 sTime.wDay = atoi(Buf);\r
4794                                         }\r
4795 \r
4796                                         FindField(Str, Buf, 7+offs+offs2, NO);\r
4797                                         if(GetHourAndMinute(Buf, &sTime.wHour, &sTime.wMinute) == FFFTP_FAIL)\r
4798                                         {\r
4799                                                 sTime.wYear = atoi(Buf);\r
4800                                         }\r
4801                                         else\r
4802                                         {\r
4803                                                 *InfoExist |= FINFO_TIME;\r
4804 \r
4805                                                 /* 年がない */\r
4806                                                 /* 現在の日付から推定 */\r
4807                                                 // 恐らくホストとローカルの時刻が異なる場合の対処のようだがとりあえず無効にする\r
4808 //                                              if((sTimeNow.wMonth == 12) && (sTime.wMonth == 1))\r
4809 //                                                      sTime.wYear++;\r
4810 //                                              else if(sTimeNow.wMonth+1 == sTime.wMonth)\r
4811                                                 if(sTimeNow.wMonth+1 == sTime.wMonth)\r
4812                                                         /* nothing */;\r
4813                                                 else if(sTimeNow.wMonth < sTime.wMonth)\r
4814                                                         sTime.wYear--;\r
4815 \r
4816 \r
4817 //#################\r
4818                                                 /* 今年の今日以降のファイルは、実は去年のファイル */\r
4819                                                 if((sTime.wYear == sTimeNow.wYear) &&\r
4820                                                    ((sTime.wMonth > sTimeNow.wMonth) ||\r
4821                                                         ((sTime.wMonth == sTimeNow.wMonth) && (sTime.wDay > sTimeNow.wDay))))\r
4822                                                 {\r
4823                                                         sTime.wYear--;\r
4824                                                 }\r
4825                                         }\r
4826                                 }\r
4827                         }\r
4828                         else\r
4829                         {\r
4830                                 /* LIST_UNIX_?4, LIST_UNIX_?5 の時 */\r
4831                                 FindField(Str, Buf, 5+offs, NO);\r
4832                                 sTime.wYear = atoi(Buf);\r
4833                                 FindField(Str, Buf, 6+offs, NO);\r
4834                                 sTime.wMonth = atoi(Buf);\r
4835                                 FindField(Str, Buf, 7+offs, NO);\r
4836                                 sTime.wDay = atoi(Buf);\r
4837                                 sTime.wHour = 0;\r
4838                                 sTime.wMinute = 0;\r
4839                                 sTime.wSecond = 0;\r
4840                                 sTime.wMilliseconds = 0;\r
4841                         }\r
4842                         SystemTimeToFileTime(&sTime, Time);\r
4843                         SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4844 \r
4845                         /* 名前 */\r
4846                         if(FindField(Str, Fname, 8+offs+offs2, YES) == FFFTP_SUCCESS)\r
4847                         {\r
4848                                 Flag = 'B';\r
4849                                 if(OrgListType & LIST_MELCOM)\r
4850                                 {\r
4851                                         Flag = Fname[14];\r
4852                                         Fname[14] = NUL;\r
4853                                         RemoveTailingSpaces(Fname);\r
4854                                 }\r
4855                                 else\r
4856                                 {\r
4857                                         if((Pos = strstr(Fname, " -> ")) != NULL)\r
4858                                                 *Pos = NUL;\r
4859                                 }\r
4860 \r
4861                                 if(strchr("dl", *Str) != NULL)\r
4862                                 {\r
4863                                         // 0x5Cが含まれる文字列を扱えないバグ修正\r
4864 //                                      if((_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "/") == 0) ||\r
4865 //                                         (_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "\\") == 0))\r
4866 //                                      {\r
4867 //                                              *(Fname + strlen(Fname) - 1) = NUL;\r
4868 //                                      }\r
4869                                         Ret = NODE_DIR;\r
4870                                         if(*Str == 'l')\r
4871                                                 *Link = YES;\r
4872                                 }\r
4873                                 else if(strchr("-+f", *Str) != NULL)\r
4874                                         Ret = NODE_FILE;\r
4875 \r
4876                                 if((Ret == NODE_FILE) && (Flag != 'B'))\r
4877                                         Ret = NODE_NONE;\r
4878                         }\r
4879                         break;\r
4880 \r
4881                         // MLSD対応\r
4882                 case LIST_MLSD:\r
4883                         {\r
4884                                 int i = 0;\r
4885                                 char Tmp[FMAX_PATH + 1];\r
4886                                 char Name[FMAX_PATH + 1];\r
4887                                 char Value[FMAX_PATH + 1];\r
4888                                 while(FindField2(Str, Tmp, ';', i, NO) == FFFTP_SUCCESS)\r
4889                                 {\r
4890                                         if(i >= 1 && strncmp(Tmp, " ", 1) == 0)\r
4891                                                 strcpy(Fname, strstr(Str, "; ") + 2);\r
4892                                         else if(FindField2(Tmp, Name, '=', 0, NO) == FFFTP_SUCCESS && FindField2(Tmp, Value, '=', 1, NO) == FFFTP_SUCCESS)\r
4893                                         {\r
4894                                                 if(_stricmp(Name, "type") == 0)\r
4895                                                 {\r
4896                                                         if(_stricmp(Value, "dir") == 0)\r
4897                                                                 Ret = NODE_DIR;\r
4898                                                         else if(_stricmp(Value, "file") == 0)\r
4899                                                                 Ret = NODE_FILE;\r
4900                                                 }\r
4901                                                 else if(_stricmp(Name, "size") == 0)\r
4902                                                 {\r
4903                                                         *Size = _atoi64(Value);\r
4904                                                         *InfoExist |= FINFO_SIZE;\r
4905                                                 }\r
4906                                                 else if(_stricmp(Name, "modify") == 0)\r
4907                                                 {\r
4908                                                         sTime.wYear = atoi_n(Value, 4);\r
4909                                                         sTime.wMonth = atoi_n(Value + 4, 2);\r
4910                                                         sTime.wDay = atoi_n(Value + 6, 2);\r
4911                                                         sTime.wHour = atoi_n(Value + 8, 2);\r
4912                                                         sTime.wMinute = atoi_n(Value + 10, 2);\r
4913                                                         sTime.wSecond = atoi_n(Value + 12, 2);\r
4914                                                         sTime.wMilliseconds = 0;\r
4915                                                         SystemTimeToFileTime(&sTime, Time);\r
4916 //                                                      SpecificLocalFileTime2FileTime(Time, AskHostTimeZone());\r
4917                                                         *InfoExist |= FINFO_DATE | FINFO_TIME;\r
4918                                                 }\r
4919                                                 else if(_stricmp(Name, "UNIX.mode") == 0)\r
4920                                                 {\r
4921                                                         *Attr = strtol(Value, NULL, 16);\r
4922                                                         *InfoExist |= FINFO_ATTR;\r
4923                                                 }\r
4924                                                 else if(_stricmp(Name, "UNIX.owner") == 0)\r
4925                                                         strcpy(Owner, Value);\r
4926                                         }\r
4927                                         i++;\r
4928                                 }\r
4929                         }\r
4930                         break;\r
4931         }\r
4932 \r
4933         // UTF-8対応\r
4934 //      if((Ret != NODE_NONE) && (strlen(Fname) > 0))\r
4935         if(!(OrgListType & LIST_RAW_NAME) && (Ret != NODE_NONE) && (strlen(Fname) > 0))\r
4936         {\r
4937                 // UTF-8対応\r
4938 //              if(CheckSpecialDirName(Fname) == YES)\r
4939 //                      Ret = NODE_NONE;\r
4940 //              else\r
4941 //                      ChangeFnameRemote2Local(Fname, FMAX_PATH);\r
4942                 ChangeFnameRemote2Local(Fname, FMAX_PATH);\r
4943                 // UTF-8の冗長表現によるディレクトリトラバーサル対策\r
4944                 FixStringM(Fname, Fname);\r
4945                 // 0x5Cが含まれる文字列を扱えないバグ修正\r
4946                 if((_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "/") == 0)\r
4947                         || (_mbscmp(_mbsninc(Fname, _mbslen(Fname) - 1), "\\") == 0))\r
4948                         *(Fname + strlen(Fname) - 1) = NUL;\r
4949                 if(CheckSpecialDirName(Fname) == YES)\r
4950                         Ret = NODE_NONE;\r
4951                 // 文字コードが正しくないために長さが0になったファイル名は表示しない\r
4952                 if(strlen(Fname) == 0)\r
4953                         Ret = NODE_NONE;\r
4954         }\r
4955         return(Ret);\r
4956 }\r
4957 \r
4958 \r
4959 /*----- 指定の番号のフィールドを求める ----------------------------------------\r
4960 *\r
4961 *       Parameter\r
4962 *               char *Str : 文字列\r
4963 *               char *Buf : 文字列のコピー先\r
4964 *               int Num : フィールド番号\r
4965 *               int ToLast : 文字列の最後までコピー (YES/NO)\r
4966 *\r
4967 *       Return Value\r
4968 *               int ステータス\r
4969 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
4970 *----------------------------------------------------------------------------*/\r
4971 \r
4972 static int FindField(char *Str, char *Buf, int Num, int ToLast)\r
4973 {\r
4974         char *Pos;\r
4975         int Sts;\r
4976 \r
4977         Sts = FFFTP_FAIL;\r
4978         *Buf = NUL;\r
4979         if(Num >= 0)\r
4980         {\r
4981                 while(*Str == ' ')\r
4982                         Str++;\r
4983 \r
4984                 for(; Num > 0; Num--)\r
4985                 {\r
4986                         if((Str = strchr(Str, ' ')) != NULL)\r
4987                         {\r
4988                                 while(*Str == ' ')\r
4989                                 {\r
4990                                         if(*Str == NUL)\r
4991                                         {\r
4992                                                 Str = NULL;\r
4993                                                 break;\r
4994                                         }\r
4995                                         Str++;\r
4996                                 }\r
4997                         }\r
4998                         else\r
4999                                 break;\r
5000                 }\r
5001         }\r
5002 \r
5003         if(Str != NULL)\r
5004         {\r
5005                 if((ToLast == YES) || ((Pos = strchr(Str, ' ')) == NULL))\r
5006                         strcpy(Buf, Str);\r
5007                 else\r
5008                 {\r
5009                         strncpy(Buf, Str, Pos - Str);\r
5010                         *(Buf + (Pos - Str)) = NUL;\r
5011                 }\r
5012                 Sts = FFFTP_SUCCESS;\r
5013         }\r
5014         return(Sts);\r
5015 }\r
5016 \r
5017 \r
5018 // MLSD対応\r
5019 static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast)\r
5020 {\r
5021         char *Pos;\r
5022         int Sts;\r
5023 \r
5024         Sts = FFFTP_FAIL;\r
5025         *Buf = NUL;\r
5026         if(Num >= 0)\r
5027         {\r
5028                 while(*Str == Separator)\r
5029                         Str++;\r
5030 \r
5031                 for(; Num > 0; Num--)\r
5032                 {\r
5033                         if((Str = strchr(Str, Separator)) != NULL)\r
5034                         {\r
5035                                 while(*Str == Separator)\r
5036                                 {\r
5037                                         if(*Str == NUL)\r
5038                                         {\r
5039                                                 Str = NULL;\r
5040                                                 break;\r
5041                                         }\r
5042                                         Str++;\r
5043                                 }\r
5044                         }\r
5045                         else\r
5046                                 break;\r
5047                 }\r
5048         }\r
5049 \r
5050         if(Str != NULL)\r
5051         {\r
5052                 if((ToLast == YES) || ((Pos = strchr(Str, Separator)) == NULL))\r
5053                         strcpy(Buf, Str);\r
5054                 else\r
5055                 {\r
5056                         strncpy(Buf, Str, Pos - Str);\r
5057                         *(Buf + (Pos - Str)) = NUL;\r
5058                 }\r
5059                 Sts = FFFTP_SUCCESS;\r
5060         }\r
5061         return(Sts);\r
5062 }\r
5063 \r
5064 \r
5065 /*----- 文字列から月を求める --------------------------------------------------\r
5066 *\r
5067 *       Parameter\r
5068 *               char *Str : 文字列\r
5069 *               WORD *Month : 月 (0=月を表す文字列ではない)\r
5070 *               WORD *Day : 日 (0=日は含まれていない)\r
5071 *\r
5072 *       Return Value\r
5073 *               なし\r
5074 *----------------------------------------------------------------------------*/\r
5075 \r
5076 static void GetMonth(char *Str, WORD *Month, WORD *Day)\r
5077 {\r
5078         static const char DateStr[] = { "JanFebMarAprMayJunJulAugSepOctNovDec" };\r
5079         char *Pos;\r
5080 \r
5081         *Month = 0;\r
5082         *Day = 0;\r
5083 \r
5084         if(IsDigit(*Str) == 0)\r
5085         {\r
5086                 _strlwr(Str);\r
5087                 *Str = toupper(*Str);\r
5088                 if((Pos = strstr(DateStr, Str)) != NULL)\r
5089                         *Month = ((Pos - DateStr) / 3) + 1;\r
5090         }\r
5091         else\r
5092         {\r
5093                 /* 「10月」のような日付を返すものがある */\r
5094                 /* 漢字がJISの時のみSJISに変換 */\r
5095                 ConvAutoToSJIS(Str, KANJI_NOCNV);\r
5096 \r
5097                 Pos = Str;\r
5098                 while(*Pos != NUL)\r
5099                 {\r
5100                         if(!IsDigit(*Pos))\r
5101                         {\r
5102                                 // UTF-8対応\r
5103 //                              if((_mbsncmp(Pos, "月", 1) == 0) ||\r
5104 //                                 (memcmp(Pos, "\xB7\xEE", 2) == 0) || /* EUCの「月」 */\r
5105 //                                 (memcmp(Pos, "\xD4\xC2", 2) == 0))   /* GBコードの「月」 */\r
5106                                 if(memcmp(Pos, "\xE6\x9C\x88", 3) == 0 || memcmp(Pos, "\x8C\x8E", 2) == 0 || memcmp(Pos, "\xB7\xEE", 2) == 0 || memcmp(Pos, "\xD4\xC2", 2) == 0)\r
5107                                 {\r
5108                                         Pos += 2;\r
5109                                         *Month = atoi(Str);\r
5110                                         if((*Month < 1) || (*Month > 12))\r
5111                                                 *Month = 0;\r
5112                                         else\r
5113                                         {\r
5114                                                 /* 「10月11日」のように日がくっついている事がある */\r
5115                                                 if(*Pos != NUL)\r
5116                                                 {\r
5117                                                         *Day = atoi(Pos);\r
5118                                                         if((*Day < 1) || (*Day > 31))\r
5119                                                                 *Day = 0;\r
5120                                                 }\r
5121                                         }\r
5122                                 }\r
5123                                 else if(_mbsncmp(Pos, "/", 1) == 0)\r
5124                                 {\r
5125                                         /* 「10/」のような日付を返すものがある */\r
5126                                         Pos += 1;\r
5127                                         *Month = atoi(Str);\r
5128                                         if((*Month < 1) || (*Month > 12))\r
5129                                                 *Month = 0;\r
5130                                         else\r
5131                                         {\r
5132                                                 /* 「10/11」のように日がくっついている事がある */\r
5133                                                 if(*Pos != NUL)\r
5134                                                 {\r
5135                                                         *Day = atoi(Pos);\r
5136                                                         if((*Day < 1) || (*Day > 31))\r
5137                                                                 *Day = 0;\r
5138                                                 }\r
5139                                         }\r
5140                                 }\r
5141                                 break;\r
5142                         }\r
5143                         Pos++;\r
5144                 }\r
5145         }\r
5146         return;\r
5147 }\r
5148 \r
5149 \r
5150 /*----- 文字列から年月日を求める ----------------------------------------------\r
5151 *\r
5152 *       Parameter\r
5153 *               char *Str : 文字列\r
5154 *               WORD *Year : 年\r
5155 *               WORD *Month : 月\r
5156 *               WORD *Day : 日\r
5157 *\r
5158 *       Return Value\r
5159 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)\r
5160 *\r
5161 *       Note\r
5162 *               以下の形式をサポート\r
5163 *                       01/07/25\r
5164 *               FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0\r
5165 *----------------------------------------------------------------------------*/\r
5166 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day)\r
5167 {\r
5168         int Sts;\r
5169 \r
5170         Sts = FFFTP_FAIL;\r
5171         if(strlen(Str) == 8)\r
5172         {\r
5173                 if(IsDigit(Str[0]) && IsDigit(Str[1]) && !IsDigit(Str[2]) &&\r
5174                    IsDigit(Str[3]) && IsDigit(Str[4]) && !IsDigit(Str[5]) &&\r
5175                    IsDigit(Str[6]) && IsDigit(Str[7]))\r
5176                 {\r
5177                         *Year = atoi(&Str[0]);\r
5178                         *Month = atoi(&Str[3]);\r
5179                         *Day = atoi(&Str[6]);\r
5180                         Sts = FFFTP_SUCCESS;\r
5181                 }\r
5182         }\r
5183         return(Sts);\r
5184 }\r
5185 \r
5186 \r
5187 /*----- 文字列から時刻を取り出す ----------------------------------------------\r
5188 *\r
5189 *       Parameter\r
5190 *               char *Str : 文字列\r
5191 *               WORD *Hour : 時\r
5192 *               WORD *Minute : 分\r
5193 *\r
5194 *       Return Value\r
5195 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=時刻を表す文字ではない)\r
5196 *\r
5197 *       Note\r
5198 *               以下の形式をサポート\r
5199 *                       HH:MM\r
5200 *                       HH時MM分\r
5201 *               FFFTP_FAILを返す時は *Hour = 0; *Minute = 0\r
5202 *----------------------------------------------------------------------------*/\r
5203 \r
5204 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute)\r
5205 {\r
5206         int Ret;\r
5207         char *Pos;\r
5208 \r
5209         Ret = FFFTP_FAIL;\r
5210         if((_mbslen(Str) >= 3) && (isdigit(Str[0]) != 0))\r
5211         {\r
5212                 *Hour = atoi(Str);\r
5213                 if(*Hour <= 24)\r
5214                 {\r
5215                         if((Pos = _mbschr(Str, ':')) != NULL)\r
5216                         {\r
5217                                 Pos++;\r
5218                                 if(IsDigit(*Pos) != 0)\r
5219                                 {\r
5220                                         *Minute = atoi(Pos);\r
5221                                         if(*Minute < 60)\r
5222                                                 Ret = FFFTP_SUCCESS;\r
5223                                 }\r
5224                         }\r
5225                         else\r
5226                         {\r
5227                                 /* 漢字がJISの時のみSJISに変換 */\r
5228                                 ConvAutoToSJIS(Str, KANJI_NOCNV);\r
5229 \r
5230                                 Pos = Str;\r
5231                                 while(*Pos != NUL)\r
5232                                 {\r
5233                                         if(IsDigit(*Pos) == 0)\r
5234                                         {\r
5235                                                 // UTF-8対応\r
5236 //                                              if((_mbsncmp(Pos, "時", 1) == 0) ||\r
5237 //                                                 (memcmp(Pos, "\xBB\xFE", 2) == 0))   /* EUCの「時」 */\r
5238                                                 if(memcmp(Pos, "\xE6\x99\x82", 3) == 0 || memcmp(Pos, "\x8E\x9E", 2) == 0 || memcmp(Pos, "\xBB\xFE", 2) == 0)\r
5239                                                 {\r
5240                                                         Pos += 2;\r
5241                                                         if(*Pos != NUL)\r
5242                                                         {\r
5243                                                                 *Minute = atoi(Pos);\r
5244                                                                 if(*Minute < 60)\r
5245                                                                         Ret = FFFTP_SUCCESS;\r
5246                                                         }\r
5247                                                 }\r
5248                                                 break;\r
5249                                         }\r
5250                                         Pos++;\r
5251                                 }\r
5252                         }\r
5253                 }\r
5254         }\r
5255         else if((_stricmp(Str, "a:m") == 0) || (_stricmp(Str, "p:m") == 0))\r
5256         {\r
5257                 *Hour = 0;\r
5258                 *Minute = 0;\r
5259                 Ret = FFFTP_SUCCESS;\r
5260         }\r
5261 \r
5262         if(Ret == FFFTP_FAIL)\r
5263         {\r
5264                 *Hour = 0;\r
5265                 *Minute = 0;\r
5266         }\r
5267         return(Ret);\r
5268 }\r
5269 \r
5270 \r
5271 /*----- VAX VMSの日付文字列から日付を取り出す ---------------------------------\r
5272 *\r
5273 *       Parameter\r
5274 *               char *Str : 文字列\r
5275 *               WORD *Year : 年\r
5276 *               WORD *Month : 月\r
5277 *               WORD *Day : 日\r
5278 *\r
5279 *       Return Value\r
5280 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL=日付を表す文字ではない)\r
5281 *\r
5282 *       Note\r
5283 *               以下の形式をサポート\r
5284 *                       18-SEP-1998\r
5285 *               FFFTP_FAILを返す時は *Year = 0; *Month = 0; *Day = 0\r
5286 *----------------------------------------------------------------------------*/\r
5287 \r
5288 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day)\r
5289 {\r
5290         char *Pos;\r
5291         int Ret;\r
5292         WORD Tmp;\r
5293         char Buf[4];\r
5294 \r
5295         Ret = FFFTP_FAIL;\r
5296         *Day = atoi(Str);\r
5297         if((Pos = strchr(Str, '-')) != NULL)\r
5298         {\r
5299                 Pos++;\r
5300                 strncpy(Buf, Pos, 3);\r
5301                 Buf[3] = NUL;\r
5302                 GetMonth(Buf, Month, &Tmp);\r
5303                 if((Pos = strchr(Pos, '-')) != NULL)\r
5304                 {\r
5305                         Pos++;\r
5306                         *Year = atoi(Pos);\r
5307                         Ret = FFFTP_SUCCESS;\r
5308                 }\r
5309         }\r
5310 \r
5311         if(Ret == FFFTP_FAIL)\r
5312         {\r
5313                 *Year = 0;\r
5314                 *Month = 0;\r
5315                 *Day = 0;\r
5316         }\r
5317         return(Ret);\r
5318 }\r
5319 \r
5320 \r
5321 /*----- 1900年代か2000年代かを決める ------------------------------------------\r
5322 *\r
5323 *       Parameter\r
5324 *               int Year : 年(2桁)\r
5325 *\r
5326 *       Return Value\r
5327 *               int 年\r
5328 *----------------------------------------------------------------------------*/\r
5329 \r
5330 int Assume1900or2000(int Year)\r
5331 {\r
5332         if(Year >= 60)\r
5333                 Year += 1900;\r
5334         else\r
5335                 Year += 2000;\r
5336         return(Year);\r
5337 }\r
5338 \r
5339 \r
5340 \r
5341 /*----- "."や".."かどうかを返す -----------------------------------------------\r
5342 *\r
5343 *       Parameter\r
5344 *               char *Fname : ファイル名\r
5345 *\r
5346 *       Return Value\r
5347 *               int ステータス (YES="."か".."のどちらか/NO)\r
5348 *----------------------------------------------------------------------------*/\r
5349 \r
5350 static int CheckSpecialDirName(char *Fname)\r
5351 {\r
5352         int Sts;\r
5353 \r
5354         Sts = NO;\r
5355         if((strcmp(Fname, ".") == 0) || (strcmp(Fname, "..") == 0))\r
5356                 Sts = YES;\r
5357 \r
5358         return(Sts);\r
5359 }\r
5360 \r
5361 \r
5362 /*----- フィルタに指定されたファイル名かどうかを返す --------------------------\r
5363 *\r
5364 *       Parameter\r
5365 *               char Fname : ファイル名\r
5366 *               int Type : ファイルのタイプ (NODE_xxx)\r
5367 *\r
5368 *       Return Value\r
5369 *               int ステータス\r
5370 *                       YES/NO=表示しない\r
5371 *\r
5372 *       Note\r
5373 *               フィルタ文字列は以下の形式\r
5374 *                       *.txt;*.log\r
5375 *----------------------------------------------------------------------------*/\r
5376 \r
5377 static int AskFilterStr(char *Fname, int Type)\r
5378 {\r
5379         int Ret;\r
5380         char *Tbl;\r
5381         char *Pos;\r
5382         char Tmp[FILTER_EXT_LEN+1];\r
5383 \r
5384         Tbl = FilterStr;\r
5385         Ret = YES;\r
5386         if((strlen(Tbl) > 0) && (Type == NODE_FILE))\r
5387         {\r
5388                 Ret = NO;\r
5389                 while((Tbl != NULL) && (*Tbl != NUL))\r
5390                 {\r
5391                         while(*Tbl == ';')\r
5392                                 Tbl++;\r
5393                         if(*Tbl == NUL)\r
5394                                 break;\r
5395 \r
5396                         strcpy(Tmp, Tbl);\r
5397                         if((Pos = strchr(Tmp, ';')) != NULL)\r
5398                                 *Pos = NUL;\r
5399 \r
5400                         if(CheckFname(Fname, Tmp) == FFFTP_SUCCESS)\r
5401                         {\r
5402                                 Ret = YES;\r
5403                                 break;\r
5404                         }\r
5405 \r
5406                         Tbl = strchr(Tbl, ';');\r
5407                 }\r
5408         }\r
5409         return(Ret);\r
5410 }\r
5411 \r
5412 \r
5413 /*----- フィルタを設定する ----------------------------------------------------\r
5414 *\r
5415 *       Parameter\r
5416 *               なし\r
5417 *\r
5418 *       Return Value\r
5419 *               なし\r
5420 *----------------------------------------------------------------------------*/\r
5421 \r
5422 void SetFilter(int *CancelCheckWork)\r
5423 {\r
5424         if(DialogBox(GetFtpInst(), MAKEINTRESOURCE(filter_dlg), GetMainHwnd(), FilterWndProc) == YES)\r
5425         {\r
5426                 DispWindowTitle();\r
5427                 GetLocalDirForWnd();\r
5428                 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);\r
5429         }\r
5430         return;\r
5431 }\r
5432 \r
5433 \r
5434 /*----- フィルタ入力ダイアログのコールバック ----------------------------------\r
5435 *\r
5436 *       Parameter\r
5437 *               HWND hDlg : ウインドウハンドル\r
5438 *               UINT message : メッセージ番号\r
5439 *               WPARAM wParam : メッセージの WPARAM 引数\r
5440 *               LPARAM lParam : メッセージの LPARAM 引数\r
5441 *\r
5442 *       Return Value\r
5443 *               BOOL TRUE/FALSE\r
5444 *----------------------------------------------------------------------------*/\r
5445 \r
5446 // 64ビット対応\r
5447 //static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
5448 static INT_PTR CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
5449 {\r
5450         switch (iMessage)\r
5451         {\r
5452                 case WM_INITDIALOG :\r
5453                         SendDlgItemMessage(hDlg, FILTER_STR, EM_LIMITTEXT, FILTER_EXT_LEN+1, 0);\r
5454                         SendDlgItemMessage(hDlg, FILTER_STR, WM_SETTEXT, 0, (LPARAM)FilterStr);\r
5455                         return(TRUE);\r
5456 \r
5457                 case WM_COMMAND :\r
5458                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
5459                         {\r
5460                                 case IDOK :\r
5461                                         SendDlgItemMessage(hDlg, FILTER_STR, WM_GETTEXT, FILTER_EXT_LEN, (LPARAM)FilterStr);\r
5462                                         EndDialog(hDlg, YES);\r
5463                                         break;\r
5464 \r
5465                                 case IDCANCEL :\r
5466                                         EndDialog(hDlg, NO);\r
5467                                         break;\r
5468 \r
5469                                 case FILTER_NOR :\r
5470                                         strcpy(FilterStr, "*");\r
5471                                         EndDialog(hDlg, YES);\r
5472                                         break;\r
5473 \r
5474                                 case IDHELP :\r
5475                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000021);\r
5476                                         break;\r
5477                         }\r
5478             return(TRUE);\r
5479         }\r
5480         return(FALSE);\r
5481 }\r
5482 \r
5483 \r
5484 \r
5485 \r
5486 \r
5487 static int atoi_n(const char *Str, int Len)\r
5488 {\r
5489         char *Tmp;\r
5490         int Ret;\r
5491 \r
5492         Ret = 0;\r
5493         if((Tmp = malloc(Len+1)) != NULL)\r
5494         {\r
5495                 memset(Tmp, 0, Len+1);\r
5496                 strncpy(Tmp, Str, Len);\r
5497                 Ret = atoi(Tmp);\r
5498                 free(Tmp);\r
5499         }\r
5500         return(Ret);\r
5501 }\r
5502 \r
5503 \r
5504 \r
5505 \r
5506 // UTF-8対応\r
5507 // ファイル一覧から漢字コードを推測\r
5508 // 優先度はUTF-8、Shift_JIS、EUC、JISの順\r
5509 int AnalyzeNameKanjiCode(int Num)\r
5510 {\r
5511         char Str[FMAX_PATH+1];\r
5512         char Name[FMAX_PATH+1];\r
5513         LONGLONG Size;\r
5514         FILETIME Time;\r
5515         int Attr;\r
5516         FILE *fd;\r
5517         int Node;\r
5518         int ListType;\r
5519         char Owner[OWNER_NAME_LEN+1];\r
5520         int Link;\r
5521         int InfoExist;\r
5522         int NameKanjiCode;\r
5523         int Point;\r
5524         int PointSJIS;\r
5525         int PointJIS;\r
5526         int PointEUC;\r
5527         int PointUTF8N;\r
5528         char* p;\r
5529 \r
5530         NameKanjiCode = KANJI_AUTO;\r
5531         Point = 0;\r
5532         PointSJIS = 0;\r
5533         PointJIS = 0;\r
5534         PointEUC = 0;\r
5535         PointUTF8N = 0;\r
5536         MakeCacheFileName(Num, Str);\r
5537         if((fd = fopen(Str, "rb")) != NULL)\r
5538         {\r
5539                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
5540                 {\r
5541                         if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
5542                         {\r
5543                                 strcpy(Name, "");\r
5544                                 Node = ResolvFileInfo(Str, ListType | LIST_RAW_NAME, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
5545                                 p = Name;\r
5546                                 while(*p != '\0')\r
5547                                 {\r
5548                                         if(*p & 0x80)\r
5549                                         {\r
5550                                                 p = NULL;\r
5551                                                 break;\r
5552                                         }\r
5553                                         p++;\r
5554                                 }\r
5555                                 if(!p)\r
5556                                 {\r
5557                                         if(!CheckStringM(Name))\r
5558                                                 PointUTF8N++;\r
5559                                         else\r
5560                                         {\r
5561                                                 switch(CheckKanjiCode(Name, strlen(Name), KANJI_SJIS))\r
5562                                                 {\r
5563                                                 case KANJI_SJIS:\r
5564                                                         PointSJIS++;\r
5565                                                         break;\r
5566                                                 case KANJI_JIS:\r
5567                                                         PointJIS++;\r
5568                                                         break;\r
5569                                                 case KANJI_EUC:\r
5570                                                         PointEUC++;\r
5571                                                         break;\r
5572                                                 }\r
5573                                         }\r
5574                                 }\r
5575                         }\r
5576                 }\r
5577                 fclose(fd);\r
5578         }\r
5579         if(PointJIS >= Point)\r
5580         {\r
5581                 NameKanjiCode = KANJI_JIS;\r
5582                 Point = PointJIS;\r
5583         }\r
5584         if(PointEUC >= Point)\r
5585         {\r
5586                 NameKanjiCode = KANJI_EUC;\r
5587                 Point = PointEUC;\r
5588         }\r
5589         if(PointSJIS >= Point)\r
5590         {\r
5591                 NameKanjiCode = KANJI_SJIS;\r
5592                 Point = PointSJIS;\r
5593         }\r
5594         if(PointUTF8N >= Point)\r
5595         {\r
5596                 NameKanjiCode = KANJI_UTF8N;\r
5597                 Point = PointUTF8N;\r
5598         }\r
5599         return NameKanjiCode;\r
5600 }\r
5601 \r