#include <time.h>\r
#include <windowsx.h>\r
#include <commctrl.h>\r
+// UPnP対応\r
+#include <natupnp.h>\r
\r
#include "common.h"\r
#include "resource.h"\r
int FdRead;\r
int FdWrite;\r
int Error;\r
+ // ソケットにデータを付与\r
+ struct sockaddr_in HostAddrIPv4;\r
+ struct sockaddr_in SocksAddrIPv4;\r
+ struct sockaddr_in6 HostAddrIPv6;\r
+ struct sockaddr_in6 SocksAddrIPv6;\r
+ int MapPort;\r
} ASYNCSIGNAL;\r
\r
\r
static LRESULT CALLBACK SocketWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);\r
static int AskAsyncDone(SOCKET s, int *Error, int Mask);\r
static int AskAsyncDoneDbase(HANDLE Async, int *Error);\r
-static int RegistAsyncTable(SOCKET s);\r
-static int RegistAsyncTableDbase(HANDLE Async);\r
-static int UnRegistAsyncTable(SOCKET s);\r
-static int UnRegistAsyncTableDbase(HANDLE Async);\r
+static int RegisterAsyncTable(SOCKET s);\r
+static int RegisterAsyncTableDbase(HANDLE Async);\r
+static int UnregisterAsyncTable(SOCKET s);\r
+static int UnregisterAsyncTableDbase(HANDLE Async);\r
\r
\r
/*===== 外部参照 =====*/\r
// スレッド衝突のバグ修正\r
static HANDLE hAsyncTblAccMutex;\r
\r
+// UPnP対応\r
+IUPnPNAT* pUPnPNAT;\r
+IStaticPortMappingCollection* pUPnPMap;\r
\r
\r
\r
\r
case WM_ASYNC_DBASE :\r
// APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
- RegistAsyncTableDbase((HANDLE)wParam);\r
+ RegisterAsyncTableDbase((HANDLE)wParam);\r
// スレッド衝突のバグ修正\r
WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
* \r
*----------------------------------------------------------------------------*/\r
\r
-static int RegistAsyncTable(SOCKET s)\r
+static int RegisterAsyncTable(SOCKET s)\r
{\r
int Sts;\r
int Pos;\r
Signal[Pos].FdAccept = 0;\r
Signal[Pos].FdRead = 0;\r
Signal[Pos].FdWrite = 0;\r
+ // ソケットにデータを付与\r
+ memset(&Signal[Pos].HostAddrIPv4, 0, sizeof(struct sockaddr_in));\r
+ memset(&Signal[Pos].SocksAddrIPv4, 0, sizeof(struct sockaddr_in));\r
+ memset(&Signal[Pos].HostAddrIPv6, 0, sizeof(struct sockaddr_in6));\r
+ memset(&Signal[Pos].SocksAddrIPv6, 0, sizeof(struct sockaddr_in6));\r
+ Signal[Pos].MapPort = 0;\r
Sts = YES;\r
break;\r
}\r
* \r
*----------------------------------------------------------------------------*/\r
\r
-static int RegistAsyncTableDbase(HANDLE Async)\r
+static int RegisterAsyncTableDbase(HANDLE Async)\r
{\r
int Sts;\r
int Pos;\r
* \r
*----------------------------------------------------------------------------*/\r
\r
-static int UnRegistAsyncTable(SOCKET s)\r
+static int UnregisterAsyncTable(SOCKET s)\r
{\r
int Sts;\r
int Pos;\r
* \r
*----------------------------------------------------------------------------*/\r
\r
-static int UnRegistAsyncTableDbase(HANDLE Async)\r
+static int UnregisterAsyncTableDbase(HANDLE Async)\r
{\r
int Sts;\r
int Pos;\r
}\r
\r
\r
+// ソケットにデータを付与\r
+\r
+int SetAsyncTableDataIPv4(SOCKET s, struct sockaddr_in* Host, struct sockaddr_in* Socks)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ if(Host != NULL)\r
+ memcpy(&Signal[Pos].HostAddrIPv4, Host, sizeof(struct sockaddr_in));\r
+ if(Socks != NULL)\r
+ memcpy(&Signal[Pos].SocksAddrIPv4, Socks, sizeof(struct sockaddr_in));\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
+int SetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_in6* Socks)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ if(Host != NULL)\r
+ memcpy(&Signal[Pos].HostAddrIPv6, Host, sizeof(struct sockaddr_in6));\r
+ if(Socks != NULL)\r
+ memcpy(&Signal[Pos].SocksAddrIPv6, Socks, sizeof(struct sockaddr_in6));\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
+int SetAsyncTableDataMapPort(SOCKET s, int Port)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ Signal[Pos].MapPort = Port;\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
+int GetAsyncTableDataIPv4(SOCKET s, struct sockaddr_in* Host, struct sockaddr_in* Socks)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ if(Host != NULL)\r
+ memcpy(Host, &Signal[Pos].HostAddrIPv4, sizeof(struct sockaddr_in));\r
+ if(Socks != NULL)\r
+ memcpy(Socks, &Signal[Pos].SocksAddrIPv4, sizeof(struct sockaddr_in));\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
+int GetAsyncTableDataIPv6(SOCKET s, struct sockaddr_in6* Host, struct sockaddr_in6* Socks)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ if(Host != NULL)\r
+ memcpy(Host, &Signal[Pos].HostAddrIPv6, sizeof(struct sockaddr_in6));\r
+ if(Socks != NULL)\r
+ memcpy(Socks, &Signal[Pos].SocksAddrIPv6, sizeof(struct sockaddr_in6));\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
+int GetAsyncTableDataMapPort(SOCKET s, int* Port)\r
+{\r
+ int Sts;\r
+ int Pos;\r
+\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
+ Sts = NO;\r
+ for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
+ {\r
+ if(Signal[Pos].Socket == s)\r
+ {\r
+ *Port = Signal[Pos].MapPort;\r
+ Sts = YES;\r
+ break;\r
+ }\r
+ }\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
+\r
+ return(Sts);\r
+}\r
+\r
\r
\r
\r
hAsync = WSAAsyncGetHostByNameM(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
if(hAsync != NULL)\r
{\r
- RegistAsyncTableDbase(hAsync);\r
+ RegisterAsyncTableDbase(hAsync);\r
while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
{\r
Sleep(1);\r
{\r
Ret = (struct hostent *)Buf;\r
}\r
- UnRegistAsyncTableDbase(hAsync);\r
+ UnregisterAsyncTableDbase(hAsync);\r
}\r
return(Ret);\r
#else\r
hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6);\r
if(hAsync != NULL)\r
{\r
- RegistAsyncTableDbase(hAsync);\r
+ RegisterAsyncTableDbase(hAsync);\r
while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
{\r
Sleep(1);\r
\r
if(*CancelCheckWork == YES)\r
{\r
- WSACancelAsyncRequest(hAsync);\r
+ WSACancelAsyncRequestIPv6(hAsync);\r
}\r
else if(Error == 0)\r
{\r
Ret = (struct hostent *)Buf;\r
}\r
- UnRegistAsyncTableDbase(hAsync);\r
+ UnregisterAsyncTableDbase(hAsync);\r
}\r
return(Ret);\r
#else\r
Ret = socket(af, type, protocol);\r
if(Ret != INVALID_SOCKET)\r
{\r
- RegistAsyncTable(Ret);\r
+ RegisterAsyncTable(Ret);\r
}\r
#if DBG_MSG\r
DoPrintf("# do_socket (S=%x)", Ret);\r
\r
// スレッド衝突のバグ修正\r
WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
- UnRegistAsyncTable(s);\r
+ UnregisterAsyncTable(s);\r
// FTPS対応\r
// Ret = closesocket(s);\r
Ret = FTPS_closesocket(s);\r
if(BackgrndMessageProc() == YES)\r
CancelCheckWork = YES;\r
// スレッド衝突のバグ修正\r
-// UnRegistAsyncTable(s);\r
+// UnregisterAsyncTable(s);\r
\r
#if DBG_MSG\r
DoPrintf("# Exit close");\r
DoPrintf("## do_sccept (S=%x)", Ret2);\r
DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
#endif\r
- RegistAsyncTable(Ret2);\r
- if(WSAAsyncSelect(Ret2, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE) == SOCKET_ERROR)\r
+ RegisterAsyncTable(Ret2);\r
+ // 高速化のためFD_READとFD_WRITEを使用しない\r
+// if(WSAAsyncSelect(Ret2, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE) == SOCKET_ERROR)\r
+ if(WSAAsyncSelect(Ret2, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT) == SOCKET_ERROR)\r
{\r
do_closesocket(Ret2);\r
Ret2 = INVALID_SOCKET;\r
{\r
char buf[1024];\r
int len;\r
- int Error;\r
- while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
+// int Error;\r
+ while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) > 0)\r
{\r
- AskAsyncDone(s, &Error, FD_READ);\r
+// AskAsyncDone(s, &Error, FD_READ);\r
FTPS_recv(s, buf, len, 0);\r
}\r
}\r
\r
+// UPnP対応\r
+int LoadUPnP()\r
+{\r
+ int Sts;\r
+ Sts = FFFTP_FAIL;\r
+ if(CoCreateInstance(&CLSID_UPnPNAT, NULL, CLSCTX_ALL, &IID_IUPnPNAT, (void**)&pUPnPNAT) == S_OK)\r
+ {\r
+ if(pUPnPNAT->lpVtbl->get_StaticPortMappingCollection(pUPnPNAT, &pUPnPMap) == S_OK)\r
+ Sts = FFFTP_SUCCESS;\r
+ }\r
+ return Sts;\r
+}\r
+\r
+void FreeUPnP()\r
+{\r
+ if(pUPnPMap != NULL)\r
+ pUPnPMap->lpVtbl->Release(pUPnPMap);\r
+ pUPnPMap = NULL;\r
+ if(pUPnPNAT != NULL)\r
+ pUPnPNAT->lpVtbl->Release(pUPnPNAT);\r
+ pUPnPNAT = NULL;\r
+}\r
+\r
+int IsUPnPLoaded()\r
+{\r
+ int Sts;\r
+ Sts = NO;\r
+ if(pUPnPNAT != NULL && pUPnPMap != NULL)\r
+ Sts = YES;\r
+ return Sts;\r
+}\r
+\r
+int AddPortMapping(char* Adrs, int Port)\r
+{\r
+ int Sts;\r
+ WCHAR Tmp1[40];\r
+ BSTR Tmp2;\r
+ BSTR Tmp3;\r
+ BSTR Tmp4;\r
+ IStaticPortMapping* pPortMap;\r
+ Sts = FFFTP_FAIL;\r
+ MtoW(Tmp1, 40, Adrs, -1);\r
+ if((Tmp2 = SysAllocString(Tmp1)) != NULL)\r
+ {\r
+ if((Tmp3 = SysAllocString(L"TCP")) != NULL)\r
+ {\r
+ if((Tmp4 = SysAllocString(L"FFFTP")) != NULL)\r
+ {\r
+ if(pUPnPMap->lpVtbl->Add(pUPnPMap, Port, Tmp3, Port, Tmp2, VARIANT_TRUE, Tmp4, &pPortMap) == S_OK)\r
+ {\r
+ Sts = FFFTP_SUCCESS;\r
+ pPortMap->lpVtbl->Release(pPortMap);\r
+ }\r
+ SysFreeString(Tmp4);\r
+ }\r
+ SysFreeString(Tmp3);\r
+ }\r
+ SysFreeString(Tmp2);\r
+ }\r
+ return Sts;\r
+}\r
+\r
+int RemovePortMapping(int Port)\r
+{\r
+ int Sts;\r
+ BSTR Tmp;\r
+ Sts = FFFTP_FAIL;\r
+ if((Tmp = SysAllocString(L"TCP")) != NULL)\r
+ {\r
+ if(pUPnPMap->lpVtbl->Remove(pUPnPMap, Port, Tmp) == S_OK)\r
+ Sts = FFFTP_SUCCESS;\r
+ SysFreeString(Tmp);\r
+ }\r
+ return Sts;\r
+}\r
+\r
\r
/*----- \r
*\r
\r
\r
\r
+// 同時接続対応\r
+int CheckClosedAndReconnectTrnSkt(SOCKET *Skt, int *CancelCheckWork)\r
+{\r
+ int Error;\r
+ int Sts;\r
+\r
+//SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
+\r
+ Sts = FFFTP_SUCCESS;\r
+ if(AskAsyncDone(*Skt, &Error, FD_CLOSE) == YES)\r
+ {\r
+ Sts = ReConnectTrnSkt(Skt, CancelCheckWork);\r
+ }\r
+ return(Sts);\r
+}\r
+\r