-/*=============================================================================\r
+/*=============================================================================\r
*\r
-* \83\\83P\83b\83g\r
+* ソケット\r
*\r
===============================================================================\r
/ Copyright (C) 1997-2007 Sota. All rights reserved.\r
/============================================================================*/\r
\r
#define STRICT\r
+// IPv6対応\r
+#include <winsock2.h>\r
#include <windows.h>\r
#include <stdio.h>\r
#include <stdlib.h>\r
#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
\r
\r
\r
-#define FD_CONNECT_BIT 0x0001\r
-#define FD_CLOSE_BIT 0x0002\r
-#define FD_ACCEPT_BIT 0x0004\r
-#define FD_READ_BIT 0x0008\r
-#define FD_WRITE_BIT 0x0010\r
+// Winsock2で定義される定数と名前が重複し値が異なるため使用不可\r
+//#define FD_CONNECT_BIT 0x0001\r
+//#define FD_CLOSE_BIT 0x0002\r
+//#define FD_ACCEPT_BIT 0x0004\r
+//#define FD_READ_BIT 0x0008\r
+//#define FD_WRITE_BIT 0x0010\r
\r
\r
\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
} ASYNCSIGNALDATABASE;\r
\r
\r
-#define MAX_SIGNAL_ENTRY 10\r
-#define MAX_SIGNAL_ENTRY_DBASE 5\r
+// スレッド衝突のバグ修正\r
+// 念のためテーブルを増量\r
+//#define MAX_SIGNAL_ENTRY 10\r
+//#define MAX_SIGNAL_ENTRY_DBASE 5\r
+#define MAX_SIGNAL_ENTRY 16\r
+#define MAX_SIGNAL_ENTRY_DBASE 16\r
\r
\r
\r
\r
-/*===== \83v\83\8d\83g\83^\83C\83v =====*/\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
-/*===== \8aO\95\94\8eQ\8fÆ =====*/\r
+/*===== 外部参照 =====*/\r
\r
extern int TimeOut;\r
\r
\r
-/*===== \83\8d\81[\83J\83\8b\82È\83\8f\81[\83N =====*/\r
+/*===== ローカルなワーク =====*/\r
\r
static const char SocketWndClass[] = "FFFTPSocketWnd";\r
static HWND hWndSocket;\r
static ASYNCSIGNALDATABASE SignalDbase[MAX_SIGNAL_ENTRY_DBASE];\r
\r
//static HANDLE hAsyncTblAccMutex;\r
+// スレッド衝突のバグ修正\r
+static HANDLE hAsyncTblAccMutex;\r
\r
+// UPnP対応\r
+IUPnPNAT* pUPnPNAT;\r
+IStaticPortMappingCollection* pUPnPMap;\r
\r
\r
\r
* Parameter\r
*\r
* Return Value\r
-* int \83X\83e\81[\83^\83X\r
-* SUCCESS/FAIL\r
+* int ステータス\r
+* FFFTP_SUCCESS/FFFTP_FAIL\r
*----------------------------------------------------------------------------*/\r
\r
int MakeSocketWin(HWND hWnd, HINSTANCE hInst)\r
wClass.hIconSm = NULL;\r
RegisterClassEx(&wClass);\r
\r
- Sts = FAIL;\r
+ Sts = FFFTP_FAIL;\r
hWndSocket = CreateWindowEx(0, SocketWndClass, NULL,\r
WS_BORDER | WS_POPUP,\r
0, 0, 0, 0,\r
{\r
// hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL);\r
\r
- for(i = 0; i < MAX_SIGNAL_ENTRY; i++)\r
- Signal[i].Socket = INVALID_SOCKET;\r
- for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++)\r
- SignalDbase[i].Async = 0;\r
- Sts = SUCCESS;\r
+ // スレッド衝突のバグ修正\r
+// for(i = 0; i < MAX_SIGNAL_ENTRY; i++)\r
+// Signal[i].Socket = INVALID_SOCKET;\r
+// for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++)\r
+// SignalDbase[i].Async = 0;\r
+ if(hAsyncTblAccMutex = CreateMutex(NULL, FALSE, NULL))\r
+ {\r
+ for(i = 0; i < MAX_SIGNAL_ENTRY; i++)\r
+ Signal[i].Socket = INVALID_SOCKET;\r
+ for(i = 0; i < MAX_SIGNAL_ENTRY_DBASE; i++)\r
+ SignalDbase[i].Async = 0;\r
+ }\r
+ Sts = FFFTP_SUCCESS;\r
}\r
return(Sts);\r
}\r
/*----- \r
*\r
* Parameter\r
-* \82È\82µ\r
+* なし\r
*\r
* Return Value\r
-* \82È\82µ\r
+* なし\r
*----------------------------------------------------------------------------*/\r
\r
void DeleteSocketWin(void)\r
{\r
// CloseHandle(hAsyncTblAccMutex);\r
+ // スレッド衝突のバグ修正\r
+ CloseHandle(hAsyncTblAccMutex);\r
+ hAsyncTblAccMutex = NULL;\r
\r
if(hWndSocket != NULL)\r
DestroyWindow(hWndSocket);\r
/*----- \r
*\r
* Parameter\r
-* HWND hWnd : \83E\83C\83\93\83h\83E\83n\83\93\83h\83\8b\r
-* UINT message : \83\81\83b\83Z\81[\83W\94Ô\8d\86\r
-* WPARAM wParam : \83\81\83b\83Z\81[\83W\82Ì WPARAM \88ø\90\94\r
-* LPARAM lParam : \83\81\83b\83Z\81[\83W\82Ì LPARAM \88ø\90\94\r
+* HWND hWnd : ウインドウハンドル\r
+* UINT message : メッセージ番号\r
+* WPARAM wParam : メッセージの WPARAM 引数\r
+* LPARAM lParam : メッセージの LPARAM 引数\r
*\r
* Return Value\r
* BOOL TRUE/FALSE\r
switch(message)\r
{\r
case WM_ASYNC_SOCKET :\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
{\r
if(Signal[Pos].Socket == (SOCKET)wParam)\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
break;\r
\r
case WM_ASYNC_DBASE :\r
+ // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
+ RegisterAsyncTableDbase((HANDLE)wParam);\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
{\r
if(SignalDbase[Pos].Async == (HANDLE)wParam)\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
break;\r
\r
default :\r
int Sts;\r
int Pos;\r
\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
Sts = NO;\r
*Error = 0;\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
*Error = Signal[Pos].Error;\r
if(Signal[Pos].Error != 0)\r
Sts = YES;\r
- if((Mask & FD_CONNECT_BIT) && (Signal[Pos].FdConnect != 0))\r
+ if((Mask & FD_CONNECT) && (Signal[Pos].FdConnect != 0))\r
{\r
Sts = YES;\r
#if DBG_MSG\r
DoPrintf("### Ask: connect (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_CLOSE_BIT) && (Signal[Pos].FdClose != 0))\r
-// if(Mask & FD_CLOSE_BIT)\r
+ if((Mask & FD_CLOSE) && (Signal[Pos].FdClose != 0))\r
+// if(Mask & FD_CLOSE)\r
{\r
Sts = YES;\r
#if DBG_MSG\r
DoPrintf("### Ask: close (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_ACCEPT_BIT) && (Signal[Pos].FdAccept != 0))\r
+ if((Mask & FD_ACCEPT) && (Signal[Pos].FdAccept != 0))\r
{\r
Signal[Pos].FdAccept = 0;\r
Sts = YES;\r
DoPrintf("### Ask: accept (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_READ_BIT) && (Signal[Pos].FdRead != 0))\r
+ if((Mask & FD_READ) && (Signal[Pos].FdRead != 0))\r
{\r
Signal[Pos].FdRead = 0;\r
Sts = YES;\r
DoPrintf("### Ask: read (Sts=%d, Error=%d)", Sts, *Error);\r
#endif\r
}\r
- if((Mask & FD_WRITE_BIT) && (Signal[Pos].FdWrite != 0))\r
+ if((Mask & FD_WRITE) && (Signal[Pos].FdWrite != 0))\r
{\r
Signal[Pos].FdWrite = 0;\r
Sts = YES;\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY)\r
{\r
- if(Mask & FD_CLOSE_BIT)\r
+ if(Mask & FD_CLOSE)\r
{\r
Sts = YES;\r
}\r
int Sts;\r
int Pos;\r
\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
Sts = NO;\r
*Error = 0;\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
{\r
* \r
*----------------------------------------------------------------------------*/\r
\r
-static int RegistAsyncTable(SOCKET s)\r
+static int RegisterAsyncTable(SOCKET s)\r
{\r
int Sts;\r
int Pos;\r
\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
- MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK);\r
- break;\r
+ // 強制的に閉じられたソケットがあると重複する可能性あり\r
+// MessageBox(GetMainHwnd(), "Async socket already registerd.", "FFFTP inner error", MB_OK);\r
+// break;\r
+ Signal[Pos].Socket = INVALID_SOCKET;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY)\r
{\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
{\r
if(Signal[Pos].Socket == INVALID_SOCKET)\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
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY)\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
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
Sts = NO;\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
{\r
if(SignalDbase[Pos].Async == Async)\r
{\r
- MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK);\r
+ // 強制的に閉じられたハンドルがあると重複する可能性あり\r
+// MessageBox(GetMainHwnd(), "Async handle already registerd.", "FFFTP inner error", MB_OK);\r
+ // APIの仕様上ハンドルが登録される前にウィンドウメッセージが呼び出される可能性あり\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
{\r
+ // スレッド衝突のバグ修正\r
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
{\r
if(SignalDbase[Pos].Async == 0)\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
\r
if(Pos == MAX_SIGNAL_ENTRY_DBASE)\r
{\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
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
Sts = NO;\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY; Pos++)\r
{\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
return(Sts);\r
}\r
\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
+ WaitForSingleObject(hAsyncTblAccMutex, INFINITE);\r
Sts = NO;\r
for(Pos = 0; Pos < MAX_SIGNAL_ENTRY_DBASE; Pos++)\r
{\r
break;\r
}\r
}\r
+ // スレッド衝突のバグ修正\r
+ ReleaseMutex(hAsyncTblAccMutex);\r
return(Sts);\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
-struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\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
+\r
+\r
+\r
+// IPv6対応\r
+//struct hostent *do_gethostbyname(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+struct hostent *do_gethostbynameIPv4(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
{\r
#if USE_THIS\r
struct hostent *Ret;\r
DoPrintf("# Start gethostbyname");\r
#endif\r
Ret = NULL;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
\r
- hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+ // UTF-8対応\r
+// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\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
+ return(gethostbyname(Name));\r
+#endif\r
+}\r
+\r
+\r
+struct hostent *do_gethostbynameIPv6(const char *Name, char *Buf, int Len, int *CancelCheckWork)\r
+{\r
+#if USE_THIS\r
+ struct hostent *Ret;\r
+ HANDLE hAsync;\r
+ int Error;\r
+\r
+#if DBG_MSG\r
+ DoPrintf("# Start gethostbyname");\r
+#endif\r
+ Ret = NULL;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
+\r
+ // UTF-8対応\r
+// hAsync = WSAAsyncGetHostByName(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len);\r
+ hAsync = WSAAsyncGetHostByNameIPv6M(hWndSocket, WM_ASYNC_DBASE, Name, Buf, Len, AF_INET6);\r
+ if(hAsync != NULL)\r
+ {\r
+ RegisterAsyncTableDbase(hAsync);\r
+ while((*CancelCheckWork == NO) && (AskAsyncDoneDbase(hAsync, &Error) != YES))\r
+ {\r
+ Sleep(1);\r
+ if(BackgrndMessageProc() == YES)\r
+ *CancelCheckWork = YES;\r
+ }\r
+\r
+ if(*CancelCheckWork == YES)\r
+ {\r
+ WSACancelAsyncRequestIPv6(hAsync);\r
+ }\r
+ else if(Error == 0)\r
+ {\r
+ Ret = (struct hostent *)Buf;\r
+ }\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
#endif\r
CancelCheckWork = NO;\r
\r
- Ret = closesocket(s);\r
+ // スレッド衝突のバグ修正\r
+ WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+ UnregisterAsyncTable(s);\r
+ // FTPS対応\r
+// Ret = closesocket(s);\r
+ Ret = FTPS_closesocket(s);\r
if(Ret == SOCKET_ERROR)\r
{\r
Error = 0;\r
- while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE_BIT) != YES))\r
+ while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CLOSE) != YES))\r
{\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
Ret = 0;\r
}\r
\r
- WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
+ // スレッド衝突のバグ修正\r
+// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, 0);\r
if(BackgrndMessageProc() == YES)\r
CancelCheckWork = YES;\r
- UnRegistAsyncTable(s);\r
+ // スレッド衝突のバグ修正\r
+// UnregisterAsyncTable(s);\r
\r
#if DBG_MSG\r
DoPrintf("# Exit close");\r
#if DBG_MSG\r
DoPrintf("# Start connect (S=%x)", s);\r
#endif\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
\r
#if DBG_MSG\r
DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
#endif\r
- Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ // 高速化のためFD_READとFD_WRITEを使用しない\r
+// Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ Ret = WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT);\r
if(Ret != SOCKET_ERROR)\r
{\r
Ret = connect(s, name, namelen);\r
do\r
{\r
Error = 0;\r
- while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT_BIT) != YES))\r
+ while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_CONNECT) != YES))\r
{\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
Ret2 = INVALID_SOCKET;\r
Error = 0;\r
\r
- while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT_BIT) != YES))\r
+ while((CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_ACCEPT) != YES))\r
{\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
+ if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
{\r
Error = 1;\r
break;\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
\r
\r
-/*----- recv\91\8a\93\96\82Ì\8aÖ\90\94 --------------------------------------------------------\r
+/*----- recv相当の関数 --------------------------------------------------------\r
*\r
* Parameter\r
-* SOCKET s : \83\\83P\83b\83g\r
-* char *buf : \83f\81[\83^\82ð\93Ç\82Ý\8d\9e\82Þ\83o\83b\83t\83@\r
-* int len : \92·\82³\r
-* int flags : recv\82É\97^\82¦\82é\83t\83\89\83O\r
-* int *TimeOutErr : \83^\83C\83\80\83A\83E\83g\82µ\82½\82©\82Ç\82¤\82©\82ð\95Ô\82·\83\8f\81[\83N\r
+* SOCKET s : ソケット\r
+* char *buf : データを読み込むバッファ\r
+* int len : 長さ\r
+* int flags : recvに与えるフラグ\r
+* int *TimeOutErr : タイムアウトしたかどうかを返すワーク\r
*\r
* Return Value\r
-* int : recv\82Ì\96ß\82è\92l\82Æ\93¯\82¶\r
+* int : recvの戻り値と同じ\r
*\r
* Note\r
-* \83^\83C\83\80\83A\83E\83g\82Ì\8e\9e\82Í TimeOut=YES\81ARet=SOCKET_ERROR \82É\82È\82é\r
+* タイムアウトの時は TimeOut=YES、Ret=SOCKET_ERROR になる\r
*----------------------------------------------------------------------------*/\r
int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *CancelCheckWork)\r
{\r
DoPrintf("# Start recv (S=%x)", s);\r
#endif\r
*TimeOutErr = NO;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
Ret = SOCKET_ERROR;\r
Error = 0;\r
\r
if(TimeOut != 0)\r
time(&StartTime);\r
\r
- while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ_BIT) != YES))\r
- {\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
- {\r
- Ret = 0;\r
- break;\r
- }\r
- Sleep(1);\r
- if(BackgrndMessageProc() == YES)\r
- *CancelCheckWork = YES;\r
- else if(TimeOut != 0)\r
- {\r
- time(&ElapseTime);\r
- ElapseTime -= StartTime;\r
- if(ElapseTime >= TimeOut)\r
- {\r
- DoPrintf("do_recv timed out");\r
- *TimeOutErr = YES;\r
- *CancelCheckWork = YES;\r
- }\r
- }\r
- }\r
+ // FTPS対応\r
+ // OpenSSLでは受信確認はFD_READが複数回受信される可能性がある\r
+// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+ // 短時間にFD_READが2回以上通知される対策\r
+// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_READ) != YES))\r
+// {\r
+// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
+// {\r
+// Ret = 0;\r
+// break;\r
+// }\r
+// Sleep(1);\r
+// if(BackgrndMessageProc() == YES)\r
+// *CancelCheckWork = YES;\r
+// else if(TimeOut != 0)\r
+// {\r
+// time(&ElapseTime);\r
+// ElapseTime -= StartTime;\r
+// if(ElapseTime >= TimeOut)\r
+// {\r
+// DoPrintf("do_recv timed out");\r
+// *TimeOutErr = YES;\r
+// *CancelCheckWork = YES;\r
+// }\r
+// }\r
+// }\r
\r
if(/*(Ret != 0) && */(Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
{\r
DoPrintf("## recv()");\r
#endif\r
\r
- Ret = recv(s, buf, len, flags);\r
+ // FTPS対応\r
+// Ret = recv(s, buf, len, flags);\r
+ Ret = FTPS_recv(s, buf, len, flags);\r
if(Ret != SOCKET_ERROR)\r
break;\r
Error = WSAGetLastError();\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
break;\r
+ // FTPS対応\r
+ // 受信確認をバイパスしたためここでタイムアウトの確認\r
+ if(BackgrndMessageProc() == YES)\r
+ *CancelCheckWork = YES;\r
+ else if(TimeOut != 0)\r
+ {\r
+ time(&ElapseTime);\r
+ ElapseTime -= StartTime;\r
+ if(ElapseTime >= TimeOut)\r
+ {\r
+ DoPrintf("do_recv timed out");\r
+ *TimeOutErr = YES;\r
+ *CancelCheckWork = YES;\r
+ }\r
+ }\r
+ if(*CancelCheckWork == YES)\r
+ break;\r
}\r
while(Error == WSAEWOULDBLOCK);\r
}\r
DoPrintf("# Start send (S=%x)", s);\r
#endif\r
*TimeOutErr = NO;\r
- *CancelCheckWork = NO;\r
+ // 同時接続対応\r
+// *CancelCheckWork = NO;\r
Ret = SOCKET_ERROR;\r
Error = 0;\r
\r
#if DBG_MSG\r
DoPrintf("## Async set: FD_CONNECT|FD_CLOSE|FD_ACCEPT|FD_READ|FD_WRITE");\r
#endif\r
- WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
+ // Windows 2000でFD_WRITEが通知されないことがあるバグ修正\r
+ // 毎回通知されたのはNT 4.0までのバグであり仕様ではない\r
+ // XP以降は互換性のためか毎回通知される\r
+// WSAAsyncSelect(s, hWndSocket, WM_ASYNC_SOCKET, FD_CONNECT | FD_CLOSE | FD_ACCEPT | FD_READ | FD_WRITE);\r
if(BackgrndMessageProc() == YES)\r
*CancelCheckWork = YES;\r
\r
- while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE_BIT) != YES))\r
- {\r
- if(AskAsyncDone(s, &Error, FD_CLOSE_BIT) == YES)\r
- {\r
- Error = 1;\r
- break;\r
- }\r
-\r
- Sleep(1);\r
- if(BackgrndMessageProc() == YES)\r
- *CancelCheckWork = YES;\r
- else if(TimeOut != 0)\r
- {\r
- time(&ElapseTime);\r
- ElapseTime -= StartTime;\r
- if(ElapseTime >= TimeOut)\r
- {\r
- DoPrintf("do_write timed out");\r
- *TimeOutErr = YES;\r
- *CancelCheckWork = YES;\r
- }\r
- }\r
- }\r
+ // FTPS対応\r
+ // 送信バッファの空き確認には影響しないが念のため\r
+// while((*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
+ // Windows 2000でFD_WRITEが通知されないことがあるバグ修正\r
+// while(!IsSSLAttached(s) && (*CancelCheckWork == NO) && (AskAsyncDone(s, &Error, FD_WRITE) != YES))\r
+// {\r
+// if(AskAsyncDone(s, &Error, FD_CLOSE) == YES)\r
+// {\r
+// Error = 1;\r
+// break;\r
+// }\r
+//\r
+// Sleep(1);\r
+// if(BackgrndMessageProc() == YES)\r
+// *CancelCheckWork = YES;\r
+// else if(TimeOut != 0)\r
+// {\r
+// time(&ElapseTime);\r
+// ElapseTime -= StartTime;\r
+// if(ElapseTime >= TimeOut)\r
+// {\r
+// DoPrintf("do_write timed out");\r
+// *TimeOutErr = YES;\r
+// *CancelCheckWork = YES;\r
+// }\r
+// }\r
+// }\r
\r
if((Error == 0) && (*CancelCheckWork == NO) && (*TimeOutErr == NO))\r
{\r
DoPrintf("## send()");\r
#endif\r
\r
- Ret = send(s, buf, len, flags);\r
+ // FTPS対応\r
+// Ret = send(s, buf, len, flags);\r
+ Ret = FTPS_send(s, buf, len, flags);\r
if(Ret != SOCKET_ERROR)\r
{\r
#if DBG_MSG\r
Sleep(1);\r
if(BackgrndMessageProc() == YES)\r
break;\r
+ // FTPS対応\r
+ // 送信バッファ確認をバイパスしたためここでタイムアウトの確認\r
+ if(BackgrndMessageProc() == YES)\r
+ *CancelCheckWork = YES;\r
+ else if(TimeOut != 0)\r
+ {\r
+ time(&ElapseTime);\r
+ ElapseTime -= StartTime;\r
+ if(ElapseTime >= TimeOut)\r
+ {\r
+ DoPrintf("do_recv timed out");\r
+ *TimeOutErr = YES;\r
+ *CancelCheckWork = YES;\r
+ }\r
+ }\r
+ if(*CancelCheckWork == YES)\r
+ break;\r
}\r
while(Error == WSAEWOULDBLOCK);\r
}\r
}\r
\r
\r
+// 同時接続対応\r
+void RemoveReceivedData(SOCKET s)\r
+{\r
+ char buf[1024];\r
+ int len;\r
+// int Error;\r
+ while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) > 0)\r
+ {\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
* Parameter\r
*\r
* Return Value\r
-* int \83X\83e\81[\83^\83X\r
-* SUCCESS/FAIL\r
+* int ステータス\r
+* FFFTP_SUCCESS/FFFTP_FAIL\r
*----------------------------------------------------------------------------*/\r
\r
int CheckClosedAndReconnect(void)\r
\r
//SetTaskMsg("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");\r
\r
- Sts = SUCCESS;\r
- if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE_BIT) == YES)\r
+ Sts = FFFTP_SUCCESS;\r
+ if(AskAsyncDone(AskCmdCtrlSkt(), &Error, FD_CLOSE) == YES)\r
{\r
Sts = ReConnectCmdSkt();\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