OSDN Git Service

Fix bugs process protection.
[ffftp/ffftp.git] / filelist.c
1 /*=============================================================================\r
2 *\r
3 *                                                               ファイル一覧\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 // UTF-8対応\r
31 //#define _WIN32_WINNT  0x400\r
32 \r
33 #define STRICT\r
34 #include <windows.h>\r
35 #include <stdio.h>\r
36 #include <stdlib.h>\r
37 #include <string.h>\r
38 #include <ctype.h>\r
39 #include <time.h>\r
40 #include <mbstring.h>\r
41 #include <malloc.h>\r
42 #include <windowsx.h>\r
43 #include <commctrl.h>\r
44 #include <sys/types.h>\r
45 #include <sys/stat.h>\r
46 #include <direct.h>\r
47 \r
48 #include "common.h"\r
49 #include "resource.h"\r
50 \r
51 #include <htmlhelp.h>\r
52 #include "helpid.h"\r
53 \r
54 #include <shlobj.h>\r
55 #include "OleDragDrop.h"\r
56 #include "common.h"\r
57 \r
58 // UTF-8対応\r
59 #undef __MBSWRAPPER_H__\r
60 #include "mbswrapper.h"\r
61 \r
62 #define BUF_SIZE                256\r
63 #define CF_CNT 2\r
64 #define WM_DRAGDROP             (WM_APP + 100)\r
65 #define WM_GETDATA              (WM_APP + 101)\r
66 #define WM_DRAGOVER             (WM_APP + 102)\r
67 \r
68 \r
69 /*===== ファイルリストのリスト用ストラクチャ =====*/\r
70 \r
71 typedef struct {\r
72         FILELIST *Top;                  /* ファイルリストの先頭 */\r
73         int Files;                              /* ファイルの数 */\r
74 } FLISTANCHOR;\r
75 \r
76 /*===== プロトタイプ =====*/\r
77 \r
78 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
79 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
80 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
81 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win);\r
82 static void EraseDispFileList(FLISTANCHOR *Anchor);\r
83 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor);\r
84 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist);\r
85 static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
86 static void DispListList(FILELIST *Pos, char *Title);\r
87 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
88 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork);\r
89 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List);\r
90 static int GetListOneLine(char *Buf, int Max, FILE *Fd);\r
91 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir);\r
92 static void MakeLocalTree(char *Path, FILELIST **Base);\r
93 static void AddFileList(FILELIST *Pkt, FILELIST **Base);\r
94 static int AnalizeFileInfo(char *Str);\r
95 static int CheckUnixType(char *Str, char *Tmp, int Add1, int Add2, int Day);\r
96 static int CheckHHMMformat(char *Str);\r
97 static int CheckYYMMDDformat(char *Str, char Sym, int Dig3);\r
98 static int CheckYYYYMMDDformat(char *Str, char Sym);\r
99 static int ResolvFileInfo(char *Str, int ListType, char *Fname, LONGLONG *Size, FILETIME *Time, int *Attr, char *Owner, int *Link, int *InfoExist);\r
100 static int FindField(char *Str, char *Buf, int Num, int ToLast);\r
101 // MLSD対応\r
102 static int FindField2(char *Str, char *Buf, char Separator, int Num, int ToLast);\r
103 static void GetMonth(char *Str, WORD *Month, WORD *Day);\r
104 static int GetYearMonthDay(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
105 static int GetHourAndMinute(char *Str, WORD *Hour, WORD *Minute);\r
106 static int GetVMSdate(char *Str, WORD *Year, WORD *Month, WORD *Day);\r
107 static int CheckSpecialDirName(char *Fname);\r
108 static int AskFilterStr(char *Fname, int Type);\r
109 static BOOL CALLBACK FilterWndProc(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
110 static int atoi_n(const char *Str, int Len);\r
111 \r
112 /*===== 外部参照 =====*/\r
113 \r
114 extern int SepaWidth;\r
115 extern int RemoteWidth;\r
116 extern int ListHeight;\r
117 extern char FilterStr[FILTER_EXT_LEN+1];\r
118 extern HWND hHelpWin;\r
119 \r
120 /* 設定値 */\r
121 extern int LocalWidth;\r
122 extern int LocalTabWidth[4];\r
123 extern int RemoteTabWidth[6];\r
124 extern char UserMailAdrs[USER_MAIL_LEN+1];\r
125 extern HFONT ListFont;\r
126 extern int ListType;\r
127 extern int FindMode;\r
128 extern int DotFile;\r
129 extern int DispIgnoreHide;\r
130 extern int DispDrives;\r
131 extern int MoveMode;\r
132 \r
133 /*===== ローカルなワーク =====*/\r
134 \r
135 static HWND hWndListLocal = NULL;\r
136 static HWND hWndListRemote = NULL;\r
137 \r
138 static WNDPROC LocalProcPtr;\r
139 static WNDPROC RemoteProcPtr;\r
140 \r
141 static HIMAGELIST ListImg = NULL;\r
142 \r
143 static char FindStr[40+1] = { "*" };            /* 検索文字列 */\r
144 static int IgnoreNew = NO;\r
145 static int IgnoreOld = NO;\r
146 static int IgnoreExist = NO;\r
147 \r
148 static int Dragging = NO;\r
149 \r
150 static int StratusMode;                 /* 0=ファイル, 1=ディレクトリ, 2=リンク */\r
151 \r
152 \r
153 // リモートファイルリスト (2007.9.3 yutaka)\r
154 static FILELIST *remoteFileListBase;\r
155 static FILELIST *remoteFileListBaseNoExpand;\r
156 static char remoteFileDir[FMAX_PATH + 1];\r
157 \r
158 \r
159 /*----- ファイルリストウインドウを作成する ------------------------------------\r
160 *\r
161 *       Parameter\r
162 *               HWND hWnd : 親ウインドウのウインドウハンドル\r
163 *               HINSTANCE hInst : インスタンスハンドル\r
164 *\r
165 *       Return Value\r
166 *               int ステータス\r
167 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
168 *----------------------------------------------------------------------------*/\r
169 \r
170 int MakeListWin(HWND hWnd, HINSTANCE hInst)\r
171 {\r
172         int Sts;\r
173         LV_COLUMN LvCol;\r
174         long Tmp;\r
175 \r
176         /*===== ローカル側のリストビュー =====*/\r
177 \r
178         hWndListLocal = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
179                         WC_LISTVIEWA, NULL,\r
180                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
181                         0, TOOLWIN_HEIGHT*2, LocalWidth, ListHeight,\r
182                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
183 \r
184         if(hWndListLocal != NULL)\r
185         {\r
186                 LocalProcPtr = (WNDPROC)SetWindowLong(hWndListLocal, GWL_WNDPROC, (LONG)LocalWndProc);\r
187 \r
188             Tmp = SendMessage(hWndListLocal, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
189             Tmp |= LVS_EX_FULLROWSELECT;\r
190             SendMessage(hWndListLocal, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
191 \r
192                 if(ListFont != NULL)\r
193                         SendMessage(hWndListLocal, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
194 \r
195                 ListImg = ImageList_LoadBitmap(hInst, MAKEINTRESOURCE(dirattr_bmp), 16, 9, RGB(255,0,0));\r
196                 SendMessage(hWndListLocal, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
197                 ShowWindow(hWndListLocal, SW_SHOW);\r
198 \r
199                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
200                 LvCol.cx = LocalTabWidth[0];\r
201                 LvCol.pszText = MSGJPN038;\r
202                 LvCol.iSubItem = 0;\r
203                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
204 \r
205                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
206                 LvCol.cx = LocalTabWidth[1];\r
207                 LvCol.pszText = MSGJPN039;\r
208                 LvCol.iSubItem = 1;\r
209                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
210 \r
211                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
212                 LvCol.fmt = LVCFMT_RIGHT;\r
213                 LvCol.cx = LocalTabWidth[2];\r
214                 LvCol.pszText = MSGJPN040;\r
215                 LvCol.iSubItem = 2;\r
216                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
217 \r
218                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
219                 LvCol.cx = LocalTabWidth[3];\r
220                 LvCol.pszText = MSGJPN041;\r
221                 LvCol.iSubItem = 3;\r
222                 SendMessage(hWndListLocal, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
223         }\r
224 \r
225         /*===== ホスト側のリストビュー =====*/\r
226 \r
227         hWndListRemote = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
228                         WC_LISTVIEWA, NULL,\r
229                         WS_CHILD | /*WS_BORDER | */LVS_REPORT | LVS_SHOWSELALWAYS,\r
230                         LocalWidth + SepaWidth, TOOLWIN_HEIGHT*2, RemoteWidth, ListHeight,\r
231                         GetMainHwnd(), (HMENU)1500, hInst, NULL);\r
232 \r
233         if(hWndListRemote != NULL)\r
234         {\r
235                 RemoteProcPtr = (WNDPROC)SetWindowLong(hWndListRemote, GWL_WNDPROC, (LONG)RemoteWndProc);\r
236 \r
237             Tmp = SendMessage(hWndListRemote, LVM_GETEXTENDEDLISTVIEWSTYLE, 0, 0);\r
238             Tmp |= LVS_EX_FULLROWSELECT;\r
239             SendMessage(hWndListRemote, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, (LPARAM)Tmp);\r
240 \r
241                 if(ListFont != NULL)\r
242                         SendMessage(hWndListRemote, WM_SETFONT, (WPARAM)ListFont, MAKELPARAM(TRUE, 0));\r
243 \r
244                 SendMessage(hWndListRemote, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)ListImg);\r
245                 ShowWindow(hWndListRemote, SW_SHOW);\r
246 \r
247                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
248                 LvCol.cx = RemoteTabWidth[0];\r
249                 LvCol.pszText = MSGJPN042;\r
250                 LvCol.iSubItem = 0;\r
251                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 0, (LPARAM)&LvCol);\r
252 \r
253                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
254                 LvCol.cx = RemoteTabWidth[1];\r
255                 LvCol.pszText = MSGJPN043;\r
256                 LvCol.iSubItem = 1;\r
257                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 1, (LPARAM)&LvCol);\r
258 \r
259                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM | LVCF_FMT;\r
260                 LvCol.fmt = LVCFMT_RIGHT;\r
261                 LvCol.cx = RemoteTabWidth[2];\r
262                 LvCol.pszText = MSGJPN044;\r
263                 LvCol.iSubItem = 2;\r
264                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 2, (LPARAM)&LvCol);\r
265 \r
266                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
267                 LvCol.cx = RemoteTabWidth[3];\r
268                 LvCol.pszText = MSGJPN045;\r
269                 LvCol.iSubItem = 3;\r
270                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 3, (LPARAM)&LvCol);\r
271 \r
272                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
273                 LvCol.cx = RemoteTabWidth[4];\r
274                 LvCol.pszText = MSGJPN046;\r
275                 LvCol.iSubItem = 4;\r
276                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 4, (LPARAM)&LvCol);\r
277 \r
278                 LvCol.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;\r
279                 LvCol.cx = RemoteTabWidth[5];\r
280                 LvCol.pszText = MSGJPN047;\r
281                 LvCol.iSubItem = 5;\r
282                 SendMessage(hWndListRemote, LVM_INSERTCOLUMN, 5, (LPARAM)&LvCol);\r
283         }\r
284 \r
285         Sts = FFFTP_SUCCESS;\r
286         if((hWndListLocal == NULL) ||\r
287            (hWndListRemote == NULL))\r
288         {\r
289                 Sts = FFFTP_FAIL;\r
290         }\r
291         return(Sts);\r
292 }\r
293 \r
294 \r
295 /*----- ファイルリストウインドウを削除 ----------------------------------------\r
296 *\r
297 *       Parameter\r
298 *               なし\r
299 *\r
300 *       Return Value\r
301 *               なし\r
302 *----------------------------------------------------------------------------*/\r
303 \r
304 void DeleteListWin(void)\r
305 {\r
306 //      if(ListImg != NULL)\r
307 //              ImageList_Destroy(ListImg);\r
308         if(hWndListLocal != NULL)\r
309                 DestroyWindow(hWndListLocal);\r
310         if(hWndListRemote != NULL)\r
311                 DestroyWindow(hWndListRemote);\r
312         return;\r
313 }\r
314 \r
315 \r
316 /*----- ローカル側のファイルリストのウインドウハンドルを返す ------------------\r
317 *\r
318 *       Parameter\r
319 *               なし\r
320 *\r
321 *       Return Value\r
322 *               HWND ウインドウハンドル\r
323 *----------------------------------------------------------------------------*/\r
324 \r
325 HWND GetLocalHwnd(void)\r
326 {\r
327         return(hWndListLocal);\r
328 }\r
329 \r
330 \r
331 /*----- ホスト側のファイルリストのウインドウハンドルを返す --------------------\r
332 *\r
333 *       Parameter\r
334 *               なし\r
335 *\r
336 *       Return Value\r
337 *               HWND ウインドウハンドル\r
338 *----------------------------------------------------------------------------*/\r
339 \r
340 HWND GetRemoteHwnd(void)\r
341 {\r
342         return(hWndListRemote);\r
343 }\r
344 \r
345 \r
346 /*----- ローカル側のファイルリストウインドウのメッセージ処理 ------------------\r
347 *\r
348 *       Parameter\r
349 *               HWND hWnd : ウインドウハンドル\r
350 *               UINT message  : メッセージ番号\r
351 *               WPARAM wParam : メッセージの WPARAM 引数\r
352 *               LPARAM lParam : メッセージの LPARAM 引数\r
353 *\r
354 *       Return Value\r
355 *               メッセージに対応する戻り値\r
356 *----------------------------------------------------------------------------*/\r
357 \r
358 static LRESULT CALLBACK LocalWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
359 {\r
360         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
361 }\r
362 \r
363 \r
364 /*----- ホスト側のファイルリストウインドウのメッセージ処理 --------------------\r
365 *\r
366 *       Parameter\r
367 *               HWND hWnd : ウインドウハンドル\r
368 *               UINT message  : メッセージ番号\r
369 *               WPARAM wParam : メッセージの WPARAM 引数\r
370 *               LPARAM lParam : メッセージの LPARAM 引数\r
371 *\r
372 *       Return Value\r
373 *               メッセージに対応する戻り値\r
374 *----------------------------------------------------------------------------*/\r
375 \r
376 static LRESULT CALLBACK RemoteWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
377 {\r
378         return(FileListCommonWndProc(hWnd, message, wParam, lParam));\r
379 }\r
380 \r
381 \r
382 // ダイアログプロシージャ\r
383 static BOOL CALLBACK doOleDlgProc(HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)\r
384 {\r
385 #define TIMER_ID     (100)      // 作成するタイマの識別ID\r
386 #define TIMER_ELAPSE (100)       // WM_TIMERの発生間隔\r
387         MSG message;\r
388 \r
389         switch( msg ){\r
390         case WM_INITDIALOG:  // ダイアログボックスが作成されたとき\r
391                 SetTimer( hDlg, TIMER_ID, 0, NULL);\r
392                 return TRUE;\r
393 \r
394         case WM_TIMER:\r
395                 ShowWindow(hDlg, SW_HIDE);  // ダイアログは隠す\r
396 \r
397                 if (wp != TIMER_ID)\r
398                         break;\r
399 \r
400                 if (PeekMessage(&message, NULL, 0, 0, PM_REMOVE)) {\r
401                                 TranslateMessage(&message);\r
402                                 DispatchMessage(&message);\r
403 \r
404                 } else {\r
405                         if (AskTransferNow() == NO) {\r
406                                 EndDialog( hDlg, 0 );\r
407                                 return TRUE;\r
408                         }\r
409                 }\r
410 \r
411                 SetTimer( hDlg, TIMER_ID, TIMER_ELAPSE, NULL );\r
412                 return TRUE;\r
413 \r
414         case WM_COMMAND:     // ダイアログボックス内の何かが選択されたとき\r
415                 switch( LOWORD( wp ) ){\r
416 //              case IDOK:       // 「OK」ボタンが選択された\r
417                 case IDCANCEL:   // 「キャンセル」ボタンが選択された\r
418                         // ダイアログボックスを消す\r
419                         EndDialog( hDlg, 0 );\r
420                         break;\r
421                 }\r
422                 return TRUE;\r
423         }\r
424 \r
425         return FALSE;  // DefWindowProc()ではなく、FALSEを返すこと!\r
426 #undef TIMER_ID     \r
427 #undef TIMER_ELAPSE \r
428 }\r
429 \r
430 \r
431 static void doTransferRemoteFile(void)\r
432 {\r
433         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
434         int CancelFlg = NO;\r
435         char LocDir[FMAX_PATH+1];\r
436         char TmpDir[FMAX_PATH+1];\r
437         char buf[32];\r
438         int i;\r
439         DWORD pid;\r
440 \r
441         // すでにリモートから転送済みなら何もしない。(2007.9.3 yutaka)\r
442         if (remoteFileListBase != NULL)\r
443                 return;\r
444 \r
445         FileListBase = NULL;\r
446         MakeSelectedFileList(WIN_REMOTE, YES, NO, &FileListBase, &CancelFlg);\r
447         FileListBaseNoExpand = NULL;\r
448         MakeSelectedFileList(WIN_REMOTE, NO, NO, &FileListBaseNoExpand, &CancelFlg);\r
449 \r
450         // set temporary folder\r
451         AskLocalCurDir(LocDir, FMAX_PATH);\r
452 \r
453         // アプリを多重起動してもコンフリクトしないように、テンポラリフォルダ名にプロセスID\r
454         // を付加する。(2007.9.13 yutaka)\r
455         GetTempPath(sizeof(TmpDir), TmpDir);\r
456         pid = GetCurrentProcessId();\r
457         _snprintf_s(buf, sizeof(buf), _TRUNCATE, "ffftp%d", pid);\r
458         strncat_s(TmpDir, sizeof(TmpDir), buf, _TRUNCATE);\r
459         _mkdir(TmpDir);\r
460 #if 0\r
461         if (TmpDir[strlen(TmpDir) - 1] == '\\') {\r
462                 TmpDir[strlen(TmpDir) - 1] = '\0';\r
463         }\r
464 #endif\r
465 \r
466         // 既存のファイルを削除する\r
467         for (pf = FileListBase ; pf ; pf = pf->Next) {\r
468                 char fn[FMAX_PATH+1];\r
469 \r
470                 strncpy_s(fn, sizeof(fn), TmpDir, _TRUNCATE);\r
471                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
472                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
473 \r
474                 remove(fn);\r
475         }\r
476 \r
477         // ダウンロード先をテンポラリに設定\r
478         SetLocalDirHist(TmpDir);\r
479 \r
480         // FFFTPにダウンロード要求を出し、ダウンロードの完了を待つ。\r
481         PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
482 \r
483         for (i = 0 ; i < 10 ; i++) {\r
484                 MSG msg;\r
485 \r
486                 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {\r
487                         TranslateMessage(&msg);\r
488                         DispatchMessage(&msg);\r
489 \r
490                 } else {\r
491                         // 転送スレッドが動き出したら抜ける。\r
492                         if (AskTransferNow() == YES)\r
493                                 break;\r
494                 }\r
495 \r
496                 Sleep(10);\r
497         }\r
498 \r
499         // OLE D&D中にメインウィンドウをユーザに操作させると、おかしくなるので、\r
500         // 隠しモーダルダイアログを作る。\r
501         // (2007.9.11 yutaka)\r
502         DialogBox(GetFtpInst(), MAKEINTRESOURCE(IDD_OLEDRAG), GetMainHwnd(), (DLGPROC)doOleDlgProc);\r
503 \r
504         // ダウンロード先を元に戻す\r
505         SetLocalDirHist(LocDir);\r
506         SetCurrentDirAsDirHist();\r
507 \r
508         remoteFileListBase = FileListBase;  // あとでフリーすること\r
509         remoteFileListBaseNoExpand = FileListBaseNoExpand;  // あとでフリーすること\r
510         strncpy_s(remoteFileDir, sizeof(remoteFileDir), TmpDir, _TRUNCATE);\r
511 \r
512 #if 0\r
513         // add temporary list\r
514         if (remoteFileListBase != NULL) {\r
515                 FILELIST *pf = remoteFileListBase;\r
516                 char fn[FMAX_PATH + 1];\r
517                 while (pf) {\r
518                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
519                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
520                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
521                         AddTempFileList(fn);\r
522                         pf = pf->Next;\r
523                 }\r
524         }\r
525 #endif\r
526 }\r
527 \r
528 \r
529 int isDirectory(char *fn)\r
530 {\r
531         struct _stat buf;\r
532 \r
533         if (_stat(fn, &buf) == 0) {\r
534                 if (buf.st_mode & _S_IFDIR) { // is directory\r
535                         return 1;\r
536                 }\r
537         }\r
538         return 0;\r
539 }\r
540 \r
541 // テンポラリのファイルおよびフォルダを削除する。\r
542 void doDeleteRemoteFile(void)\r
543 {\r
544         if (remoteFileListBase != NULL) {\r
545 #if 0\r
546                 int dirs = 0;\r
547                 int i, count;\r
548                 FILELIST *pf = remoteFileListBase;\r
549                 char fn[FMAX_PATH + 1];\r
550                 while (pf) {\r
551                         strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
552                         strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
553                         strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
554                         if (isDirectory(fn)) {\r
555                                 dirs++;\r
556                         } else {\r
557                                 remove(fn);\r
558                         }\r
559                         pf = pf->Next;\r
560                 }\r
561 \r
562                 count = 0;\r
563                 for (i = 0 ; i < 1000 ; i++) {\r
564                         pf = remoteFileListBase;\r
565                         while (pf) {\r
566                                 strncpy_s(fn, sizeof(fn), remoteFileDir, _TRUNCATE);\r
567                                 strncat_s(fn, sizeof(fn), "\\", _TRUNCATE);\r
568                                 strncat_s(fn, sizeof(fn), pf->File, _TRUNCATE);\r
569                                 if (isDirectory(fn)) {\r
570                                         if (_rmdir(fn) == 0) { // ディレクトリを消せたらカウントアップ\r
571                                                 count++;\r
572                                                 if (count >= dirs)  // すべて消せたら終わり\r
573                                                         goto skip;\r
574                                         }\r
575                                 }\r
576                                 pf = pf->Next;\r
577                         }\r
578                 }\r
579 skip:\r
580                 _rmdir(remoteFileDir);  // 自分で作ったディレクトリも消す\r
581 #else\r
582                 SHFILEOPSTRUCT FileOp = { NULL, FO_DELETE, remoteFileDir, NULL, \r
583                         FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI, \r
584                         FALSE, NULL, NULL };    \r
585                 SHFileOperation(&FileOp);\r
586 #endif\r
587 \r
588                 DeleteFileList(&remoteFileListBase);\r
589                 remoteFileListBase = NULL;\r
590         }\r
591 \r
592         if (remoteFileListBaseNoExpand != NULL) {\r
593                 DeleteFileList(&remoteFileListBaseNoExpand);\r
594                 remoteFileListBaseNoExpand = NULL;\r
595         }\r
596 }\r
597 \r
598 \r
599 // yutaka\r
600 // cf. http://www.nakka.com/lib/\r
601 /* ドロップファイルの作成 */\r
602 static HDROP APIPRIVATE CreateDropFileMem(char **FileName,int cnt,BOOL fWide)\r
603 {\r
604         HDROP hDrop;\r
605         LPDROPFILES lpDropFile;\r
606         wchar_t wbuf[BUF_SIZE];\r
607         int flen = 0;\r
608         int i;\r
609         \r
610         if(fWide == TRUE){\r
611                 /* ワイドキャラ */\r
612                 for(i = 0;i < cnt;i++){\r
613                         // UTF-8対応\r
614 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
615 //                      flen += (wcslen(wbuf) + 1) * sizeof(wchar_t);\r
616                         flen += sizeof(wchar_t) * MtoW(NULL, 0, FileName[i], -1);\r
617                 }\r
618                 flen++;\r
619         }else{\r
620                 /* マルチバイト */\r
621                 for(i = 0;i < cnt;i++){\r
622                         // UTF-8対応\r
623 //                      flen += lstrlen(FileName[i]) + 1;\r
624                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
625                         flen += sizeof(char) * WtoA(NULL, 0, wbuf, -1);\r
626                 }\r
627         }\r
628 \r
629         hDrop = (HDROP)GlobalAlloc(GHND,sizeof(DROPFILES) + flen + 1);\r
630         if (hDrop == NULL){\r
631                 return NULL;\r
632         }\r
633 \r
634         lpDropFile = (LPDROPFILES) GlobalLock(hDrop);\r
635         lpDropFile->pFiles = sizeof(DROPFILES);         /* ファイル名のリストまでのオフセット */\r
636         lpDropFile->pt.x = 0;\r
637         lpDropFile->pt.y = 0;\r
638         lpDropFile->fNC = FALSE;\r
639         lpDropFile->fWide = fWide;                                      /* ワイドキャラの場合は TRUE */\r
640 \r
641         /* 構造体の後ろにファイル名のリストをコピーする。(ファイル名\0ファイル名\0ファイル名\0\0) */\r
642         if(fWide == TRUE){\r
643                 /* ワイドキャラ */\r
644                 wchar_t *buf;\r
645 \r
646                 buf = (wchar_t *)(&lpDropFile[1]);\r
647                 for(i = 0;i < cnt;i++){\r
648                         // UTF-8対応\r
649 //                      MultiByteToWideChar(CP_ACP,0,FileName[i],-1,wbuf,BUF_SIZE);\r
650 //                      wcscpy(buf,wbuf);\r
651 //                      buf += wcslen(wbuf) + 1;\r
652                         buf += MtoW(buf, BUF_SIZE, FileName[i], -1);\r
653                 }\r
654         }else{\r
655                 /* マルチバイト */\r
656                 char *buf;\r
657 \r
658                 buf = (char *)(&lpDropFile[1]);\r
659                 for(i = 0;i < cnt;i++){\r
660                         // UTF-8対応\r
661 //                      lstrcpy(buf,FileName[i]);\r
662 //                      buf += lstrlen(FileName[i]) + 1;\r
663                         MtoW(wbuf, BUF_SIZE, FileName[i], -1);\r
664                         buf += WtoA(buf, BUF_SIZE, wbuf, -1);\r
665                 }\r
666         }\r
667 \r
668         GlobalUnlock(hDrop);\r
669         return(hDrop);\r
670 }\r
671 \r
672 \r
673 // OLE D&Dを開始する \r
674 // (2007.8.30 yutaka)\r
675 static void doDragDrop(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
676 {\r
677         UINT cf[CF_CNT];\r
678         POINT pt;\r
679         int ret;\r
680 \r
681         // テンポラリをきれいにする (2007.9.3 yutaka)\r
682         doDeleteRemoteFile();\r
683 \r
684         /* ドラッグ&ドロップの開始 */\r
685         cf[0] = CF_HDROP;\r
686         cf[1] = CF_HDROP;       /* ファイル */\r
687         if((ret = OLE_IDropSource_Start(hWnd,WM_GETDATA, WM_DRAGOVER, cf,1,DROPEFFECT_COPY | DROPEFFECT_MOVE | DROPEFFECT_LINK)) == DROPEFFECT_MOVE){\r
688         }\r
689 \r
690         // ドロップ先のアプリに WM_LBUTTONUP を飛ばす。\r
691         GetCursorPos(&pt);\r
692         ScreenToClient(hWnd, &pt);\r
693         PostMessage(hWnd,WM_LBUTTONUP,0,MAKELPARAM(pt.x,pt.y));\r
694 }\r
695 \r
696 \r
697 \r
698 /*----- ファイル一覧ウインドウの共通メッセージ処理 ----------------------------\r
699 *\r
700 *       Parameter\r
701 *               HWND hWnd : ウインドウハンドル\r
702 *               UINT message  : メッセージ番号\r
703 *               WPARAM wParam : メッセージの WPARAM 引数\r
704 *               LPARAM lParam : メッセージの LPARAM 引数\r
705 *\r
706 *       Return Value\r
707 *               メッセージに対応する戻り値\r
708 *----------------------------------------------------------------------------*/\r
709 \r
710 static LRESULT FileListCommonWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\r
711 {\r
712         POINT Point;\r
713         HWND hWndPnt;\r
714         HWND hWndParent;\r
715         static HCURSOR hCsrDrg;\r
716         static HCURSOR hCsrNoDrg;\r
717         static POINT DragPoint;\r
718         static HWND hWndDragStart;\r
719         static int RemoteDropFileIndex = -1;\r
720         int Win;\r
721         HWND hWndDst;\r
722         WNDPROC ProcPtr;\r
723         HWND hWndHistEdit;\r
724 \r
725         Win = WIN_LOCAL;\r
726         hWndDst = hWndListRemote;\r
727         ProcPtr = LocalProcPtr;\r
728         hWndHistEdit = GetLocalHistEditHwnd();\r
729         if(hWnd == hWndListRemote)\r
730         {\r
731                 Win = WIN_REMOTE;\r
732                 hWndDst = hWndListLocal;\r
733                 ProcPtr = RemoteProcPtr;\r
734                 hWndHistEdit = GetRemoteHistEditHwnd();\r
735         }\r
736 \r
737         switch (message)\r
738         {\r
739         case WM_SYSKEYDOWN:\r
740                         if (wParam == 'D') {    // Alt+D\r
741                                 SetFocus(hWndHistEdit);\r
742                                 break;\r
743                         }\r
744                         EraseListViewTips();\r
745                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
746 \r
747         case WM_KEYDOWN:\r
748                         if(wParam == 0x09)\r
749                         {\r
750                                 SetFocus(hWndDst);\r
751                                 break;\r
752                         }\r
753                         EraseListViewTips();\r
754                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
755 \r
756                 case WM_SETFOCUS :\r
757                         SetFocusHwnd(hWnd);\r
758                         MakeButtonsFocus();\r
759                         DispCurrentWindow(Win);\r
760                         DispSelectedSpace();\r
761                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
762 \r
763                 case WM_KILLFOCUS :\r
764                         EraseListViewTips();\r
765                         MakeButtonsFocus();\r
766                         DispCurrentWindow(-1);\r
767                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
768 \r
769                 case WM_DROPFILES :\r
770                         // ドラッグ中は処理しない。ドラッグ後にWM_LBUTTONDOWNが飛んでくるため、そこで処理する。\r
771                         if (Dragging == YES) \r
772                                 return (FALSE);\r
773 \r
774                         if(hWnd == hWndListRemote)\r
775                         {\r
776                                 if(AskConnecting() == YES)\r
777                                         UpLoadDragProc(wParam);\r
778                         }\r
779                         else if(hWnd == hWndListLocal)\r
780                         {\r
781                                 ChangeDirDropFileProc(wParam);\r
782                         }\r
783                         break;\r
784 \r
785                 case WM_LBUTTONDOWN :\r
786                         EraseListViewTips();\r
787                         SetFocus(hWnd);\r
788                         DragPoint.x = LOWORD(lParam);\r
789                         DragPoint.y = HIWORD(lParam);\r
790                         hWndDragStart = hWnd;\r
791                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
792                         break;\r
793 \r
794                 case WM_LBUTTONUP :\r
795                         if(Dragging == YES)\r
796                         {\r
797                                 Dragging = NO;\r
798                                 ReleaseCapture();\r
799                                 hCsrDrg = LoadCursor(NULL, IDC_ARROW);\r
800                                 SetCursor(hCsrDrg);\r
801 \r
802                                 Point.x = (long)(short)LOWORD(lParam);\r
803                                 Point.y = (long)(short)HIWORD(lParam);\r
804                                 ClientToScreen(hWnd, &Point);\r
805                                 hWndPnt = WindowFromPoint(Point);\r
806                                 if(hWndPnt == hWndDst)  // local <-> remote \r
807                                 {\r
808                                         if(hWndPnt == hWndListRemote) {\r
809                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_UPLOAD, 0), 0);\r
810                                         } else if(hWndPnt == hWndListLocal) {\r
811                                                 PostMessage(GetMainHwnd(), WM_COMMAND, MAKEWPARAM(MENU_DOWNLOAD, 0), 0);\r
812                                         }\r
813                                 } else { // 同一ウィンドウ内の場合 (yutaka)\r
814                                         if (hWndDragStart == hWndListRemote && hWndPnt == hWndListRemote) {\r
815                                                 // remote <-> remoteの場合は、サーバでのファイルの移動を行う。(2007.9.5 yutaka)\r
816                                                 if (RemoteDropFileIndex != -1) {\r
817                                                         ListView_SetItemState(hWnd, RemoteDropFileIndex, 0, LVIS_DROPHILITED);\r
818                                                         MoveRemoteFileProc(RemoteDropFileIndex);\r
819                                                 }\r
820 \r
821                                         }\r
822 \r
823                                 }\r
824                         }\r
825                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
826 \r
827                 case WM_DRAGDROP:  \r
828                         // OLE D&Dを開始する (yutaka)\r
829                         doDragDrop(hWnd, message, wParam, lParam);\r
830                         return (TRUE);\r
831                         break;\r
832  \r
833                 case WM_GETDATA:  // ファイルのパスをD&D先のアプリへ返す (yutaka)\r
834                         switch(wParam)\r
835                         {\r
836                         case CF_HDROP:          /* ファイル */\r
837                                 {\r
838                                         OSVERSIONINFO os_info;\r
839                                         BOOL NTFlag = FALSE;\r
840                                         char **FileNameList;\r
841                                         int filelen;\r
842                                         int i, j, filenum = 0;\r
843  \r
844                                         FILELIST *FileListBase, *FileListBaseNoExpand, *pf;\r
845                                         int CancelFlg = NO;\r
846                                         char LocDir[FMAX_PATH+1];\r
847                                         char *PathDir;\r
848  \r
849                                         // 変数が未初期化のバグ修正\r
850                                         FileListBaseNoExpand = NULL;\r
851                                         // ローカル側で選ばれているファイルをFileListBaseに登録\r
852                                         if (hWndDragStart == hWndListLocal) {\r
853                                                 AskLocalCurDir(LocDir, FMAX_PATH);\r
854                                                 PathDir = LocDir;\r
855  \r
856                                                 FileListBase = NULL;\r
857                                                 MakeSelectedFileList(WIN_LOCAL, YES, NO, &FileListBase, &CancelFlg);                    \r
858  \r
859                                         } else if (hWndDragStart == hWndListRemote) {\r
860                                                 GetCursorPos(&Point);\r
861                                                 hWndPnt = WindowFromPoint(Point);\r
862                                                 hWndParent = GetParent(hWndPnt);\r
863                                                 if (hWndPnt == hWndListRemote || hWndPnt == hWndListLocal ||\r
864                                                         hWndParent == hWndListRemote || hWndParent == hWndListLocal) {\r
865                                                         FileListBase = NULL;\r
866  \r
867                                                 } else {\r
868                                                         // 選択されているリモートファイルのリストアップ\r
869                                                         // このタイミングでリモートからローカルの一時フォルダへダウンロードする\r
870                                                         // (2007.8.31 yutaka)\r
871                                                         doTransferRemoteFile();\r
872                                                         PathDir = remoteFileDir;\r
873                                                         FileListBase = remoteFileListBase;\r
874                                                         FileListBaseNoExpand = remoteFileListBaseNoExpand;\r
875                                                 }\r
876  \r
877                                         } \r
878  \r
879                                         pf = FileListBaseNoExpand;\r
880                                         for (filenum = 0; pf ; filenum++) {\r
881                                                 pf = pf->Next;\r
882                                         }\r
883                                         // ファイルが未選択の場合は何もしない。(yutaka)\r
884                                         if (filenum <= 0) {\r
885                                                 *((HANDLE *)lParam) = NULL;\r
886                                                 return (FALSE);\r
887                                         }\r
888                                         \r
889                                         /* ファイル名の配列を作成する */\r
890                                         // TODO: GlobalAllocが返すのはメモリポインタではなくハンドルだが実際は同じ値\r
891                                         FileNameList = (char **)GlobalAlloc(GPTR,sizeof(char *) * filenum);\r
892                                         if(FileNameList == NULL){\r
893                                                 abort();\r
894                                         }\r
895                                         pf = FileListBaseNoExpand;\r
896                                         for (j = 0; pf ; j++) {\r
897                                                 filelen = strlen(PathDir) + 1 + strlen(pf->File) + 1;\r
898                                                 FileNameList[j] = (char *)GlobalAlloc(GPTR, filelen);\r
899                                                 strncpy_s(FileNameList[j], filelen, PathDir, _TRUNCATE);\r
900                                                 strncat_s(FileNameList[j], filelen, "\\", _TRUNCATE);\r
901                                                 strncat_s(FileNameList[j], filelen, pf->File, _TRUNCATE);\r
902                                                 pf = pf->Next;\r
903 #if 0\r
904                                                 if (FileListBase->Node == NODE_DIR) { \r
905                                                         // フォルダを掴んだ場合はそれ以降展開しない\r
906                                                         filenum = 1;\r
907                                                         break;\r
908                                                 }\r
909 #endif\r
910                                         }\r
911                                         \r
912                                         os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);\r
913                                         GetVersionEx(&os_info);\r
914                                         if(os_info.dwPlatformId == VER_PLATFORM_WIN32_NT){\r
915                                                 NTFlag = TRUE;\r
916                                         }\r
917  \r
918                                         /* ドロップファイルリストの作成 */\r
919                                         /* NTの場合はUNICODEになるようにする */\r
920                                         *((HANDLE *)lParam) = CreateDropFileMem(FileNameList, filenum, NTFlag);\r
921  \r
922                                         /* ファイル名の配列を解放する */\r
923                                         for (i = 0; i < filenum ; i++) {\r
924                                                 GlobalFree(FileNameList[i]);\r
925                                         }\r
926                                         GlobalFree(FileNameList);\r
927  \r
928                                         if (hWndDragStart == hWndListLocal) {\r
929                                                 DeleteFileList(&FileListBase);\r
930                                         } else {\r
931                                                 // あとでファイル削除してフリーする\r
932                                         }\r
933  \r
934                                         return (TRUE);\r
935                                 }\r
936                                 break;\r
937  \r
938                         default:\r
939                                 *((HANDLE *)lParam) = NULL;\r
940                                 break;\r
941                         }\r
942  \r
943                         break;\r
944 \r
945                 case WM_DRAGOVER:\r
946                         {\r
947                                 LVHITTESTINFO hi;\r
948                                 int Node, index;\r
949                                 static int prev_index = -1;\r
950 \r
951                                 // 同一ウィンドウ内でのD&Dはリモート側のみ\r
952                                 if (Win != WIN_REMOTE)\r
953                                         break;\r
954 \r
955                                 if(MoveMode == MOVE_DISABLE)\r
956                                         break;\r
957 \r
958                                 memset(&hi, 0, sizeof(hi));\r
959 \r
960                                 GetCursorPos(&Point);\r
961                                 hWndPnt = WindowFromPoint(Point);\r
962                                 ScreenToClient(hWnd, &Point);\r
963 \r
964                                 hi.pt = Point;\r
965 \r
966                                 // 以前の選択を消す\r
967                                 ListView_SetItemState(hWnd, prev_index, 0, LVIS_DROPHILITED);\r
968                                 RemoteDropFileIndex = -1;\r
969 \r
970                                 if ((hWndPnt == hWndListRemote) && (ListView_HitTest(hWnd, &hi) != -1)) {\r
971                                         if (hi.flags == LVHT_ONITEMLABEL) { // The position is over a list-view item's text.\r
972                                         \r
973                                                 index = hi.iItem;\r
974                                                 prev_index = index;\r
975                                                 Node = GetNodeType(Win, index);\r
976                                                 if (Node == NODE_DIR) {\r
977                                                         ListView_SetItemState(hWnd, index, LVIS_DROPHILITED, LVIS_DROPHILITED);\r
978                                                         RemoteDropFileIndex = index;\r
979                                                 }\r
980                                         }\r
981                                 } \r
982 \r
983                         }\r
984                         break;\r
985 \r
986                 case WM_RBUTTONDOWN :\r
987                         /* ここでファイルを選ぶ */\r
988                         CallWindowProc(ProcPtr, hWnd, message, wParam, lParam);\r
989 \r
990                         EraseListViewTips();\r
991                         SetFocus(hWnd);\r
992                         if(hWnd == hWndListRemote)\r
993                                 RemoteRbuttonMenu(0);\r
994                         else if(hWnd == hWndListLocal)\r
995                                 LocalRbuttonMenu(0);\r
996                         break;\r
997 \r
998                 case WM_LBUTTONDBLCLK :\r
999                         DoubleClickProc(Win, NO, -1);\r
1000                         break;\r
1001 \r
1002                 case WM_MOUSEMOVE :\r
1003                         if(wParam == MK_LBUTTON)\r
1004                         {\r
1005                                 if((Dragging == NO) && \r
1006                                    (hWnd == hWndDragStart) &&\r
1007                                    (AskConnecting() == YES) &&\r
1008                                    (SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0) > 0) &&\r
1009                                    ((abs((short)LOWORD(lParam) - DragPoint.x) > 5) ||\r
1010                                         (abs((short)HIWORD(lParam) - DragPoint.y) > 5)))\r
1011                                 {\r
1012                                         SetCapture(hWnd);\r
1013                                         Dragging = YES;\r
1014                                         hCsrDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(drag_csr));\r
1015                                         hCsrNoDrg = LoadCursor(GetFtpInst(), MAKEINTRESOURCE(nodrop_csr));\r
1016                                         SetCursor(hCsrDrg);\r
1017                                 }\r
1018                                 else if(Dragging == YES)\r
1019                                 {\r
1020                                         Point.x = (long)(short)LOWORD(lParam);\r
1021                                         Point.y = (long)(short)HIWORD(lParam);\r
1022                                         ClientToScreen(hWnd, &Point);\r
1023                                         hWndPnt = WindowFromPoint(Point);\r
1024                                         if((hWndPnt == hWndListRemote) || (hWndPnt == hWndListLocal))\r
1025                                                 SetCursor(hCsrDrg);\r
1026                                         else {\r
1027                                                 // マウスポインタの×表示をやめる (yutaka)\r
1028 #if 0\r
1029                                                 SetCursor(hCsrNoDrg);\r
1030 #endif\r
1031                                         }\r
1032 \r
1033                                         // OLE D&Dの開始を指示する\r
1034                                         PostMessage(hWnd, WM_DRAGDROP, MAKEWPARAM(wParam, lParam), 0);\r
1035 \r
1036                                 }\r
1037                                 else\r
1038                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1039                         }\r
1040                         else\r
1041                         {\r
1042                                 CheckTipsDisplay(hWnd, lParam);\r
1043                                 return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1044                         }\r
1045                         break;\r
1046 \r
1047                 case WM_MOUSEWHEEL :\r
1048                         if(Dragging == NO)\r
1049                         {\r
1050                 short zDelta = (short)HIWORD(wParam);\r
1051 \r
1052                                 EraseListViewTips();\r
1053                                 Point.x = (short)LOWORD(lParam);\r
1054                                 Point.y = (short)HIWORD(lParam);\r
1055                                 hWndPnt = WindowFromPoint(Point);\r
1056 \r
1057                                 if((wParam & MAKEWPARAM(MK_SHIFT, 0)) && \r
1058                                    ((hWndPnt == hWndListRemote) ||\r
1059                                         (hWndPnt == hWndListLocal) || \r
1060                                         (hWndPnt == GetTaskWnd())))\r
1061                                 {\r
1062                                         PostMessage(hWndPnt, WM_VSCROLL, zDelta > 0 ? MAKEWPARAM(SB_PAGEUP, 0) : MAKEWPARAM(SB_PAGEDOWN, 0), 0);\r
1063 //                                      PostMessage(hWndPnt, WM_VSCROLL, MAKEWPARAM(SB_ENDSCROLL, 0), 0);\r
1064                                 }\r
1065                                 else if(hWndPnt == hWnd)\r
1066                                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1067                                 else if((hWndPnt == hWndDst) || (hWndPnt == GetTaskWnd()))\r
1068                                         PostMessage(hWndPnt, message, wParam, lParam);\r
1069                         }\r
1070                         break;\r
1071 \r
1072                 default :\r
1073                         return(CallWindowProc(ProcPtr, hWnd, message, wParam, lParam));\r
1074         }\r
1075     return(0L);\r
1076 }\r
1077 \r
1078 \r
1079 /*----- ファイルリストのタブ幅を取得する --------------------------------------\r
1080 *\r
1081 *       Parameter\r
1082 *               なし\r
1083 *\r
1084 *       Return Value\r
1085 *               なし\r
1086 *----------------------------------------------------------------------------*/\r
1087 \r
1088 void GetListTabWidth(void)\r
1089 {\r
1090         LV_COLUMN LvCol;\r
1091         int i;\r
1092 \r
1093         for(i = 0; i <= 3; i++)\r
1094         {\r
1095                 LvCol.mask = LVCF_WIDTH;\r
1096                 if(SendMessage(hWndListLocal, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1097                         LocalTabWidth[i] = LvCol.cx;\r
1098         }\r
1099 \r
1100         for(i = 0; i <= 5; i++)\r
1101         {\r
1102                 LvCol.mask = LVCF_WIDTH;\r
1103                 if(SendMessage(hWndListRemote, LVM_GETCOLUMN, i, (LPARAM)&LvCol) == TRUE)\r
1104                         RemoteTabWidth[i] = LvCol.cx;\r
1105         }\r
1106         return;\r
1107 }\r
1108 \r
1109 \r
1110 /*----- ファイル一覧方法にしたがってリストビューを設定する --------------------\r
1111 *\r
1112 *       Parameter\r
1113 *               なし\r
1114 *\r
1115 *       Return Value\r
1116 *               なし\r
1117 *----------------------------------------------------------------------------*/\r
1118 \r
1119 void SetListViewType(void)\r
1120 {\r
1121         long lStyle;\r
1122 \r
1123         switch(ListType)\r
1124         {\r
1125                 case LVS_LIST :\r
1126                         lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1127                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1128                         lStyle |= LVS_LIST;\r
1129                         SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1130 \r
1131                         lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1132                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1133                         lStyle |= LVS_LIST;\r
1134                         SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1135                         break;\r
1136 \r
1137                 default :\r
1138                         lStyle = GetWindowLong(GetLocalHwnd(), GWL_STYLE);\r
1139                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1140                         lStyle |= LVS_REPORT;\r
1141                         SetWindowLong(GetLocalHwnd(), GWL_STYLE, lStyle);\r
1142 \r
1143                         lStyle = GetWindowLong(GetRemoteHwnd(), GWL_STYLE);\r
1144                         lStyle &= ~(LVS_REPORT | LVS_LIST);\r
1145                         lStyle |= LVS_REPORT;\r
1146                         SetWindowLong(GetRemoteHwnd(), GWL_STYLE, lStyle);\r
1147                         break;\r
1148         }\r
1149         return;\r
1150 }\r
1151 \r
1152 \r
1153 /*----- ホスト側のファイル一覧ウインドウにファイル名をセット ------------------\r
1154 *\r
1155 *       Parameter\r
1156 *               int Mode : キャッシュモード (CACHE_xxx)\r
1157 *\r
1158 *       Return Value\r
1159 *               なし\r
1160 *----------------------------------------------------------------------------*/\r
1161 \r
1162 void GetRemoteDirForWnd(int Mode, int *CancelCheckWork)\r
1163 {\r
1164         FILE *fd;\r
1165         LONGLONG Size;\r
1166         char Str[FMAX_PATH+1];\r
1167         char Buf[FMAX_PATH+1];\r
1168         FILETIME Time;\r
1169         int Attr;\r
1170         int Type;\r
1171         int ListType;\r
1172         int Num;\r
1173         FLISTANCHOR Anchor;\r
1174         char Owner[OWNER_NAME_LEN+1];\r
1175         int Link;\r
1176         int InfoExist;\r
1177 \r
1178 //#pragma aaa\r
1179 //DoPrintf("===== GetRemoteDirForWnd");\r
1180 \r
1181         Anchor.Top = NULL;\r
1182         Anchor.Files = 0;\r
1183 \r
1184         if(AskConnecting() == YES)\r
1185         {\r
1186 //              SetCursor(LoadCursor(NULL, IDC_WAIT));\r
1187                 DisableUserOpe();\r
1188 \r
1189                 AskRemoteCurDir(Buf, FMAX_PATH);\r
1190                 SetRemoteDirHist(Buf);\r
1191 \r
1192                 Type = FTP_COMPLETE;\r
1193                 if(Mode != CACHE_LASTREAD)\r
1194                 {\r
1195 \r
1196                         if((Num = AskCached(Buf)) == -1)\r
1197                         {\r
1198                                 Num = AskFreeCache();\r
1199                                 Mode = CACHE_REFRESH;\r
1200                         }\r
1201 \r
1202                         if(Mode == CACHE_REFRESH)\r
1203                         {\r
1204                                 if((Type = DoDirListCmdSkt("", "", Num, CancelCheckWork)) == FTP_COMPLETE)\r
1205                                         SetCache(Num, Buf);\r
1206                                 else\r
1207                                         ClearCache(Num);\r
1208                         }\r
1209                 }\r
1210                 else\r
1211                         Num = AskCurrentFileListNum();\r
1212 \r
1213                 if(Type == FTP_COMPLETE)\r
1214                 {\r
1215                         SetCurrentFileListNum(Num);\r
1216                         MakeCacheFileName(Num, Buf);\r
1217                         if((fd = fopen(Buf, "rb"))!=NULL)\r
1218                         {\r
1219                                 ListType = LIST_UNKNOWN;\r
1220 \r
1221                                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
1222                                 {\r
1223                                         if((ListType = AnalizeFileInfo(Str)) != LIST_UNKNOWN)\r
1224                                         {\r
1225                                                 if((Type = ResolvFileInfo(Str, ListType, Buf, &Size, &Time, &Attr, Owner, &Link, &InfoExist)) != NODE_NONE)\r
1226                                                 {\r
1227                                                         if(AskFilterStr(Buf, Type) == YES)\r
1228                                                         {\r
1229                                                                 if((DotFile == YES) || (Buf[0] != '.'))\r
1230                                                                 {\r
1231                                                                         AddDispFileList(&Anchor, Buf, &Time, Size, Attr, Type, Link, Owner, InfoExist, WIN_REMOTE);\r
1232                                                                 }\r
1233                                                         }\r
1234                                                 }\r
1235                                         }\r
1236                                 }\r
1237                                 fclose(fd);\r
1238 \r
1239                                 DispFileList2View(GetRemoteHwnd(), &Anchor);\r
1240                                 EraseDispFileList(&Anchor);\r
1241 \r
1242                                 // 先頭のアイテムを選択\r
1243                                 ListView_SetItemState(GetRemoteHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1244                         }\r
1245                         else\r
1246                         {\r
1247                                 SetTaskMsg(MSGJPN048);\r
1248                                 SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1249                         }\r
1250                 }\r
1251                 else\r
1252                 {\r
1253 #if defined(HAVE_OPENVMS)\r
1254                         /* OpenVMSの場合空ディレクトリ移動の時に出るので、メッセージだけ出さない\r
1255                          * ようにする(VIEWはクリアして良い) */\r
1256                         if (AskHostType() != HTYPE_VMS)\r
1257 #endif\r
1258                         SetTaskMsg(MSGJPN049);\r
1259                         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
1260                 }\r
1261 \r
1262 //              SetCursor(LoadCursor(NULL, IDC_ARROW));\r
1263                 EnableUserOpe();\r
1264 \r
1265         }\r
1266 \r
1267 //#pragma aaa\r
1268 //DoPrintf("===== GetRemoteDirForWnd Done");\r
1269 \r
1270         return;\r
1271 }\r
1272 \r
1273 \r
1274 /*----- ローカル側のファイル一覧ウインドウにファイル名をセット ----------------\r
1275 *\r
1276 *       Parameter\r
1277 *               なし\r
1278 *\r
1279 *       Return Value\r
1280 *               なし\r
1281 *----------------------------------------------------------------------------*/\r
1282 \r
1283 void GetLocalDirForWnd(void)\r
1284 {\r
1285         HANDLE fHnd;\r
1286         WIN32_FIND_DATA Find;\r
1287         char Scan[FMAX_PATH+1];\r
1288         char *Pos;\r
1289         char Buf[10];\r
1290         FILETIME Time;\r
1291         FLISTANCHOR Anchor;\r
1292         DWORD NoDrives;\r
1293         int Tmp;\r
1294 \r
1295         Anchor.Top = NULL;\r
1296         Anchor.Files = 0;\r
1297 \r
1298         DoLocalPWD(Scan);\r
1299         SetLocalDirHist(Scan);\r
1300         DispLocalFreeSpace(Scan);\r
1301 \r
1302         /* ディレクトリ/ファイル */\r
1303 \r
1304         SetYenTail(Scan);\r
1305         strcat(Scan, "*");\r
1306         if((fHnd = FindFirstFileAttr(Scan, &Find, DispIgnoreHide)) != INVALID_HANDLE_VALUE)\r
1307         {\r
1308                 do\r
1309                 {\r
1310                         if((strcmp(Find.cFileName, ".") != 0) &&\r
1311                            (strcmp(Find.cFileName, "..") != 0))\r
1312                         {\r
1313                                 if((DotFile == YES) || (Find.cFileName[0] != '.'))\r
1314                                 {\r
1315                                         if(Find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)\r
1316                                                 AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_DIR, NO, "", FINFO_ALL, WIN_LOCAL);\r
1317                                         else\r
1318                                         {\r
1319                                                 if(AskFilterStr(Find.cFileName, NODE_FILE) == YES)\r
1320                                                 {\r
1321                                                         AddDispFileList(&Anchor, Find.cFileName, &Find.ftLastWriteTime, MakeLongLong(Find.nFileSizeHigh, Find.nFileSizeLow), 0, NODE_FILE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1322                                                 }\r
1323                                         }\r
1324                                 }\r
1325                         }\r
1326                 }\r
1327                 while(FindNextFileAttr(fHnd, &Find, DispIgnoreHide) == TRUE);\r
1328                 FindClose(fHnd);\r
1329         }\r
1330 \r
1331         /* ドライブ */\r
1332         if(DispDrives)\r
1333         {\r
1334                 GetLogicalDriveStrings(FMAX_PATH, Scan);\r
1335                 NoDrives = LoadHideDriveListRegistory();\r
1336 \r
1337                 Pos = Scan;\r
1338                 while(*Pos != NUL)\r
1339                 {\r
1340                         Tmp = toupper(*Pos) - 'A';\r
1341                         if((NoDrives & (0x00000001 << Tmp)) == 0)\r
1342                         {\r
1343                                 sprintf(Buf, "%s", Pos);\r
1344                                 memset(&Time, 0, sizeof(FILETIME));\r
1345                                 AddDispFileList(&Anchor, Buf, &Time, 0, 0, NODE_DRIVE, NO, "", FINFO_ALL, WIN_LOCAL);\r
1346                         }\r
1347                         Pos = strchr(Pos, NUL) + 1;\r
1348                 }\r
1349         }\r
1350 \r
1351         DispFileList2View(GetLocalHwnd(), &Anchor);\r
1352         EraseDispFileList(&Anchor);\r
1353 \r
1354         // 先頭のアイテムを選択\r
1355         ListView_SetItemState(GetLocalHwnd(), 0, LVIS_FOCUSED, LVIS_FOCUSED);\r
1356 \r
1357         return;\r
1358 }\r
1359 \r
1360 \r
1361 /*----- ファイル情報をファイル一覧用リストに登録する --------------------------\r
1362 *\r
1363 *       Parameter\r
1364 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1365 *               char *Name : ファイル名\r
1366 *               FILETIME *Time : 日付\r
1367 *               LONGLONG Size : サイズ\r
1368 *               int Attr : 属性\r
1369 *               int Type : タイプ (NODE_xxxx)\r
1370 *               int Link : リンクかどうか (YES/NO)\r
1371 *               char *Owner : オーナ名\r
1372 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1373 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1374 *\r
1375 *       Return Value\r
1376 *               なし\r
1377 *----------------------------------------------------------------------------*/\r
1378 \r
1379 static void AddDispFileList(FLISTANCHOR *Anchor, char *Name, FILETIME *Time, LONGLONG Size, int Attr, int Type, int Link, char *Owner, int InfoExist, int Win)\r
1380 {\r
1381         int i;\r
1382         FILELIST *Pos;\r
1383         FILELIST *Prev;\r
1384         FILELIST *New;\r
1385         int FileSort;\r
1386         int DirSort;\r
1387         int Sort;\r
1388         LONGLONG Cmp;\r
1389 \r
1390         FileSort = AskSortType(ITEM_LFILE);\r
1391         DirSort = AskSortType(ITEM_LDIR);\r
1392         if(Win == WIN_REMOTE)\r
1393         {\r
1394                 FileSort = AskSortType(ITEM_RFILE);\r
1395                 DirSort = AskSortType(ITEM_RDIR);\r
1396         }\r
1397 \r
1398         Pos = Anchor->Top;\r
1399         for(i = 0; i < Anchor->Files; i++)\r
1400         {\r
1401                 if((Type == NODE_DIR) && (Pos->Node == NODE_FILE))\r
1402                         break;\r
1403                 if((Type == NODE_FILE) && (Pos->Node == NODE_DRIVE))\r
1404                         break;\r
1405 \r
1406                 if(Type == Pos->Node)\r
1407                 {\r
1408                         if(Type == NODE_DIR)\r
1409                                 Sort = DirSort;\r
1410                         else\r
1411                                 Sort = FileSort;\r
1412 \r
1413                         if((Sort & SORT_GET_ORD) == SORT_ASCENT)\r
1414                         {\r
1415                                 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1416                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) < 0)) ||\r
1417                                    (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1418                                         ((Cmp = Size - Pos->Size) < 0)) ||\r
1419                                    (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1420                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) < 0)))\r
1421                                 {\r
1422                                         break;\r
1423                                 }\r
1424 \r
1425                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1426                                 {\r
1427                                         if(_mbsicmp(Name, Pos->File) < 0)\r
1428                                                 break;\r
1429                                 }\r
1430                         }\r
1431                         else\r
1432                         {\r
1433                                 if((((Sort & SORT_MASK_ORD) == SORT_EXT) &&\r
1434                                         ((Cmp = _mbsicmp(GetFileExt(Name), GetFileExt(Pos->File))) > 0)) ||\r
1435                                    (((Sort & SORT_MASK_ORD) == SORT_SIZE) &&\r
1436                                         ((Cmp = Size - Pos->Size) > 0)) ||\r
1437                                    (((Sort & SORT_MASK_ORD) == SORT_DATE) &&\r
1438                                         ((Cmp = CompareFileTime(Time, &Pos->Time)) > 0)))\r
1439                                 {\r
1440                                         break;\r
1441                                 }\r
1442 \r
1443                                 if(((Sort & SORT_MASK_ORD) == SORT_NAME) || (Cmp == 0))\r
1444                                 {\r
1445                                         if(_mbsicmp(Name, Pos->File) > 0)\r
1446                                                 break;\r
1447                                 }\r
1448                         }\r
1449                 }\r
1450                 Prev = Pos;\r
1451                 Pos = Pos->Next;\r
1452         }\r
1453 \r
1454         if((New = malloc(sizeof(FILELIST))) != NULL)\r
1455         {\r
1456                 strcpy(New->File, Name);\r
1457                 New->Node = Type;\r
1458                 New->Link = Link;\r
1459                 New->Size = Size;\r
1460                 New->Attr = Attr;\r
1461                 New->Time = *Time;\r
1462                 strcpy(New->Owner, Owner);\r
1463                 New->InfoExist = InfoExist;\r
1464 \r
1465                 if(Pos == Anchor->Top)\r
1466                 {\r
1467                         New->Next = Anchor->Top;\r
1468                         Anchor->Top = New;\r
1469                 }\r
1470                 else\r
1471                 {\r
1472                         New->Next = Prev->Next;\r
1473                         Prev->Next = New;\r
1474                 }\r
1475                 Anchor->Files += 1;\r
1476         }\r
1477         return;\r
1478 }\r
1479 \r
1480 \r
1481 /*----- ファイル一覧用リストをクリアする --------------------------------------\r
1482 *\r
1483 *       Parameter\r
1484 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1485 *\r
1486 *       Return Value\r
1487 *               なし\r
1488 *----------------------------------------------------------------------------*/\r
1489 \r
1490 static void EraseDispFileList(FLISTANCHOR *Anchor)\r
1491 {\r
1492         FILELIST *Pos;\r
1493         FILELIST *Next;\r
1494         int i;\r
1495 \r
1496         Pos = Anchor->Top;\r
1497         for(i = 0; i < Anchor->Files; i++)\r
1498         {\r
1499                 Next = Pos->Next;\r
1500                 free(Pos);\r
1501                 Pos = Next;\r
1502         }\r
1503         Anchor->Files = 0;\r
1504         Anchor->Top = NULL;\r
1505         return;\r
1506 }\r
1507 \r
1508 \r
1509 /*----- ファイル一覧用リストの内容をファイル一覧ウインドウにセット ------------\r
1510 *\r
1511 *       Parameter\r
1512 *               HWND hWnd : ウインドウハンドル\r
1513 *               FLISTANCHOR *Anchor : ファイルリストの先頭\r
1514 *\r
1515 *       Return Value\r
1516 *               なし\r
1517 *----------------------------------------------------------------------------*/\r
1518 \r
1519 static void DispFileList2View(HWND hWnd, FLISTANCHOR *Anchor)\r
1520 {\r
1521         int i;\r
1522         FILELIST *Pos;\r
1523 \r
1524         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)FALSE, 0);\r
1525         SendMessage(hWnd, LVM_DELETEALLITEMS, 0, 0);\r
1526 \r
1527         Pos = Anchor->Top;\r
1528         for(i = 0; i < Anchor->Files; i++)\r
1529         {\r
1530                 AddListView(hWnd, -1, Pos->File, Pos->Node, Pos->Size, &Pos->Time, Pos->Attr, Pos->Owner, Pos->Link, Pos->InfoExist);\r
1531                 Pos = Pos->Next;\r
1532         }\r
1533 \r
1534         SendMessage(hWnd, WM_SETREDRAW, (WPARAM)TRUE, 0);\r
1535         UpdateWindow(hWnd);\r
1536 \r
1537         DispSelectedSpace();\r
1538         return;\r
1539 }\r
1540 \r
1541 \r
1542 /*----- ファイル一覧ウインドウ(リストビュー)に追加 --------------------------\r
1543 *\r
1544 *       Parameter\r
1545 *               HWND hWnd : ウインドウハンドル\r
1546 *               int Pos : 挿入位置\r
1547 *               char *Name : 名前\r
1548 *               int Type : タイプ (NIDE_xxxx)\r
1549 *               LONGLONG Size : サイズ\r
1550 *               FILETIME *Time : 日付\r
1551 *               int Attr : 属性\r
1552 *               char Owner : オーナ名\r
1553 *               int Link : リンクかどうか\r
1554 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1555 *\r
1556 *       Return Value\r
1557 *               なし\r
1558 *----------------------------------------------------------------------------*/\r
1559 \r
1560 static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size, FILETIME *Time, int Attr, char *Owner, int Link, int InfoExist)\r
1561 {\r
1562         LV_ITEM LvItem;\r
1563         char Tmp[20];\r
1564 \r
1565         if(Pos == -1)\r
1566                 Pos = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);\r
1567 \r
1568         /* アイコン/ファイル名 */\r
1569         LvItem.mask = LVIF_TEXT | LVIF_IMAGE;\r
1570         LvItem.iItem = Pos;\r
1571         LvItem.iSubItem = 0;\r
1572         LvItem.pszText = Name;\r
1573         if((Type == NODE_FILE) && (AskTransferTypeAssoc(Name, TYPE_X) == TYPE_I))\r
1574                 Type = 3;\r
1575         if(Link == NO)\r
1576                 LvItem.iImage = Type;\r
1577         else\r
1578                 LvItem.iImage = 4;\r
1579         LvItem.iItem = SendMessage(hWnd, LVM_INSERTITEM, 0, (LPARAM)&LvItem);\r
1580 \r
1581         /* 日付/時刻 */\r
1582         FileTime2TimeString(Time, Tmp, DISPFORM_LEGACY, InfoExist);\r
1583         LvItem.mask = LVIF_TEXT;\r
1584         LvItem.iItem = Pos;\r
1585         LvItem.iSubItem = 1;\r
1586         LvItem.pszText = Tmp;\r
1587         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1588 \r
1589         /* サイズ */\r
1590         if(Type == NODE_DIR)\r
1591                 strcpy(Tmp, "<DIR>");\r
1592         else if(Type == NODE_DRIVE)\r
1593                 strcpy(Tmp, "<DRIVE>");\r
1594         else if(Size >= 0)\r
1595                 MakeNumString(Size, Tmp, TRUE);\r
1596         else\r
1597                 strcpy(Tmp, "");\r
1598         LvItem.mask = LVIF_TEXT;\r
1599         LvItem.iItem = Pos;\r
1600         LvItem.iSubItem = 2;\r
1601         LvItem.pszText = Tmp;\r
1602         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1603 \r
1604         /* 拡張子 */\r
1605         LvItem.mask = LVIF_TEXT;\r
1606         LvItem.iItem = Pos;\r
1607         LvItem.iSubItem = 3;\r
1608         LvItem.pszText = GetFileExt(Name);\r
1609         LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1610 \r
1611         if(hWnd == GetRemoteHwnd())\r
1612         {\r
1613                 /* 属性 */\r
1614                 strcpy(Tmp, "");\r
1615                 if(InfoExist & FINFO_ATTR)\r
1616                         AttrValue2String(Attr, Tmp);\r
1617                 LvItem.mask = LVIF_TEXT;\r
1618                 LvItem.iItem = Pos;\r
1619                 LvItem.iSubItem = 4;\r
1620                 LvItem.pszText = Tmp;\r
1621                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1622 \r
1623                 /* オーナ名 */\r
1624                 LvItem.mask = LVIF_TEXT;\r
1625                 LvItem.iItem = Pos;\r
1626                 LvItem.iSubItem = 5;\r
1627                 LvItem.pszText = Owner;\r
1628                 LvItem.iItem = SendMessage(hWnd, LVM_SETITEM, 0, (LPARAM)&LvItem);\r
1629         }\r
1630         return;\r
1631 }\r
1632 \r
1633 \r
1634 /*----- ファイル名一覧ウインドウをソートし直す --------------------------------\r
1635 *\r
1636 *       Parameter\r
1637 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1638 *\r
1639 *       Return Value\r
1640 *               なし\r
1641 *----------------------------------------------------------------------------*/\r
1642 \r
1643 void ReSortDispList(int Win, int *CancelCheckWork)\r
1644 {\r
1645         if(Win == WIN_REMOTE)\r
1646                 GetRemoteDirForWnd(CACHE_LASTREAD, CancelCheckWork);\r
1647         else\r
1648                 GetLocalDirForWnd();\r
1649         return;\r
1650 }\r
1651 \r
1652 \r
1653 /*----- ファイル一覧ウインドウのファイルを選択する ----------------------------\r
1654 *\r
1655 *       Parameter\r
1656 *               HWND hWnd : ウインドウハンドル\r
1657 *               int Type : 選択方法 (SELECT_xxx)\r
1658 *\r
1659 *       Return Value\r
1660 *               なし\r
1661 *----------------------------------------------------------------------------*/\r
1662 \r
1663 void SelectFileInList(HWND hWnd, int Type)\r
1664 {\r
1665         int Win;\r
1666         int WinDst;\r
1667         int i;\r
1668         int Num;\r
1669         char RegExp[FMAX_PATH+1];\r
1670         char Name[FMAX_PATH+1];\r
1671         LV_ITEM LvItem;\r
1672         int CsrPos;\r
1673         FILETIME Time1;\r
1674         FILETIME Time2;\r
1675         int Find;\r
1676 \r
1677         Win = WIN_LOCAL;\r
1678         WinDst = WIN_REMOTE;\r
1679         if(hWnd == GetRemoteHwnd())\r
1680         {\r
1681                 Win = WIN_REMOTE;\r
1682                 WinDst = WIN_LOCAL;\r
1683         }\r
1684 \r
1685         Num = GetItemCount(Win);\r
1686         switch(Type)\r
1687         {\r
1688                 case SELECT_ALL :\r
1689                         LvItem.state = 0;\r
1690                         if(GetSelectedCount(Win) <= 1)\r
1691                                 LvItem.state = LVIS_SELECTED;\r
1692                         for(i = 0; i < Num; i++)\r
1693                         {\r
1694                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1695                                 {\r
1696                                         LvItem.mask = LVIF_STATE;\r
1697                                         LvItem.iItem = i;\r
1698                                         LvItem.stateMask = LVIS_SELECTED;\r
1699                                         LvItem.iSubItem = 0;\r
1700                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1701                                 }\r
1702                         }\r
1703                         break;\r
1704 \r
1705                 case SELECT_REGEXP :\r
1706                         if(((Win == WIN_LOCAL) &&\r
1707                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_local_dlg), hWnd, SelectDialogCallBack) == YES)) ||\r
1708                            ((Win == WIN_REMOTE) &&\r
1709                                 (DialogBox(GetFtpInst(), MAKEINTRESOURCE(sel_remote_dlg), hWnd, SelectDialogCallBack) == YES)))\r
1710                         {\r
1711                                 strcpy(RegExp, FindStr);\r
1712 //                              if(FindMode == 0)\r
1713 //                                      WildCard2RegExp(RegExp);\r
1714 \r
1715                                 _mbslwr(RegExp);\r
1716                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
1717                                 {\r
1718                                         CsrPos = -1;\r
1719                                         for(i = 0; i < Num; i++)\r
1720                                         {\r
1721                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1722                                                 Find = FindNameNode(WinDst, Name);\r
1723 \r
1724                                                 _mbslwr(Name);\r
1725                                                 LvItem.state = 0;\r
1726                                                 if(GetNodeType(Win, i) != NODE_DRIVE)\r
1727                                                 {\r
1728                                                         if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1729                                                            ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1730                                                         {\r
1731                                                                 LvItem.state = LVIS_SELECTED;\r
1732 \r
1733                                                                 if(Find >= 0)\r
1734                                                                 {\r
1735                                                                         if(IgnoreExist == YES)\r
1736                                                                                 LvItem.state = 0;\r
1737 \r
1738                                                                         if((LvItem.state != 0) && (IgnoreNew == YES))\r
1739                                                                         {\r
1740                                                                                 GetNodeTime(Win, i, &Time1);\r
1741                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1742                                                                                 if(CompareFileTime(&Time1, &Time2) > 0)\r
1743                                                                                         LvItem.state = 0;\r
1744                                                                         }\r
1745 \r
1746                                                                         if((LvItem.state != 0) && (IgnoreOld == YES))\r
1747                                                                         {\r
1748                                                                                 GetNodeTime(Win, i, &Time1);\r
1749                                                                                 GetNodeTime(WinDst, Find, &Time2);\r
1750                                                                                 if(CompareFileTime(&Time1, &Time2) < 0)\r
1751                                                                                         LvItem.state = 0;\r
1752                                                                         }\r
1753                                                                 }\r
1754                                                         }\r
1755                                                 }\r
1756 \r
1757                                                 if((LvItem.state != 0) && (CsrPos == -1))\r
1758                                                         CsrPos = i;\r
1759 \r
1760                                                 LvItem.mask = LVIF_STATE;\r
1761                                                 LvItem.iItem = i;\r
1762                                                 LvItem.stateMask = LVIS_SELECTED;\r
1763                                                 LvItem.iSubItem = 0;\r
1764                                                 SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1765                                         }\r
1766                                         if(CsrPos != -1)\r
1767                                         {\r
1768                                                 LvItem.mask = LVIF_STATE;\r
1769                                                 LvItem.iItem = CsrPos;\r
1770                                                 LvItem.state = LVIS_FOCUSED;\r
1771                                                 LvItem.stateMask = LVIS_FOCUSED;\r
1772                                                 LvItem.iSubItem = 0;\r
1773                                                 SendMessage(hWnd, LVM_SETITEMSTATE, CsrPos, (LPARAM)&LvItem);\r
1774                                                 SendMessage(hWnd, LVM_ENSUREVISIBLE, CsrPos, (LPARAM)TRUE);\r
1775                                         }\r
1776                                 }\r
1777                         }\r
1778                         break;\r
1779         }\r
1780         return;\r
1781 }\r
1782 \r
1783 \r
1784 /*----- 選択ダイアログのコールバック ------------------------------------------\r
1785 *\r
1786 *       Parameter\r
1787 *               HWND hDlg : ウインドウハンドル\r
1788 *               UINT message : メッセージ番号\r
1789 *               WPARAM wParam : メッセージの WPARAM 引数\r
1790 *               LPARAM lParam : メッセージの LPARAM 引数\r
1791 *\r
1792 *       Return Value\r
1793 *               BOOL TRUE/FALSE\r
1794 *----------------------------------------------------------------------------*/\r
1795 \r
1796 static BOOL CALLBACK SelectDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
1797 {\r
1798         switch (iMessage)\r
1799         {\r
1800                 case WM_INITDIALOG :\r
1801                         SendDlgItemMessage(hDlg, SEL_FNAME, EM_LIMITTEXT, 40, 0);\r
1802                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_SETTEXT, 0, (LPARAM)FindStr);\r
1803                         SendDlgItemMessage(hDlg, SEL_REGEXP, BM_SETCHECK, FindMode, 0);\r
1804                         SendDlgItemMessage(hDlg, SEL_NOOLD, BM_SETCHECK, IgnoreOld, 0);\r
1805                         SendDlgItemMessage(hDlg, SEL_NONEW, BM_SETCHECK, IgnoreNew, 0);\r
1806                         SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_SETCHECK, IgnoreExist, 0);\r
1807                         return(TRUE);\r
1808 \r
1809                 case WM_COMMAND :\r
1810                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
1811                         {\r
1812                                 case IDOK :\r
1813                                         SendDlgItemMessage(hDlg, SEL_FNAME, WM_GETTEXT, 40+1, (LPARAM)FindStr);\r
1814                                         FindMode = SendDlgItemMessage(hDlg, SEL_REGEXP, BM_GETCHECK, 0, 0);\r
1815                                         IgnoreOld = SendDlgItemMessage(hDlg, SEL_NOOLD, BM_GETCHECK, 0, 0);\r
1816                                         IgnoreNew = SendDlgItemMessage(hDlg, SEL_NONEW, BM_GETCHECK, 0, 0);\r
1817                                         IgnoreExist = SendDlgItemMessage(hDlg, SEL_NOEXIST, BM_GETCHECK, 0, 0);\r
1818                                         EndDialog(hDlg, YES);\r
1819                                         break;\r
1820 \r
1821                                 case IDCANCEL :\r
1822                                         EndDialog(hDlg, NO);\r
1823                                         break;\r
1824 \r
1825                                 case IDHELP :\r
1826                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, IDH_HELP_TOPIC_0000061);\r
1827                                         break;\r
1828                         }\r
1829             return(TRUE);\r
1830         }\r
1831         return(FALSE);\r
1832 }\r
1833 \r
1834 \r
1835 /*----- ファイル一覧ウインドウのファイルを検索する ----------------------------\r
1836 *\r
1837 *       Parameter\r
1838 *               HWND hWnd : ウインドウハンドル\r
1839 *               int Type : 検索方法 (FIND_xxx)\r
1840 *\r
1841 *       Return Value\r
1842 *               なし\r
1843 *----------------------------------------------------------------------------*/\r
1844 \r
1845 void FindFileInList(HWND hWnd, int Type)\r
1846 {\r
1847         int Win;\r
1848         int i;\r
1849         int Num;\r
1850         static char RegExp[FMAX_PATH+1] = { "" };\r
1851         char Name[FMAX_PATH+1];\r
1852         LV_ITEM LvItem;\r
1853         char *Title;\r
1854 \r
1855         Win = WIN_LOCAL;\r
1856         Title = MSGJPN050;\r
1857         if(hWnd == GetRemoteHwnd())\r
1858         {\r
1859                 Win = WIN_REMOTE;\r
1860                 Title = MSGJPN051;\r
1861         }\r
1862 \r
1863         Num = GetItemCount(Win);\r
1864         switch(Type)\r
1865         {\r
1866                 case FIND_FIRST :\r
1867                         if(InputDialogBox(find_dlg, hWnd, Title, FindStr, 40+1, &FindMode, IDH_HELP_TOPIC_0000001) == YES)\r
1868                         {\r
1869                                 strcpy(RegExp, FindStr);\r
1870 //                              if(FindMode == 0)\r
1871 //                                      WildCard2RegExp(RegExp);\r
1872 \r
1873                                 _mbslwr(RegExp);\r
1874                                 if((FindMode == 0) || (JreCompileStr(RegExp) == TRUE))\r
1875                                 {\r
1876                                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
1877                                         {\r
1878                                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1879                                                 _mbslwr(Name);\r
1880 \r
1881                                                 LvItem.state = 0;\r
1882                                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1883                                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1884                                                 {\r
1885                                                         LvItem.mask = LVIF_STATE;\r
1886                                                         LvItem.iItem = i;\r
1887                                                         LvItem.state = LVIS_FOCUSED;\r
1888                                                         LvItem.stateMask = LVIS_FOCUSED;\r
1889                                                         LvItem.iSubItem = 0;\r
1890                                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1891                                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
1892                                                         break;\r
1893                                                 }\r
1894                                         }\r
1895                                 }\r
1896                         }\r
1897                         break;\r
1898 \r
1899                 case FIND_NEXT :\r
1900                         for(i = GetCurrentItem(Win)+1; i < Num; i++)\r
1901                         {\r
1902                                 GetNodeName(Win, i, Name, FMAX_PATH);\r
1903                                 _mbslwr(Name);\r
1904 \r
1905                                 LvItem.state = 0;\r
1906                                 if(((FindMode == 0) && (CheckFname(Name, RegExp) == FFFTP_SUCCESS)) ||\r
1907                                    ((FindMode != 0) && (JreGetStrMatchInfo(Name, 0) != NULL)))\r
1908                                 {\r
1909                                         LvItem.mask = LVIF_STATE;\r
1910                                         LvItem.iItem = i;\r
1911                                         LvItem.state = LVIS_FOCUSED;\r
1912                                         LvItem.stateMask = LVIS_FOCUSED;\r
1913                                         LvItem.iSubItem = 0;\r
1914                                         SendMessage(hWnd, LVM_SETITEMSTATE, i, (LPARAM)&LvItem);\r
1915                                         SendMessage(hWnd, LVM_ENSUREVISIBLE, i, (LPARAM)TRUE);\r
1916                                         break;\r
1917                                 }\r
1918                         }\r
1919                         break;\r
1920         }\r
1921         return;\r
1922 }\r
1923 \r
1924 \r
1925 #if 0\r
1926 /*----- ワイルドカードを正規表現に変換する ------------------------------------\r
1927 *\r
1928 *       Parameter\r
1929 *               char *Str : 文字列\r
1930 *\r
1931 *       Return Value\r
1932 *               なし\r
1933 *----------------------------------------------------------------------------*/\r
1934 \r
1935 void WildCard2RegExp(char *Str)\r
1936 {\r
1937         char Tmp[FMAX_PATH+1];\r
1938         char *Org;\r
1939         char *Pos;\r
1940         UINT Ch;\r
1941 \r
1942         Org = Str;\r
1943         Pos = Tmp;\r
1944 \r
1945         *Pos++ = '^';\r
1946         *Pos++ = '(';\r
1947         while(*Str != NUL)\r
1948         {\r
1949                 if(Pos >= Tmp + FMAX_PATH - 3)\r
1950                         break;\r
1951 \r
1952                 Ch = _mbsnextc(Str);\r
1953                 Str = _mbsinc(Str);\r
1954 \r
1955                 if(Ch <= 0x7F)\r
1956                 {\r
1957                         if(strchr("[]()^$.+", Ch) != NULL)\r
1958                         {\r
1959                                 *Pos++ = '\\';\r
1960                                 *Pos++ = Ch;\r
1961                         }\r
1962                         else if(Ch == '*')\r
1963                         {\r
1964                                 *Pos++ = '.';\r
1965                                 *Pos++ = '*';\r
1966                         }\r
1967                         else if(Ch == '?')\r
1968                                 *Pos++ = '.';\r
1969                         else if(Ch == '|')\r
1970                         {\r
1971                                 *Pos++ = '|';\r
1972                         }\r
1973                         else\r
1974                                 *Pos++ = Ch;\r
1975                 }\r
1976                 else\r
1977                 {\r
1978                         _mbsnset(Pos, Ch, 1);\r
1979                         Pos = _mbsinc(Pos);\r
1980                 }\r
1981         }\r
1982         *Pos++ = ')';\r
1983         *Pos++ = '$';\r
1984         *Pos = NUL;\r
1985         strcpy(Org, Tmp);\r
1986 \r
1987         return;\r
1988 }\r
1989 #endif\r
1990 \r
1991 \r
1992 /*----- カーソル位置のアイテム番号を返す --------------------------------------\r
1993 *\r
1994 *       Parameter\r
1995 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
1996 *\r
1997 *       Return Value\r
1998 *               int アイテム番号\r
1999 *----------------------------------------------------------------------------*/\r
2000 \r
2001 int GetCurrentItem(int Win)\r
2002 {\r
2003         HWND hWnd;\r
2004         int Ret;\r
2005 \r
2006         hWnd = GetLocalHwnd();\r
2007         if(Win == WIN_REMOTE)\r
2008                 hWnd = GetRemoteHwnd();\r
2009 \r
2010         if((Ret = SendMessage(hWnd, LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0))) == -1)\r
2011                 Ret = 0;\r
2012 \r
2013         return(Ret);\r
2014 }\r
2015 \r
2016 \r
2017 /*----- アイテム数を返す ------------------------------------------------------\r
2018 *\r
2019 *       Parameter\r
2020 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2021 *\r
2022 *       Return Value\r
2023 *               int アイテム数\r
2024 *----------------------------------------------------------------------------*/\r
2025 \r
2026 int GetItemCount(int Win)\r
2027 {\r
2028         HWND hWnd;\r
2029 \r
2030         hWnd = GetLocalHwnd();\r
2031         if(Win == WIN_REMOTE)\r
2032                 hWnd = GetRemoteHwnd();\r
2033 \r
2034         return(SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0));\r
2035 }\r
2036 \r
2037 \r
2038 /*----- 選択されているアイテム数を返す ----------------------------------------\r
2039 *\r
2040 *       Parameter\r
2041 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2042 *\r
2043 *       Return Value\r
2044 *               int 選択されているアイテム数\r
2045 *----------------------------------------------------------------------------*/\r
2046 \r
2047 int GetSelectedCount(int Win)\r
2048 {\r
2049         HWND hWnd;\r
2050 \r
2051         hWnd = GetLocalHwnd();\r
2052         if(Win == WIN_REMOTE)\r
2053                 hWnd = GetRemoteHwnd();\r
2054 \r
2055         return(SendMessage(hWnd, LVM_GETSELECTEDCOUNT, 0, 0));\r
2056 }\r
2057 \r
2058 \r
2059 /*----- 選択されている最初のアイテム番号を返す --------------------------------\r
2060 *\r
2061 *       Parameter\r
2062 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2063 *               int All : 選ばれていないものを含める\r
2064 *\r
2065 *       Return Value\r
2066 *               int アイテム番号\r
2067 *                       -1 = 選択されていない\r
2068 *----------------------------------------------------------------------------*/\r
2069 \r
2070 int GetFirstSelected(int Win, int All)\r
2071 {\r
2072         HWND hWnd;\r
2073         int Ope;\r
2074 \r
2075         hWnd = GetLocalHwnd();\r
2076         if(Win == WIN_REMOTE)\r
2077                 hWnd = GetRemoteHwnd();\r
2078 \r
2079         Ope = LVNI_SELECTED;\r
2080         if(All == YES)\r
2081                 Ope = LVNI_ALL;\r
2082 \r
2083         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)-1, (LPARAM)MAKELPARAM(Ope, 0)));\r
2084 }\r
2085 \r
2086 \r
2087 /*----- 選択されている次のアイテム番号を返す ----------------------------------\r
2088 *\r
2089 *       Parameter\r
2090 *               int Win : ウィンドウ番号 (WIN_xxxx)\r
2091 *               int Pos : 今のアイテム番号\r
2092 *               int All : 選ばれていないものも含める\r
2093 *\r
2094 *       Return Value\r
2095 *               int アイテム番号\r
2096 *                       -1 = 選択されていない\r
2097 *----------------------------------------------------------------------------*/\r
2098 \r
2099 int GetNextSelected(int Win, int Pos, int All)\r
2100 {\r
2101         HWND hWnd;\r
2102         int Ope;\r
2103 \r
2104         hWnd = GetLocalHwnd();\r
2105         if(Win == WIN_REMOTE)\r
2106                 hWnd = GetRemoteHwnd();\r
2107 \r
2108         Ope = LVNI_SELECTED;\r
2109         if(All == YES)\r
2110                 Ope = LVNI_ALL;\r
2111 \r
2112         return(SendMessage(hWnd, LVM_GETNEXTITEM, (WPARAM)Pos, (LPARAM)MAKELPARAM(Ope, 0)));\r
2113 }\r
2114 \r
2115 \r
2116 /*----- 指定された名前のアイテムを探す ----------------------------------------\r
2117 *\r
2118 *       Parameter\r
2119 *               int Win : ウインドウ番号 (WIN_xxx)\r
2120 *               char *Name : 名前\r
2121 *\r
2122 *       Return Value\r
2123 *               int アイテム番号\r
2124 *                       -1=見つからなかった\r
2125 *----------------------------------------------------------------------------*/\r
2126 \r
2127 int FindNameNode(int Win, char *Name)\r
2128 {\r
2129         LV_FINDINFO FindInfo;\r
2130         HWND hWnd;\r
2131 \r
2132         hWnd = GetLocalHwnd();\r
2133         if(Win == WIN_REMOTE)\r
2134                 hWnd = GetRemoteHwnd();\r
2135 \r
2136         FindInfo.flags = LVFI_STRING;\r
2137         FindInfo.psz = Name;\r
2138         return(SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)&FindInfo));\r
2139 }\r
2140 \r
2141 \r
2142 /*----- 指定位置のアイテムの名前を返す ----------------------------------------\r
2143 *\r
2144 *       Parameter\r
2145 *               int Win : ウインドウ番号 (WIN_xxx)\r
2146 *               int Pos : 位置\r
2147 *               char *Buf : 名前を返すバッファ\r
2148 *               int Max : バッファのサイズ\r
2149 *\r
2150 *       Return Value\r
2151 *               なし\r
2152 *----------------------------------------------------------------------------*/\r
2153 \r
2154 void GetNodeName(int Win, int Pos, char *Buf, int Max)\r
2155 {\r
2156         HWND hWnd;\r
2157         LV_ITEM LvItem;\r
2158 \r
2159         hWnd = GetLocalHwnd();\r
2160         if(Win == WIN_REMOTE)\r
2161                 hWnd = GetRemoteHwnd();\r
2162 \r
2163         LvItem.mask = LVIF_TEXT;\r
2164         LvItem.iItem = Pos;\r
2165         LvItem.iSubItem = 0;\r
2166         LvItem.pszText = Buf;\r
2167         LvItem.cchTextMax = Max;\r
2168         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2169         return;\r
2170 }\r
2171 \r
2172 \r
2173 /*----- 指定位置のアイテムの日付を返す ----------------------------------------\r
2174 *\r
2175 *       Parameter\r
2176 *               int Win : ウインドウ番号 (WIN_xxx)\r
2177 *               int Pos : 位置\r
2178 *               FILETIME *Buf : 日付を返すバッファ\r
2179 *\r
2180 *       Return Value\r
2181 *               int ステータス\r
2182 *                       YES/NO=日付情報がなかった\r
2183 *----------------------------------------------------------------------------*/\r
2184 \r
2185 int GetNodeTime(int Win, int Pos, FILETIME *Buf)\r
2186 {\r
2187         HWND hWnd;\r
2188         LV_ITEM LvItem;\r
2189         char Tmp[20];\r
2190         int Ret;\r
2191 \r
2192         hWnd = GetLocalHwnd();\r
2193         if(Win == WIN_REMOTE)\r
2194                 hWnd = GetRemoteHwnd();\r
2195 \r
2196         LvItem.mask = LVIF_TEXT;\r
2197         LvItem.iItem = Pos;\r
2198         LvItem.iSubItem = 1;\r
2199         LvItem.pszText = Tmp;\r
2200         LvItem.cchTextMax = 20;\r
2201         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2202         Ret = TimeString2FileTime(Tmp, Buf);\r
2203         return(Ret);\r
2204 }\r
2205 \r
2206 \r
2207 /*----- 指定位置のアイテムのサイズを返す --------------------------------------\r
2208 *\r
2209 *       Parameter\r
2210 *               int Win : ウインドウ番号 (WIN_xxx)\r
2211 *               int Pos : 位置\r
2212 *               int *Buf : サイズを返すワーク\r
2213 *\r
2214 *       Return Value\r
2215 *               int ステータス\r
2216 *                       YES/NO=サイズ情報がなかった\r
2217 *----------------------------------------------------------------------------*/\r
2218 \r
2219 int GetNodeSize(int Win, int Pos, LONGLONG *Buf)\r
2220 {\r
2221         HWND hWnd;\r
2222         LV_ITEM LvItem;\r
2223         char Tmp[40];\r
2224         int Ret;\r
2225 \r
2226         hWnd = GetLocalHwnd();\r
2227         if(Win == WIN_REMOTE)\r
2228                 hWnd = GetRemoteHwnd();\r
2229 \r
2230         LvItem.mask = LVIF_TEXT;\r
2231         LvItem.iItem = Pos;\r
2232         LvItem.iSubItem = 2;\r
2233         LvItem.pszText = Tmp;\r
2234         LvItem.cchTextMax = 20;\r
2235         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2236         *Buf = -1;\r
2237         Ret = NO;\r
2238         if(strlen(Tmp) > 0)\r
2239         {\r
2240                 RemoveComma(Tmp);\r
2241                 *Buf = _atoi64(Tmp);\r
2242                 Ret = YES;\r
2243         }\r
2244         return(Ret);\r
2245 }\r
2246 \r
2247 \r
2248 /*----- 指定位置のアイテムの属性を返す ----------------------------------------\r
2249 *\r
2250 *       Parameter\r
2251 *               int Win : ウインドウ番号 (WIN_xxx)\r
2252 *               int Pos : 位置\r
2253 *               int *Buf : 属性を返すワーク\r
2254 *\r
2255 *       Return Value\r
2256 *               int ステータス\r
2257 *                       YES/NO=サイズ情報がなかった\r
2258 *----------------------------------------------------------------------------*/\r
2259 \r
2260 int GetNodeAttr(int Win, int Pos, int *Buf)\r
2261 {\r
2262         LV_ITEM LvItem;\r
2263         char Tmp[20];\r
2264         int Ret;\r
2265 \r
2266         *Buf = 0;\r
2267         Ret = NO;\r
2268         if(Win == WIN_REMOTE)\r
2269         {\r
2270                 LvItem.mask = LVIF_TEXT;\r
2271                 LvItem.iItem = Pos;\r
2272                 LvItem.iSubItem = 4;\r
2273                 LvItem.pszText = Tmp;\r
2274                 LvItem.cchTextMax = 20;\r
2275                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2276                 if(strlen(Tmp) > 0)\r
2277                 {\r
2278                         *Buf = AttrString2Value(Tmp);\r
2279                         Ret = YES;\r
2280                 }\r
2281         }\r
2282         return(Ret);\r
2283 }\r
2284 \r
2285 \r
2286 /*----- 指定位置のアイテムのタイプを返す --------------------------------------\r
2287 *\r
2288 *       Parameter\r
2289 *               int Win : ウインドウ番号 (WIN_xxx)\r
2290 *               int Pos : 位置\r
2291 *\r
2292 *       Return Value\r
2293 *               int タイプ (NODE_xxx)\r
2294 *----------------------------------------------------------------------------*/\r
2295 \r
2296 int GetNodeType(int Win, int Pos)\r
2297 {\r
2298         char Tmp[20];\r
2299         LV_ITEM LvItem;\r
2300         int Ret;\r
2301         HWND hWnd;\r
2302 \r
2303         hWnd = GetLocalHwnd();\r
2304         if(Win == WIN_REMOTE)\r
2305                 hWnd = GetRemoteHwnd();\r
2306 \r
2307         LvItem.mask = LVIF_TEXT;\r
2308         LvItem.iItem = Pos;\r
2309         LvItem.iSubItem = 2;\r
2310         LvItem.pszText = Tmp;\r
2311         LvItem.cchTextMax = 20;\r
2312         SendMessage(hWnd, LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2313 \r
2314         if(strcmp(Tmp, "<DIR>") == 0)\r
2315                 Ret = NODE_DIR;\r
2316         else if(strcmp(Tmp, "<DRIVE>") == 0)\r
2317                 Ret = NODE_DRIVE;\r
2318         else\r
2319                 Ret = NODE_FILE;\r
2320 \r
2321         return(Ret);\r
2322 }\r
2323 \r
2324 \r
2325 /*----- 指定位置のアイテムのオーナ名を返す ------------------------------------\r
2326 *\r
2327 *       Parameter\r
2328 *               int Win : ウインドウ番号 (WIN_xxx)\r
2329 *               int Pos : 位置\r
2330 *               char *Buf : オーナ名を返すバッファ\r
2331 *               int Max : バッファのサイズ\r
2332 *\r
2333 *       Return Value\r
2334 *               なし\r
2335 *----------------------------------------------------------------------------*/\r
2336 \r
2337 void GetNodeOwner(int Win, int Pos, char *Buf, int Max)\r
2338 {\r
2339         LV_ITEM LvItem;\r
2340 \r
2341         strcpy(Buf, "");\r
2342         if(Win == WIN_REMOTE)\r
2343         {\r
2344                 LvItem.mask = LVIF_TEXT;\r
2345                 LvItem.iItem = Pos;\r
2346                 LvItem.iSubItem = 5;\r
2347                 LvItem.pszText = Buf;\r
2348                 LvItem.cchTextMax = Max;\r
2349                 SendMessage(GetRemoteHwnd(), LVM_GETITEM, 0, (LPARAM)&LvItem);\r
2350         }\r
2351         return;\r
2352 }\r
2353 \r
2354 \r
2355 /*----- ホスト側のファイル一覧ウインドウをクリア ------------------------------\r
2356 *\r
2357 *       Parameter\r
2358 *               なし\r
2359 *\r
2360 *       Return Value\r
2361 *               なし\r
2362 *----------------------------------------------------------------------------*/\r
2363 \r
2364 void EraseRemoteDirForWnd(void)\r
2365 {\r
2366         SendMessage(GetRemoteHwnd(), LVM_DELETEALLITEMS, 0, 0);\r
2367         SendMessage(GetRemoteHistHwnd(), CB_RESETCONTENT, 0, 0);\r
2368         return;\r
2369 }\r
2370 \r
2371 \r
2372 /*----- 選択されているファイルの総サイズを返す --------------------------------\r
2373 *\r
2374 *       Parameter\r
2375 *               int Win : ウインドウ番号 (WIN_xxx)\r
2376 *\r
2377 *       Return Value\r
2378 *               double サイズ\r
2379 *----------------------------------------------------------------------------*/\r
2380 \r
2381 double GetSelectedTotalSize(int Win)\r
2382 {\r
2383         double Ret;\r
2384         LONGLONG Size;\r
2385         int Pos;\r
2386 \r
2387         Ret = 0;\r
2388         if(GetSelectedCount(Win) > 0)\r
2389         {\r
2390                 Pos = GetFirstSelected(Win, NO);\r
2391                 while(Pos != -1)\r
2392                 {\r
2393                         GetNodeSize(Win, Pos, &Size);\r
2394                         if(Size >= 0)\r
2395                                 Ret += Size;\r
2396                         Pos = GetNextSelected(Win, Pos, NO);\r
2397                 }\r
2398         }\r
2399         return(Ret);\r
2400 }\r
2401 \r
2402 \r
2403 \r
2404 /*===================================================================\r
2405 \r
2406 ===================================================================*/\r
2407 \r
2408 \r
2409 \r
2410 /*----- ファイル一覧で選ばれているファイルをリストに登録する ------------------\r
2411 *\r
2412 *       Parameter\r
2413 *               int Win : ウインドウ番号 (WIN_xxx)\r
2414 *               int Expand : サブディレクトリを展開する (YES/NO)\r
2415 *               int All : 選ばれていないものもすべて登録する (YES/NO)\r
2416 *               FILELIST **Base : ファイルリストの先頭\r
2417 *\r
2418 *       Return Value\r
2419 *               なし\r
2420 *----------------------------------------------------------------------------*/\r
2421 \r
2422 void MakeSelectedFileList(int Win, int Expand, int All, FILELIST **Base, int *CancelCheckWork)\r
2423 {\r
2424         int Pos;\r
2425         char Name[FMAX_PATH+1];\r
2426         char Cur[FMAX_PATH+1];\r
2427         FILELIST Pkt;\r
2428         int Node;\r
2429         DWORD Attr;\r
2430         int Ignore;\r
2431 \r
2432         if((All == YES) || (GetSelectedCount(Win) > 0))\r
2433         {\r
2434                 /*===== カレントディレクトリのファイル =====*/\r
2435 \r
2436                 Pos = GetFirstSelected(Win, All);\r
2437                 while(Pos != -1)\r
2438                 {\r
2439                         Node = GetNodeType(Win, Pos);\r
2440                         if((Node == NODE_FILE) ||\r
2441                            ((Expand == NO) && (Node == NODE_DIR)))\r
2442                         {\r
2443                                 Pkt.InfoExist = 0;\r
2444                                 GetNodeName(Win, Pos, Pkt.File, FMAX_PATH);\r
2445                                 if(GetNodeSize(Win, Pos, &Pkt.Size) == YES)\r
2446                                         Pkt.InfoExist |= FINFO_SIZE;\r
2447                                 if(GetNodeAttr(Win, Pos, &Pkt.Attr) == YES)\r
2448                                         Pkt.InfoExist |= FINFO_ATTR;\r
2449                                 if(GetNodeTime(Win, Pos, &Pkt.Time) == YES)\r
2450                                         Pkt.InfoExist |= (FINFO_TIME | FINFO_DATE);\r
2451                                 Pkt.Node = Node;\r
2452 \r
2453                                 Ignore = NO;\r
2454                                 if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2455                                 {\r
2456                                         AskLocalCurDir(Cur, FMAX_PATH);\r
2457                                         SetYenTail(Cur);\r
2458                                         strcat(Cur, Pkt.File);\r
2459                                         Attr = GetFileAttributes(Cur);\r
2460                                         if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2461                                                 Ignore = YES;\r
2462                                 }\r
2463 \r
2464                                 if(Ignore == NO)\r
2465                                         AddFileList(&Pkt, Base);\r
2466                         }\r
2467                         Pos = GetNextSelected(Win, Pos, All);\r
2468                 }\r
2469 \r
2470                 if(Expand == YES)\r
2471                 {\r
2472                         /*===== ディレクトリツリー =====*/\r
2473 \r
2474                         Pos = GetFirstSelected(Win, All);\r
2475                         while(Pos != -1)\r
2476                         {\r
2477                                 if(GetNodeType(Win, Pos) == NODE_DIR)\r
2478                                 {\r
2479                                         GetNodeName(Win, Pos, Name, FMAX_PATH);\r
2480                                         strcpy(Pkt.File, Name);\r
2481                                         ReplaceAll(Pkt.File, '\\', '/');\r
2482 //8/26\r
2483 \r
2484                                         Ignore = NO;\r
2485                                         if((DispIgnoreHide == YES) && (Win == WIN_LOCAL))\r
2486                                         {\r
2487                                                 AskLocalCurDir(Cur, FMAX_PATH);\r
2488                                                 SetYenTail(Cur);\r
2489                                                 strcat(Cur, Pkt.File);\r
2490                                                 ReplaceAll(Cur, '/', '\\');\r
2491                                                 Attr = GetFileAttributes(Cur);\r
2492                                                 if((Attr != 0xFFFFFFFF) && (Attr & FILE_ATTRIBUTE_HIDDEN))\r
2493                                                         Ignore = YES;\r
2494                                         }\r
2495 \r
2496                                         if(Ignore == NO)\r
2497                                         {\r
2498                                                 Pkt.Node = NODE_DIR;\r
2499                                                 Pkt.Attr = 0;\r
2500                                                 Pkt.Size = 0;\r
2501                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2502                                                 AddFileList(&Pkt, Base);\r
2503 \r
2504                                                 if(Win == WIN_LOCAL)\r
2505                                                         MakeLocalTree(Name, Base);\r
2506                                                 else\r
2507                                                 {\r
2508                                                         AskRemoteCurDir(Cur, FMAX_PATH);\r
2509 \r
2510                                                         if((AskListCmdMode() == NO) &&\r
2511                                                            (AskUseNLST_R() == YES))\r
2512                                                                 MakeRemoteTree1(Name, Cur, Base, CancelCheckWork);\r
2513                                                         else\r
2514                                                                 MakeRemoteTree2(Name, Cur, Base, CancelCheckWork);\r
2515 \r
2516 //DispListList(*Base, "LIST");\r
2517 \r
2518                                                 }\r
2519                                         }\r
2520                                 }\r
2521                                 Pos = GetNextSelected(Win, Pos, All);\r
2522                         }\r
2523                 }\r
2524         }\r
2525         return;\r
2526 }\r
2527 \r
2528 \r
2529 /* デバッグ用 */\r
2530 /* ファイルリストの内容を表示 */\r
2531 static void DispListList(FILELIST *Pos, char *Title)\r
2532 {\r
2533         DoPrintf("############ %s ############", Title);\r
2534         while(Pos != NULL)\r
2535         {\r
2536                 DoPrintf("%d %s", Pos->Node, Pos->File);\r
2537                 Pos = Pos->Next;\r
2538         }\r
2539         DoPrintf("############ END ############");\r
2540         return;\r
2541 }\r
2542 \r
2543 \r
2544 /*----- Drag&Dropされたファイルをリストに登録する -----------------------------\r
2545 *\r
2546 *       Parameter\r
2547 *               WPARAM wParam : ドロップされたファイルの情報\r
2548 *               char *Cur : カレントディレクトリを返すバッファ\r
2549 *               FILELIST **Base : ファイルリストの先頭\r
2550 *\r
2551 *       Return Value\r
2552 *               なし\r
2553 *----------------------------------------------------------------------------*/\r
2554 \r
2555 void MakeDroppedFileList(WPARAM wParam, char *Cur, FILELIST **Base)\r
2556 {\r
2557         int Max;\r
2558         int i;\r
2559         char Name[FMAX_PATH+1];\r
2560         char Tmp[FMAX_PATH+1];\r
2561         FILELIST Pkt;\r
2562         HANDLE fHnd;\r
2563         WIN32_FIND_DATA Find;\r
2564 \r
2565         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2566 \r
2567         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2568         GetUpperDir(Cur);\r
2569 \r
2570         for(i = 0; i < Max; i++)\r
2571         {\r
2572                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2573 \r
2574                 if((GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY) == 0)\r
2575                 {\r
2576                         Pkt.Node = NODE_FILE;\r
2577                         strcpy(Pkt.File, GetFileName(Name));\r
2578 \r
2579                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2580                         if((fHnd = FindFirstFile(Name, &Find)) != INVALID_HANDLE_VALUE)\r
2581                         {\r
2582                                 FindClose(fHnd);\r
2583                                 Pkt.Time = Find.ftLastWriteTime;\r
2584                         }\r
2585                         AddFileList(&Pkt, Base);\r
2586                 }\r
2587         }\r
2588 \r
2589         GetCurrentDirectory(FMAX_PATH, Tmp);\r
2590         SetCurrentDirectory(Cur);\r
2591         for(i = 0; i < Max; i++)\r
2592         {\r
2593                 DragQueryFile((HDROP)wParam, i, Name, FMAX_PATH);\r
2594 \r
2595                 if(GetFileAttributes(Name) & FILE_ATTRIBUTE_DIRECTORY)\r
2596                 {\r
2597                         Pkt.Node = NODE_DIR;\r
2598                         strcpy(Pkt.File, GetFileName(Name));\r
2599                         AddFileList(&Pkt, Base);\r
2600 \r
2601                         MakeLocalTree(Pkt.File, Base);\r
2602                 }\r
2603         }\r
2604         SetCurrentDirectory(Tmp);\r
2605 \r
2606         DragFinish((HDROP)wParam);\r
2607 \r
2608         return;\r
2609 }\r
2610 \r
2611 \r
2612 /*----- Drag&Dropされたファイルがあるフォルダを取得する -----------------------\r
2613 *\r
2614 *       Parameter\r
2615 *               WPARAM wParam : ドロップされたファイルの情報\r
2616 *               char *Cur : カレントディレクトリを返すバッファ\r
2617 *\r
2618 *       Return Value\r
2619 *               なし\r
2620 *----------------------------------------------------------------------------*/\r
2621 \r
2622 void MakeDroppedDir(WPARAM wParam, char *Cur)\r
2623 {\r
2624         int Max;\r
2625 \r
2626         Max = DragQueryFile((HDROP)wParam, 0xFFFFFFFF, NULL, 0);\r
2627         DragQueryFile((HDROP)wParam, 0, Cur, FMAX_PATH);\r
2628         GetUpperDir(Cur);\r
2629         DragFinish((HDROP)wParam);\r
2630 \r
2631         return;\r
2632 }\r
2633 \r
2634 \r
2635 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(1)-------\r
2636 *\r
2637 *       Parameter\r
2638 *               char *Path : パス名\r
2639 *               char *Cur : カレントディレクトリ\r
2640 *               FILELIST **Base : ファイルリストの先頭\r
2641 *\r
2642 *       Return Value\r
2643 *               なし\r
2644 *\r
2645 *       Note\r
2646 *               NLST -alLR を使う\r
2647 *----------------------------------------------------------------------------*/\r
2648 \r
2649 static void MakeRemoteTree1(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2650 {\r
2651         int Sts;\r
2652 \r
2653         if(DoCWD(Path, NO, NO, NO) == FTP_COMPLETE)\r
2654         {\r
2655                 /* サブフォルダも含めたリストを取得 */\r
2656                 Sts = DoDirListCmdSkt("R", "", 999, CancelCheckWork);   /* NLST -alLR*/\r
2657                 DoCWD(Cur, NO, NO, NO);\r
2658 \r
2659                 if(Sts == FTP_COMPLETE)\r
2660                         AddRemoteTreeToFileList(999, Path, RDIR_NLST, Base);\r
2661         }\r
2662         return;\r
2663 }\r
2664 \r
2665 \r
2666 /*----- ホスト側のサブディレクトリ以下のファイルをリストに登録する(2)-------\r
2667 *\r
2668 *       Parameter\r
2669 *               char *Path : パス名\r
2670 *               char *Cur : カレントディレクトリ\r
2671 *               FILELIST **Base : ファイルリストの先頭\r
2672 *\r
2673 *       Return Value\r
2674 *               なし\r
2675 *\r
2676 *       Note\r
2677 *               各フォルダに移動してリストを取得\r
2678 *----------------------------------------------------------------------------*/\r
2679 \r
2680 static void MakeRemoteTree2(char *Path, char *Cur, FILELIST **Base, int *CancelCheckWork)\r
2681 {\r
2682         int Sts;\r
2683         FILELIST *CurList;\r
2684         FILELIST *Pos;\r
2685         FILELIST Pkt;\r
2686 \r
2687         /* VAX VMS は CWD xxx/yyy という指定ができないので */\r
2688         /* CWD xxx, Cwd yyy と複数に分ける                                       */\r
2689         if(AskHostType() != HTYPE_VMS)\r
2690                 Sts = DoCWD(Path, NO, NO, NO);\r
2691         else\r
2692         {\r
2693 #if defined(HAVE_OPENVMS)\r
2694                 /* OpenVMSの場合、ディレクトリ移動時は"HOGE.DIR;1"を"HOGE"にする */\r
2695                 ReformVMSDirName(Path, TRUE);\r
2696 #endif\r
2697                 Sts = DoCWDStepByStep(Path, Cur);\r
2698         }\r
2699 \r
2700         if(Sts == FTP_COMPLETE)\r
2701         {\r
2702                 Sts = DoDirListCmdSkt("", "", 999, CancelCheckWork);            /* NLST -alL*/\r
2703                 DoCWD(Cur, NO, NO, NO);\r
2704 \r
2705                 if(Sts == FTP_COMPLETE)\r
2706                 {\r
2707                         CurList = NULL;\r
2708                         AddRemoteTreeToFileList(999, Path, RDIR_CWD, &CurList);\r
2709                         CopyTmpListToFileList(Base, CurList);\r
2710 \r
2711                         Pos = CurList;\r
2712                         while(Pos != NULL)\r
2713                         {\r
2714                                 if(Pos->Node == NODE_DIR)\r
2715                                 {\r
2716                                         /* まずディレクトリ名をセット */\r
2717                                         strcpy(Pkt.File, Pos->File);\r
2718                                         Pkt.Node = NODE_DIR;\r
2719                                         Pkt.Size = 0;\r
2720                                         Pkt.Attr = 0;\r
2721                                         memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2722                                         AddFileList(&Pkt, Base);\r
2723 \r
2724                                         /* そのディレクトリの中を検索 */\r
2725                                         MakeRemoteTree2(Pos->File, Cur, Base, CancelCheckWork);\r
2726                                 }\r
2727                                 Pos = Pos->Next;\r
2728                         }\r
2729                         DeleteFileList(&CurList);\r
2730                 }\r
2731         }\r
2732         return;\r
2733 }\r
2734 \r
2735 \r
2736 /*----- ファイルリストの内容を別のファイルリストにコピー ----------------------\r
2737 *\r
2738 *       Parameter\r
2739 *               FILELIST **Base : コピー先\r
2740 *               FILELIST *List : コピー元\r
2741 *\r
2742 *       Return Value\r
2743 *               なし\r
2744 *\r
2745 *       Note\r
2746 *               コピーするのはファイルの情報だけ\r
2747 *               ディレクトリの情報はコピーしない\r
2748 *----------------------------------------------------------------------------*/\r
2749 \r
2750 static void CopyTmpListToFileList(FILELIST **Base, FILELIST *List)\r
2751 {\r
2752         while(List != NULL)\r
2753         {\r
2754                 if(List->Node == NODE_FILE)\r
2755                         AddFileList(List, Base);\r
2756 \r
2757                 List = List->Next;\r
2758         }\r
2759         return;\r
2760 }\r
2761 \r
2762 \r
2763 /*----- ホスト側のファイル情報をファイルリストに登録 --------------------------\r
2764 *\r
2765 *       Parameter\r
2766 *               int Num : テンポラリファイルのファイル名番号 (_ffftp.???)\r
2767 *               char *Path : パス名\r
2768 *               int IncDir : 再帰検索の方法 (RDIR_xxx)\r
2769 *               FILELIST **Base : ファイルリストの先頭\r
2770 *\r
2771 *       Return Value\r
2772 *               なし\r
2773 *----------------------------------------------------------------------------*/\r
2774 \r
2775 void AddRemoteTreeToFileList(int Num, char *Path, int IncDir, FILELIST **Base)\r
2776 {\r
2777         char Str[FMAX_PATH+1];\r
2778         char Dir[FMAX_PATH+1];\r
2779         char Name[FMAX_PATH+1];\r
2780         LONGLONG Size;\r
2781         FILETIME Time;\r
2782         int Attr;\r
2783         FILELIST Pkt;\r
2784         FILE *fd;\r
2785         int Node;\r
2786         int ListType;\r
2787         char Owner[OWNER_NAME_LEN+1];\r
2788         int Link;\r
2789         int InfoExist;\r
2790 \r
2791         MakeCacheFileName(Num, Str);\r
2792         if((fd = fopen(Str, "rb")) != NULL)\r
2793         {\r
2794                 strcpy(Dir, Path);\r
2795 \r
2796                 ListType = LIST_UNKNOWN;\r
2797 \r
2798                 while(GetListOneLine(Str, FMAX_PATH, fd) == FFFTP_SUCCESS)\r
2799                 {\r
2800                         if((ListType = AnalizeFileInfo(Str)) == LIST_UNKNOWN)\r
2801                         {\r
2802                                 if(MakeDirPath(Str, ListType, Path, Dir) == FFFTP_SUCCESS)\r
2803                                 {\r
2804                                         if(IncDir == RDIR_NLST)\r
2805                                         {\r
2806                                                 strcpy(Pkt.File, Dir);\r
2807                                                 Pkt.Node = NODE_DIR;\r
2808                                                 Pkt.Size = 0;\r
2809                                                 Pkt.Attr = 0;\r
2810                                                 memset(&Pkt.Time, 0, sizeof(FILETIME));\r
2811                                                 AddFileList(&Pkt, Base);\r
2812                                         }\r
2813                                 }\r
2814                         }\r
2815                         else\r
2816                         {\r
2817                                 Node = ResolvFileInfo(Str, ListType, Name, &Size, &Time, &Attr, Owner, &Link, &InfoExist);\r
2818 \r
2819                                 if(AskFilterStr(Name, Node) == YES)\r
2820                                 {\r
2821                                         if((Node == NODE_FILE) ||\r
2822                                            ((IncDir == RDIR_CWD) && (Node == NODE_DIR)))\r
2823                                         {\r
2824                                                 strcpy(Pkt.File, Dir);\r
2825                                                 if(strlen(Pkt.File) > 0)\r
2826                                                         SetSlashTail(Pkt.File);\r
2827                                                 strcat(Pkt.File, Name);\r
2828                                                 Pkt.Node = Node;\r
2829                                                 Pkt.Link = Link;\r
2830                                                 Pkt.Size = Size;\r
2831                                                 Pkt.Attr = Attr;\r
2832                                                 Pkt.Time = Time;\r
2833                                                 Pkt.InfoExist = InfoExist;\r
2834                                                 AddFileList(&Pkt, Base);\r
2835                                         }\r
2836                                 }\r
2837                         }\r
2838                 }\r
2839                 fclose(fd);\r
2840         }\r
2841         return;\r
2842 }\r
2843 \r
2844 \r
2845 /*----- ファイル一覧情報の1行を取得 ------------------------------------------\r
2846 *\r
2847 *       Parameter\r
2848 *               char *Buf : 1行の情報をセットするバッファ\r
2849 *               int Max : 最大文字数\r
2850 *               FILE *Fd : ストリーム\r
2851 *\r
2852 *       Return Value\r
2853 *               int ステータス (FFFTP_SUCCESS/FFFTP_FAIL)\r
2854 *\r
2855 *       Note\r
2856 *               VAX VMS以外の時は fgets(Buf, Max, Fd) と同じ\r
2857 *               Vax VMSの時は、複数行のファイル情報を1行にまとめる\r
2858 *----------------------------------------------------------------------------*/\r
2859 \r
2860 static int GetListOneLine(char *Buf, int Max, FILE *Fd)\r
2861 {\r
2862         char Tmp[FMAX_PATH+1];\r
2863         int Sts;\r
2864 \r
2865         Sts = FFFTP_FAIL;\r
2866         while((Sts == FFFTP_FAIL) && (fgets(Buf, Max, Fd) != NULL))\r
2867         {\r
2868                 Sts = FFFTP_SUCCESS;\r
2869                 RemoveReturnCode(Buf);\r
2870                 ReplaceAll(Buf, '\x08', ' ');\r
2871 \r
2872                 /* VAX VMSではファイル情報が複数行にわかれている     */\r
2873                 /* それを1行にまとめる                                                               */\r
2874                 if(AskHostType() == HTYPE_VMS)\r
2875                 {\r
2876                         if(strchr(Buf, ';') == NULL)    /* ファイル名以外の行 */\r
2877                                 Sts = FFFTP_FAIL;\r
2878                         else\r
2879                         {\r
2880                                 Max -= strlen(Buf);\r
2881                                 while(strchr(Buf, ')') == NULL)\r
2882                                 {\r
2883                                         if(fgets(Tmp, FMAX_PATH, Fd) != NULL)\r
2884                                         {\r
2885                                                 RemoveReturnCode(Tmp);\r
2886                                                 ReplaceAll(Buf, '\x08', ' ');\r
2887                                                 if((int)strlen(Tmp) > Max)\r
2888                                                         Tmp[Max] = NUL;\r
2889                                                 Max -= strlen(Tmp);\r
2890                                                 strcat(Buf, Tmp);\r
2891                                         }\r
2892                                         else\r
2893                                                 break;\r
2894                                 }\r
2895                         }\r
2896                 }\r
2897         }\r
2898 \r
2899 //      DoPrintf("List : %s", Buf);\r
2900 \r
2901         return(Sts);\r
2902 }\r
2903 \r
2904 \r
2905 /*----- サブディレクトリ情報の解析 --------------------------------------------\r
2906 *\r
2907 *       Parameter\r
2908 *               char *Str : ファイル情報(1行)\r
2909 *               int ListType : リストのタイプ\r
2910 *               char *Path : 先頭からのパス名\r
2911 *               char *Dir : ディレクトリ名\r
2912 *\r
2913 *       Return Value\r
2914 *               int ステータス\r
2915 *                       FFFTP_SUCCESS/FFFTP_FAIL=ディレクトリ情報でない\r
2916 *----------------------------------------------------------------------------*/\r
2917 \r
2918 static int MakeDirPath(char *Str, int ListType, char *Path, char *Dir)\r
2919 {\r
2920         int Sts;\r
2921 \r
2922         Sts = FFFTP_FAIL;\r
2923         switch(ListType)\r
2924         {\r
2925                 case LIST_ACOS :\r
2926                 case LIST_ACOS_4 :\r
2927                         break;\r
2928 \r
2929                 default:\r
2930                         if(*(Str + strlen(Str) - 1) == ':')             /* 最後が : ならサブディレクトリ */\r
2931                         {\r
2932                                 if(strcmp(Str, ".:") != 0)\r
2933                                 {\r
2934                                         if((strncmp(Str, "./", 2) == 0) ||\r
2935                                            (strncmp(Str, ".\\", 2) == 0))\r
2936                                         {\r
2937                                                 Str += 2;\r
2938                                         }\r
2939 \r
2940                                         if(strlen(Str) > 1)\r
2941                                         {