OSDN Git Service

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