/
common.h
1481 lines (1324 loc) · 59.4 KB
/
common.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*=============================================================================
* FFFTP共通定義ファイル
*
===============================================================================
/ Copyright (C) 1997-2007 Sota. All rights reserved.
/
/ Redistribution and use in source and binary forms, with or without
/ modification, are permitted provided that the following conditions
/ are met:
/
/ 1. Redistributions of source code must retain the above copyright
/ notice, this list of conditions and the following disclaimer.
/ 2. Redistributions in binary form must reproduce the above copyright
/ notice, this list of conditions and the following disclaimer in the
/ documentation and/or other materials provided with the distribution.
/
/ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
/ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
/ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
/ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
/ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
/ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
/ USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
/ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
/ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
/ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/============================================================================*/
#pragma once
#define NOMINMAX
#define SECURITY_WIN32
#define WIN32_LEAN_AND_MEAN
#define UMDF_USING_NTSTATUS
#pragma warning(disable: 6553) // error C6553: The annotation for function 'XXX' on _Param_(YYY) does not apply to a value type.
#pragma warning(disable: 26426) // error C26426: Global initializer calls a non-constexpr function 'XXX' (i.22).
#pragma warning(disable: 26429) // error C26429: Symbol 'XXX' is never tested for nullness, it can be marked as not_null (f.23).
#pragma warning(disable: 26432) // error C26432: If you define or delete any default operation in the type 'XXX', define or delete them all (c.21).
#pragma warning(disable: 26436) // error C26436: The type 'XXX' with a virtual function needs either public virtual or protected non-virtual destructor (c.35).
#pragma warning(disable: 26440) // error C26440: Function 'XXX' can be declared 'noexcept' (f.6).
#pragma warning(disable: 26445) // error C26445: Do not assign gsl::span or std::string_view to a reference. They are cheap to construct and are not owners of the underlying data. (gsl.view).
#pragma warning(disable: 26446) // error C26446: Prefer to use gsl::at() instead of unchecked subscript operator (bounds.4).
#pragma warning(disable: 26447) // error C26447: The function is declared 'noexcept' but calls function 'XXX' which may throw exceptions (f.6).
#pragma warning(disable: 26459) // error C26459: You called an STL function 'XXX' with a raw pointer parameter at position 'YYY' that may be unsafe - this relies on the caller to check that the passed values are correct. Consider wrapping your range in a gsl::span and pass as a span iterator (stl.1).
#pragma warning(disable: 26461) // error C26461: The pointer argument 'XXX' for function 'YYY' can be marked as a pointer to const (con.3).
#pragma warning(disable: 26462) // error C26462: The value pointed to by 'XXX' is assigned only once, mark it as a pointer to const (con.4).
#pragma warning(disable: 26476) // error C26476: Expression/symbol '{0}' uses a naked union 'union ' with multiple type pointers: Use variant instead (type.7).
#pragma warning(disable: 26481) // error C26481: Don't use pointer arithmetic. Use span instead (bounds.1).
#pragma warning(disable: 26482) // error C26482: Only index into arrays using constant expressions (bounds.2).
#pragma warning(disable: 26485) // error C26485: Expression 'XXX': No array to pointer decay (bounds.3).
#pragma warning(disable: 26490) // error C26490: Don't use reinterpret_cast (type.1).
#pragma warning(disable: 26491) // error C26491: Don't use static_cast downcasts (type.2).
#pragma warning(disable: 26492) // error C26492: Don't use const_cast to cast away const or volatile (type.3).
#pragma warning(disable: 26493) // error C26493: Don't use C-style casts (type.4).
#pragma warning(disable: 26494) // error C26494: Variable 'XXX' is uninitialized. Always initialize an object (type.5).
#pragma warning(disable: 26496) // error C26496 : The variable 'XXX' does not change after construction, mark it as const (con.4).
#pragma warning(disable: 26812) // error C26812: The enum type 'XXX' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#pragma warning(disable: 26818) // error C26818: Switch statement does not cover all cases. Consider adding a 'default' label (es.79).
#pragma warning(disable: 26821) // error C26821: For 'XXX', consider using gsl::span instead of std::span to guarantee runtime bounds safety (gsl.view).
#include <algorithm>
#include <array>
#include <bit>
#include <charconv>
#include <chrono>
#include <concepts>
#include <filesystem>
#include <format>
#include <fstream>
#include <future>
#include <iterator>
#include <map>
#include <mutex>
#include <numeric>
#include <optional>
#include <ranges>
#include <span>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
#include <variant>
#include <vector>
#include <concurrent_queue.h>
#include <boost/regex.hpp>
#include <gsl/gsl>
#include <cassert>
#include <cwctype>
#include <crtdbg.h>
#include <mbstring.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <Windows.h>
#include <ObjBase.h> // for COM interface, define `interface` macro.
#include <bcrypt.h>
#include <windowsx.h>
#include <winsock2.h>
#include <CommCtrl.h>
#include <commdlg.h>
#include <cryptuiapi.h>
#include <MLang.h>
#include <MMSystem.h>
#include <mstcpip.h>
#include <natupnp.h>
#include <ntstatus.h>
#include <schannel.h>
#include <security.h>
#include <shellapi.h>
#include <ShlObj.h>
#include <Shlwapi.h>
#include <ShObjIdl.h>
#include <WS2tcpip.h>
#include <wrl/client.h>
#include <wrl/implements.h>
#include <comdef.h>
#include "config.h"
#include "dialog.h"
#include "helpid.h"
#include "Resource/resource.ja-JP.h"
#pragma comment(lib, "bcrypt.lib")
#pragma comment(lib, "Comctl32.lib")
#pragma comment(lib, "normaliz.lib")
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "Winmm.lib")
#pragma comment(lib, "Ws2_32.lib")
namespace fs = std::filesystem;
using namespace std::literals;
template<class T>
using ComPtr = Microsoft::WRL::ComPtr<T>;
template<class...>
constexpr bool false_v = false;
enum class FileType : UINT {
All = IDS_FILETYPE_ALL,
Executable = IDS_FILETYPE_EXECUTABLE,
Reg = IDS_FILETYPE_REG,
Ini = IDS_FILETYPE_INI,
Xml = IDS_FILETYPE_XML,
};
constexpr FileType AllFileTyes[]{ FileType::All, FileType::Executable, FileType::Reg, FileType::Ini, FileType::Xml, };
#define NUL '\0'
#define IsDigit(n) (isascii(n) && isdigit(n))
#define IsAlpha(n) (isascii(n) && isalpha(n))
#define FFFTP_FAIL 0
#define FFFTP_SUCCESS 1
#define NO 0
#define YES 1
#define NO_ALL 2
#define YES_ALL 3
#define YES_LIST 4
#define VER_NUM 5700 /* 設定バージョン */
/*===== ユーザ定義コマンド =====*/
#define WM_CHANGE_COND (WM_USER+1) /* ファイル一覧を変更するコマンド */
#define WM_SET_PACKET (WM_USER+2) /* 現在使用している転送パケットのアドレスを通知 */
#define WM_REFRESH_LOCAL_FLG (WM_USER+7)
#define WM_REFRESH_REMOTE_FLG (WM_USER+8)
#define WM_RECONNECTSOCKET (WM_USER+11)
#define WM_MAINTHREADRUNNER (WM_USER+13)
/*===== ホスト番号 =====*/
/* ホスト番号は 0~ の値を取る */
#define HOSTNUM_NOENTRY (-1) /* ホスト一覧に無いときのホスト番号 */
/*===== バッファサイズ =====*/
#define HOST_NAME_LEN 40 /* 一覧に表示するホストの名前 */
#define HOST_ADRS_LEN 80 /* ホスト名 */
#define USER_NAME_LEN 80 /* ユーザ名 */
#define PASSWORD_LEN 80 /* パスワード */
#define ACCOUNT_LEN 80 /* アカウント */
#define INIT_DIR_LEN (FMAX_PATH-40) /* 初期ディレクトリ */
#define FILTER_EXT_LEN 400 /* フィルタのファイル名列 */
#define BOOKMARK_SIZE 2048 /* ブックマーク */
#define CHMOD_CMD_LEN 40 /* 属性変更コマンド */
#define NLST_NAME_LEN 40 /* NLSTに付けるファイル名/オプション */
#define INITCMD_LEN 256 /* 初期化コマンド */
#define OWNER_NAME_LEN 40 /* オーナ名 */
#define RAS_NAME_LEN 256 /* RASのエントリ名の長さ */
#define FMAX_PATH 1024
/*===== 初期値 =====*/
#if defined(HAVE_TANDEM)
#define DEF_PRIEXT 4 /* Primary Extents の初期値 */
#define DEF_SECEXT 28 /* Secondary Extents の初期値 */
#define DEF_MAXEXT 978 /* Max Extents の初期値 */
#endif
/*===== 同じ名前のファイルがあった時の処理 =====*/
#define EXIST_OVW 0 /* 上書き */
#define EXIST_NEW 1 /* 新しければ上書き */
#define EXIST_RESUME 2 /* レジューム */
#define EXIST_IGNORE 3 /* 無視 */
#define EXIST_UNIQUE 4 /* ホストが名前を付ける */
#define EXIST_ABORT 5 /* 全て中止 */
// 同じ名前のファイルの処理方法追加
#define EXIST_LARGE 6 /* 大きければ上書き */
/*===== ファイル名の比較モード =====*/
#define COMP_IGNORE 0 /* 大文字/小文字は区別しない */
#define COMP_STRICT 1 /* 大文字/小文字を区別する */
#define COMP_LOWERMATCH 2 /* 大文字/小文字を区別しない(片側は全て小文字) */
/*===== FTPの応答コードの頭1桁 =====*/
#define FTP_PRELIM 1 /* */
#define FTP_COMPLETE 2 /* */
#define FTP_CONTINUE 3 /* */
#define FTP_RETRY 4 /* */
#define FTP_ERROR 5 /* */
/*===== ファイルリストのノード属性 =====*/
#define NODE_DIR 0 /* ディレクトリ */
#define NODE_FILE 1 /* ファイル */
#define NODE_DRIVE 2 /* ドライブ */
#define NODE_NONE (-1) /* なし */
/*===== 上書き確認方法の設定値 =====*/
#define TRANS_OVW 0 /* 上書き */
#define TRANS_DLG 1 /* ダイアログを出す */
/*===== ホスト内ファイル移動確認方法の設定値 =====*/
#define MOVE_NODLG 0 /* ダイアログを出さない */
#define MOVE_DLG 1 /* ダイアログを出す */
#define MOVE_DISABLE 2 /* 機能使用禁止 */
/*===== 転送方法 =====*/
#define TYPE_I 'I' /* バイナリモード */
#define TYPE_A 'A' /* アスキーモード */
#define TYPE_X 'X' /* 自動判別 */
#define TYPE_DEFAULT NUL /* 設定しない DirectConnectProc()の引数として有効 */
/*===== ソート方法 =====*/
/* 番号はListViewのカラム番号と合わせてある */
#define SORT_NAME 0 /* 名前順 */
#define SORT_DATE 1 /* 日付順 */
#define SORT_SIZE 2 /* サイズ順 */
#define SORT_EXT 3 /* 拡張子順 */
#define SORT_ASCENT 0x00 /* 昇順 */
#define SORT_DESCENT 0x80 /* 降順 */
#define SORT_MASK_ORD 0x7F /* xx順を取り出すマスク */
#define SORT_GET_ORD 0x80 /* 昇順/降順を取り出すマスク */
/*===== ウインドウ番号 =====*/
#define WIN_LOCAL 0 /* ローカル */
#define WIN_REMOTE 1 /* ホスト */
#define WIN_BOTH 2 /* 両方 */
/*===== ファイル選択方法 =====*/
#define SELECT_ALL 0 /* 全選択 */
#define SELECT_REGEXP 1 /* 検索式を入力して選択 */
// ローカル側自動更新
#define SELECT_LIST 2 /* リストに含まれるファイルを選択 */
/*===== 検索方法 =====*/
#define FIND_FIRST 0 /* 最初の検索 */
#define FIND_NEXT 1 /* 次を検索 */
/*===== ファイル名の大文字/小文字変換 =====*/
#define FNAME_NOCNV 0 /* 変換しない */
#define FNAME_LOWER 1 /* 小文字に変換 */
#define FNAME_UPPER 2 /* 大文字に変換 */
/*===== 接続ウインドウの形式 =====*/
#define DLG_TYPE_CON 0 /* 簡易(ホスト編集なし) */
#define DLG_TYPE_SET 1 /* ホスト編集あり */
/*===== ファイル一覧取得モード =====*/
#define CACHE_NORMAL 0 /* 通常(キャッシュにあれば使用、なければ読み込み) */
#define CACHE_REFRESH 1 /* 常に読み込み */
#define CACHE_LASTREAD 2 /* 最後に読み込んだものを使用 */
/*===== 漢字コード変換 =====*/
#define KANJI_SJIS 0 /* SJIS */
#define KANJI_JIS 1 /* JIS */
#define KANJI_EUC 2 /* EUC */
#define KANJI_SMB_HEX 3 /* Samba-HEX */
#define KANJI_SMB_CAP 4 /* Samba-CAP */
#define KANJI_UTF8N 5 /* UTF-8 */
// UTF-8対応
#define KANJI_UTF8BOM 6 /* UTF-8 BOM */
// UTF-8 HFS+対応
#define KANJI_UTF8HFSX 7 /* UTF-8 HFS+ */
#define KANJI_NOCNV -1 /* 漢字コード変換なし */
// UTF-8対応
#define KANJI_AUTO -1
/*===== ビューワ =====*/
#define VIEWERS 3 /* ビューワの数 */
/*===== ブックマーク =====*/
#define BMARK_SUB_MENU 2 /* ブックマークメニューのサブメニュー番号 */
#define DEFAULT_BMARK_ITEM 5 /* ブックマークメニューにある固定部分の数 */
#define MENU_BMARK_TOP 30000 /* 3000以降(3100くらいまで)は予約する */
/* resource.h の定義と重ならないように */
/*===== レジストリのタイプ =====*/
#define REGTYPE_REG 0 /* レジストリ */
#define REGTYPE_INI 1 /* INIファイル */
/*===== ホスト設定で明示的に指定するホストのタイプ =====*/
#define HTYPE_AUTO 0 /* 自動 */
#define HTYPE_ACOS 1 /* ACOS (待機結合ファイルの指定が必要) */
#define HTYPE_VMS 2 /* VAX VMS */
#define HTYPE_IRMX 3 /* IRMX */
#define HTYPE_ACOS_4 4 /* ACOS ファイル名を('')で括らない */
#define HTYPE_STRATUS 5 /* Stratus */
#define HTYPE_AGILENT 6 /* Agilent Logic analyzer */
#define HTYPE_SHIBASOKU 7 /* Shibasoku LSI test system */
#if defined(HAVE_TANDEM)
#define HTYPE_TANDEM 8 /* HP NonStop Server */
#endif
/*===== ホストのヒストリ =====*/
#define HISTORY_MAX 20 /* ファイルのヒストリの最大個数 */
#define DEF_FMENU_ITEMS 8 /* Fileメニューにある項目数の初期値 */
/*===== 中断コード =====*/
#define ABORT_NONE 0 /* 転送中断なし */
#define ABORT_USER 1 /* ユーザによる中断 */
#define ABORT_ERROR 2 /* エラーによる中断 */
#define ABORT_DISKFULL 3 /* ディスクフルよる中断 */
/*===== FireWallの種類 =====*/
#define FWALL_NONE 0 /* なし */
#define FWALL_FU_FP_SITE 1 /* FW user → FW pass → SITE host */
#define FWALL_FU_FP_USER 2 /* FW user → FW pass → USER user@host */
#define FWALL_USER 3 /* USER user@host */
#define FWALL_OPEN 4 /* OPEN host */
#define FWALL_SOCKS4 5 /* SOCKS4 */
#define FWALL_SOCKS5_NOAUTH 6 /* SOCKS5 (認証なし) */
#define FWALL_SOCKS5_USER 7 /* SOCKS5 (Username/Password認証) */
#define FWALL_FU_FP 8 /* FW user → FW pass */
#define FWALL_SIDEWINDER 9 /* USER FWuser:FWpass@host */
/*===== ワンタイムパスワード =====*/
/* コードの種類 */
#define SECURITY_DISABLE 0 /* 使用しない */
#define SECURITY_AUTO 1 /* 自動認識 */
#define MD4 2 /* MD4 */
#define MD5 3 /* MD5 */
#define SHA1 4 /* SHA-1 */
#define MAX_SEED_LEN 16 /* Seedの文字数 */
/*===== 再帰的なファイル検索の方法 =====*/
#define RDIR_NONE 0 /* 再帰検索なし */
#define RDIR_NLST 1 /* NLST -R */
#define RDIR_CWD 2 /* CWDで移動 */
/*===== 設定のレベル =====*/
#define SET_LEVEL_GROUP 0x8000 /* グループのフラグ */
#define SET_LEVEL_MASK 0x7FFF
#define SET_LEVEL_SAME 0x7FFF
/*===== 日付、数値の表示形式 =====*/
#define DISPFORM_LEGACY 0 /* 固定書式 */
#define DISPFORM_LOCALE 1 /* コントロールパネルに従う */
/*===== ファイル一覧に存在した情報 =====*/
#define FINFO_DATE 0x01 /* 日付 */
#define FINFO_TIME 0x02 /* 時間 */
#define FINFO_SIZE 0x04 /* サイズ */
#define FINFO_ATTR 0x08 /* 属性 */
#define FINFO_ALL 0xFF /* 全て */
/*===== GetMasterPasswordStatusで使うコード =====*/
#define PASSWORD_OK 0
#define PASSWORD_UNMATCH 2
#define BAD_PASSWORD_HASH 3
/*===== 暗号化パスワード設定 =====*/
#define DEFAULT_PASSWORD "DefaultPassword"
#define MAX_PASSWORD_LEN 128
// 暗号化通信対応
#define CRYPT_NONE 0
#define CRYPT_FTPES 1
#define CRYPT_FTPIS 2
#define CRYPT_SFTP 3
// FEAT対応
// UTF-8対応
#define FEATURE_UTF8 0x00000001
// MLSD対応
#define FEATURE_MLSD 0x00000002
// IPv6対応
#define FEATURE_EPRT 0x00000004
#define FEATURE_EPSV 0x00000008
// ホスト側の日時取得
#define FEATURE_MDTM 0x00000010
// ホスト側の日時設定
#define FEATURE_MFMT 0x00000020
// IPv6対応
#define NTYPE_AUTO 0 /* 自動 */
#define NTYPE_IPV4 1 /* TCP/IPv4 */
#define NTYPE_IPV6 2 /* TCP/IPv6 */
struct HostSort {
uint8_t RemoteDirectory;
uint8_t RemoteFile;
uint8_t LocalDirectory;
uint8_t LocalFile;
static constexpr HostSort NotSaved() { return { 0xFF, 0xFF, 0xFF, 0xFF }; } /* ホスト毎のセーブ方法を保存していない時の値 */
static constexpr HostSort Default() { return { SORT_NAME, SORT_NAME, SORT_NAME, SORT_NAME }; }
constexpr bool operator==(HostSort const&) const = default;
};
static_assert(sizeof(HostSort) == 4);
/* 設定値 */
inline int WinPosX = CW_USEDEFAULT;
inline int WinPosY = 0;
inline int WinWidth = 790;
inline int WinHeight = 513;
inline int LocalWidth = 389;
inline int TaskHeight = 100;
inline int LocalTabWidthDefault[4] = { 150, 120, 60, 37 };
inline int LocalTabWidth[4];
inline int RemoteTabWidthDefault[6] = { 150, 120, 60, 37, 60, 60 };
inline int RemoteTabWidth[6];
inline std::wstring UserMailAdrs = L"who@example.com"s;
inline std::wstring ViewerName[VIEWERS] = { L"notepad"s };
inline HFONT ListFont = NULL;
inline LOGFONTW ListLogFont;
inline HostSort Sort = HostSort::Default();
inline int TransMode = TYPE_X;
inline int ConnectOnStart = YES;
inline int DebugConsole = NO;
inline int SaveWinPos = NO;
inline std::vector AsciiExt = { L"*.txt"s, L"*.html"s, L"*.htm"s, L"*.cgi"s, L"*.pl"s, L"*.js"s, L"*.vbs"s, L"*.css"s, L"*.rss"s, L"*.rdf"s, L"*.xml"s, L"*.xhtml"s, L"*.xht"s, L"*.shtml"s, L"*.shtm"s, L"*.sh"s, L"*.py"s, L"*.rb"s, L"*.properties"s, L"*.sql"s, L"*.asp"s, L"*.aspx"s, L"*.php"s, L"*.htaccess"s };
inline int RecvMode = TRANS_DLG;
inline int SendMode = TRANS_DLG;
inline int MoveMode = MOVE_DLG;
inline int ListType = LVS_REPORT;
inline std::wstring DefaultLocalPath;
inline int SaveTimeStamp = YES;
inline int FindMode = 0;
inline int DotFile = YES;
inline int DclickOpen = YES;
inline int ConnectAndSet = YES;
inline int FnameCnv = FNAME_NOCNV;
inline int TimeOut = 90; // 0~300秒; 0=タイムアウトなし
inline int RmEOF = NO;
inline int RegType = REGTYPE_REG;
inline std::wstring FwallHost;
inline std::wstring FwallUser;
inline std::wstring FwallPass;
inline int FwallPort = IPPORT_FTP;
inline int FwallType = 1;
inline int FwallDefault = NO;
inline int FwallSecurity = SECURITY_AUTO;
inline int FwallResolve = NO;
inline int FwallLower = NO;
inline int FwallDelimiter = '@';
inline int PasvDefault = YES;
inline std::vector<std::wstring> MirrorNoTrn = { L"*.bak"s };
inline std::vector<std::wstring> MirrorNoDel;
inline int MirrorFnameCnv = NO;
inline int RasClose = NO;
inline int RasCloseNotify = YES;
inline int FileHist = 5;
inline std::vector<std::wstring> DefAttrList;
inline SIZE HostDlgSize = { -1, -1 };
inline SIZE BmarkDlgSize = { -1, -1 };
inline SIZE MirrorDlgSize = { -1, -1 };
inline int Sizing = SW_RESTORE;
inline int SortSave = NO;
inline int QuickAnonymous = YES;
inline int PassToHist = YES;
inline int VaxSemicolon = NO;
inline int SendQuit = NO;
inline int NoRasControl = NO;
inline int SuppressSave = NO;
inline int DispIgnoreHide = NO;
inline int DispDrives = NO;
inline int MirUpDelNotify = YES;
inline int MirDownDelNotify = YES;
inline int FolderAttr = NO;
inline int FolderAttrNum = 777;
inline int DispFileIcon = NO;
inline int DispTimeSeconds = NO;
inline int DispPermissionsNumber = NO;
inline int MakeAllDir = YES;
inline int LocalKanjiCode = KANJI_SJIS;
inline int UPnPEnabled = NO;
inline int EncryptAllSettings = NO;
inline int AutoRefreshFileList = YES;
inline int RemoveOldLog = NO;
inline int AbortOnListError = YES;
inline int MirrorNoTransferContents = NO;
inline int FwallNoSaveUser = NO;
inline int MarkAsInternet = YES;
inline int UpExistMode = EXIST_OVW; /* アップロードで同じ名前のファイルがある時の扱い方 EXIST_xxx */
inline int ExistMode = EXIST_OVW; /* 同じ名前のファイルがある時の扱い方 EXIST_xxx */
// global variables
inline time_t LastDataConnectionTime = 0;
inline int ReadOnlySettings = NO;
inline int ClientWidth;
inline int SepaWidth;
inline int RemoteWidth;
inline int ListHeight;
inline int CancelFlg;
template<class T>
constexpr T CreateInvalidateHandle() {
T handle;
SecInvalidateHandle(&handle);
return handle;
}
struct SocketContext : public WSAOVERLAPPED {
static inline int recvlen = 8192;
SOCKET const handle;
std::wstring const originalTarget;
std::wstring const punyTarget;
int mapPort = 0;
std::variant<sockaddr_storage, std::tuple<std::wstring, int>> target;
CtxtHandle sslContext = CreateInvalidateHandle<CtxtHandle>();
bool sslSecure = false;
SecPkgContext_StreamSizes sslStreamSizes = {};
std::vector<char> readRaw;
std::vector<char> readPlain;
bool sslNeedRenegotiate = false;
SECURITY_STATUS sslReadStatus = SEC_E_OK;
int recvStatus = 0;
ULONG readRawSize = 0;
inline SocketContext(SOCKET s, std::wstring originalTarget, std::wstring punyTarget);
SocketContext(SocketContext const&) = delete;
inline ~SocketContext();
static std::shared_ptr<SocketContext> Create(int af, std::variant<std::wstring_view, std::reference_wrapper<const SocketContext>> originalTarget);
std::shared_ptr<SocketContext> Accept(_Out_writes_bytes_opt_(*addrlen) struct sockaddr* addr, _Inout_opt_ int* addrlen);
BOOL AttachSSL(BOOL* pbAborted);
constexpr bool IsSSLAttached() {
return SecIsValidHandle(&sslContext);
}
std::vector<char> Encrypt(std::string_view plain);
int Connect(const sockaddr* name, int namelen, int* CancelCheckWork);
int Listen(int backlog);
void OnComplete(DWORD error, DWORD transferred, DWORD flags);
int AsyncFetch();
int GetReadStatus() noexcept;
std::tuple<int, std::wstring> ReadReply(int* CancelCheckWork);
bool ReadSpan(std::span<char>& span, int* CancelCheckWork);
template<class Data>
bool ReadData(Data& data, int* CancelCheckWork) {
std::span span{ reinterpret_cast<char*>(&data), sizeof data };
return ReadSpan(span, CancelCheckWork);
}
int ReadAll(int* CancelCheckWork, std::function<bool(std::vector<char> const&)> callback);
void ClearReadBuffer() noexcept;
int Send(const char* buf, int len, int flags, int* CancelCheckWork);
};
struct HostExeptPassword {
static inline auto DefaultChmod = L"SITE CHMOD"s; /* 属性変更コマンド */
static inline auto DefaultLsOption = L"-alL"s; /* NLSTに付けるもの */
static inline int DefaultTimeZone = []() noexcept {
TIME_ZONE_INFORMATION tzi;
GetTimeZoneInformation(&tzi);
return tzi.Bias / -60;
}();
std::wstring HostAdrs; /* ホスト名 */
std::wstring UserName; /* ユーザ名 */
std::wstring Account; /* アカウント */
std::wstring LocalInitDir; /* ローカルの開始ディレクトリ */
std::wstring RemoteInitDir; /* ホストの開始ディレクトリ */
std::wstring ChmodCmd = DefaultChmod; /* 属性変更コマンド */
std::wstring LsName = DefaultLsOption; /* NLSTに付けるファイル名/オプション*/
std::wstring InitCmd; /* ホストの初期化コマンド */
int Port = IPPORT_FTP; /* ポート番号 */
int KanjiCode = KANJI_NOCNV; /* ホストの漢字コード (KANJI_xxx) */
int KanaCnv = YES; /* 半角カナを全角に変換(YES/NO) */
int NameKanjiCode = KANJI_NOCNV; /* ファイル名の漢字コード (KANJI_xxx) */
int NameKanaCnv = NO; /* ファイル名の半角カナを全角に変換(YES/NO) */
int Pasv = YES; /* PASVモード (YES/NO) */
int FireWall = NO; /* FireWallを使う (YES/NO) */
int ListCmdOnly = YES; /* "LIST"コマンドのみ使用する */
int UseNLST_R = YES; /* "NLST -R"コマンドを使用する */
int TimeZone = DefaultTimeZone; /* タイムゾーン (-12~12) */
int HostType = HTYPE_AUTO; /* ホストのタイプ (HTYPE_xxx) */
int SyncMove = NO; /* フォルダ同時移動 (YES/NO) */
int NoFullPath = NO; /* フルパスでファイルアクセスしない (YES/NO) */
HostSort Sort = HostSort::NotSaved(); /* ソート方法 (0x11223344 : 11=LFsort 22=LDsort 33=RFsort 44=RFsort) */
int Security = SECURITY_AUTO; /* セキュリティ (SECURITY_xxx , MDx) */
int Dialup = NO; /* ダイアルアップ接続するかどうか (YES/NO) */
int DialupAlways = NO; /* 常にこのエントリへ接続するかどうか (YES/NO) */
int DialupNotify = YES; /* 再接続の際に確認する (YES/NO) */
std::wstring DialEntry; /* ダイアルアップエントリ */
int UseNoEncryption = YES; /* 暗号化なしで接続する (YES/NO) */
int UseFTPES = YES; /* FTPESで接続する (YES/NO) */
int UseFTPIS = YES; /* FTPISで接続する (YES/NO) */
int UseSFTP = YES; /* SFTPで接続する (YES/NO) */
int MaxThreadCount = 1; /* 同時接続数 */
int ReuseCmdSkt = YES; /* メインウィンドウのソケットを再利用する (YES/NO) */
int UseMLSD = YES; /* "MLSD"コマンドを使用する */
int NoopInterval = 60; /* 無意味なコマンドを送信する間隔(秒数、0で無効)*/
int TransferErrorMode = EXIST_OVW; /* 転送エラー時の処理 (EXIST_xxx) */
int TransferErrorNotify = YES; /* 転送エラー時に確認ダイアログを出すかどうか (YES/NO) */
int TransferErrorReconnect = YES; /* 転送エラー時に再接続する (YES/NO) */
int NoPasvAdrs = NO; /* PASVで返されるアドレスを無視する (YES/NO) */
inline HostExeptPassword() noexcept;
};
struct Host : HostExeptPassword {
std::wstring PassWord;
Host() = default;
Host(Host const&) = default;
Host(Host const& that, bool includePassword) : HostExeptPassword{ that }, PassWord{ includePassword ? that.PassWord : L""s } {}
};
struct HOSTDATA : Host {
int Level = 0; /* 設定のレベル */
/* 通常はグループのフラグのみが有効 */
/* レベル数は設定の登録/呼出時のみで使用 */
std::wstring HostName; /* 設定名 */
std::vector<std::wstring> BookMark; /* ブックマーク */
int Anonymous = NO; /* Anonymousフラグ */
mutable int CurNameKanjiCode = KANJI_NOCNV; /* 自動判別後のファイル名の漢字コード (KANJI_xxx) */
int LastDir = NO; /* 最後にアクセスしたフォルダを保存 */
int CryptMode = CRYPT_NONE; /* 暗号化通信モード (CRYPT_xxx) */
int NoDisplayUI = NO; /* UIを表示しない (YES/NO) */
int Feature = 0; /* 利用可能な機能のフラグ (FEATURE_xxx) */
int CurNetType = NTYPE_AUTO; /* 接続中のネットワークの種類 (NTYPE_xxx) */
HOSTDATA() = default;
HOSTDATA(struct HISTORYDATA const& history);
};
struct HISTORYDATA : Host {
int Type; /* 転送方法 (TYPE_xx) */
HISTORYDATA() noexcept : Type{ 0 } {}
HISTORYDATA(HISTORYDATA const&) = default;
HISTORYDATA(Host const& that, bool includePassword, int type) : Host{ that, includePassword }, Type{ type } {}
};
struct TRANSPACKET {
std::shared_ptr<SocketContext> ctrl_skt; /* Socket */
std::wstring Command; /* STOR/RETR/MKD */
std::wstring Remote; /* ホスト側のファイル名(フルパス) */
/* VMSの時は ddd[xxx.yyy]/yyy/zzz のように */
/* なってるので注意 */
fs::path Local; /* ローカル側のファイル名(フルパス) */
int Type = 0; /* 転送方法 (TYPE_xx) */
LONGLONG Size = 0; /* ファイルのサイズ */
LONGLONG ExistSize = 0; /* すでに存在するファイルのサイズ */
/* 転送中は、転送したファイルのサイズを格納する */
FILETIME Time = {}; /* ファイルの時間(UTC) */
int Attr = 0; /* ファイルの属性 */
int KanjiCode = 0; /* 漢字コード (KANJI_xxx) */
int KanjiCodeDesired = 0; /* ローカルの漢字コード (KANJI_xxx) */
int KanaCnv = 0; /* 半角カナを全角に変換(YES/NO) */
int Mode = 0; /* 転送モード (EXIST_xxx) */
#if defined(HAVE_TANDEM)
int FileCode = 0; /* ファイルコード */
int PriExt = 0; /* Primary Extents */
int SecExt = 0; /* Secondary Extents */
int MaxExt = 0; /* Max Extents */
#endif
HWND hWndTrans = nullptr; /* 転送中ダイアログのウインドウハンドル */
int Abort = 0; /* 転送中止フラグ (ABORT_xxx) */
int NoTransfer = 0;
int ThreadCount = 0;
};
/*===== ファイルリスト =====*/
struct FILELIST {
std::string Original;
std::wstring Name;
char Node = 0; /* 種類 (NODE_xxx) */
char Link = 0; /* リンクファイルかどうか (YES/NO) */
LONGLONG Size = 0; /* ファイルサイズ */
int Attr = 0; /* 属性 */
FILETIME Time = {}; /* 時間(UTC) */
std::wstring Owner; /* オーナ名 */
char InfoExist = 0; /* ファイル一覧に存在した情報のフラグ (FINFO_xxx) */
int ImageId = 0; /* アイコン画像番号 */
FILELIST() = default;
FILELIST(std::wstring_view name, char node) : Name{ name }, Node{ node } {}
FILELIST(std::string_view original, char node) : Original{ original }, Node{ node } {}
FILELIST(std::wstring_view name, char node, char link, int64_t size, int attr, FILETIME time, char infoExist) : Name{ name }, Node{ node }, Link{ link }, Size{ size }, Attr{ attr }, Time{ time }, InfoExist{ infoExist } {}
inline FILELIST(std::string_view original, char node, char link, int64_t size, int attr, FILETIME time, std::string_view owner, char infoExist);
// ディレクトリの階層数を返す
// 単に '\' と '/'の数を返すだけ
int DirLevel() const {
return (int)std::ranges::count_if(Name, [](auto ch) { return ch == L'/' || ch == L'\\'; });
}
};
class Sound {
const wchar_t* keyName;
const wchar_t* name;
int id;
Sound(const wchar_t* keyName, const wchar_t* name, int id) noexcept : keyName{ keyName }, name{ name }, id{ id } {}
public:
static Sound Connected;
static Sound Transferred;
static Sound Error;
void Play() noexcept { PlaySoundW(keyName, 0, SND_ASYNC | SND_NODEFAULT | SND_APPLICATION); }
static void Register();
};
class MainThreadRunner {
protected:
~MainThreadRunner() = default;
virtual int DoWork() = 0;
public:
int Run();
};
/*=================================================
* プロトタイプ
*=================================================*/
/*===== main.c =====*/
fs::path const& systemDirectory();
fs::path const& tempDirectory();
void DispWindowTitle();
HWND GetMainHwnd() noexcept;
void SetFocusHwnd(HWND hWnd) noexcept;
HINSTANCE GetFtpInst() noexcept;
void DoubleClickProc(int Win, int Mode, int App);
void ExecViewer(fs::path const& path, int App);
void ExecViewer2(fs::path const& path1, fs::path const& path2, int App);
void AddTempFileList(fs::path const& file);
void ShowHelp(DWORD_PTR helpTopicId);
fs::path const& AskIniFilePath() noexcept;
int AskForceIni() noexcept;
int BackgrndMessageProc() noexcept;
void ResetAutoExitFlg() noexcept;
int AskAutoExit() noexcept;
// マルチコアCPUの特定環境下でファイル通信中にクラッシュするバグ対策
BOOL IsMainThread() noexcept;
void Restart() noexcept;
void Terminate() noexcept;
// タスクバー進捗表示
int LoadTaskbarList3() noexcept;
void FreeTaskbarList3();
int IsTaskbarList3Loaded() noexcept;
void UpdateTaskbarProgress();
// 高DPI対応
int AskToolWinHeight() noexcept;
/*===== filelist.c =====*/
int MakeListWin();
void DeleteListWin() noexcept;
HWND GetLocalHwnd() noexcept;
HWND GetRemoteHwnd() noexcept;
void SetListViewType() noexcept;
void GetRemoteDirForWnd(int Mode, int *CancelCheckWork);
void GetLocalDirForWnd(void);
void RefreshLocal();
void ReSortDispList(int Win, int *CancelCheckWork);
bool CheckFname(std::wstring const& file, std::wstring const& spec);
void SelectFileInList(HWND hWnd, int Type, std::vector<FILELIST> const& Base);
void FindFileInList(HWND hWnd, int Type);
FILELIST const& GetItem(int Win, int Pos) noexcept;
int GetCurrentItem(int Win) noexcept;
int GetItemCount(int Win) noexcept;
int GetSelectedCount(int Win) noexcept;
int GetFirstSelected(int Win, int All) noexcept;
int GetNextSelected(int Win, int Pos, int All) noexcept;
void EraseRemoteDirForWnd() noexcept;
uintmax_t GetSelectedTotalSize(int Win) noexcept;
int MakeSelectedFileList(int Win, int Expand, int All, std::vector<FILELIST>& Base, int *CancelCheckWork);
std::tuple<fs::path, std::vector<FILELIST>> MakeDroppedFileList(WPARAM wParam);
fs::path MakeDroppedDir(WPARAM wParam);
void AddRemoteTreeToFileList(int Num, std::wstring const& Path, int IncDir, std::vector<FILELIST>& Base);
const FILELIST* SearchFileList(std::wstring_view Fname, std::vector<FILELIST> const& Base, int Caps);
static inline FILELIST* SearchFileList(std::wstring_view Fname, __pragma(warning(suppress:26460)) std::vector<FILELIST>& Base, int Caps) {
return const_cast<FILELIST*>(SearchFileList(Fname, static_cast<std::vector<FILELIST> const&>(Base), Caps));
}
void SetFilter(int *CancelCheckWork);
void doDeleteRemoteFile(void);
/*===== toolmenu.c =====*/
bool MakeToolBarWindow();
void DeleteToolBarWindow() noexcept;
HWND GetMainTbarWnd() noexcept;
HWND GetLocalHistHwnd() noexcept;
HWND GetRemoteHistHwnd() noexcept;
HWND GetLocalHistEditHwnd() noexcept;
HWND GetRemoteHistEditHwnd() noexcept;
HWND GetLocalTbarWnd() noexcept;
HWND GetRemoteTbarWnd() noexcept;
void MakeButtonsFocus() noexcept;
void DisableUserOpe(void);
void EnableUserOpe(void);
bool AskUserOpeDisabled() noexcept;
void SetTransferTypeImm(int Mode) noexcept;
void SetTransferType(int Type);
void DispTransferType(void);
int AskTransferType() noexcept;
int AskTransferTypeAssoc(std::wstring_view path, int Type);
void SaveTransferType() noexcept;
void SetHostKanjiCodeImm(int Mode);
void SetHostKanjiCode(int Type);
void DispHostKanjiCode(void);
int AskHostKanjiCode() noexcept;
void HideHostKanjiButton() noexcept;
// UTF-8対応
void SetLocalKanjiCodeImm(int Mode);
void SetLocalKanjiCode(int Type);
void DispLocalKanjiCode(void);
int AskLocalKanjiCode() noexcept;
void HideLocalKanjiButton() noexcept;
void SaveLocalKanjiCode() noexcept;
void SetHostKanaCnvImm(int Mode) noexcept;
void SetHostKanaCnv() noexcept;
void DispHostKanaCnv() noexcept;
int AskHostKanaCnv() noexcept;
void SetSortTypeImm(HostSort const& sort) noexcept;
void SetSortTypeByColumn(int Win, int Tab) noexcept;
HostSort const& AskSortType() noexcept;
void SetSaveSortToHost(int Sw) noexcept;
int AskSaveSortToHost() noexcept;
void DispListType() noexcept;
void SetSyncMoveMode(int Mode) noexcept;
void ToggleSyncMoveMode() noexcept;
void DispSyncMoveMode() noexcept;
int AskSyncMoveMode() noexcept;
void SetRemoteDirHist(std::wstring const& path);
void SetLocalDirHist(fs::path const& path);
fs::path const& AskLocalCurDir() noexcept;
std::wstring const& AskRemoteCurDir() noexcept;
void SetCurrentDirAsDirHist() noexcept;
void DispDotFileMode() noexcept;
void ShowPopupMenu(int Win, int Pos);
/*===== statuswin.c =====*/
int MakeStatusBarWindow();
void DeleteStatusBarWindow() noexcept;
HWND GetSbarWnd() noexcept;
void UpdateStatusBar();
void DispCurrentWindow(int Win);
void DispSelectedSpace(void);
void DispLocalFreeSpace(fs::path const& directory);
void DispTransferFiles(void);
void DispDownloadSize(LONGLONG Size);
bool NotifyStatusBar(const NMHDR* hdr);
/*===== taskwin.c =====*/
int MakeTaskWindow() noexcept;
void DeleteTaskWindow() noexcept;
HWND GetTaskWnd() noexcept;
void DispTaskMsg(void);
namespace detail {
void Notice(UINT id, std::wformat_args args);
void Debug(std::wstring_view format, std::wformat_args args);
}
// メッセージを表示する
template<class... Args>
static inline void Notice(UINT id, const Args&... args) {
detail::Notice(id, std::make_wformat_args(args...));
}
// デバッグメッセージを表示する
template<class... Args>
static inline void Debug(std::wstring_view format, const Args&... args) {
detail::Debug(format, std::make_wformat_args(args...));
}
void Error(std::wstring_view functionName, int lastError = GetLastError());
static inline void WSAError(std::wstring_view functionName, int lastError = WSAGetLastError()) { Error(functionName, lastError); }
/*===== hostman.c =====*/
int SelectHost(int Type);
int AddHostToList(HOSTDATA *Set, int Pos, int Level);
int CopyHostFromList(int Num, HOSTDATA *Set);
HOSTDATA GetConnectingHost();
int SetHostBookMark(int Num, std::vector<std::wstring>&& bookmark);
std::optional<std::vector<std::wstring>> AskHostBookMark(int Num);
int SetHostDir(int Num, std::wstring_view LocDir, std::wstring_view HostDir);
int SetHostPassword(int Num, std::wstring const& Pass);
int SetHostSort(int Num, HostSort const& sort);
int AskCurrentHost() noexcept;
void SetCurrentHost(int Num) noexcept;
void CopyDefaultHost(HOSTDATA *Set);
// ホスト共通設定機能
void ResetDefaultHost(void);
void SetDefaultHost(HOSTDATA *Set);
int SearchHostName(std::wstring_view name);
void ImportFromWSFTP(void);
// 暗号化通信対応
int SetHostEncryption(int Num, int UseNoEncryption, int UseFTPES, int UseFTPIS, int UseSFTP);
/*===== connect.c =====*/
HOSTDATA const& GetCurHost() noexcept;
void ConnectProc(int Type, int Num);
void QuickConnectProc(void);
void DirectConnectProc(std::wstring&& unc, int Kanji, int Kana, int Fkanji, int TrMode);
void HistoryConnectProc(int MenuCmd);
int AskHostType(void);
int AskNoFullPathMode() noexcept;
void SaveCurrentSetToHost(void);
int ReConnectCmdSkt(void);
int ReConnectTrnSkt(std::shared_ptr<SocketContext>& Skt, int *CancelCheckWork);
std::shared_ptr<SocketContext> AskCmdCtrlSkt() noexcept;
std::shared_ptr<SocketContext> AskTrnCtrlSkt() noexcept;
void SktShareProh(void);
int AskShareProh() noexcept;
void DisconnectProc(void);
void DisconnectSet() noexcept;
int AskConnecting() noexcept;
#if defined(HAVE_TANDEM)
int SetOSS(int wkOss);
int AskOSS() noexcept;
#endif
std::optional<sockaddr_storage> SocksReceiveReply(SocketContext& s, int* CancelCheckWork);
std::shared_ptr<SocketContext> connectsock(std::variant<std::wstring_view, std::reference_wrapper<const SocketContext>> originalTarget, std::wstring&& host, int port, int *CancelCheckWork);
std::shared_ptr<SocketContext> GetFTPListenSocket(std::shared_ptr<SocketContext> ctrl_skt, int *CancelCheckWork);
int AskTryingConnect() noexcept;
// キャッシュのファイル名を作成する
static inline fs::path MakeCacheFileName(int num) {
return tempDirectory() / std::format(L"_ffftp.{:03d}"sv, num);
}
/*===== ftpproc.c =====*/
void DownloadProc(int ChName, int ForceFile, int All);
void DirectDownloadProc(std::wstring_view Fname);
void MirrorDownloadProc(int Notify);
void UploadListProc(int ChName, int All);
void UploadDragProc(WPARAM wParam);
void MirrorUploadProc(int Notify);
void DeleteProc(void);
void RenameProc(void);
void MoveRemoteFileProc(int);
void MkdirProc(void);
void ChangeDirComboProc(HWND hWnd);
void ChangeDirBmarkProc(int MarkID);
void ChangeDirDirectProc(int Win);
void ChangeDirDropFileProc(WPARAM wParam);
void ChmodProc(void);
std::optional<std::wstring> ChmodDialog(std::wstring const& text);
void SomeCmdProc(void);
void CalcFileSizeProc(void);
void DispCWDerror(HWND hWnd) noexcept;
void CopyURLtoClipBoard(void);