OSDN Git Service

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