OSDN Git Service

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