OSDN Git Service

Update PEM file.
[ffftp/ffftp.git] / misc.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 #define STRICT\r
31 #include <stdio.h>\r
32 #include <stdlib.h>\r
33 #include <stdarg.h>\r
34 #include <string.h>\r
35 #include <mbstring.h>\r
36 // IPv6対応\r
37 //#include <winsock.h>\r
38 #include <winsock2.h>\r
39 #include <windowsx.h>\r
40 #include <commctrl.h>\r
41 #include <shlobj.h>\r
42 #include <locale.h>\r
43 \r
44 #include "common.h"\r
45 #include "resource.h"\r
46 \r
47 #include <htmlhelp.h>\r
48 #include "helpid.h"\r
49 \r
50 // UTF-8対応\r
51 #undef __MBSWRAPPER_H__\r
52 #include "mbswrapper.h"\r
53 \r
54 \r
55 \r
56 /*===== 入力ダイアログデータのストラクチャ =====*/\r
57 \r
58 typedef struct {\r
59         char Title[80];                 /* ダイアログのタイトル */\r
60         char Str[FMAX_PATH+1];  /* デフォルト文字列/入力された文字列(Output) */\r
61         int MaxLen;                             /* 文字列の最長 */\r
62         int Anonymous;                  /* Anonymousフラグ(Output) */\r
63 } DIALOGDATA;\r
64 \r
65 /*===== プロトタイプ =====*/\r
66 \r
67 // 64ビット対応\r
68 //static BOOL CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
69 static INT_PTR CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam);\r
70 \r
71 /*===== 外部参照 =====*/\r
72 \r
73 extern HWND hHelpWin;\r
74 \r
75 /*===== ローカルなワーク =====*/\r
76 \r
77 static DIALOGDATA *DialogData;          /* 入力ダイアログデータ */\r
78 static int HelpPage;\r
79 \r
80 \r
81 \r
82 /*----- 入力ダイアログを表示 --------------------------------------------------\r
83 *\r
84 *       Parameter\r
85 *               int Res : ダイアログボックスのID\r
86 *               HWND hWnd : 親ウインドウのウインドウハンドル\r
87 *               char *Title : ウインドウタイトル (NULL=設定しない)\r
88 *               char *Buf : エディットボックスの初期文字列/入力文字列を返すバッファ\r
89 *               int Max : バッファのサイズ (FMAX_PATH+1以下であること)\r
90 *               int *Flg : フラグの初期値/フラグを返すワーク\r
91 *               int Help : ヘルプのコンテキスト番号\r
92 *\r
93 *       Return Value\r
94 *               int ステータス (YES/NO=取り消し)\r
95 *\r
96 *       Note\r
97 *               ダイアログは1個のEditBoxと1個のButtonを持つものを使う\r
98 *----------------------------------------------------------------------------*/\r
99 \r
100 int InputDialogBox(int Res, HWND hWnd, char *Title, char *Buf, int Max, int *Flg, int Help)\r
101 {\r
102         int Ret;\r
103         DIALOGDATA dData;\r
104 \r
105         dData.MaxLen = Max;\r
106         memset(dData.Str, NUL, FMAX_PATH+1);\r
107         strncpy(dData.Str, Buf, FMAX_PATH);\r
108         strcpy(dData.Title, "");\r
109         if(Title != NULL)\r
110                 strcpy(dData.Title, Title);\r
111         dData.Anonymous = *Flg;\r
112         DialogData = &dData;\r
113         HelpPage = Help;\r
114 \r
115         Ret = DialogBox(GetFtpInst(), MAKEINTRESOURCE(Res), hWnd, InputDialogCallBack);\r
116 \r
117         if(Ret == YES)\r
118         {\r
119                 memset(Buf, NUL, Max);\r
120                 strncpy(Buf, dData.Str, Max-1);\r
121                 *Flg = dData.Anonymous;\r
122         }\r
123         return(Ret);\r
124 }\r
125 \r
126 \r
127 /*----- 入力ダイアログのコールバック ------------------------------------------\r
128 *\r
129 *       Parameter\r
130 *               HWND hDlg : ウインドウハンドル\r
131 *               UINT message : メッセージ番号\r
132 *               WPARAM wParam : メッセージの WPARAM 引数\r
133 *               LPARAM lParam : メッセージの LPARAM 引数\r
134 *\r
135 *       Return Value\r
136 *               BOOL TRUE/FALSE\r
137 *----------------------------------------------------------------------------*/\r
138 \r
139 // 64ビット対応\r
140 //static BOOL CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
141 static INT_PTR CALLBACK InputDialogCallBack(HWND hDlg, UINT iMessage, WPARAM wParam, LPARAM lParam)\r
142 {\r
143         char Tmp[FMAX_PATH+1];\r
144 \r
145         switch (iMessage)\r
146         {\r
147                 case WM_INITDIALOG :\r
148                         // プロセス保護\r
149                         ProtectAllEditControls(hDlg);\r
150                         if(strlen(DialogData->Title) != 0)\r
151                                 SendMessage(hDlg, WM_SETTEXT, 0, (LPARAM)DialogData->Title);\r
152                         SendDlgItemMessage(hDlg, INP_INPSTR, EM_LIMITTEXT, DialogData->MaxLen-1, 0);\r
153                         SendDlgItemMessage(hDlg, INP_INPSTR, WM_SETTEXT, 0, (LPARAM)DialogData->Str);\r
154                         SendDlgItemMessage(hDlg, INP_ANONYMOUS, BM_SETCHECK, DialogData->Anonymous, 0);\r
155                         return(TRUE);\r
156 \r
157                 case WM_COMMAND :\r
158                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
159                         {\r
160                                 case IDOK :\r
161                                         SendDlgItemMessage(hDlg, INP_INPSTR, WM_GETTEXT, DialogData->MaxLen, (LPARAM)DialogData->Str);\r
162                                         DialogData->Anonymous = SendDlgItemMessage(hDlg, INP_ANONYMOUS, BM_GETCHECK, 0, 0);\r
163                                         EndDialog(hDlg, YES);\r
164                                         break;\r
165 \r
166                                 case IDCANCEL :\r
167                                         EndDialog(hDlg, NO);\r
168                                         break;\r
169 \r
170                                 case IDHELP :\r
171                                         hHelpWin = HtmlHelp(NULL, AskHelpFilePath(), HH_HELP_CONTEXT, HelpPage);\r
172                                         break;\r
173 \r
174                                 case INP_BROWSE :\r
175                                         if(SelectDir(hDlg, Tmp, FMAX_PATH) == TRUE)\r
176                                                 SendDlgItemMessage(hDlg, INP_INPSTR, WM_SETTEXT, 0, (LPARAM)Tmp);\r
177                                         break;\r
178                         }\r
179             return(TRUE);\r
180         }\r
181         return(FALSE);\r
182 }\r
183 \r
184 \r
185 /*----- [実行]と[取消]だけのダイアログの共通コールバック関数 --------------\r
186 *\r
187 *       Parameter\r
188 *               HWND hDlg : ウインドウハンドル\r
189 *               UINT message : メッセージ番号\r
190 *               WPARAM wParam : メッセージの WPARAM 引数\r
191 *               LPARAM lParam : メッセージの LPARAM 引数\r
192 *\r
193 *       Return Value\r
194 *               BOOL TRUE/FALSE\r
195 *----------------------------------------------------------------------------*/\r
196 \r
197 // 64ビット対応\r
198 //BOOL CALLBACK ExeEscDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
199 INT_PTR CALLBACK ExeEscDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
200 {\r
201         switch (message)\r
202         {\r
203                 case WM_INITDIALOG :\r
204                         return(TRUE);\r
205 \r
206                 case WM_COMMAND :\r
207                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
208                         {\r
209                                 case IDOK :\r
210                                         EndDialog(hDlg, YES);\r
211                                         break;\r
212 \r
213                                 case IDCANCEL :\r
214                                         EndDialog(hDlg, NO);\r
215                                         break;\r
216                         }\r
217                         return(TRUE);\r
218         }\r
219     return(FALSE);\r
220 }\r
221 \r
222 \r
223 /*----- [実行]と[取消]だけのダイアログの共通コールバック関数(テキスト表示つき)\r
224 *\r
225 *       Parameter\r
226 *               HWND hDlg : ウインドウハンドル\r
227 *               UINT message : メッセージ番号\r
228 *               WPARAM wParam : メッセージの WPARAM 引数\r
229 *               LPARAM lParam : メッセージの LPARAM 引数\r
230 *\r
231 *       Return Value\r
232 *               BOOL TRUE/FALSE\r
233 *----------------------------------------------------------------------------*/\r
234 \r
235 // 64ビット対応\r
236 //BOOL CALLBACK ExeEscTextDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
237 INT_PTR CALLBACK ExeEscTextDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)\r
238 {\r
239         switch (message)\r
240         {\r
241                 case WM_INITDIALOG :\r
242                         SendDlgItemMessage(hDlg, COMMON_TEXT, WM_SETTEXT, 0, lParam);\r
243                         return(TRUE);\r
244 \r
245                 case WM_COMMAND :\r
246                         switch(GET_WM_COMMAND_ID(wParam, lParam))\r
247                         {\r
248                                 case IDOK :\r
249                                         EndDialog(hDlg, YES);\r
250                                         break;\r
251 \r
252                                 case IDCANCEL :\r
253                                         EndDialog(hDlg, NO);\r
254                                         break;\r
255                         }\r
256                         return(TRUE);\r
257         }\r
258     return(FALSE);\r
259 }\r
260 \r
261 \r
262 /*----- 文字列の最後に "\" を付ける -------------------------------------------\r
263 *\r
264 *       Parameter\r
265 *               char *Str : 文字列\r
266 *\r
267 *       Return Value\r
268 *               なし\r
269 *\r
270 *       Note\r
271 *               オリジナルの文字列 char *Str が変更されます。\r
272 *----------------------------------------------------------------------------*/\r
273 \r
274 void SetYenTail(char *Str)\r
275 {\r
276         if(_mbscmp(_mbsninc(Str, _mbslen(Str) - 1), "\\") != 0)\r
277                 strcat(Str, "\\");\r
278 \r
279         return;;\r
280 }\r
281 \r
282 \r
283 /*----- 文字列の最後の "\" を取り除く -----------------------------------------\r
284 *\r
285 *       Parameter\r
286 *               char *Str : 文字列\r
287 *\r
288 *       Return Value\r
289 *               なし\r
290 *\r
291 *       Note\r
292 *               オリジナルの文字列 char *Str が変更されます。\r
293 *----------------------------------------------------------------------------*/\r
294 \r
295 void RemoveYenTail(char *Str)\r
296 {\r
297         char *Pos;\r
298 \r
299         if(strlen(Str) > 0)\r
300         {\r
301                 Pos = _mbsninc(Str, _mbslen(Str) - 1);\r
302                 if(_mbscmp(Pos, "\\") == 0)\r
303                         *Pos = NUL;\r
304         }\r
305         return;;\r
306 }\r
307 \r
308 \r
309 /*----- 文字列の最後に "/" を付ける -------------------------------------------\r
310 *\r
311 *       Parameter\r
312 *               char *Str : 文字列\r
313 *\r
314 *       Return Value\r
315 *               なし\r
316 *\r
317 *       Note\r
318 *               オリジナルの文字列 char *Str が変更されます。\r
319 *----------------------------------------------------------------------------*/\r
320 \r
321 void SetSlashTail(char *Str)\r
322 {\r
323 #if defined(HAVE_TANDEM)\r
324     /* Tandem では / の代わりに . を追加 */\r
325         if(AskHostType() == HTYPE_TANDEM) {\r
326                 if(_mbscmp(_mbsninc(Str, _mbslen(Str) - 1), ".") != 0)\r
327                         strcat(Str, ".");\r
328         } else\r
329 #endif\r
330         if(_mbscmp(_mbsninc(Str, _mbslen(Str) - 1), "/") != 0)\r
331                 strcat(Str, "/");\r
332 \r
333         return;\r
334 }\r
335 \r
336 \r
337 /*----- 文字列から改行コードを取り除く ----------------------------------------\r
338 *\r
339 *       Parameter\r
340 *               char *Str : 文字列\r
341 *\r
342 *       Return Value\r
343 *               なし\r
344 *\r
345 *       Note\r
346 *               オリジナルの文字列 char *Str が変更されます。\r
347 *----------------------------------------------------------------------------*/\r
348 \r
349 void RemoveReturnCode(char *Str)\r
350 {\r
351         char *Pos;\r
352 \r
353         if((Pos = strchr(Str, 0x0D)) != NULL)\r
354                 *Pos = NUL;\r
355         if((Pos = strchr(Str, 0x0A)) != NULL)\r
356                 *Pos = NUL;\r
357         return;\r
358 }\r
359 \r
360 \r
361 /*----- 文字列内の特定の文字を全て置き換える ----------------------------------\r
362 *\r
363 *       Parameter\r
364 *               char *Str : 文字列\r
365 *               char Src : 検索文字\r
366 *               char Dst : 置換文字\r
367 *\r
368 *       Return Value\r
369 *               なし\r
370 *----------------------------------------------------------------------------*/\r
371 \r
372 void ReplaceAll(char *Str, char Src, char Dst)\r
373 {\r
374         char *Pos;\r
375 \r
376 /* Tandem ではノード名の変換を行わない */\r
377 /* 最初の1文字が \ でもそのままにする */\r
378 #if defined(HAVE_TANDEM)\r
379         if (AskRealHostType() == HTYPE_TANDEM && strlen(Str) > 0)\r
380                 Str++;\r
381 #endif\r
382         while((Pos = _mbschr(Str, Src)) != NULL)\r
383                 *Pos = Dst;\r
384         return;\r
385 }\r
386 \r
387 \r
388 /*----- 数字もしくは特定の1文字かチェック ------------------------------------\r
389 *\r
390 *       Parameter\r
391 *               int Ch : チェックする文字\r
392 *               int Sym : 記号\r
393 *\r
394 *       Return Value\r
395 *               int ステータス\r
396 *                       0=数字でも特定の記号でもない\r
397 *----------------------------------------------------------------------------*/\r
398 \r
399 int IsDigitSym(int Ch, int Sym)\r
400 {\r
401         int Ret;\r
402 \r
403         if((Ret = IsDigit(Ch)) == 0)\r
404         {\r
405                 if((Sym != NUL) && (Sym == Ch))\r
406                         Ret = 1;\r
407         }\r
408         return(Ret);\r
409 }\r
410 \r
411 \r
412 /*----- 文字列が全て同じ文字かチェック ----------------------------------------\r
413 *\r
414 *       Parameter\r
415 *               char *Str : 文字列\r
416 *               int Ch : 文字\r
417 *\r
418 *       Return Value\r
419 *               int ステータス\r
420 *                       YES/NO\r
421 *----------------------------------------------------------------------------*/\r
422 \r
423 int StrAllSameChar(char *Str, char Ch)\r
424 {\r
425         int Ret;\r
426 \r
427         Ret = YES;\r
428         while(*Str != NUL)\r
429         {\r
430                 if(*Str != Ch)\r
431                 {\r
432                         Ret = NO;\r
433                         break;\r
434                 }\r
435                 Str++;\r
436         }\r
437         return(Ret);\r
438 }\r
439 \r
440 \r
441 /*----- 文字列の末尾のスペースを削除 ------------------------------------------\r
442 *\r
443 *       Parameter\r
444 *               char *Str : 文字列\r
445 *\r
446 *       Return Value\r
447 *               なし\r
448 *----------------------------------------------------------------------------*/\r
449 \r
450 void RemoveTailingSpaces(char *Str)\r
451 {\r
452         char *Pos;\r
453 \r
454         Pos = Str + strlen(Str);\r
455         while(--Pos > Str)\r
456         {\r
457                 if(*Pos != ' ')\r
458                         break;\r
459                 *Pos = NUL;\r
460         }\r
461         return;\r
462 }\r
463 \r
464 \r
465 /*----- 大文字/小文字を区別しないstrstr --------------------------------------\r
466 *\r
467 *       Parameter\r
468 *               char *s1 : 文字列1\r
469 *               char *s2 : 文字列2\r
470 *\r
471 *       Return Value\r
472 *               char *文字列1中で文字列2が見つかった位置\r
473 *                       NULL=見つからなかった\r
474 *----------------------------------------------------------------------------*/\r
475 \r
476 char *stristr(char *s1, char *s2)\r
477 {\r
478         char *Ret;\r
479 \r
480         Ret = NULL;\r
481         while(*s1 != NUL)\r
482         {\r
483                 if((tolower(*s1) == tolower(*s2)) &&\r
484                    (_strnicmp(s1, s2, strlen(s2)) == 0))\r
485                 {\r
486                         Ret = s1;\r
487                         break;\r
488                 }\r
489                 s1++;\r
490         }\r
491         return(Ret);\r
492 }\r
493 \r
494 \r
495 /*----- 文字列中のスペースで区切られた次のフィールドを返す --------------------\r
496 *\r
497 *       Parameter\r
498 *               char *Str : 文字列\r
499 *\r
500 *       Return Value\r
501 *               char *次のフィールド\r
502 *                       NULL=見つからなかった\r
503 *----------------------------------------------------------------------------*/\r
504 \r
505 char *GetNextField(char *Str)\r
506 {\r
507         if((Str = strchr(Str, ' ')) != NULL)\r
508         {\r
509                 while(*Str == ' ')\r
510                 {\r
511                         if(*Str == NUL)\r
512                         {\r
513                                 Str = NULL;\r
514                                 break;\r
515                         }\r
516                         Str++;\r
517                 }\r
518         }\r
519         return(Str);\r
520 }\r
521 \r
522 \r
523 /*----- 現在のフィールドの文字列をコピーする ----------------------------------\r
524 *\r
525 *       Parameter\r
526 *               char *Str : 文字列\r
527 *               char *Buf : コピー先\r
528 *               int Max : 最大文字数\r
529 *\r
530 *       Return Value\r
531 *               int ステータス\r
532 *                       FFFTP_SUCCESS/FFFTP_FAIL=長さが長すぎる\r
533 *----------------------------------------------------------------------------*/\r
534 \r
535 int GetOneField(char *Str, char *Buf, int Max)\r
536 {\r
537         int Sts;\r
538         char *Pos;\r
539 \r
540         Sts = FFFTP_FAIL;\r
541         if((Pos = strchr(Str, ' ')) == NULL)\r
542         {\r
543                 if((int)strlen(Str) <= Max)\r
544                 {\r
545                         strcpy(Buf, Str);\r
546                         Sts = FFFTP_SUCCESS;\r
547                 }\r
548         }\r
549         else\r
550         {\r
551                 if(Pos - Str <= Max)\r
552                 {\r
553                         strncpy(Buf, Str, Pos - Str);\r
554                         *(Buf + (Pos - Str)) = NUL;\r
555                         Sts = FFFTP_SUCCESS;\r
556                 }\r
557         }\r
558         return(Sts);\r
559 }\r
560 \r
561 \r
562 /*----- カンマを取り除く ------------------------------------------------------\r
563 *\r
564 *       Parameter\r
565 *               char *Str : 文字列\r
566 *\r
567 *       Return Value\r
568 *               なし\r
569 *----------------------------------------------------------------------------*/\r
570 \r
571 void RemoveComma(char *Str)\r
572 {\r
573         char *Put;\r
574 \r
575         Put = Str;\r
576         while(*Str != NUL)\r
577         {\r
578                 if(*Str != ',')\r
579                 {\r
580                         *Put = *Str;\r
581                         Put++;\r
582                 }\r
583                 Str++;\r
584         }\r
585         *Put = NUL;\r
586         return;\r
587 }\r
588 \r
589 \r
590 /*----- パス名の中のファイル名の先頭を返す ------------------------------------\r
591 *\r
592 *       Parameter\r
593 *               char *Path : パス名\r
594 *\r
595 *       Return Value\r
596 *               char *ファイル名の先頭\r
597 *\r
598 *       Note\r
599 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
600 *----------------------------------------------------------------------------*/\r
601 \r
602 char *GetFileName(char *Path)\r
603 {\r
604         char *Pos;\r
605 \r
606         if((Pos = _mbschr(Path, ':')) != NULL)\r
607                 Path = Pos + 1;\r
608 \r
609         if((Pos = _mbsrchr(Path, '\\')) != NULL)\r
610                 Path = Pos + 1;\r
611 \r
612         if((Pos = _mbsrchr(Path, '/')) != NULL)\r
613                 Path = Pos + 1;\r
614 \r
615 #if defined(HAVE_TANDEM)\r
616         /* Tandem は . がデリミッタとなる */\r
617         if((AskHostType() == HTYPE_TANDEM) && ((Pos = _mbsrchr(Path, '.')) != NULL))\r
618                 Path = Pos + 1;\r
619 #endif\r
620         return(Path);\r
621 }\r
622 \r
623 \r
624 /*----- ツールの表示名を返す --------------------------------------------------\r
625 *\r
626 *       Parameter\r
627 *               char *Path : パス名\r
628 *\r
629 *       Return Value\r
630 *               char * : 表示名\r
631 *----------------------------------------------------------------------------*/\r
632 \r
633 char *GetToolName(char *Path)\r
634 {\r
635         char *Pos;\r
636 \r
637         if((Pos = _mbschr(Path, ':')) != NULL)\r
638                 Path = Pos + 1;\r
639 \r
640         if((Pos = _mbsrchr(Path, '\\')) != NULL)\r
641                 Path = Pos + 1;\r
642 \r
643         return(Path);\r
644 }\r
645 \r
646 \r
647 /*----- パス名の中の拡張子の先頭を返す ----------------------------------------\r
648 *\r
649 *       Parameter\r
650 *               char *Path : パス名\r
651 *\r
652 *       Return Value\r
653 *               char *拡張子の先頭\r
654 *----------------------------------------------------------------------------*/\r
655 \r
656 char *GetFileExt(char *Path)\r
657 {\r
658         char *Ret;\r
659 \r
660         Ret = _mbschr(Path, NUL);\r
661         if((_mbscmp(Path, ".") != 0) &&\r
662            (_mbscmp(Path, "..") != 0))\r
663         {\r
664                 while((Path = _mbschr(Path, '.')) != NULL)\r
665                 {\r
666                         Path++;\r
667                         Ret = Path;\r
668                 }\r
669         }\r
670         return(Ret);\r
671 }\r
672 \r
673 \r
674 /*----- パス名からファイル名を取り除く ----------------------------------------\r
675 *\r
676 *       Parameter\r
677 *               char *Path : パス名\r
678 *               char *Buf : ファイル名を除いたパス名のコピー先\r
679 *\r
680 *       Return Value\r
681 *               なし\r
682 *\r
683 *       Note\r
684 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
685 *----------------------------------------------------------------------------*/\r
686 \r
687 void RemoveFileName(char *Path, char *Buf)\r
688 {\r
689         char *Pos;\r
690 \r
691         strcpy(Buf, Path);\r
692 \r
693         if((Pos = _mbsrchr(Buf, '/')) != NULL)\r
694                 *Pos = NUL;\r
695         else if((Pos = _mbsrchr(Buf, '\\')) != NULL)\r
696         {\r
697                 if((Pos == Buf) || \r
698                    ((Pos != Buf) && (*(Pos - 1) != ':')))\r
699                         *Pos = NUL;\r
700         }\r
701         return;\r
702 }\r
703 \r
704 \r
705 /*----- 上位ディレクトリのパス名を取得 ----------------------------------------\r
706 *\r
707 *       Parameter\r
708 *               char *Path : パス名\r
709 *\r
710 *       Return Value\r
711 *               なし\r
712 *\r
713 *       Note\r
714 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
715 *               最初の "\"や"/"は残す\r
716 *                       例) "/pub"   --> "/"\r
717 *                       例) "C:\DOS" --> "C:\"\r
718 *----------------------------------------------------------------------------*/\r
719 \r
720 void GetUpperDir(char *Path)\r
721 {\r
722         char *Top;\r
723         char *Pos;\r
724 \r
725         if(((Top = _mbschr(Path, '/')) != NULL) ||\r
726            ((Top = _mbschr(Path, '\\')) != NULL))\r
727         {\r
728                 Top++;\r
729                 if(((Pos = _mbsrchr(Top, '/')) != NULL) ||\r
730                    ((Pos = _mbsrchr(Top, '\\')) != NULL))\r
731                         *Pos = NUL;\r
732                 else\r
733                         *Top = NUL;\r
734         }\r
735         return;\r
736 }\r
737 \r
738 \r
739 /*----- 上位ディレクトリのパス名を取得 ----------------------------------------\r
740 *\r
741 *       Parameter\r
742 *               char *Path : パス名\r
743 *\r
744 *       Return Value\r
745 *               なし\r
746 *\r
747 *       Note\r
748 *               ディレクトリの区切り記号は "\" と "/" の両方が有効\r
749 *               最初の "\"や"/"も消す\r
750 *                       例) "/pub"   --> ""\r
751 *                       例) "C:\DOS" --> "C:"\r
752 *----------------------------------------------------------------------------*/\r
753 \r
754 void GetUpperDirEraseTopSlash(char *Path)\r
755 {\r
756         char *Pos;\r
757 \r
758         if(((Pos = _mbsrchr(Path, '/')) != NULL) ||\r
759            ((Pos = _mbsrchr(Path, '\\')) != NULL))\r
760                 *Pos = NUL;\r
761         else\r
762                 *Path = NUL;\r
763 \r
764         return;\r
765 }\r
766 \r
767 \r
768 /*----- ディレクトリの階層数を返す --------------------------------------------\r
769 *\r
770 *       Parameter\r
771 *               char *Path : パス名\r
772 *\r
773 *       Return Value\r
774 *               なし\r
775 *\r
776 *       Note\r
777 *               単に '\' と '/'の数を返すだけ\r
778 *----------------------------------------------------------------------------*/\r
779 \r
780 int AskDirLevel(char *Path)\r
781 {\r
782         char *Pos;\r
783         int Level;\r
784 \r
785         Level = 0;\r
786         while(((Pos = _mbschr(Path, '/')) != NULL) ||\r
787                   ((Pos = _mbschr(Path, '\\')) != NULL))\r
788         {\r
789                 Path = Pos + 1;\r
790                 Level++;\r
791         }\r
792         return(Level);\r
793 }\r
794 \r
795 \r
796 /*----- ファイルサイズを文字列に変換する --------------------------------------\r
797 *\r
798 *       Parameter\r
799 *               double Size : ファイルサイズ\r
800 *               char *Buf : 文字列を返すバッファ\r
801 *\r
802 *       Return Value\r
803 *               なし\r
804 *----------------------------------------------------------------------------*/\r
805 \r
806 void MakeSizeString(double Size, char *Buf)\r
807 {\r
808         // 修正\r
809 //      if(Size >= (1024*1024))\r
810 //      {\r
811 //              Size /= (1024*1024);\r
812 //              sprintf(Buf, "%.2fM Bytes", Size);\r
813 //      }\r
814 //      else if (Size >= 1024)\r
815 //      {\r
816 //              Size /= 1024;\r
817 //              sprintf(Buf, "%.2fK Bytes", Size);\r
818 //      }\r
819 //      else\r
820 //              sprintf(Buf, "%.0f Bytes", Size);\r
821         if(Size >= 1024.0)\r
822         {\r
823                 Size /= 1024.0;\r
824                 if(Size >= 1024.0)\r
825                 {\r
826                         Size /= 1024.0;\r
827                         if(Size >= 1024.0)\r
828                         {\r
829                                 Size /= 1024.0;\r
830                                 if(Size >= 1024.0)\r
831                                 {\r
832                                         Size /= 1024.0;\r
833                                         sprintf(Buf, "%.2lfT Bytes", Size);\r
834                                 }\r
835                                 else\r
836                                         sprintf(Buf, "%.2lfG Bytes", Size);\r
837                         }\r
838                         else\r
839                                 sprintf(Buf, "%.2lfM Bytes", Size);\r
840                 }\r
841                 else\r
842                         sprintf(Buf, "%.2lfK Bytes", Size);\r
843         }\r
844         else\r
845                 sprintf(Buf, "%.0lf Bytes", Size);\r
846 \r
847         return;\r
848 }\r
849 \r
850 \r
851 /*----- StaticTextの領域に収まるようにパス名を整形して表示 --------------------\r
852 *\r
853 *       Parameter\r
854 *               HWND hWnd : ウインドウハンドル\r
855 *               char *Str : 文字列 (長さはFMAX_PATH以下)\r
856 *\r
857 *       Return Value\r
858 *               なし\r
859 *----------------------------------------------------------------------------*/\r
860 \r
861 void DispStaticText(HWND hWnd, char *Str)\r
862 {\r
863         char Buf[FMAX_PATH+1];\r
864         char *Pos;\r
865         char *Tmp;\r
866         RECT Rect;\r
867         SIZE fSize;\r
868         HDC hDC;\r
869         int Force;\r
870 \r
871         GetClientRect(hWnd, &Rect);\r
872         Rect.right -= Rect.left;\r
873 \r
874         hDC = GetDC(hWnd);\r
875         strcpy(Buf, Str);\r
876         Pos = Buf;\r
877         Force = NO;\r
878         while(Force == NO)\r
879         {\r
880                 GetTextExtentPoint32(hDC, Pos, strlen(Pos), &fSize);\r
881 \r
882                 if(fSize.cx <= Rect.right)\r
883                         break;\r
884 \r
885                 if(_mbslen(Pos) <= 4)\r
886                         Force = YES;\r
887                 else\r
888                 {\r
889                         Pos = _mbsninc(Pos, 4);\r
890                         if((Tmp = _mbschr(Pos, '\\')) == NULL)\r
891                                 Tmp = _mbschr(Pos, '/');\r
892 \r
893                         if(Tmp == NULL)\r
894                                 Tmp = _mbsninc(Pos, 4);\r
895 \r
896                         Pos = Tmp - 3;\r
897                         memset(Pos, '.', 3);\r
898                 }\r
899         }\r
900         ReleaseDC(hWnd, hDC);\r
901 \r
902         SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)Pos);\r
903         return;\r
904 }\r
905 \r
906 \r
907 /*----- 文字列アレイの長さを求める --------------------------------------------\r
908 *\r
909 *       Parameter\r
910 *               char *Str : 文字列アレイ (末尾はNUL2つ)\r
911 *\r
912 *       Return Value\r
913 *               int 長さ\r
914 *\r
915 *       Note\r
916 *               終端の2つのNULのうちの最後の物は数えない\r
917 *                       StrMultiLen("") = 0\r
918 *                       StrMultiLen("abc\0xyz\0") = 8\r
919 *                       StrMultiLen("abc") = 終端が2つのNULでないので求められない\r
920 *----------------------------------------------------------------------------*/\r
921 \r
922 int StrMultiLen(char *Str)\r
923 {\r
924         int Len;\r
925         int Tmp;\r
926 \r
927         Len = 0;\r
928         while(*Str != NUL)\r
929         {\r
930                 Tmp = strlen(Str) + 1;\r
931                 Str += Tmp;\r
932                 Len += Tmp;\r
933         }\r
934         return(Len);\r
935 }\r
936 \r
937 \r
938 /*----- RECTをクライアント座標からスクリーン座標に変換 ------------------------\r
939 *\r
940 *       Parameter\r
941 *               HWND hWnd : ウインドウハンドル\r
942 *               RECT *Rect : RECT\r
943 *\r
944 *       Return Value\r
945 *               なし\r
946 *----------------------------------------------------------------------------*/\r
947 \r
948 void RectClientToScreen(HWND hWnd, RECT *Rect)\r
949 {\r
950         POINT Tmp;\r
951 \r
952         Tmp.x = Rect->left;\r
953         Tmp.y = Rect->top;\r
954         ClientToScreen(hWnd, &Tmp);\r
955         Rect->left = Tmp.x;\r
956         Rect->top = Tmp.y;\r
957 \r
958         Tmp.x = Rect->right;\r
959         Tmp.y = Rect->bottom;\r
960         ClientToScreen(hWnd, &Tmp);\r
961         Rect->right = Tmp.x;\r
962         Rect->bottom = Tmp.y;\r
963 \r
964         return;\r
965 }\r
966 \r
967 \r
968 /*----- 16進文字をバイナリに変換 ----------------------------------------------\r
969 *\r
970 *       Parameter\r
971 *               char Ch : 16進文字\r
972 *\r
973 *       Return Value\r
974 *               int バイナリ値\r
975 *----------------------------------------------------------------------------*/\r
976 \r
977 int hex2bin(char Ch)\r
978 {\r
979         int Ret;\r
980 \r
981         if((Ch >= '0') && (Ch <= '9'))\r
982                 Ret = Ch - '0';\r
983         else if((Ch >= 'A') && (Ch <= 'F'))\r
984                 Ret = Ch - 'A' + 10;\r
985         else if((Ch >= 'a') && (Ch <= 'f'))\r
986                 Ret = Ch - 'a' + 10;\r
987 \r
988         return(Ret);\r
989 }\r
990 \r
991 \r
992 /*----- UNC文字列を分解する ------------------------------------------------\r
993 *\r
994 *       Parameter\r
995 *               char *unc : UNC文字列\r
996 *               char *Host : ホスト名をコピーするバッファ (サイズは HOST_ADRS_LEN+1)\r
997 *               char *Path : パス名をコピーするバッファ (サイズは FMAX_PATH+1)\r
998 *               char *File : ファイル名をコピーするバッファ (サイズは FMAX_PATH+1)\r
999 *               char *User : ユーザ名をコピーするバッファ (サイズは USER_NAME_LEN+1)\r
1000 *               char *Pass : パスワードをコピーするバッファ (サイズは PASSWORD_LEN+1)\r
1001 *               int *Port : ポート番号をコピーするバッファ\r
1002 *\r
1003 *       Return Value\r
1004 *               int ステータス\r
1005 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1006 *\r
1007 *       "\"は全て"/"に置き換える\r
1008 *----------------------------------------------------------------------------*/\r
1009 \r
1010 int SplitUNCpath(char *unc, char *Host, char *Path, char *File, char *User, char *Pass, int *Port)\r
1011 {\r
1012         int Sts;\r
1013         char *Pos1;\r
1014         char *Pos2;\r
1015         char Tmp[FMAX_PATH+1];\r
1016 \r
1017         memset(Host, NUL, HOST_ADRS_LEN+1);\r
1018         memset(Path, NUL, FMAX_PATH+1);\r
1019         memset(File, NUL, FMAX_PATH+1);\r
1020         memset(User, NUL, USER_NAME_LEN+1);\r
1021         memset(Pass, NUL, PASSWORD_LEN+1);\r
1022         *Port = PORT_NOR;\r
1023 \r
1024         ReplaceAll(unc, '\\', '/');\r
1025 \r
1026         if((Pos1 = _mbsstr(unc, "//")) != NULL)\r
1027                 Pos1 += 2;\r
1028         else\r
1029                 Pos1 = unc;\r
1030 \r
1031         if((Pos2 = _mbschr(Pos1, '@')) != NULL)\r
1032         {\r
1033                 memset(Tmp, NUL, FMAX_PATH+1);\r
1034                 memcpy(Tmp, Pos1, Pos2-Pos1);\r
1035                 Pos1 = Pos2 + 1;\r
1036 \r
1037                 if((Pos2 = _mbschr(Tmp, ':')) != NULL)\r
1038                 {\r
1039                         memcpy(User, Tmp, min1(Pos2-Tmp, USER_NAME_LEN));\r
1040                         strncpy(Pass, Pos2+1, PASSWORD_LEN);\r
1041                 }\r
1042                 else\r
1043                         strncpy(User, Tmp, USER_NAME_LEN);\r
1044         }\r
1045 \r
1046         // IPv6対応\r
1047         if((Pos2 = _mbschr(Pos1, '[')) != NULL && Pos2 < _mbschr(Pos1, ':'))\r
1048         {\r
1049                 Pos1 = Pos2 + 1;\r
1050                 if((Pos2 = _mbschr(Pos2, ']')) != NULL)\r
1051                 {\r
1052                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1053                         Pos1 = Pos2 + 1;\r
1054                 }\r
1055         }\r
1056 \r
1057         if((Pos2 = _mbschr(Pos1, ':')) != NULL)\r
1058         {\r
1059                 // IPv6対応\r
1060 //              memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1061                 if(strlen(Host) == 0)\r
1062                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1063                 Pos2++;\r
1064                 if(IsDigit(*Pos2))\r
1065                 {\r
1066                         *Port = atoi(Pos2);\r
1067                         while(*Pos2 != NUL)\r
1068                         {\r
1069                                 if(IsDigit(*Pos2) == 0)\r
1070                                         break;\r
1071                                 Pos2++;\r
1072                         }\r
1073                 }\r
1074                 RemoveFileName(Pos2, Path);\r
1075                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1076         }\r
1077         else if((Pos2 = _mbschr(Pos1, '/')) != NULL)\r
1078         {\r
1079                 // IPv6対応\r
1080 //              memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1081                 if(strlen(Host) == 0)\r
1082                         memcpy(Host, Pos1, min1(Pos2-Pos1, HOST_ADRS_LEN));\r
1083                 RemoveFileName(Pos2, Path);\r
1084                 strncpy(File, GetFileName(Pos2), FMAX_PATH);\r
1085         }\r
1086         else\r
1087         {\r
1088                 // IPv6対応\r
1089 //              strncpy(Host, Pos1, HOST_ADRS_LEN);\r
1090                 if(strlen(Host) == 0)\r
1091                         strncpy(Host, Pos1, HOST_ADRS_LEN);\r
1092         }\r
1093 \r
1094         Sts = FFFTP_FAIL;\r
1095         if(strlen(Host) > 0)\r
1096                 Sts = FFFTP_SUCCESS;\r
1097 \r
1098         return(Sts);\r
1099 }\r
1100 \r
1101 \r
1102 /*----- 日付文字列(JST)をFILETIME(UTC)に変換 ----------------------------------\r
1103 *\r
1104 *       Parameter\r
1105 *               char *Time : 日付文字列 ("yyyy/mm/dd hh:mm")\r
1106 *               FILETIME *Buf : ファイルタイムを返すワーク\r
1107 *\r
1108 *       Return Value\r
1109 *               int ステータス\r
1110 *                       YES/NO=日付情報がなかった\r
1111 *----------------------------------------------------------------------------*/\r
1112 \r
1113 int TimeString2FileTime(char *Time, FILETIME *Buf)\r
1114 {\r
1115         SYSTEMTIME sTime;\r
1116         FILETIME fTime;\r
1117         int Ret;\r
1118 \r
1119         Ret = NO;\r
1120     Buf->dwLowDateTime = 0;\r
1121     Buf->dwHighDateTime = 0;\r
1122 \r
1123         if(strlen(Time) >= 16)\r
1124         {\r
1125                 if(IsDigit(Time[0]) && IsDigit(Time[5]) && IsDigit(Time[8]) && \r
1126                    IsDigit(Time[12]) && IsDigit(Time[14]))\r
1127                 {\r
1128                         Ret = YES;\r
1129                 }\r
1130 \r
1131                 sTime.wYear = atoi(Time);\r
1132                 sTime.wMonth = atoi(Time + 5);\r
1133                 sTime.wDay = atoi(Time + 8);\r
1134                 if(Time[11] != ' ')\r
1135                         sTime.wHour = atoi(Time + 11);\r
1136                 else\r
1137                         sTime.wHour = atoi(Time + 12);\r
1138                 sTime.wMinute = atoi(Time + 14);\r
1139                 // タイムスタンプのバグ修正\r
1140 //              sTime.wSecond = 0;\r
1141                 if(strlen(Time) >= 19)\r
1142                         sTime.wSecond = atoi(Time + 17);\r
1143                 else\r
1144                         sTime.wSecond = 0;\r
1145                 sTime.wMilliseconds = 0;\r
1146 \r
1147                 SystemTimeToFileTime(&sTime, &fTime);\r
1148                 LocalFileTimeToFileTime(&fTime, Buf);\r
1149         }\r
1150         return(Ret);\r
1151 }\r
1152 \r
1153 \r
1154 /*----- FILETIME(UTC)を日付文字列(JST)に変換 ----------------------------------\r
1155 *\r
1156 *       Parameter\r
1157 *               FILETIME *Time : ファイルタイム\r
1158 *               char *Buf : 日付文字列を返すワーク\r
1159 *               int Mode : モード (DISPFORM_xxx)\r
1160 *               int InfoExist : 情報があるかどうか (FINFO_xxx)\r
1161 *\r
1162 *       Return Value\r
1163 *               なし\r
1164 *----------------------------------------------------------------------------*/\r
1165 \r
1166 // タイムスタンプのバグ修正\r
1167 //void FileTime2TimeString(FILETIME *Time, char *Buf, int Mode, int InfoExist)\r
1168 void FileTime2TimeString(FILETIME *Time, char *Buf, int Mode, int InfoExist, int ShowSeconds)\r
1169 {\r
1170         SYSTEMTIME sTime;\r
1171         FILETIME fTime;\r
1172 \r
1173         if(Mode == DISPFORM_LEGACY)\r
1174         {\r
1175                 if((Time->dwLowDateTime == 0) && (Time->dwHighDateTime == 0))\r
1176                         InfoExist = 0;\r
1177 \r
1178                 // タイムスタンプのバグ修正\r
1179 //              /* "yyyy/mm/dd hh:mm" */\r
1180                 /* "yyyy/mm/dd hh:mm:ss" */\r
1181                 FileTimeToLocalFileTime(Time, &fTime);\r
1182                 FileTimeToSystemTime(&fTime, &sTime);\r
1183 \r
1184                 // タイムスタンプのバグ修正\r
1185 //              if(InfoExist & FINFO_DATE)\r
1186 //                      sprintf(Buf, "%04d/%02d/%02d ", sTime.wYear, sTime.wMonth, sTime.wDay);\r
1187 //              else\r
1188 //                      sprintf(Buf, "           ");\r
1189 //\r
1190 //              if(InfoExist & FINFO_TIME)\r
1191 //                      sprintf(Buf+11, "%2d:%02d", sTime.wHour, sTime.wMinute);\r
1192 //              else\r
1193 //                      sprintf(Buf+11, "     ");\r
1194                 if(InfoExist & (FINFO_DATE | FINFO_TIME))\r
1195                 {\r
1196                         if(InfoExist & FINFO_DATE)\r
1197                                 sprintf(Buf, "%04d/%02d/%02d ", sTime.wYear, sTime.wMonth, sTime.wDay);\r
1198                         else\r
1199                                 sprintf(Buf, "           ");\r
1200                         if(ShowSeconds == YES)\r
1201                         {\r
1202                                 if(InfoExist & FINFO_TIME)\r
1203                                         sprintf(Buf+11, "%2d:%02d:%02d", sTime.wHour, sTime.wMinute, sTime.wSecond);\r
1204                                 else\r
1205                                         sprintf(Buf+11, "        ");\r
1206                         }\r
1207                         else\r
1208                         {\r
1209                                 if(InfoExist & FINFO_TIME)\r
1210                                         sprintf(Buf+11, "%2d:%02d", sTime.wHour, sTime.wMinute);\r
1211                                 else\r
1212                                         sprintf(Buf+11, "     ");\r
1213                         }\r
1214                 }\r
1215                 else\r
1216                         Buf[0] = NUL;\r
1217         }\r
1218         else\r
1219         {\r
1220 //              if (!strftime((char *)str, 100, "%c",  (const struct tm *)thetime))\r
1221 //                      SetTaskMsg("strftime が失敗しました!\n");\r
1222         }\r
1223         return;\r
1224 }\r
1225 \r
1226 \r
1227 /*----- ファイルタイムを指定タイムゾーンのローカルタイムからGMTに変換 ---------\r
1228 *\r
1229 *       Parameter\r
1230 *               FILETIME *Time : ファイルタイム\r
1231 *               int TimeZone : タイムゾーン\r
1232 *\r
1233 *       Return Value\r
1234 *               なし\r
1235 *----------------------------------------------------------------------------*/\r
1236 \r
1237 void SpecificLocalFileTime2FileTime(FILETIME *Time, int TimeZone)\r
1238 {\r
1239         unsigned __int64 Tmp64;\r
1240 \r
1241         Tmp64 = (unsigned __int64)Time->dwLowDateTime +\r
1242                         ((unsigned __int64)Time->dwHighDateTime << 32);\r
1243 \r
1244         Tmp64 -= (__int64)TimeZone * (__int64)36000000000;\r
1245 \r
1246         Time->dwHighDateTime = (DWORD)(Tmp64 >> 32);\r
1247         Time->dwLowDateTime = (DWORD)(Tmp64 & 0xFFFFFFFF);\r
1248 \r
1249         return;\r
1250 }\r
1251 \r
1252 \r
1253 /*----- 属性文字列を値に変換 --------------------------------------------------\r
1254 *\r
1255 *       Parameter\r
1256 *               char *Str : 属性文字列 ("rwxrwxrwx")\r
1257 *\r
1258 *       Return Value\r
1259 *               int 値\r
1260 *----------------------------------------------------------------------------*/\r
1261 \r
1262 int AttrString2Value(char *Str)\r
1263 {\r
1264         int Ret;\r
1265         char Tmp[10];\r
1266 \r
1267         Ret = 0;\r
1268         memset(Tmp, 0, 10);\r
1269         // ファイルの属性を数字で表示\r
1270 //      strncpy(Tmp, Str, 9);\r
1271 //\r
1272 //      if(Tmp[0] != '-')\r
1273 //              Ret |= 0x400;\r
1274 //      if(Tmp[1] != '-')\r
1275 //              Ret |= 0x200;\r
1276 //      if(Tmp[2] != '-')\r
1277 //              Ret |= 0x100;\r
1278 //\r
1279 //      if(Tmp[3] != '-')\r
1280 //              Ret |= 0x40;\r
1281 //      if(Tmp[4] != '-')\r
1282 //              Ret |= 0x20;\r
1283 //      if(Tmp[5] != '-')\r
1284 //              Ret |= 0x10;\r
1285 //\r
1286 //      if(Tmp[6] != '-')\r
1287 //              Ret |= 0x4;\r
1288 //      if(Tmp[7] != '-')\r
1289 //              Ret |= 0x2;\r
1290 //      if(Tmp[8] != '-')\r
1291 //              Ret |= 0x1;\r
1292         if(strlen(Str) >= 9)\r
1293         {\r
1294                 strncpy(Tmp, Str, 9);\r
1295 \r
1296                 if(Tmp[0] != '-')\r
1297                         Ret |= 0x400;\r
1298                 if(Tmp[1] != '-')\r
1299                         Ret |= 0x200;\r
1300                 if(Tmp[2] != '-')\r
1301                         Ret |= 0x100;\r
1302 \r
1303                 if(Tmp[3] != '-')\r
1304                         Ret |= 0x40;\r
1305                 if(Tmp[4] != '-')\r
1306                         Ret |= 0x20;\r
1307                 if(Tmp[5] != '-')\r
1308                         Ret |= 0x10;\r
1309 \r
1310                 if(Tmp[6] != '-')\r
1311                         Ret |= 0x4;\r
1312                 if(Tmp[7] != '-')\r
1313                         Ret |= 0x2;\r
1314                 if(Tmp[8] != '-')\r
1315                         Ret |= 0x1;\r
1316         }\r
1317         else if(strlen(Str) >= 3)\r
1318         {\r
1319                 strncpy(Tmp, Str, 3);\r
1320                 Ret = strtol(Tmp, NULL, 16);\r
1321         }\r
1322 \r
1323         return(Ret);\r
1324 }\r
1325 \r
1326 \r
1327 /*----- 属性の値を文字列に変換 ------------------------------------------------\r
1328 *\r
1329 *       Parameter\r
1330 *               int Attr : 属性の値\r
1331 *               char *Buf : 属性文字列をセットするバッファ ("rwxrwxrwx")\r
1332 *\r
1333 *       Return Value\r
1334 *               int 値\r
1335 *----------------------------------------------------------------------------*/\r
1336 \r
1337 // ファイルの属性を数字で表示\r
1338 //void AttrValue2String(int Attr, char *Buf)\r
1339 void AttrValue2String(int Attr, char *Buf, int ShowNumber)\r
1340 {\r
1341         // ファイルの属性を数字で表示\r
1342 //      strcpy(Buf, "---------");\r
1343 //\r
1344 //      if(Attr & 0x400)\r
1345 //              Buf[0] = 'r';\r
1346 //      if(Attr & 0x200)\r
1347 //              Buf[1] = 'w';\r
1348 //      if(Attr & 0x100)\r
1349 //              Buf[2] = 'x';\r
1350 //\r
1351 //      if(Attr & 0x40)\r
1352 //              Buf[3] = 'r';\r
1353 //      if(Attr & 0x20)\r
1354 //              Buf[4] = 'w';\r
1355 //      if(Attr & 0x10)\r
1356 //              Buf[5] = 'x';\r
1357 //\r
1358 //      if(Attr & 0x4)\r
1359 //              Buf[6] = 'r';\r
1360 //      if(Attr & 0x2)\r
1361 //              Buf[7] = 'w';\r
1362 //      if(Attr & 0x1)\r
1363 //              Buf[8] = 'x';\r
1364         if(ShowNumber == YES)\r
1365         {\r
1366                 sprintf(Buf, "%03x", Attr);\r
1367         }\r
1368         else\r
1369         {\r
1370                 strcpy(Buf, "---------");\r
1371 \r
1372                 if(Attr & 0x400)\r
1373                         Buf[0] = 'r';\r
1374                 if(Attr & 0x200)\r
1375                         Buf[1] = 'w';\r
1376                 if(Attr & 0x100)\r
1377                         Buf[2] = 'x';\r
1378 \r
1379                 if(Attr & 0x40)\r
1380                         Buf[3] = 'r';\r
1381                 if(Attr & 0x20)\r
1382                         Buf[4] = 'w';\r
1383                 if(Attr & 0x10)\r
1384                         Buf[5] = 'x';\r
1385 \r
1386                 if(Attr & 0x4)\r
1387                         Buf[6] = 'r';\r
1388                 if(Attr & 0x2)\r
1389                         Buf[7] = 'w';\r
1390                 if(Attr & 0x1)\r
1391                         Buf[8] = 'x';\r
1392         }\r
1393 \r
1394         return;\r
1395 }\r
1396 \r
1397 \r
1398 /*----- INIファイル文字列を整形 -----------------------------------------------\r
1399 *\r
1400 *       Parameter\r
1401 *               char *Str : 文字列\r
1402 *\r
1403 *       Return Value\r
1404 *               なし\r
1405 *----------------------------------------------------------------------------*/\r
1406 \r
1407 void FormatIniString(char *Str)\r
1408 {\r
1409         char *Put;\r
1410 \r
1411         Put = Str;\r
1412         while(*Str != NUL)\r
1413         {\r
1414                 if((*Str != ' ') && (*Str != '\t') && (*Str != '\n'))\r
1415                         *Put++ = *Str;\r
1416                 if(*Str++ == '=')\r
1417                         break;\r
1418         }\r
1419 \r
1420         while(*Str != NUL)\r
1421         {\r
1422                 if((*Str != 0x22) && (*Str != '\n'))\r
1423                         *Put++ = *Str;\r
1424                 Str++;\r
1425         }\r
1426         *Put = NUL;\r
1427 \r
1428         return;\r
1429 }\r
1430 \r
1431 \r
1432 /*----- ファイル選択 ----------------------------------------------------------\r
1433 *\r
1434 *       Parameter\r
1435 *               HWND hWnd : ウインドウハンドル\r
1436 *               char *Fname : ファイル名を返すバッファ\r
1437 *               char *Title : タイトル\r
1438 *               char *Filters : フィルター文字列\r
1439 *               char *Ext : デフォルト拡張子\r
1440 *               int Flags : 追加するフラグ\r
1441 *               int Save : 「開く」か「保存」か (0=開く, 1=保存)\r
1442 *\r
1443 *       Return Value\r
1444 *               int ステータス\r
1445 *                       TRUE/FALSE=取消\r
1446 *----------------------------------------------------------------------------*/\r
1447 \r
1448 int SelectFile(HWND hWnd, char *Fname, char *Title, char *Filters, char *Ext, int Flags, int Save)\r
1449 {\r
1450         OPENFILENAME OpenFile;\r
1451         char Tmp[FMAX_PATH+1];\r
1452         char Cur[FMAX_PATH+1];\r
1453         int Sts;\r
1454 \r
1455         GetCurrentDirectory(FMAX_PATH, Cur);\r
1456 \r
1457         strcpy(Tmp, Fname);\r
1458         // 変数が未初期化のバグ修正\r
1459         memset(&OpenFile, 0, sizeof(OPENFILENAME));\r
1460         OpenFile.lStructSize = sizeof(OPENFILENAME);\r
1461         OpenFile.hwndOwner = hWnd;\r
1462         OpenFile.hInstance = 0;\r
1463         OpenFile.lpstrFilter = Filters;\r
1464         OpenFile.lpstrCustomFilter = NULL;\r
1465         OpenFile.nFilterIndex = 1;\r
1466         OpenFile.lpstrFile = Tmp;\r
1467         OpenFile.nMaxFile = FMAX_PATH;\r
1468         OpenFile.lpstrFileTitle = NULL;\r
1469         OpenFile.nMaxFileTitle = 0;\r
1470         OpenFile.lpstrInitialDir = NULL;\r
1471         OpenFile.lpstrTitle = Title;\r
1472         OpenFile.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | Flags;\r
1473         OpenFile.nFileOffset = 0;\r
1474         OpenFile.nFileExtension = 0;\r
1475         OpenFile.lpstrDefExt = Ext;\r
1476         OpenFile.lCustData = 0;\r
1477         OpenFile.lpfnHook = NULL;\r
1478         OpenFile.lpTemplateName = NULL;\r
1479 \r
1480         if(Save == 0)\r
1481         {\r
1482                 if((Sts = GetOpenFileName(&OpenFile)) == TRUE)\r
1483                         strcpy(Fname,Tmp);\r
1484         }\r
1485         else\r
1486         {\r
1487                 if((Sts = GetSaveFileName(&OpenFile)) == TRUE)\r
1488                         strcpy(Fname,Tmp);\r
1489         }\r
1490         SetCurrentDirectory(Cur);\r
1491         return(Sts);\r
1492 }\r
1493 \r
1494 \r
1495 /*----- ディレクトリを選択 ----------------------------------------------------\r
1496 *\r
1497 *       Parameter\r
1498 *               HWND hWnd : ウインドウハンドル\r
1499 *               char *Buf : ディレクトリ名を返すバッファ(初期ディレクトリ名)\r
1500 *               int MaxLen : バッファのサイズ\r
1501 *\r
1502 *       Return Value\r
1503 *               int ステータス\r
1504 *                       TRUE/FALSE=取消\r
1505 *----------------------------------------------------------------------------*/\r
1506 \r
1507 int SelectDir(HWND hWnd, char *Buf, int MaxLen)\r
1508 {\r
1509         char Tmp[FMAX_PATH+1];\r
1510         char Cur[FMAX_PATH+1];\r
1511         BROWSEINFO  Binfo;\r
1512         LPITEMIDLIST lpIdll;\r
1513         int Sts;\r
1514         LPMALLOC lpMalloc;\r
1515 \r
1516         Sts = FALSE;\r
1517         GetCurrentDirectory(FMAX_PATH, Cur);\r
1518 \r
1519         if(SHGetMalloc(&lpMalloc) == NOERROR)\r
1520         {\r
1521                 Binfo.hwndOwner = hWnd;\r
1522                 Binfo.pidlRoot = NULL;\r
1523                 Binfo.pszDisplayName = Tmp;\r
1524                 Binfo.lpszTitle = MSGJPN185;\r
1525                 Binfo.ulFlags = BIF_RETURNONLYFSDIRS;\r
1526                 Binfo.lpfn = NULL;\r
1527                 Binfo.lParam = 0;\r
1528                 Binfo.iImage = 0;\r
1529                 if((lpIdll = SHBrowseForFolder(&Binfo)) != NULL)\r
1530                 {\r
1531                         SHGetPathFromIDList(lpIdll, Tmp);\r
1532                         memset(Buf, NUL, MaxLen);\r
1533                         strncpy(Buf, Tmp, MaxLen-1);\r
1534                         Sts = TRUE;\r
1535                         lpMalloc->lpVtbl->Free(lpMalloc, lpIdll);\r
1536             }\r
1537             lpMalloc->lpVtbl->Release(lpMalloc);\r
1538                 SetCurrentDirectory(Cur);\r
1539         }\r
1540         return(Sts);\r
1541 }\r
1542 \r
1543 \r
1544 /*----- 値に関連付けられたラジオボタンをチェックする --------------------------\r
1545 *\r
1546 *       Parameter\r
1547 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1548 *               int Value : 値\r
1549 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1550 *               int Num : ボタンの数\r
1551 *\r
1552 *       Return Value\r
1553 *               なし\r
1554 *\r
1555 *       Note\r
1556 *               値に関連付けられたボタンが無い時は、テーブルの最初に登録されているボタ\r
1557 *               ンをチェックする\r
1558 *----------------------------------------------------------------------------*/\r
1559 \r
1560 void SetRadioButtonByValue(HWND hDlg, int Value, const RADIOBUTTON *Buttons, int Num)\r
1561 {\r
1562         int i;\r
1563         int Def;\r
1564 \r
1565         Def = Buttons->ButID;\r
1566         for(i = 0; i < Num; i++)\r
1567         {\r
1568                 if(Value == Buttons->Value)\r
1569                 {\r
1570                         SendDlgItemMessage(hDlg, Buttons->ButID, BM_SETCHECK, 1, 0);\r
1571                         /* ラジオボタンを変更した時に他の項目のハイドなどを行なう事が      */\r
1572                         /* あるので、そのために WM_COMMAND を送る                                          */\r
1573                         SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Buttons->ButID, 0), 0);\r
1574                         break;\r
1575                 }\r
1576                 Buttons++;\r
1577         }\r
1578         if(i == Num)\r
1579         {\r
1580                 SendDlgItemMessage(hDlg, Def, BM_SETCHECK, 1, 0);\r
1581                 SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(Def, 0), 0);\r
1582         }\r
1583         return;\r
1584 }\r
1585 \r
1586 \r
1587 /*----- チェックされているボタンに関連付けられた値を返す ----------------------\r
1588 *\r
1589 *       Parameter\r
1590 *               HWND hDlg : ダイアログボックスのウインドウハンドル\r
1591 *               const RADIOBUTTON *Buttons : ラジオボタンと値の関連付けテーブル\r
1592 *               int Num : ボタンの数\r
1593 *\r
1594 *       Return Value\r
1595 *               int 値\r
1596 *\r
1597 *       Note\r
1598 *               どのボタンもチェックされていない時は、テーブルの最初に登録されているボ\r
1599 *               タンの値を返す\r
1600 *----------------------------------------------------------------------------*/\r
1601 \r
1602 int AskRadioButtonValue(HWND hDlg, const RADIOBUTTON *Buttons, int Num)\r
1603 {\r
1604         int i;\r
1605         int Ret;\r
1606 \r
1607         Ret = Buttons->Value;\r
1608         for(i = 0; i < Num; i++)\r
1609         {\r
1610                 if(SendDlgItemMessage(hDlg, Buttons->ButID, BM_GETCHECK, 0, 0) == 1)\r
1611                 {\r
1612                         Ret = Buttons->Value;\r
1613                         break;\r
1614                 }\r
1615                 Buttons++;\r
1616         }\r
1617         return(Ret);\r
1618 }\r
1619 \r
1620 \r
1621 /*----- 16進文字列を数値に変換 ----------------------------------------------\r
1622 *\r
1623 *       Parameter\r
1624 *               char *Str : 文字列\r
1625 *\r
1626 *       Return Value\r
1627 *               int 値\r
1628 *----------------------------------------------------------------------------*/\r
1629 \r
1630 int xtoi(char *Str)\r
1631 {\r
1632         int Ret;\r
1633 \r
1634         Ret = 0;\r
1635         while(*Str != NUL)\r
1636         {\r
1637                 Ret *= 0x10;\r
1638                 if((*Str >= '0') && (*Str <= '9'))\r
1639                         Ret += *Str - '0';\r
1640                 else if((*Str >= 'A') && (*Str <= 'F'))\r
1641                         Ret += *Str - 'A' + 10;\r
1642                 else if((*Str >= 'a') && (*Str <= 'f'))\r
1643                         Ret += *Str - 'a' + 10;\r
1644                 else\r
1645                         break;\r
1646 \r
1647                 Str++;\r
1648         }\r
1649         return(Ret);\r
1650 }\r
1651 \r
1652 \r
1653 /*----- ファイルが読み取り可能かどうかを返す ----------------------------------\r
1654 *\r
1655 *       Parameter\r
1656 *               char *Fname : ファイル名\r
1657 *\r
1658 *       Return Value\r
1659 *               int ステータス\r
1660 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
1661 *----------------------------------------------------------------------------*/\r
1662 \r
1663 int CheckFileReadable(char *Fname)\r
1664 {\r
1665         int Sts;\r
1666         HANDLE iFileHandle;\r
1667         SECURITY_ATTRIBUTES Sec;\r
1668 \r
1669         Sts = FFFTP_FAIL;\r
1670 \r
1671         Sec.nLength = sizeof(SECURITY_ATTRIBUTES);\r
1672         Sec.lpSecurityDescriptor = NULL;\r
1673         Sec.bInheritHandle = FALSE;\r
1674 \r
1675         if((iFileHandle = CreateFile(Fname, GENERIC_READ,\r
1676                 FILE_SHARE_READ|FILE_SHARE_WRITE, &Sec, OPEN_EXISTING, 0, NULL)) != INVALID_HANDLE_VALUE)\r
1677         {\r
1678                 Sts = FFFTP_SUCCESS;\r
1679                 CloseHandle(iFileHandle);\r
1680         }\r
1681         return(Sts);\r
1682 }\r
1683 \r
1684 \r
1685 \r
1686 \r
1687 \r
1688 int max1(int n, int m)\r
1689 {\r
1690         if(n > m)\r
1691                 return(n);\r
1692         else\r
1693                 return(m);\r
1694 }\r
1695 \r
1696 \r
1697 \r
1698 int min1(int n, int m)\r
1699 {\r
1700         if(n < m)\r
1701                 return(n);\r
1702         else\r
1703                 return(m);\r
1704 }\r
1705 \r
1706 \r
1707 void ExcEndianDWORD(DWORD *x)\r
1708 {\r
1709         BYTE *Pos;\r
1710         BYTE Tmp;\r
1711 \r
1712         Pos = (BYTE *)x;\r
1713         Tmp = *(Pos + 0);\r
1714         *(Pos + 0) = *(Pos + 3);\r
1715         *(Pos + 3) = Tmp;\r
1716         Tmp = *(Pos + 1);\r
1717         *(Pos + 1) = *(Pos + 2);\r
1718         *(Pos + 2) = Tmp;\r
1719         return;\r
1720 }\r
1721 \r
1722 \r
1723 \r
1724 \r
1725 /*----- int値の入れ替え -------------------------------------------------------\r
1726 *\r
1727 *       Parameter\r
1728 *               int *Num1 : 数値1\r
1729 *               int *Num2 : 数値2\r
1730 *\r
1731 *       Return Value\r
1732 *               なし\r
1733 *----------------------------------------------------------------------------*/\r
1734 \r
1735 void SwapInt(int *Num1, int *Num2)\r
1736 {\r
1737         int Tmp;\r
1738 \r
1739         Tmp = *Num1;\r
1740         *Num1 = *Num2;\r
1741         *Num2 = Tmp;\r
1742         return;\r
1743 }\r
1744 \r
1745 \r
1746 /*----- 指定されたフォルダがあるかどうかチェック -------------------------------\r
1747 *\r
1748 *       Parameter\r
1749 *               char *Path : パス\r
1750 *\r
1751 *       Return Value\r
1752 *               int ステータス (YES/NO)\r
1753 *----------------------------------------------------------------------------*/\r
1754 \r
1755 int IsFolderExist(char *Path)\r
1756 {\r
1757         int Sts;\r
1758         char Tmp[FMAX_PATH+1];\r
1759         DWORD Attr;\r
1760 \r
1761         Sts = YES;\r
1762         if(strlen(Path) > 0)\r
1763         {\r
1764                 strcpy(Tmp, Path);\r
1765                 if(_mbscmp(Tmp+1, ":\\") != 0)\r
1766                         RemoveYenTail(Tmp);\r
1767 \r
1768                 Attr = GetFileAttributes(Tmp);\r
1769                 if((Attr == 0xFFFFFFFF) || ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0))\r
1770                         Sts = NO;\r
1771         }\r
1772         return(Sts);\r
1773 }\r
1774 \r
1775 \r
1776 /*----- テーブルにしたがって数値を登録 -----------------------------------------\r
1777 *\r
1778 *       Parameter\r
1779 *               int x : 数値\r
1780 *               int Dir : 変換方向\r
1781 *               INTCONVTBL *Tbl : テーブル\r
1782 *               int Num : テーブルの数値の数\r
1783 *\r
1784 *       Return Value\r
1785 *               int 数値\r
1786 *----------------------------------------------------------------------------*/\r
1787 \r
1788 int ConvertNum(int x, int Dir, const INTCONVTBL *Tbl, int Num)\r
1789 {\r
1790         int i;\r
1791         int Ret;\r
1792 \r
1793         Ret = x;\r
1794         for(i = 0; i < Num; i++)\r
1795         {\r
1796                 if((Dir == 0) && (Tbl->Num1 == x))\r
1797                 {\r
1798                         Ret = Tbl->Num2;\r
1799                         break;\r
1800                 }\r
1801                 else if((Dir == 1) && (Tbl->Num2 == x))\r
1802                 {\r
1803                         Ret = Tbl->Num1;\r
1804                         break;\r
1805                 }\r
1806                 Tbl++;\r
1807         }\r
1808         return(Ret);\r
1809 }\r
1810 \r
1811 \r
1812 \r
1813 \r
1814 \r
1815 \r
1816 /*----- ファイルをゴミ箱に削除 ------------------------------------------------\r
1817 *\r
1818 *       Parameter\r
1819 *               char *Path : ファイル名\r
1820 *\r
1821 *       Return Value\r
1822 *               int ステータス (0=正常終了)\r
1823 *----------------------------------------------------------------------------*/\r
1824 \r
1825 int MoveFileToTrashCan(char *Path)\r
1826 {\r
1827         SHFILEOPSTRUCT FileOp;\r
1828         char Tmp[FMAX_PATH+2];\r
1829 \r
1830         memset(Tmp, 0, FMAX_PATH+2);\r
1831         strcpy(Tmp, Path);\r
1832         FileOp.hwnd = NULL;\r
1833         FileOp.wFunc = FO_DELETE;\r
1834         FileOp.pFrom = Tmp;\r
1835         FileOp.pTo = "";\r
1836         FileOp.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_ALLOWUNDO;\r
1837         FileOp.lpszProgressTitle = "";\r
1838         return(SHFileOperation(&FileOp));\r
1839 }\r
1840 \r
1841 \r
1842 \r
1843 \r
1844 LONGLONG MakeLongLong(DWORD High, DWORD Low)\r
1845 {\r
1846         LONGLONG z;\r
1847         LONGLONG x1, y1;\r
1848 \r
1849         x1 = (LONGLONG)Low;\r
1850         y1 = (LONGLONG)High;\r
1851         z = x1 | (y1 << 32);\r
1852         return(z);\r
1853 }\r
1854 \r
1855 \r
1856 char *MakeNumString(LONGLONG Num, char *Buf, BOOL Comma)\r
1857 {\r
1858         int i;\r
1859         char *Pos;\r
1860 \r
1861         Pos = Buf;\r
1862         *Pos = '\0';\r
1863 \r
1864         i = 1;\r
1865         do\r
1866         {\r
1867                 *Pos++ = (char)(Num % 10) + '0';\r
1868                 Num /= 10;\r
1869                 if((Comma == TRUE) && ((i % 3) == 0) && (Num != 0))\r
1870                         *Pos++ = ',';\r
1871                 i++;\r
1872         }\r
1873         while(Num != 0);\r
1874         *Pos = NUL;\r
1875         _strrev(Buf);\r
1876 \r
1877         return(Buf);\r
1878 }\r
1879 \r
1880 \r
1881 // 異なるファイルが表示されるバグ修正\r
1882 \r
1883 // ShellExecute等で使用されるファイル名を修正\r
1884 // UNCでない場合に末尾の半角スペースは無視されるため拡張子が補完されなくなるまで半角スペースを追加\r
1885 // 現在UNC対応の予定は無い\r
1886 char* MakeDistinguishableFileName(char* Out, char* In)\r
1887 {\r
1888         char* Fname;\r
1889         char Tmp[FMAX_PATH+1];\r
1890         char Tmp2[FMAX_PATH+3];\r
1891         HANDLE hFind;\r
1892         WIN32_FIND_DATA Find;\r
1893         if(strlen(GetFileExt(GetFileName(In))) > 0)\r
1894                 strcpy(Out, In);\r
1895         else\r
1896         {\r
1897                 Fname = GetFileName(In);\r
1898                 strcpy(Tmp, In);\r
1899                 strcpy(Tmp2, Tmp);\r
1900                 strcat(Tmp2, ".*");\r
1901                 while(strlen(Tmp) < FMAX_PATH && (hFind = FindFirstFile(Tmp2, &Find)) != INVALID_HANDLE_VALUE)\r
1902                 {\r
1903                         do\r
1904                         {\r
1905                                 if(strcmp(Find.cFileName, Fname) != 0)\r
1906                                         break;\r
1907                         }\r
1908                         while(FindNextFile(hFind, &Find));\r
1909                         FindClose(hFind);\r
1910                         if(strcmp(Find.cFileName, Fname) != 0)\r
1911                         {\r
1912                                 strcat(Tmp, " ");\r
1913                                 strcpy(Tmp2, Tmp);\r
1914                                 strcat(Tmp2, ".*");\r
1915                         }\r
1916                         else\r
1917                                 break;\r
1918                 }\r
1919                 strcpy(Out, Tmp);\r
1920         }\r
1921         return Out;\r
1922 }\r
1923 \r
1924 // 環境依存の不具合対策\r
1925 char* GetAppTempPath(char* Buf)\r
1926 {\r
1927         char Temp[32];\r
1928         GetTempPath(MAX_PATH, Buf);\r
1929         SetYenTail(Buf);\r
1930         sprintf(Temp, "ffftp%08x", GetCurrentProcessId());\r
1931         strcat(Buf, Temp);\r
1932         return Buf;\r
1933 }\r
1934 \r
1935 #if defined(HAVE_TANDEM)\r
1936 /*----- ファイルサイズからEXTENTサイズの計算を行う ----------------------------\r
1937 *\r
1938 *       Parameter\r
1939 *               LONGLONG Size : ファイルサイズ\r
1940 *\r
1941 *       Return Value\r
1942 *               なし\r
1943 *----------------------------------------------------------------------------*/\r
1944 void CalcExtentSize(TRANSPACKET *Pkt, LONGLONG Size)\r
1945 {\r
1946         LONGLONG extent;\r
1947 \r
1948         /* EXTENTS(4,28) MAXEXTENTS 978 */\r
1949         if(Size < 56025088) {\r
1950                 Pkt->PriExt = DEF_PRIEXT;\r
1951                 Pkt->SecExt = DEF_SECEXT;\r
1952                 Pkt->MaxExt = DEF_MAXEXT;\r
1953         } else {\r
1954                 /* 増加余地を残すため Used 75% 近辺になるように EXTENT サイズを調整) */\r
1955                 extent = (LONGLONG)(Size / ((DEF_MAXEXT * 0.75) * 2048LL));\r
1956                 /* 28未満にすると誤差でFile Fullになる可能性がある */\r
1957                 if(extent < 28)\r
1958                         extent = 28;\r
1959 \r
1960                 Pkt->PriExt = (int)extent;\r
1961                 Pkt->SecExt = (int)extent;\r
1962                 Pkt->MaxExt = DEF_MAXEXT;\r
1963         }\r
1964 }\r
1965 #endif\r