FFFTPのソースコードです。
Revisión | 91f406cab5f34e42988386c9078f877783d7e816 (tree) |
---|---|
Tiempo | 2013-02-18 01:18:32 |
Autor | s_kawamoto <s_kawamoto@user...> |
Commiter | s_kawamoto |
Add support for UPnP port mapping (Windows XP or later only).
@@ -963,6 +963,7 @@ BEGIN | ||
963 | 963 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,94,196,10 |
964 | 964 | CONTROL "切断時にQUITコマンドを送る(&U)",CONNECT_SENDQUIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,108,173,10 |
965 | 965 | CONTROL "RASの制御を行わない(&R)",CONNECT_NORAS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,122,173,10 |
966 | + CONTROL "非PASVモード時にUPnPを制御する(&U)",CONNECT_UPNP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,136,173,10 | |
966 | 967 | END |
967 | 968 | |
968 | 969 | rasnotify_dlg DIALOG 0, 0, 158, 46 |
@@ -235,6 +235,7 @@ | ||
235 | 235 | #define PERM_A_WRITE 1018 |
236 | 236 | #define CONNECT_NORAS 1018 |
237 | 237 | #define PERM_A_EXEC 1019 |
238 | +#define CONNECT_UPNP 1019 | |
238 | 239 | #define PERM_TEXT 1020 |
239 | 240 | #define PERM_NOW 1021 |
240 | 241 | #define SORT_LFILE_FILE 1022 |
@@ -984,6 +984,8 @@ BEGIN | ||
984 | 984 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,109,173,10 |
985 | 985 | CONTROL "Do not control dialup (&RAS) connection",CONNECT_NORAS, |
986 | 986 | "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,122,173,10 |
987 | + CONTROL "Control &UPnP when using non PASV mode",CONNECT_UPNP, | |
988 | + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,136,173,10 | |
987 | 989 | END |
988 | 990 | |
989 | 991 | rasnotify_dlg DIALOG 0, 0, 158, 46 |
@@ -235,6 +235,7 @@ | ||
235 | 235 | #define PERM_A_WRITE 1018 |
236 | 236 | #define CONNECT_NORAS 1018 |
237 | 237 | #define PERM_A_EXEC 1019 |
238 | +#define CONNECT_UPNP 1019 | |
238 | 239 | #define PERM_TEXT 1020 |
239 | 240 | #define PERM_NOW 1021 |
240 | 241 | #define SORT_LFILE_FILE 1022 |
@@ -1915,8 +1915,10 @@ void DeleteSocketWin(void); | ||
1915 | 1915 | // ソケットにデータを付与 |
1916 | 1916 | int SetAsyncTableDataIPv4(SOCKET s, struct sockaddr_in* Host, struct sockaddr_in* Socks); |
1917 | 1917 | int SetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_in6* Socks); |
1918 | +int SetAsyncTableDataMapPort(SOCKET s, int Port); | |
1918 | 1919 | int GetAsyncTableDataIPv4(SOCKET s, struct sockaddr_in* Host, struct sockaddr_in* Socks); |
1919 | 1920 | int GetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_in6* Socks); |
1921 | +int GetAsyncTableDataMapPort(SOCKET s, int* Port); | |
1920 | 1922 | // IPv6対応 |
1921 | 1923 | //struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork); |
1922 | 1924 | struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork); |
@@ -1930,6 +1932,12 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOut, int *CancelCh | ||
1930 | 1932 | int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork); |
1931 | 1933 | // 同時接続対応 |
1932 | 1934 | void RemoveReceivedData(SOCKET s); |
1935 | +// UPnP対応 | |
1936 | +int LoadUPnP(); | |
1937 | +void FreeUPnP(); | |
1938 | +int IsUPnPLoaded(); | |
1939 | +int AddPortMapping(char* Adrs, int Port); | |
1940 | +int RemovePortMapping(int Port); | |
1933 | 1941 | int CheckClosedAndReconnect(void); |
1934 | 1942 | // 同時接続対応 |
1935 | 1943 | int CheckClosedAndReconnectTrnSkt(SOCKET *Skt, int *CancelCheckWork); |
@@ -2616,6 +2616,10 @@ SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2616 | 2616 | int Len; |
2617 | 2617 | int Fwall; |
2618 | 2618 | |
2619 | + // UPnP対応 | |
2620 | + char Adrs[16]; | |
2621 | + int Port; | |
2622 | + | |
2619 | 2623 | // ソケットにデータを付与 |
2620 | 2624 | GetAsyncTableDataIPv4(ctrl_skt, &CurSockAddr, &SocksSockAddr); |
2621 | 2625 |
@@ -2724,6 +2728,12 @@ SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2724 | 2728 | |
2725 | 2729 | a = (char *)&saTmpAddr.sin_addr; |
2726 | 2730 | p = (char *)&saCtrlAddr.sin_port; |
2731 | + // UPnP対応 | |
2732 | + if(IsUPnPLoaded() == YES) | |
2733 | + { | |
2734 | + if(AddPortMapping(AddressToStringIPv4(Adrs, &saTmpAddr.sin_addr), ntohs(saCtrlAddr.sin_port)) == FFFTP_SUCCESS) | |
2735 | + SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin_port)); | |
2736 | + } | |
2727 | 2737 | } |
2728 | 2738 | else |
2729 | 2739 | { |
@@ -2769,6 +2779,12 @@ SOCKET GetFTPListenSocketIPv4(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2769 | 2779 | // IPv6対応 |
2770 | 2780 | // SetTaskMsg(MSGJPN031); |
2771 | 2781 | SetTaskMsg(MSGJPN031, MSGJPN333); |
2782 | + // UPnP対応 | |
2783 | + if(IsUPnPLoaded() == YES) | |
2784 | + { | |
2785 | + if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES) | |
2786 | + RemovePortMapping(Port); | |
2787 | + } | |
2772 | 2788 | do_closesocket(listen_skt); |
2773 | 2789 | listen_skt = INVALID_SOCKET; |
2774 | 2790 | } |
@@ -2796,6 +2812,8 @@ SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2796 | 2812 | int Fwall; |
2797 | 2813 | |
2798 | 2814 | char Adrs[40]; |
2815 | + // UPnP対応 | |
2816 | + int Port; | |
2799 | 2817 | |
2800 | 2818 | // ソケットにデータを付与 |
2801 | 2819 | GetAsyncTableDataIPv6(ctrl_skt, &CurSockAddr, &SocksSockAddr); |
@@ -2867,6 +2885,12 @@ SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2867 | 2885 | |
2868 | 2886 | a = (char *)&saTmpAddr.sin6_addr; |
2869 | 2887 | p = (char *)&saCtrlAddr.sin6_port; |
2888 | + // UPnP対応 | |
2889 | + if(IsUPnPLoaded() == YES) | |
2890 | + { | |
2891 | + if(AddPortMapping(AddressToStringIPv6(Adrs, &saTmpAddr.sin6_addr), ntohs(saCtrlAddr.sin6_port)) == FFFTP_SUCCESS) | |
2892 | + SetAsyncTableDataMapPort(listen_skt, ntohs(saCtrlAddr.sin6_port)); | |
2893 | + } | |
2870 | 2894 | } |
2871 | 2895 | else |
2872 | 2896 | { |
@@ -2908,6 +2932,12 @@ SOCKET GetFTPListenSocketIPv6(SOCKET ctrl_skt, int *CancelCheckWork) | ||
2908 | 2932 | (UC(p[0]) << 8) | UC(p[1])) / 100) != FTP_COMPLETE) |
2909 | 2933 | { |
2910 | 2934 | SetTaskMsg(MSGJPN031, MSGJPN334); |
2935 | + // UPnP対応 | |
2936 | + if(IsUPnPLoaded() == YES) | |
2937 | + { | |
2938 | + if(GetAsyncTableDataMapPort(listen_skt, &Port) == YES) | |
2939 | + RemovePortMapping(Port); | |
2940 | + } | |
2911 | 2941 | do_closesocket(listen_skt); |
2912 | 2942 | listen_skt = INVALID_SOCKET; |
2913 | 2943 | } |
@@ -1429,6 +1429,8 @@ static int DownloadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) | ||
1429 | 1429 | // struct sockaddr_in saSockAddr1; |
1430 | 1430 | struct sockaddr_in saSockAddrIPv4; |
1431 | 1431 | struct sockaddr_in6 saSockAddrIPv6; |
1432 | + // UPnP対応 | |
1433 | + int Port; | |
1432 | 1434 | char Reply[ERR_MSG_LEN+7]; |
1433 | 1435 | |
1434 | 1436 | if((listen_socket = GetFTPListenSocket(Pkt->ctrl_skt, CancelCheckWork)) != INVALID_SOCKET) |
@@ -1460,6 +1462,12 @@ static int DownloadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) | ||
1460 | 1462 | |
1461 | 1463 | if(shutdown(listen_socket, 1) != 0) |
1462 | 1464 | ReportWSError("shutdown listen", WSAGetLastError()); |
1465 | + // UPnP対応 | |
1466 | + if(IsUPnPLoaded() == YES) | |
1467 | + { | |
1468 | + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) | |
1469 | + RemovePortMapping(Port); | |
1470 | + } | |
1463 | 1471 | listen_socket = DoClose(listen_socket); |
1464 | 1472 | |
1465 | 1473 | if(data_socket == INVALID_SOCKET) |
@@ -1506,12 +1514,29 @@ static int DownloadNonPassive(TRANSPACKET *Pkt, int *CancelCheckWork) | ||
1506 | 1514 | { |
1507 | 1515 | SetErrorMsg(Reply); |
1508 | 1516 | SetTaskMsg(MSGJPN090); |
1517 | + // UPnP対応 | |
1518 | + if(IsUPnPLoaded() == YES) | |
1519 | + { | |
1520 | + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) | |
1521 | + RemovePortMapping(Port); | |
1522 | + } | |
1509 | 1523 | listen_socket = DoClose(listen_socket); |
1510 | 1524 | iRetCode = 500; |
1511 | 1525 | } |
1512 | 1526 | } |
1513 | 1527 | else |
1528 | + // バグ修正 | |
1529 | +// iRetCode = 500; | |
1530 | + { | |
1531 | + // UPnP対応 | |
1532 | + if(IsUPnPLoaded() == YES) | |
1533 | + { | |
1534 | + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) | |
1535 | + RemovePortMapping(Port); | |
1536 | + } | |
1537 | + listen_socket = DoClose(listen_socket); | |
1514 | 1538 | iRetCode = 500; |
1539 | + } | |
1515 | 1540 | } |
1516 | 1541 | else |
1517 | 1542 | { |
@@ -2704,6 +2729,8 @@ static int UploadNonPassive(TRANSPACKET *Pkt) | ||
2704 | 2729 | // struct sockaddr_in saSockAddr1; |
2705 | 2730 | struct sockaddr_in saSockAddrIPv4; |
2706 | 2731 | struct sockaddr_in6 saSockAddrIPv6; |
2732 | + // UPnP対応 | |
2733 | + int Port; | |
2707 | 2734 | int Resume; |
2708 | 2735 | char Reply[ERR_MSG_LEN+7]; |
2709 | 2736 |
@@ -2757,6 +2784,12 @@ static int UploadNonPassive(TRANSPACKET *Pkt) | ||
2757 | 2784 | |
2758 | 2785 | if(shutdown(listen_socket, 1) != 0) |
2759 | 2786 | ReportWSError("shutdown listen", WSAGetLastError()); |
2787 | + // UPnP対応 | |
2788 | + if(IsUPnPLoaded() == YES) | |
2789 | + { | |
2790 | + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) | |
2791 | + RemovePortMapping(Port); | |
2792 | + } | |
2760 | 2793 | listen_socket = DoClose(listen_socket); |
2761 | 2794 | |
2762 | 2795 | if(data_socket == INVALID_SOCKET) |
@@ -2803,6 +2836,12 @@ static int UploadNonPassive(TRANSPACKET *Pkt) | ||
2803 | 2836 | { |
2804 | 2837 | SetErrorMsg(Reply); |
2805 | 2838 | SetTaskMsg(MSGJPN108); |
2839 | + // UPnP対応 | |
2840 | + if(IsUPnPLoaded() == YES) | |
2841 | + { | |
2842 | + if(GetAsyncTableDataMapPort(listen_socket, &Port) == YES) | |
2843 | + RemovePortMapping(Port); | |
2844 | + } | |
2806 | 2845 | listen_socket = DoClose(listen_socket); |
2807 | 2846 | iRetCode = 500; |
2808 | 2847 | } |
@@ -256,6 +256,8 @@ int MakeAllDir = YES; | ||
256 | 256 | int LocalKanjiCode = KANJI_SJIS; |
257 | 257 | // 自動切断対策 |
258 | 258 | int NoopEnable = NO; |
259 | +// UPnP対応 | |
260 | +int UPnPEnabled = NO; | |
259 | 261 | time_t LastDataConnectionTime = 0; |
260 | 262 | |
261 | 263 |
@@ -360,6 +362,10 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi | ||
360 | 362 | |
361 | 363 | InitCommonControls(); |
362 | 364 | |
365 | + // UPnP対応 | |
366 | + CoInitialize(NULL); | |
367 | + LoadUPnP(); | |
368 | + | |
363 | 369 | // FTPS対応 |
364 | 370 | #ifdef USE_OPENSSL |
365 | 371 | LoadOpenSSL(); |
@@ -405,6 +411,9 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi | ||
405 | 411 | #endif |
406 | 412 | // SFTP対応 |
407 | 413 | FreePuTTY(); |
414 | + // UPnP対応 | |
415 | + FreeUPnP(); | |
416 | + CoUninitialize(); | |
408 | 417 | OleUninitialize(); |
409 | 418 | return(Ret); |
410 | 419 | } |
@@ -178,6 +178,8 @@ extern int DispTimeSeconds; | ||
178 | 178 | extern int DispPermissionsNumber; |
179 | 179 | // ディレクトリ自動作成 |
180 | 180 | extern int MakeAllDir; |
181 | +// UPnP対応 | |
182 | +extern int UPnPEnabled; | |
181 | 183 | |
182 | 184 | |
183 | 185 | /*----- オプションのプロパティシート ------------------------------------------ |
@@ -1291,6 +1293,14 @@ static INT_PTR CALLBACK ConnectSettingProc(HWND hDlg, UINT message, WPARAM wPara | ||
1291 | 1293 | SendDlgItemMessage(hDlg, CONNECT_HIST_PASS, BM_SETCHECK, PassToHist, 0); |
1292 | 1294 | SendDlgItemMessage(hDlg, CONNECT_SENDQUIT, BM_SETCHECK, SendQuit, 0); |
1293 | 1295 | SendDlgItemMessage(hDlg, CONNECT_NORAS, BM_SETCHECK, NoRasControl, 0); |
1296 | + // UPnP対応 | |
1297 | + if(IsUPnPLoaded() == YES) | |
1298 | + SendDlgItemMessage(hDlg, CONNECT_UPNP, BM_SETCHECK, UPnPEnabled, 0); | |
1299 | + else | |
1300 | + { | |
1301 | + SendDlgItemMessage(hDlg, CONNECT_UPNP, BM_SETCHECK, BST_UNCHECKED, 0); | |
1302 | + EnableWindow(GetDlgItem(hDlg, CONNECT_UPNP), FALSE); | |
1303 | + } | |
1294 | 1304 | return(TRUE); |
1295 | 1305 | |
1296 | 1306 | case WM_NOTIFY: |
@@ -1308,6 +1318,9 @@ static INT_PTR CALLBACK ConnectSettingProc(HWND hDlg, UINT message, WPARAM wPara | ||
1308 | 1318 | PassToHist = SendDlgItemMessage(hDlg, CONNECT_HIST_PASS, BM_GETCHECK, 0, 0); |
1309 | 1319 | SendQuit = SendDlgItemMessage(hDlg, CONNECT_SENDQUIT, BM_GETCHECK, 0, 0); |
1310 | 1320 | NoRasControl = SendDlgItemMessage(hDlg, CONNECT_NORAS, BM_GETCHECK, 0, 0); |
1321 | + // UPnP対応 | |
1322 | + if(IsUPnPLoaded() == YES) | |
1323 | + UPnPEnabled = SendDlgItemMessage(hDlg, CONNECT_UPNP, BM_GETCHECK, 0, 0); | |
1311 | 1324 | break; |
1312 | 1325 | |
1313 | 1326 | case PSN_RESET : |
@@ -203,6 +203,8 @@ extern int DispPermissionsNumber; | ||
203 | 203 | extern int MakeAllDir; |
204 | 204 | // UTF-8対応 |
205 | 205 | extern int LocalKanjiCode; |
206 | +// UPnP対応 | |
207 | +extern int UPnPEnabled; | |
206 | 208 | |
207 | 209 | /*----- マスタパスワードの設定 ---------------------------------------------- |
208 | 210 | * |
@@ -641,6 +643,8 @@ void SaveRegistry(void) | ||
641 | 643 | WriteIntValueToReg(hKey4, "MakeDir", MakeAllDir); |
642 | 644 | // UTF-8対応 |
643 | 645 | WriteIntValueToReg(hKey4, "Kanji", LocalKanjiCode); |
646 | + // UPnP対応 | |
647 | + WriteIntValueToReg(hKey4, "UPnP", UPnPEnabled); | |
644 | 648 | } |
645 | 649 | CloseSubKey(hKey4); |
646 | 650 | } |
@@ -1053,6 +1057,8 @@ int LoadRegistry(void) | ||
1053 | 1057 | ReadIntValueFromReg(hKey4, "MakeDir", &MakeAllDir); |
1054 | 1058 | // UTF-8対応 |
1055 | 1059 | ReadIntValueFromReg(hKey4, "Kanji", &LocalKanjiCode); |
1060 | + // UPnP対応 | |
1061 | + ReadIntValueFromReg(hKey4, "UPnP", &UPnPEnabled); | |
1056 | 1062 | |
1057 | 1063 | CloseSubKey(hKey4); |
1058 | 1064 | } |
@@ -37,6 +37,8 @@ | ||
37 | 37 | #include <time.h> |
38 | 38 | #include <windowsx.h> |
39 | 39 | #include <commctrl.h> |
40 | +// UPnP対応 | |
41 | +#include <natupnp.h> | |
40 | 42 | |
41 | 43 | #include "common.h" |
42 | 44 | #include "resource.h" |
@@ -71,6 +73,7 @@ typedef struct { | ||
71 | 73 | struct sockaddr_in SocksAddrIPv4; |
72 | 74 | struct sockaddr_in6 HostAddrIPv6; |
73 | 75 | struct sockaddr_in6 SocksAddrIPv6; |
76 | + int MapPort; | |
74 | 77 | } ASYNCSIGNAL; |
75 | 78 | |
76 | 79 |
@@ -119,6 +122,9 @@ static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE]; | ||
119 | 122 | // スレッド衝突のバグ修正 |
120 | 123 | static HANDLE hAsyncTblAccMutex; |
121 | 124 | |
125 | +// UPnP対応 | |
126 | +IUPnPNAT* pUPnPNAT; | |
127 | +IStaticPortMappingCollection* pUPnPMap; | |
122 | 128 | |
123 | 129 | |
124 | 130 |
@@ -499,6 +505,7 @@ static int RegisterAsyncTable(SOCKET s) | ||
499 | 505 | memset(&Signal[Pos].SocksAddrIPv4, 0, sizeof(struct sockaddr_in)); |
500 | 506 | memset(&Signal[Pos].HostAddrIPv6, 0, sizeof(struct sockaddr_in6)); |
501 | 507 | memset(&Signal[Pos].SocksAddrIPv6, 0, sizeof(struct sockaddr_in6)); |
508 | + Signal[Pos].MapPort = 0; | |
502 | 509 | Sts = YES; |
503 | 510 | break; |
504 | 511 | } |
@@ -699,6 +706,27 @@ int SetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_i | ||
699 | 706 | return(Sts); |
700 | 707 | } |
701 | 708 | |
709 | +int SetAsyncTableDataMapPort(SOCKET s, int Port) | |
710 | +{ | |
711 | + int Sts; | |
712 | + int Pos; | |
713 | + | |
714 | + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); | |
715 | + Sts = NO; | |
716 | + for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) | |
717 | + { | |
718 | + if(Signal[Pos].Socket == s) | |
719 | + { | |
720 | + Signal[Pos].MapPort = Port; | |
721 | + Sts = YES; | |
722 | + break; | |
723 | + } | |
724 | + } | |
725 | + ReleaseMutex(hAsyncTblAccMutex); | |
726 | + | |
727 | + return(Sts); | |
728 | +} | |
729 | + | |
702 | 730 | int GetAsyncTableDataIPv4(SOCKET s, struct sockaddr_in* Host, struct sockaddr_in* Socks) |
703 | 731 | { |
704 | 732 | int Sts; |
@@ -747,6 +775,27 @@ int GetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_i | ||
747 | 775 | return(Sts); |
748 | 776 | } |
749 | 777 | |
778 | +int GetAsyncTableDataMapPort(SOCKET s, int* Port) | |
779 | +{ | |
780 | + int Sts; | |
781 | + int Pos; | |
782 | + | |
783 | + WaitForSingleObject(hAsyncTblAccMutex, INFINITE); | |
784 | + Sts = NO; | |
785 | + for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++) | |
786 | + { | |
787 | + if(Signal[Pos].Socket == s) | |
788 | + { | |
789 | + *Port = Signal[Pos].MapPort; | |
790 | + Sts = YES; | |
791 | + break; | |
792 | + } | |
793 | + } | |
794 | + ReleaseMutex(hAsyncTblAccMutex); | |
795 | + | |
796 | + return(Sts); | |
797 | +} | |
798 | + | |
750 | 799 | |
751 | 800 | |
752 | 801 |
@@ -1308,6 +1357,82 @@ void RemoveReceivedData(SOCKET s) | ||
1308 | 1357 | } |
1309 | 1358 | } |
1310 | 1359 | |
1360 | +// UPnP対応 | |
1361 | +int LoadUPnP() | |
1362 | +{ | |
1363 | + int Sts; | |
1364 | + Sts = FFFTP_FAIL; | |
1365 | + if(CoCreateInstance(&CLSID_UPnPNAT, NULL, CLSCTX_ALL, &IID_IUPnPNAT, (void**)&pUPnPNAT) == S_OK) | |
1366 | + { | |
1367 | + if(pUPnPNAT->lpVtbl->get_StaticPortMappingCollection(pUPnPNAT, &pUPnPMap) == S_OK) | |
1368 | + Sts = FFFTP_SUCCESS; | |
1369 | + } | |
1370 | + return Sts; | |
1371 | +} | |
1372 | + | |
1373 | +void FreeUPnP() | |
1374 | +{ | |
1375 | + if(pUPnPMap != NULL) | |
1376 | + pUPnPMap->lpVtbl->Release(pUPnPMap); | |
1377 | + pUPnPMap = NULL; | |
1378 | + if(pUPnPNAT != NULL) | |
1379 | + pUPnPNAT->lpVtbl->Release(pUPnPNAT); | |
1380 | + pUPnPNAT = NULL; | |
1381 | +} | |
1382 | + | |
1383 | +int IsUPnPLoaded() | |
1384 | +{ | |
1385 | + int Sts; | |
1386 | + Sts = FFFTP_FAIL; | |
1387 | + if(pUPnPNAT != NULL && pUPnPMap != NULL) | |
1388 | + Sts = FFFTP_SUCCESS; | |
1389 | + return Sts; | |
1390 | +} | |
1391 | + | |
1392 | +int AddPortMapping(char* Adrs, int Port) | |
1393 | +{ | |
1394 | + int Sts; | |
1395 | + WCHAR Tmp1[40]; | |
1396 | + BSTR Tmp2; | |
1397 | + BSTR Tmp3; | |
1398 | + BSTR Tmp4; | |
1399 | + IStaticPortMapping* pPortMap; | |
1400 | + Sts = FFFTP_FAIL; | |
1401 | + MtoW(Tmp1, 40, Adrs, -1); | |
1402 | + if((Tmp2 = SysAllocString(Tmp1)) != NULL) | |
1403 | + { | |
1404 | + if((Tmp3 = SysAllocString(L"TCP")) != NULL) | |
1405 | + { | |
1406 | + if((Tmp4 = SysAllocString(L"FFFTP")) != NULL) | |
1407 | + { | |
1408 | + if(pUPnPMap->lpVtbl->Add(pUPnPMap, Port, Tmp3, Port, Tmp2, VARIANT_TRUE, Tmp4, &pPortMap) == S_OK) | |
1409 | + { | |
1410 | + Sts = FFFTP_SUCCESS; | |
1411 | + pPortMap->lpVtbl->Release(pPortMap); | |
1412 | + } | |
1413 | + SysFreeString(Tmp4); | |
1414 | + } | |
1415 | + SysFreeString(Tmp3); | |
1416 | + } | |
1417 | + SysFreeString(Tmp2); | |
1418 | + } | |
1419 | + return Sts; | |
1420 | +} | |
1421 | + | |
1422 | +int RemovePortMapping(int Port) | |
1423 | +{ | |
1424 | + int Sts; | |
1425 | + BSTR Tmp; | |
1426 | + Sts = FFFTP_FAIL; | |
1427 | + if((Tmp = SysAllocString(L"TCP")) != NULL) | |
1428 | + { | |
1429 | + if(pUPnPMap->lpVtbl->Remove(pUPnPMap, Port, Tmp) == S_OK) | |
1430 | + Sts = FFFTP_SUCCESS; | |
1431 | + SysFreeString(Tmp); | |
1432 | + } | |
1433 | + return Sts; | |
1434 | +} | |
1435 | + | |
1311 | 1436 | |
1312 | 1437 | /*----- |
1313 | 1438 | * |
@@ -794,6 +794,16 @@ int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle) | ||
794 | 794 | return Result; |
795 | 795 | } |
796 | 796 | |
797 | +char* AddressToStringIPv4(char* str, void* in) | |
798 | +{ | |
799 | + char* pResult; | |
800 | + unsigned char* p; | |
801 | + pResult = str; | |
802 | + p = (unsigned char*)in; | |
803 | + sprintf(str, "%u.%u.%u.%u", p[0], p[1], p[2], p[3]); | |
804 | + return pResult; | |
805 | +} | |
806 | + | |
797 | 807 | char* AddressToStringIPv6(char* str, void* in6) |
798 | 808 | { |
799 | 809 | char* pResult; |
@@ -34,6 +34,7 @@ int FTPS_recv(SOCKET s, char * buf, int len, int flags); | ||
34 | 34 | |
35 | 35 | HANDLE WSAAsyncGetHostByNameIPv6(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family); |
36 | 36 | int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle); |
37 | +char* AddressToStringIPv4(char* str, void* in); | |
37 | 38 | char* AddressToStringIPv6(char* str, void* in6); |
38 | 39 | char* inet6_ntoa(struct in6_addr in6); |
39 | 40 | struct in6_addr inet6_addr(const char* cp); |