home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / AsyncSocketEx.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-04-26  |  49.9 KB  |  1,850 lines

  1. /*CAsyncSocketEx by Tim Kosse (Tim.Kosse@gmx.de)
  2.             Version 1.3 (2003-04-26)
  3. --------------------------------------------------------
  4.  
  5. Introduction:
  6. -------------
  7.  
  8. CAsyncSocketEx is a replacement for the MFC class CAsyncSocket.
  9. This class was written because CAsyncSocket is not the fastest WinSock
  10. wrapper and it's very hard to add new functionality to CAsyncSocket
  11. derived classes. This class offers the same functionality as CAsyncSocket.
  12. Also, CAsyncSocketEx offers some enhancements which were not possible with
  13. CAsyncSocket without some tricks.
  14.  
  15. How do I use it?
  16. ----------------
  17. Basically exactly like CAsyncSocket.
  18. To use CAsyncSocketEx, just replace all occurrences of CAsyncSocket in your
  19. code with CAsyncSocketEx, if you did not enhance CAsyncSocket yourself in
  20. any way, you won't have to change anything else in your code.
  21.  
  22. Why is CAsyncSocketEx faster?
  23. -----------------------------
  24.  
  25. CAsyncSocketEx is slightly faster when dispatching notification event messages.
  26. First have a look at the way CAsyncSocket works. For each thread that uses
  27. CAsyncSocket, a window is created. CAsyncSocket calls WSAAsyncSelect with
  28. the handle of that window. Until here, CAsyncSocketEx works the same way.
  29. But CAsyncSocket uses only one window message (WM_SOCKET_NOTIFY) for all
  30. sockets within one thread. When the window recieve WM_SOCKET_NOTIFY, wParam
  31. contains the socket handle and the window looks up an CAsyncSocket instance
  32. using a map. CAsyncSocketEx works differently. It's helper window uses a
  33. wide range of different window messages (WM_USER through 0xBFFF) and passes
  34. a different message to WSAAsyncSelect for each socket. When a message in
  35. the specified range is received, CAsyncSocketEx looks up the pointer to a
  36. CAsyncSocketEx instance in an Array using the index of message - WM_USER.
  37. As you can see, CAsyncSocketEx uses the helper window in a more efficient
  38. way, as it don't have to use the slow maps to lookup it's own instance.
  39. Still, speed increase is not very much, but it may be noticeable when using
  40. a lot of sockets at the same time.
  41. Please note that the changes do not affect the raw data throughput rate,
  42. CAsyncSocketEx only dispatches the notification messages faster.
  43.  
  44. What else does CAsyncSocketEx offer?
  45. ------------------------------------
  46.  
  47. CAsyncSocketEx offers a flexible layer system. One example is the proxy layer.
  48. Just create an instance of the proxy layer, configure it and add it to the layer
  49. chain of your CAsyncSocketEx instance. After that, you can connect through
  50. proxies.
  51. Benefit: You don't have to change much to use the layer system.
  52. Another layer that is currently in development is the SSL layer to establish
  53. SSL encrypted connections.
  54.  
  55. License
  56. -------
  57.  
  58. Feel free to use this class, as long as you don't claim that you wrote it
  59. and this copyright notice stays intact in the source files.
  60. If you use this class in commercial applications, please send a short message
  61. to tim.kosse@gmx.de
  62. */
  63.  
  64. #include "stdafx.h"
  65. #include "AsyncSocketEx.h"
  66. #include "wtypes.h"
  67. #include "oleauto.h"
  68. #include "atlconv.h"
  69.  
  70. #ifndef NOLAYERS
  71. #include "AsyncSocketExLayer.h"
  72. #endif //NOLAYERS
  73.  
  74. #ifdef _DEBUG
  75. #undef THIS_FILE
  76. static char THIS_FILE[]=__FILE__;
  77. #endif
  78.  
  79. #ifndef CCRITICALSECTIONWRAPPERINCLUDED
  80. class CCriticalSectionWrapper
  81. {
  82. public:
  83.     CCriticalSectionWrapper()
  84.     {
  85.         m_bInitialized = TRUE;
  86.         InitializeCriticalSection(&m_criticalSection);
  87.     }
  88.  
  89.     ~CCriticalSectionWrapper()
  90.     {
  91.         if (m_bInitialized)
  92.             DeleteCriticalSection(&m_criticalSection);
  93.         m_bInitialized = FALSE;
  94.     }
  95.  
  96.     void Lock()
  97.     {
  98.         if (m_bInitialized)
  99.             EnterCriticalSection(&m_criticalSection);
  100.     }
  101.     void Unlock()
  102.     {
  103.         if (m_bInitialized)
  104.             LeaveCriticalSection(&m_criticalSection);
  105.     }
  106. protected:
  107.     CRITICAL_SECTION m_criticalSection;
  108.     BOOL m_bInitialized;
  109. };
  110. #define CCRITICALSECTIONWRAPPERINCLUDED
  111. #endif
  112.  
  113. CCriticalSectionWrapper CAsyncSocketEx::m_sGlobalCriticalSection;
  114. CAsyncSocketEx::t_AsyncSocketExThreadDataList *CAsyncSocketEx::m_spAsyncSocketExThreadDataList = 0;
  115. HMODULE CAsyncSocketEx::m_hDll = 0;
  116. t_getaddrinfo CAsyncSocketEx::p_getaddrinfo = 0;
  117. t_freeaddrinfo CAsyncSocketEx::p_freeaddrinfo = 0;
  118.  
  119.  
  120. #ifndef _AFX
  121. #ifndef VERIFY
  122. #define VERIFY(x) (void(x))
  123. #endif //VERIFY
  124. #ifndef ASSERT
  125. #define ASSERT(x)
  126. #endif //ASSERT
  127. #endif //_AFX
  128.  
  129. /////////////////////////////
  130. //Helper Window class
  131. #define WM_SOCKETEX_NOTIFY (WM_USER+3)
  132. #define MAX_SOCKETS (0xBFFF-WM_SOCKETEX_NOTIFY+1)
  133.  
  134. class CAsyncSocketExHelperWindow
  135. {
  136. public:
  137.     CAsyncSocketExHelperWindow(CAsyncSocketEx::t_AsyncSocketExThreadData* pThreadData)
  138.     {
  139.         //Initialize data
  140.         m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  141.         memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  142.         m_nWindowDataSize=512;
  143.         m_nSocketCount=0;
  144.         m_nWindowDataPos=0;
  145.         m_pThreadData = pThreadData;
  146.  
  147.         //Create window
  148.         WNDCLASSEX wndclass;
  149.         wndclass.cbSize=sizeof wndclass;
  150.         wndclass.style=0;
  151.         wndclass.lpfnWndProc=WindowProc;
  152.         wndclass.cbClsExtra=0;
  153.         wndclass.cbWndExtra=0;
  154.         wndclass.hInstance=GetModuleHandle(0);
  155.         wndclass.hIcon=0;
  156.         wndclass.hCursor=0;
  157.         wndclass.hbrBackground=0;
  158.         wndclass.lpszMenuName=0;
  159.         wndclass.lpszClassName=_T("CAsyncSocketEx Helper Window");
  160.         wndclass.hIconSm=0;
  161.  
  162.         RegisterClassEx(&wndclass);
  163.  
  164.         m_hWnd=CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
  165.         ASSERT(m_hWnd);
  166.         SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)this);
  167.     };
  168.  
  169.     virtual ~CAsyncSocketExHelperWindow()
  170.     {
  171.         //Clean up socket storage
  172.         delete [] m_pAsyncSocketExWindowData;
  173.         m_pAsyncSocketExWindowData=0;
  174.         m_nWindowDataSize=0;
  175.         m_nSocketCount=0;
  176.  
  177.         //Destroy window
  178.         if (m_hWnd)
  179.         {
  180.             DestroyWindow(m_hWnd);
  181.             m_hWnd=0;
  182.         }
  183.     }
  184.  
  185.     //Adds a socket to the list of attached sockets
  186.     BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  187.     {
  188.         ASSERT(pSocket);
  189.         if (!m_nWindowDataSize)
  190.         {
  191.             ASSERT(!m_nSocketCount);
  192.             m_nWindowDataSize=512;
  193.             m_pAsyncSocketExWindowData=new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  194.             memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  195.         }
  196.  
  197.         if (nSocketIndex!=-1)
  198.         {
  199.             ASSERT(m_pAsyncSocketExWindowData);
  200.             ASSERT(m_nWindowDataSize>nSocketIndex);
  201.             ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  202.             ASSERT(m_nSocketCount);
  203.             return TRUE;
  204.         }
  205.  
  206.         //Increase socket storage if too small
  207.         if (m_nSocketCount>=(m_nWindowDataSize-10))
  208.         {
  209.             int nOldWindowDataSize=m_nWindowDataSize;
  210.             ASSERT(m_nWindowDataSize<MAX_SOCKETS);
  211.             m_nWindowDataSize+=512;
  212.             if (m_nWindowDataSize>MAX_SOCKETS)
  213.                 m_nWindowDataSize=MAX_SOCKETS;
  214.             t_AsyncSocketExWindowData *tmp=m_pAsyncSocketExWindowData;
  215.             m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
  216.             memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
  217.             memset(m_pAsyncSocketExWindowData+nOldWindowDataSize, 0, (m_nWindowDataSize-nOldWindowDataSize)*sizeof(t_AsyncSocketExWindowData));
  218.             delete [] tmp;
  219.         }
  220.  
  221.         //Search for free slot
  222.         for (int i=m_nWindowDataPos;i<(m_nWindowDataSize+m_nWindowDataPos);i++)
  223.         {
  224.             if (!m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket)
  225.             {
  226.                 m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket=pSocket;
  227.                 nSocketIndex=i%m_nWindowDataSize;
  228.                 m_nWindowDataPos=(i+1)%m_nWindowDataSize;
  229.                 m_nSocketCount++;
  230.                 return TRUE;
  231.             }
  232.         }
  233.  
  234.         //No slot found, maybe there are too much sockets!
  235.         return FALSE;
  236.     }
  237.  
  238.     //Removes a socket from the socket storage
  239.     BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  240.     {
  241.         ASSERT(pSocket);
  242.         if (nSocketIndex==-1)
  243.             return TRUE;
  244.  
  245.         ASSERT(m_pAsyncSocketExWindowData);
  246.         ASSERT(m_nWindowDataSize>0);
  247.         ASSERT(m_nSocketCount>0);
  248.         ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  249.         m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket=0;
  250.         nSocketIndex=-1;
  251.         m_nSocketCount--;
  252.  
  253.         return TRUE;
  254.     }
  255.  
  256.     //Processes event notifications sent by the sockets or the layers
  257.     static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  258.     {
  259.         if (message>=WM_SOCKETEX_NOTIFY)
  260.         {
  261.             //Verify parameters
  262.             ASSERT(hWnd);
  263.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  264.             ASSERT(pWnd);
  265.             
  266.             if (message<static_cast<UINT>(WM_SOCKETEX_NOTIFY+pWnd->m_nWindowDataSize)) //Index is within socket storage
  267.             {
  268.                 //Lookup socket and verify if it's valid
  269.                 CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[message-WM_SOCKETEX_NOTIFY].m_pSocket;
  270.                 SOCKET hSocket=wParam;
  271.                 if (!pSocket)
  272.                     return 0;
  273.                 if (hSocket==INVALID_SOCKET)
  274.                     return 0;
  275.                 if (pSocket->m_SocketData.hSocket != hSocket)
  276.                     return 0;
  277.                 
  278.                 int nEvent=lParam&0xFFFF;
  279.                 int nErrorCode=lParam>>16;
  280.  
  281.                 //Dispatch notification
  282. #ifndef NOLAYERS
  283.                 if (!pSocket->m_pFirstLayer)
  284.                 {
  285. #endif //NOLAYERS
  286.                     //Dispatch to CAsyncSocketEx instance
  287.                     switch (nEvent)
  288.                     {
  289.                     case FD_READ:
  290. #ifndef NOSOCKETSTATES
  291.                         if (pSocket->GetState() == connecting && !nErrorCode)
  292.                         {
  293.                             pSocket->m_nPendingEvents |= FD_READ;
  294.                             break;
  295.                         }
  296.                         else if (pSocket->GetState() == attached)
  297.                             pSocket->SetState(connected);
  298.                         if (pSocket->GetState() != connected)
  299.                             break;
  300.  
  301.                         // Ignore further FD_READ events after FD_CLOSE has been received
  302.                         if (pSocket->m_SocketData.onCloseCalled)
  303.                             break;
  304. #endif //NOSOCKETSTATES
  305.                         
  306.                         if (pSocket->m_lEvent & FD_READ)
  307.                         {
  308.                             DWORD nBytes = 0;
  309.                             if (!nErrorCode)
  310.                                 if (!pSocket->IOCtl(FIONREAD, &nBytes))
  311.                                     nErrorCode = WSAGetLastError();
  312. #ifndef NOSOCKETSTATES
  313.                             if (nErrorCode)
  314.                                 pSocket->SetState(aborted);
  315. #endif //NOSOCKETSTATES
  316.                             if (nBytes != 0 || nErrorCode != 0)
  317.                                 pSocket->OnReceive(nErrorCode);
  318.                         }
  319.                         break;
  320.                     case FD_FORCEREAD: //Forceread does not check if there's data waiting
  321. #ifndef NOSOCKETSTATES
  322.                         if (pSocket->GetState() == connecting && !nErrorCode)
  323.                         {
  324.                             pSocket->m_nPendingEvents |= FD_FORCEREAD;
  325.                             break;
  326.                         }
  327.                         else if (pSocket->GetState() == attached)
  328.                             pSocket->SetState(connected);
  329.                         if (pSocket->GetState() != connected)
  330.                             break;
  331. #endif //NOSOCKETSTATES
  332.                         if (pSocket->m_lEvent & FD_READ)
  333.                         {
  334. #ifndef NOSOCKETSTATES
  335.                             if (nErrorCode)
  336.                                 pSocket->SetState(aborted);
  337. #endif //NOSOCKETSTATES
  338.                             pSocket->OnReceive(nErrorCode);
  339.                         }
  340.                         break;
  341.                     case FD_WRITE:
  342. #ifndef NOSOCKETSTATES
  343.                         if (pSocket->GetState() == connecting && !nErrorCode)
  344.                         {
  345.                             pSocket->m_nPendingEvents |= FD_WRITE;
  346.                             break;
  347.                         }
  348.                         else if (pSocket->GetState() == attached && !nErrorCode)
  349.                             pSocket->SetState(connected);
  350.                         if (pSocket->GetState() != connected)
  351.                             break;
  352. #endif //NOSOCKETSTATES
  353.                         if (pSocket->m_lEvent & FD_WRITE)
  354.                         {
  355. #ifndef NOSOCKETSTATES
  356.                             if (nErrorCode)
  357.                                 pSocket->SetState(aborted);
  358. #endif //NOSOCKETSTATES
  359.                             pSocket->OnSend(nErrorCode);
  360.                         }
  361.                         break;
  362.                     case FD_CONNECT:
  363. #ifndef NOSOCKETSTATES
  364.                         if (pSocket->GetState() == connecting)
  365.                         {
  366.                             if (nErrorCode && pSocket->m_SocketData.nextAddr)
  367.                             {
  368.                                 if (pSocket->TryNextProtocol())
  369.                                     break;
  370.                             }
  371.                             pSocket->SetState(connected);
  372.                         }
  373.                         else if (pSocket->GetState() == attached && !nErrorCode)
  374.                             pSocket->SetState(connected);
  375. #endif //NOSOCKETSTATES
  376.                         if (pSocket->m_lEvent & FD_CONNECT)
  377.                             pSocket->OnConnect(nErrorCode);
  378. #ifndef NOSOCKETSTATES
  379.                         if (!nErrorCode)
  380.                         {
  381.                             if ((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected)
  382.                                 pSocket->OnReceive(0);
  383.                             if ((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected)
  384.                                 pSocket->OnReceive(0);
  385.                             if ((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected)
  386.                                 pSocket->OnSend(0);
  387.                         }
  388.                         pSocket->m_nPendingEvents = 0;
  389. #endif
  390.                         break;
  391.                     case FD_ACCEPT:
  392. #ifndef NOSOCKETSTATES
  393.                         if (pSocket->GetState() != listening && pSocket->GetState() != attached)
  394.                             break;
  395. #endif //NOSOCKETSTATES
  396.                         if (pSocket->m_lEvent & FD_ACCEPT)
  397.                             pSocket->OnAccept(nErrorCode);
  398.                         break;
  399.                     case FD_CLOSE:
  400. #ifndef NOSOCKETSTATES
  401.                         if (pSocket->GetState() != connected && pSocket->GetState() != attached)
  402.                             break;
  403.  
  404.                         // If there are still bytes left to read, call OnReceive instead of 
  405.                         // OnClose and trigger a new OnClose
  406.                         DWORD nBytes = 0;
  407.                         if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  408.                         {
  409.                             if (nBytes > 0)
  410.                             {
  411.                                 // Just repeat message.
  412.                                 PostMessage(hWnd, message, wParam, lParam);
  413.                                 pSocket->m_SocketData.onCloseCalled = true;                                
  414.                                 pSocket->OnReceive(WSAESHUTDOWN);
  415.                                 break;
  416.                             }
  417.                         }
  418.  
  419.                         pSocket->SetState(nErrorCode?aborted:closed);
  420. #endif //NOSOCKETSTATES
  421.                         pSocket->OnClose(nErrorCode);
  422.                         break;
  423.                     }
  424.                 }
  425. #ifndef NOLAYERS
  426.                 else //Dispatch notification to the lowest layer
  427.                 {
  428.                     if (nEvent == FD_READ)
  429.                     {
  430.                         // Ignore further FD_READ events after FD_CLOSE has been received
  431.                         if (pSocket->m_SocketData.onCloseCalled)
  432.                             return 0;
  433.  
  434.                         DWORD nBytes;
  435.                         if (!pSocket->IOCtl(FIONREAD, &nBytes))
  436.                             nErrorCode = WSAGetLastError();
  437.                         if (nBytes != 0 || nErrorCode != 0)
  438.                             pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  439.                     }
  440.                     else if (nEvent == FD_CLOSE)
  441.                     {
  442.                         // If there are still bytes left to read, call OnReceive instead of 
  443.                         // OnClose and trigger a new OnClose
  444.                         DWORD nBytes = 0;
  445.                         if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  446.                         {
  447.                             if (nBytes > 0)
  448.                             {
  449.                                 // Just repeat message.
  450.                                 pSocket->ResendCloseNotify();
  451.                                 pSocket->m_pLastLayer->CallEvent(FD_READ, 0);
  452.                                 return 0;
  453.                             }
  454.                         }
  455.                         pSocket->m_SocketData.onCloseCalled = true;
  456.                         pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  457.                     }
  458.                     else
  459.                         pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  460.                 }
  461.             }
  462. #endif //NOLAYERS
  463.             return 0;
  464.         }
  465. #ifndef NOLAYERS
  466.         else if (message == WM_USER) //Notification event sent by a layer
  467.         {
  468.             //Verify parameters, lookup socket and notification message
  469.             //Verify parameters
  470.             ASSERT(hWnd);
  471.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  472.             ASSERT(pWnd);
  473.             
  474.             if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  475.             {
  476.                 return 0;
  477.             }
  478.             
  479.             CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  480.             CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg=(CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
  481.             if (!pMsg || !pSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket)
  482.             {
  483.                 delete pMsg;
  484.                 return 0;
  485.             }
  486.             int nEvent=pMsg->lEvent&0xFFFF;
  487.             int nErrorCode=pMsg->lEvent>>16;
  488.             
  489.             //Dispatch to layer
  490.             if (pMsg->pLayer)
  491.                 pMsg->pLayer->CallEvent(nEvent, nErrorCode);
  492.             else
  493.             {
  494.                 //Dispatch to CAsyncSocketEx instance
  495.                 switch (nEvent)
  496.                 {
  497.                 case FD_READ:
  498. #ifndef NOSOCKETSTATES
  499.                     if (pSocket->GetState() == connecting && !nErrorCode)
  500.                     {
  501.                         pSocket->m_nPendingEvents |= FD_READ;
  502.                         break;
  503.                     }
  504.                     else if (pSocket->GetState() == attached && !nErrorCode)
  505.                         pSocket->SetState(connected);
  506.                     if (pSocket->GetState() != connected)
  507.                         break;
  508. #endif //NOSOCKETSTATES
  509.                     if (pSocket->m_lEvent & FD_READ)
  510.                     {
  511. #ifndef NOSOCKETSTATES
  512.                         if (nErrorCode)
  513.                             pSocket->SetState(aborted);
  514. #endif //NOSOCKETSTATES
  515.                         pSocket->OnReceive(nErrorCode);
  516.                     }
  517.                     break;
  518.                 case FD_FORCEREAD: //Forceread does not check if there's data waiting
  519. #ifndef NOSOCKETSTATES
  520.                     if (pSocket->GetState() == connecting && !nErrorCode)
  521.                     {
  522.                         pSocket->m_nPendingEvents |= FD_FORCEREAD;
  523.                         break;
  524.                     }
  525.                     else if (pSocket->GetState() == attached && !nErrorCode)
  526.                         pSocket->SetState(connected);
  527.                     if (pSocket->GetState() != connected)
  528.                         break;
  529. #endif //NOSOCKETSTATES
  530.                     if (pSocket->m_lEvent & FD_READ)
  531.                     {
  532. #ifndef NOSOCKETSTATES
  533.                         if (nErrorCode)
  534.                             pSocket->SetState(aborted);
  535. #endif //NOSOCKETSTATES
  536.                         pSocket->OnReceive(nErrorCode);
  537.                     }
  538.                     break;
  539.                 case FD_WRITE:
  540. #ifndef NOSOCKETSTATES
  541.                     if (pSocket->GetState() == connecting && !nErrorCode)
  542.                     {
  543.                         pSocket->m_nPendingEvents |= FD_WRITE;
  544.                         break;
  545.                     }
  546.                     else if (pSocket->GetState() == attached && !nErrorCode)
  547.                         pSocket->SetState(connected);
  548.                     if (pSocket->GetState() != connected)
  549.                         break;
  550. #endif //NOSOCKETSTATES
  551.                     if (pSocket->m_lEvent & FD_WRITE)
  552.                     {
  553. #ifndef NOSOCKETSTATES
  554.                         if (nErrorCode)
  555.                             pSocket->SetState(aborted);
  556. #endif //NOSOCKETSTATES
  557.                         pSocket->OnSend(nErrorCode);
  558.                     }
  559.                     break;
  560.                 case FD_CONNECT:
  561. #ifndef NOSOCKETSTATES
  562.                     if (pSocket->GetState() == connecting)
  563.                         pSocket->SetState(connected);
  564.                     else if (pSocket->GetState() == attached && !nErrorCode)
  565.                         pSocket->SetState(connected);
  566. #endif //NOSOCKETSTATES
  567.                     if (pSocket->m_lEvent & FD_CONNECT)
  568.                         pSocket->OnConnect(nErrorCode);
  569. #ifndef NOSOCKETSTATES
  570.                     if (!nErrorCode)
  571.                     {
  572.                         if (((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  573.                             pSocket->OnReceive(0);
  574.                         if (((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  575.                             pSocket->OnReceive(0);
  576.                         if (((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_WRITE))
  577.                             pSocket->OnSend(0);
  578.                     }
  579.                     pSocket->m_nPendingEvents = 0;
  580. #endif //NOSOCKETSTATES
  581.                     break;
  582.                 case FD_ACCEPT:
  583. #ifndef NOSOCKETSTATES
  584.                     if ((pSocket->GetState() == listening || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_ACCEPT))
  585. #endif //NOSOCKETSTATES
  586.                     {
  587.                         pSocket->OnAccept(nErrorCode);
  588.                     }
  589.                     break;
  590.                 case FD_CLOSE:
  591. #ifndef NOSOCKETSTATES
  592.                     if ((pSocket->GetState() == connected || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_CLOSE))
  593.                     {
  594.                         pSocket->SetState(nErrorCode?aborted:closed);
  595. #else
  596.                     {
  597. #endif //NOSOCKETSTATES
  598.                         pSocket->OnClose(nErrorCode);
  599.                     }
  600.                     break;
  601.                 }
  602.             }
  603.             delete pMsg;
  604.             return 0;
  605.         }
  606. #endif //NOLAYERS
  607.         else if (message == WM_USER+1)
  608.         {
  609.             // WSAAsyncGetHostByName reply
  610.  
  611.             // Verify parameters
  612.             ASSERT(hWnd);
  613.             CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  614.             ASSERT(pWnd);
  615.  
  616.             CAsyncSocketEx *pSocket = NULL;
  617.             for (int i = 0; i < pWnd->m_nWindowDataSize; i++)
  618.             {
  619.                 pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
  620.                 if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
  621.                     pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
  622.                     break;
  623.             }
  624.             if (!pSocket)
  625.                 return 0;
  626.  
  627.             int nErrorCode = lParam >> 16;
  628.             if (nErrorCode)
  629.             {
  630.                 pSocket->OnConnect(nErrorCode);
  631.                 return 0;
  632.             }
  633.  
  634.             SOCKADDR_IN sockAddr;
  635.             memset(&sockAddr,0,sizeof(sockAddr));
  636.             sockAddr.sin_family=AF_INET;
  637.             sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
  638.  
  639.             sockAddr.sin_port = htons(pSocket->m_nAsyncGetHostByNamePort);
  640.  
  641.             BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  642.             delete [] pSocket->m_pAsyncGetHostByNameBuffer;
  643.             pSocket->m_pAsyncGetHostByNameBuffer=0;
  644.             pSocket->m_hAsyncGetHostByNameHandle=0;
  645.  
  646.             if (!res)
  647.                 if (GetLastError()!=WSAEWOULDBLOCK)
  648.                     pSocket->OnConnect(GetLastError());
  649.             return 0;
  650.         }
  651.         else if (message == WM_USER + 2)
  652.         {
  653.             //Verify parameters, lookup socket and notification message
  654.             //Verify parameters
  655.             if (!hWnd)
  656.                 return 0;
  657.  
  658.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  659.             if (!pWnd)
  660.                 return 0;
  661.  
  662.             if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  663.                 return 0;
  664.             
  665.             CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  666.             if (!pSocket)
  667.                 return 0;
  668.             
  669.             // Process pending callbacks
  670.             std::list<t_callbackMsg> tmp;
  671.             tmp.swap(pSocket->m_pendingCallbacks);
  672.             pSocket->OnLayerCallback(tmp);
  673.         }
  674.         else if (message == WM_TIMER)
  675.         {
  676.             if (wParam != 1)
  677.                 return 0;
  678.             
  679.             ASSERT(hWnd);
  680.             CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  681.             ASSERT(pWnd);
  682.  
  683.             if (pWnd->m_pThreadData->layerCloseNotify.empty())
  684.             {
  685.                 KillTimer(hWnd, 1);
  686.                 return 0;
  687.             }
  688.             CAsyncSocketEx* socket = pWnd->m_pThreadData->layerCloseNotify.front();
  689.             pWnd->m_pThreadData->layerCloseNotify.pop_front();
  690.             if (pWnd->m_pThreadData->layerCloseNotify.empty())
  691.                 KillTimer(hWnd, 1);
  692.  
  693.             PostMessage(hWnd, socket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, socket->m_SocketData.hSocket, FD_CLOSE);
  694.             return 0;
  695.         }
  696.         return DefWindowProc(hWnd, message, wParam, lParam);
  697.     }
  698.  
  699.     HWND CAsyncSocketExHelperWindow::GetHwnd()
  700.     {
  701.         return m_hWnd;
  702.     }
  703.  
  704. private:
  705.     HWND m_hWnd;
  706.     struct t_AsyncSocketExWindowData
  707.     {
  708.         CAsyncSocketEx *m_pSocket;
  709.     } *m_pAsyncSocketExWindowData;
  710.     int m_nWindowDataSize;
  711.     int m_nWindowDataPos;
  712.     int m_nSocketCount;
  713.     CAsyncSocketEx::t_AsyncSocketExThreadData* m_pThreadData;
  714. };
  715.  
  716. //////////////////////////////////////////////////////////////////////
  717. // Konstruktion/Destruktion
  718. //////////////////////////////////////////////////////////////////////
  719.  
  720. CAsyncSocketEx::CAsyncSocketEx()
  721. {
  722.     m_SocketData.hSocket = INVALID_SOCKET;
  723.     m_SocketData.nSocketIndex = -1;
  724.     m_SocketData.nFamily = AF_UNSPEC;
  725.     m_SocketData.onCloseCalled = false;
  726.     m_pLocalAsyncSocketExThreadData = 0;
  727.  
  728. #ifndef NOSOCKETSTATES
  729.     m_nPendingEvents = 0;
  730.     m_nState = notsock;
  731. #endif //NOSOCKETSTATES
  732.  
  733. #ifndef NOLAYERS
  734.     m_pFirstLayer = 0;
  735.     m_pLastLayer = 0;
  736. #endif //NOLAYERS
  737.     m_pAsyncGetHostByNameBuffer = NULL;
  738.     m_hAsyncGetHostByNameHandle = NULL;
  739.  
  740.     m_nSocketPort = 0;
  741.     m_lpszSocketAddress = 0;
  742.  
  743.     m_SocketData.addrInfo = 0;
  744.     m_SocketData.nextAddr = 0;
  745. }
  746.  
  747. CAsyncSocketEx::~CAsyncSocketEx()
  748. {
  749.     Close();
  750.     FreeAsyncSocketExInstance();
  751. }
  752.  
  753. BOOL CAsyncSocketEx::Create(UINT nSocketPort /*=0*/, int nSocketType /*=SOCK_STREAM*/, long lEvent /*=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/, LPCTSTR lpszSocketAddress /*=NULL*/, int nFamily /*=AF_INET*/)
  754. {
  755.     ASSERT(GetSocketHandle() == INVALID_SOCKET);
  756.  
  757.     //Close the socket, although this should not happen
  758.     if (GetSocketHandle() != INVALID_SOCKET)
  759.     {
  760.         WSASetLastError(WSAEALREADY);
  761.         return FALSE;
  762.     }
  763.  
  764.     BOOL res = InitAsyncSocketExInstance();
  765.     ASSERT(res);
  766.     if (!res)
  767.     {
  768.         WSASetLastError(WSANOTINITIALISED);
  769.         return FALSE;
  770.     }
  771.  
  772.     m_SocketData.nFamily = nFamily;
  773.  
  774. #ifndef NOLAYERS
  775.     if (m_pFirstLayer)
  776.     {
  777.         BOOL res = m_pFirstLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily);
  778. #ifndef NOSOCKETSTATES
  779.         if (res)
  780.             SetState(unconnected);
  781. #endif //NOSOCKETSTATES
  782.         return res;
  783.     }
  784.     else
  785. #endif //NOLAYERS
  786.     {
  787.         if (m_SocketData.nFamily == AF_UNSPEC)
  788.         {
  789. #ifndef NOSOCKETSTATES
  790.             SetState(unconnected);
  791. #endif //NOSOCKETSTATES
  792.             m_lEvent = lEvent;
  793.  
  794.             m_nSocketPort = nSocketPort;
  795.         
  796.             delete [] m_lpszSocketAddress;
  797.             if (lpszSocketAddress && *lpszSocketAddress)
  798.             {
  799.                 m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  800.                 _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  801.             }
  802.             else
  803.                 m_lpszSocketAddress = 0;
  804.  
  805.             return TRUE;
  806.         }
  807.         else
  808.         {
  809.             SOCKET hSocket = socket(m_SocketData.nFamily, nSocketType, 0);
  810.             if (hSocket == INVALID_SOCKET)
  811.                 return FALSE;
  812.             m_SocketData.hSocket = hSocket;
  813.             AttachHandle(hSocket);
  814.         
  815. #ifndef NOLAYERS
  816.             if (m_pFirstLayer)
  817.             {
  818.                 m_lEvent = lEvent;
  819.                 if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
  820.                 {
  821.                     Close();
  822.                     return FALSE;
  823.                 }
  824.             }
  825.             else
  826. #endif //NOLAYERS
  827.             {
  828.                 if (!AsyncSelect(lEvent))
  829.                 {
  830.                     Close();
  831.                     return FALSE;
  832.                 }
  833.             }
  834.  
  835.             if (!Bind(nSocketPort, lpszSocketAddress))
  836.             {
  837.                 Close();
  838.                 return FALSE;
  839.             }
  840.  
  841. #ifndef NOSOCKETSTATES
  842.             SetState(unconnected);
  843. #endif //NOSOCKETSTATES
  844.         
  845.             return TRUE;
  846.         }
  847.     }
  848. }
  849.  
  850. void CAsyncSocketEx::OnReceive(int nErrorCode)
  851. {
  852. }
  853.  
  854. void CAsyncSocketEx::OnSend(int nErrorCode)
  855. {
  856. }
  857.  
  858. void CAsyncSocketEx::OnConnect(int nErrorCode)
  859. {
  860. }
  861.  
  862. void CAsyncSocketEx::OnAccept(int nErrorCode)
  863. {
  864. }
  865.  
  866. void CAsyncSocketEx::OnClose(int nErrorCode)
  867. {
  868. }
  869.  
  870. BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
  871. {
  872.     delete [] m_lpszSocketAddress;
  873.     if (lpszSocketAddress && *lpszSocketAddress)
  874.     {
  875.         m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  876.         _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  877.     }
  878.     else
  879.         m_lpszSocketAddress = 0;
  880.     m_nSocketPort = nSocketPort;
  881.  
  882.     if (m_SocketData.nFamily == AF_UNSPEC)
  883.         return TRUE;
  884.  
  885.     USES_CONVERSION;
  886.     
  887.     LPSTR lpszAscii = (lpszSocketAddress && *lpszSocketAddress) ? T2A((LPTSTR)lpszSocketAddress) : 0;
  888.     
  889.     if ((m_SocketData.nFamily == AF_INET6 || m_SocketData.nFamily == AF_INET) && lpszAscii)
  890.     {
  891.         if (!p_getaddrinfo)
  892.         {
  893.             if (m_SocketData.nFamily != AF_INET)
  894.             {
  895.                 WSASetLastError(WSAEPROTONOSUPPORT);
  896.                 return FALSE;
  897.             }
  898.             else
  899.             {
  900.                 unsigned long ip = inet_addr(lpszAscii);
  901.                 if (!ip)
  902.                 {
  903.                     WSASetLastError(WSAEINVAL);
  904.                     return FALSE;
  905.                 }
  906.  
  907.                 SOCKADDR_IN sockAddr;
  908.                 memset(&sockAddr, 0, sizeof(sockAddr));
  909.                 sockAddr.sin_family = m_SocketData.nFamily;
  910.                 sockAddr.sin_addr.s_addr = ip;
  911.                 sockAddr.sin_port = htons((u_short)nSocketPort);
  912.                 return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  913.             }
  914.         }
  915.         addrinfo hints, *res0, *res;
  916.         int error;
  917.         char port[10];
  918.         BOOL ret = FALSE;
  919.  
  920.         memset(&hints, 0, sizeof(addrinfo));
  921.         hints.ai_family = m_SocketData.nFamily;
  922.         hints.ai_socktype = SOCK_STREAM;
  923.         _snprintf(port, 9, "%lu", nSocketPort);
  924.         error = p_getaddrinfo(lpszAscii, port, &hints, &res0);
  925.         if (error)
  926.             return FALSE;
  927.  
  928.         for (res = res0; res; res = res->ai_next)
  929.             if (Bind(res->ai_addr, res->ai_addrlen))
  930.             {
  931.                 ret = TRUE;
  932.                 break;
  933.             }
  934.             else
  935.                 continue ;
  936.  
  937.             p_freeaddrinfo(res0);
  938.  
  939.             return ret ;
  940.     }
  941.     else if (!lpszAscii && m_SocketData.nFamily == AF_INET6)
  942.     {
  943.         SOCKADDR_IN6 sockAddr6;
  944.  
  945.         memset(&sockAddr6, 0, sizeof(sockAddr6));
  946.         sockAddr6.sin6_family = AF_INET6 ;
  947.         sockAddr6.sin6_addr = in6addr_any ;
  948.         sockAddr6.sin6_port = htons((u_short)nSocketPort);
  949.  
  950.         return Bind((SOCKADDR*)&sockAddr6, sizeof(sockAddr6));
  951.     }
  952.     else if (!lpszAscii && m_SocketData.nFamily == AF_INET)
  953.     {
  954.         SOCKADDR_IN sockAddr;
  955.  
  956.         memset(&sockAddr, 0, sizeof(sockAddr));
  957.         sockAddr.sin_family = AF_INET ;
  958.         sockAddr.sin_addr.s_addr = INADDR_ANY ;
  959.         sockAddr.sin_port = htons((u_short)nSocketPort);
  960.  
  961.         return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  962.     }
  963.     else
  964.         return FALSE ;
  965. }
  966.  
  967. BOOL CAsyncSocketEx::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  968. {
  969.     if (!bind(m_SocketData.hSocket, lpSockAddr, nSockAddrLen))
  970.         return TRUE;
  971.     else
  972.         return FALSE;
  973. }
  974.  
  975. void CAsyncSocketEx::AttachHandle(SOCKET hSocket)
  976. {
  977.     ASSERT(m_pLocalAsyncSocketExThreadData);
  978.     VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->AddSocket(this, m_SocketData.nSocketIndex));
  979. #ifndef NOSOCKETSTATES
  980.     SetState(attached);
  981. #endif //NOSOCKETSTATES
  982. }
  983.  
  984. void CAsyncSocketEx::DetachHandle(SOCKET hSocket)
  985. {
  986.     ASSERT(m_pLocalAsyncSocketExThreadData);
  987.     if (!m_pLocalAsyncSocketExThreadData)
  988.         return;
  989.     ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  990.     if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  991.         return;
  992.     VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveSocket(this, m_SocketData.nSocketIndex));
  993. #ifndef NOSOCKETSTATES
  994.     SetState(notsock);
  995. #endif //NOSOCKETSTATES
  996. }
  997.  
  998. void CAsyncSocketEx::Close()
  999. {
  1000. #ifndef NOSOCKETSTATES
  1001.     m_nPendingEvents = 0;
  1002. #endif //NOSOCKETSTATES
  1003. #ifndef NOLAYERS
  1004.     if (m_pFirstLayer)
  1005.         m_pFirstLayer->Close();
  1006. #endif //NOLAYERS
  1007.     if (m_SocketData.hSocket != INVALID_SOCKET)
  1008.     {
  1009.         VERIFY((closesocket(m_SocketData.hSocket) != SOCKET_ERROR));
  1010.         DetachHandle(m_SocketData.hSocket);
  1011.         m_SocketData.hSocket = INVALID_SOCKET;
  1012.     }
  1013.     if (m_SocketData.addrInfo)
  1014.     {
  1015.         p_freeaddrinfo(m_SocketData.addrInfo);
  1016.         m_SocketData.addrInfo = 0;
  1017.         m_SocketData.nextAddr = 0;
  1018.     }
  1019.     m_SocketData.nFamily = AF_UNSPEC;
  1020.     delete [] m_lpszSocketAddress;
  1021.     m_lpszSocketAddress = 0;
  1022.     m_nSocketPort = 0;
  1023. #ifndef NOLAYERS
  1024.     RemoveAllLayers();
  1025. #endif //NOLAYERS
  1026.     delete [] m_pAsyncGetHostByNameBuffer;
  1027.     m_pAsyncGetHostByNameBuffer = NULL;
  1028.     if (m_hAsyncGetHostByNameHandle)
  1029.         WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
  1030.     m_hAsyncGetHostByNameHandle = NULL;
  1031.     m_SocketData.onCloseCalled = false;
  1032. }
  1033.  
  1034. BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
  1035. {
  1036.     //Check if already initialized
  1037.     if (m_pLocalAsyncSocketExThreadData)
  1038.         return TRUE;
  1039.  
  1040.     DWORD id=GetCurrentThreadId();
  1041.  
  1042.     m_sGlobalCriticalSection.Lock();
  1043.  
  1044.     //Get thread specific data
  1045.     if (m_spAsyncSocketExThreadDataList)
  1046.     {
  1047.         t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  1048.         while (pList)
  1049.         {
  1050.             ASSERT(pList->pThreadData);
  1051.             ASSERT(pList->pThreadData->nInstanceCount>0);
  1052.  
  1053.             if (pList->pThreadData->nThreadId==id)
  1054.             {
  1055.                 m_pLocalAsyncSocketExThreadData=pList->pThreadData;
  1056.                 m_pLocalAsyncSocketExThreadData->nInstanceCount++;
  1057.                 break;
  1058.             }
  1059.             pList=pList->pNext;
  1060.         }
  1061.         //Current thread yet has no sockets
  1062.         if (!pList)
  1063.         {
  1064.             //Initialize data for current thread
  1065.             pList=new t_AsyncSocketExThreadDataList;
  1066.             pList->pNext=m_spAsyncSocketExThreadDataList;
  1067.             m_spAsyncSocketExThreadDataList=pList;
  1068.             m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  1069.             m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  1070.             m_pLocalAsyncSocketExThreadData->nThreadId=id;
  1071.             m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  1072.             m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  1073.         }
  1074.     }
  1075.     else
  1076.     {    //No thread has instances of CAsyncSocketEx; Initialize data
  1077.         m_spAsyncSocketExThreadDataList=new t_AsyncSocketExThreadDataList;
  1078.         m_spAsyncSocketExThreadDataList->pNext=0;
  1079.         m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  1080.         m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  1081.         m_pLocalAsyncSocketExThreadData->nThreadId=id;
  1082.         m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  1083.         m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  1084.  
  1085.         m_hDll = LoadLibrary(_T("WS2_32.dll"));
  1086.         if (m_hDll)
  1087.         {
  1088.             p_getaddrinfo = (t_getaddrinfo)GetProcAddress(m_hDll, "getaddrinfo");
  1089.             p_freeaddrinfo = (t_freeaddrinfo)GetProcAddress(m_hDll, "freeaddrinfo");
  1090.  
  1091.             if (!p_getaddrinfo || !p_freeaddrinfo)
  1092.             {
  1093.                 p_getaddrinfo = 0;
  1094.                 p_freeaddrinfo = 0;
  1095.                 FreeLibrary(m_hDll);
  1096.                 m_hDll = 0;
  1097.             }
  1098.         }
  1099.     }
  1100.     m_sGlobalCriticalSection.Unlock();
  1101.     return TRUE;
  1102. }
  1103.  
  1104. void CAsyncSocketEx::FreeAsyncSocketExInstance()
  1105. {
  1106.     //Check if already freed
  1107.     if (!m_pLocalAsyncSocketExThreadData)
  1108.         return;
  1109.  
  1110.     for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1111.     {
  1112.         if (*iter != this)
  1113.             continue;
  1114.  
  1115.         m_pLocalAsyncSocketExThreadData->layerCloseNotify.erase(iter);
  1116.         if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.empty())
  1117.             KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1);
  1118.     }
  1119.  
  1120.     DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
  1121.     m_sGlobalCriticalSection.Lock();
  1122.  
  1123.     ASSERT(m_spAsyncSocketExThreadDataList);
  1124.     t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  1125.     t_AsyncSocketExThreadDataList *pPrev=0;
  1126.  
  1127.     //Serach for data for current thread and decrease instance count
  1128.     while (pList)
  1129.     {
  1130.         ASSERT(pList->pThreadData);
  1131.         ASSERT(pList->pThreadData->nInstanceCount>0);
  1132.  
  1133.         if (pList->pThreadData->nThreadId==id)
  1134.         {
  1135.             ASSERT(m_pLocalAsyncSocketExThreadData==pList->pThreadData);
  1136.             m_pLocalAsyncSocketExThreadData->nInstanceCount--;
  1137.  
  1138.             //Freeing last instance?
  1139.             //If so, destroy helper window
  1140.             if (!m_pLocalAsyncSocketExThreadData->nInstanceCount)
  1141.             {
  1142.                 delete m_pLocalAsyncSocketExThreadData->m_pHelperWindow;
  1143.                 delete m_pLocalAsyncSocketExThreadData;
  1144.                 if (pPrev)
  1145.                     pPrev->pNext=pList->pNext;
  1146.                 else
  1147.                     m_spAsyncSocketExThreadDataList=pList->pNext;
  1148.                 delete pList;
  1149.  
  1150.                 // Last thread closed, free dll
  1151.                 if (!m_spAsyncSocketExThreadDataList)
  1152.                 {
  1153.                     if (m_hDll)
  1154.                     {
  1155.                         p_getaddrinfo = 0;
  1156.                         p_freeaddrinfo = 0;
  1157.                         FreeLibrary(m_hDll);
  1158.                         m_hDll = 0;
  1159.                     }
  1160.                 }
  1161.                 break;
  1162.             }
  1163.             break;
  1164.         }
  1165.         pPrev=pList;
  1166.         pList=pList->pNext;
  1167.         ASSERT(pList);
  1168.     }
  1169.  
  1170.     m_sGlobalCriticalSection.Unlock();
  1171. }
  1172.  
  1173. int CAsyncSocketEx::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1174. {
  1175. #ifndef NOLAYERS
  1176.     if (m_pFirstLayer)
  1177.         return m_pFirstLayer->Receive(lpBuf, nBufLen, nFlags);
  1178.     else
  1179. #endif //NOLAYERS
  1180.         return recv(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1181. }
  1182.  
  1183.  
  1184. int CAsyncSocketEx::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1185. {
  1186. #ifndef NOLAYERS
  1187.     if (m_pFirstLayer)
  1188.         return m_pFirstLayer->Send(lpBuf, nBufLen, nFlags);
  1189.     else
  1190. #endif //NOLAYERS
  1191.         return send(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1192. }
  1193.  
  1194. BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  1195. {
  1196. #ifndef NOLAYERS
  1197.     if (m_pFirstLayer)
  1198.     {
  1199.         BOOL res = m_pFirstLayer->Connect(lpszHostAddress, nHostPort);
  1200. #ifndef NOSOCKETSTATES
  1201.         if (res || GetLastError()==WSAEWOULDBLOCK)
  1202.             SetState(connecting);
  1203. #endif //NOSOCKETSTATES
  1204.         return res;
  1205.     } else
  1206. #endif //NOLAYERS
  1207.     if (m_SocketData.nFamily == AF_INET)
  1208.     {
  1209.         USES_CONVERSION;
  1210.  
  1211.         ASSERT(lpszHostAddress != NULL);
  1212.  
  1213.         SOCKADDR_IN sockAddr;
  1214.         memset(&sockAddr,0,sizeof(sockAddr));
  1215.  
  1216.         LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  1217.         sockAddr.sin_family = AF_INET;
  1218.         sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  1219.  
  1220.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  1221.         {
  1222.             m_pAsyncGetHostByNameBuffer=new char[MAXGETHOSTSTRUCT];
  1223.  
  1224.             m_nAsyncGetHostByNamePort=nHostPort;
  1225.  
  1226.             m_hAsyncGetHostByNameHandle=WSAAsyncGetHostByName(GetHelperWindowHandle(), WM_USER+1, lpszAscii, m_pAsyncGetHostByNameBuffer, MAXGETHOSTSTRUCT);
  1227.             if (!m_hAsyncGetHostByNameHandle)
  1228.                 return FALSE;
  1229.  
  1230.             WSASetLastError(WSAEWOULDBLOCK);
  1231. #ifndef NOSOCKETSTATES
  1232.             SetState(connecting);
  1233. #endif //NOSOCKETSTATES
  1234.             return FALSE;
  1235.         }
  1236.  
  1237.         sockAddr.sin_port = htons((u_short)nHostPort);
  1238.  
  1239.         return CAsyncSocketEx::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  1240.     }
  1241.     else
  1242.     {
  1243.         if (!p_getaddrinfo)
  1244.         {
  1245.             WSASetLastError(WSAEPROTONOSUPPORT);
  1246.             return FALSE;
  1247.         }
  1248.  
  1249.         USES_CONVERSION;
  1250.  
  1251.         ASSERT( lpszHostAddress != NULL );
  1252.  
  1253.         if (m_SocketData.addrInfo)
  1254.         {
  1255.             p_freeaddrinfo(m_SocketData.addrInfo);
  1256.             m_SocketData.addrInfo = 0;
  1257.             m_SocketData.nextAddr = 0;
  1258.         }
  1259.  
  1260.         addrinfo hints;
  1261.         int error;
  1262.         BOOL ret;
  1263.         char port[10];
  1264.  
  1265.         memset(&hints, 0, sizeof(addrinfo));
  1266.         hints.ai_family = m_SocketData.nFamily;
  1267.         hints.ai_socktype = SOCK_STREAM;
  1268.         _snprintf(port, 9, "%lu", nHostPort);
  1269.         error = p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
  1270.         if (error)
  1271.             return FALSE;
  1272.  
  1273.         for (m_SocketData.nextAddr = m_SocketData.addrInfo; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1274.         {
  1275.             bool newSocket = false;
  1276.             if (m_SocketData.nFamily == AF_UNSPEC)
  1277.             {
  1278.                 newSocket = true;
  1279.                 m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1280.  
  1281.                 if (m_SocketData.hSocket == INVALID_SOCKET)
  1282.                     continue;
  1283.  
  1284.                 m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1285.                 AttachHandle(m_SocketData.hSocket);
  1286.                 if (!AsyncSelect(m_lEvent))
  1287.                 {
  1288.                     if (newSocket)
  1289.                     {
  1290.                         DetachHandle(m_SocketData.hSocket);
  1291.                         closesocket(m_SocketData.hSocket);
  1292.                         m_SocketData.hSocket = INVALID_SOCKET;
  1293.                     }
  1294.                     continue;
  1295.                 }
  1296.             }
  1297.             else if (m_SocketData.hSocket == INVALID_SOCKET)
  1298.                 continue;
  1299.  
  1300. #ifndef NOLAYERS
  1301.             if (m_pFirstLayer)
  1302.             {
  1303.                 if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1304.                 {
  1305.                     if (newSocket)
  1306.                     {
  1307.                         m_SocketData.nFamily = AF_UNSPEC;
  1308.                         DetachHandle(m_SocketData.hSocket);
  1309.                         closesocket(m_SocketData.hSocket);
  1310.                         m_SocketData.hSocket = INVALID_SOCKET;
  1311.                     }
  1312.                     continue;
  1313.                 }
  1314.             }
  1315. #endif //NOLAYERS
  1316.  
  1317.             if (newSocket)
  1318.             {
  1319.                 m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1320.                 if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1321.                 { 
  1322.                     m_SocketData.nFamily = AF_UNSPEC;
  1323.                     DetachHandle(m_SocketData.hSocket);
  1324.                     closesocket(m_SocketData.hSocket);
  1325.                     m_SocketData.hSocket = INVALID_SOCKET;
  1326.                     continue; 
  1327.                 }
  1328.             }
  1329.  
  1330.             if (!(ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen)) && GetLastError() != WSAEWOULDBLOCK)
  1331.             {
  1332.                 if (newSocket)
  1333.                 {
  1334.                     m_SocketData.nFamily = AF_UNSPEC;
  1335.                     DetachHandle(m_SocketData.hSocket);
  1336.                     closesocket(m_SocketData.hSocket);
  1337.                     m_SocketData.hSocket = INVALID_SOCKET;
  1338.                 }
  1339.                 continue;
  1340.             }
  1341.  
  1342.             break;
  1343.         }
  1344.  
  1345.         if (m_SocketData.nextAddr)
  1346.             m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1347.  
  1348.         if (!m_SocketData.nextAddr)
  1349.         {
  1350.             p_freeaddrinfo(m_SocketData.addrInfo);
  1351.             m_SocketData.nextAddr = 0;
  1352.             m_SocketData.addrInfo = 0;
  1353.         }
  1354.  
  1355.         if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1356.             return FALSE;
  1357.         else
  1358.             return TRUE;
  1359.     }
  1360. }
  1361.  
  1362. BOOL CAsyncSocketEx::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  1363. {
  1364.     BOOL res;
  1365. #ifndef NOLAYERS
  1366.     if (m_pFirstLayer)
  1367.         res = SOCKET_ERROR!=m_pFirstLayer->Connect(lpSockAddr, nSockAddrLen);
  1368.     else
  1369. #endif //NOLAYERS
  1370.         res = SOCKET_ERROR!=connect(m_SocketData.hSocket, lpSockAddr, nSockAddrLen);
  1371.  
  1372. #ifndef NOSOCKETSTATES
  1373.     if (res || GetLastError()==WSAEWOULDBLOCK)
  1374.         SetState(connecting);
  1375. #endif //NOSOCKETSTATES
  1376.     return res;
  1377. }
  1378.  
  1379. #ifdef _AFX
  1380. BOOL CAsyncSocketEx::GetPeerName( CString& rPeerAddress, UINT& rPeerPort )
  1381. {
  1382. #ifndef NOLAYERS
  1383.     if (m_pFirstLayer)
  1384.         return m_pFirstLayer->GetPeerName(rPeerAddress, rPeerPort);
  1385. #endif NOLAYERS
  1386.  
  1387.     SOCKADDR* sockAddr;
  1388.     int nSockAddrLen;
  1389.  
  1390.     if (m_SocketData.nFamily == AF_INET6)
  1391.     {
  1392.         sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1393.         nSockAddrLen = sizeof(SOCKADDR_IN6);
  1394.     } 
  1395.     else if (m_SocketData.nFamily == AF_INET)
  1396.     {
  1397.         sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1398.         nSockAddrLen = sizeof(SOCKADDR_IN);
  1399.     }
  1400.  
  1401.     memset(sockAddr, 0, nSockAddrLen);
  1402.  
  1403.     BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);
  1404.  
  1405.     if (bResult)
  1406.     {
  1407.         if (m_SocketData.nFamily == AF_INET6)
  1408.         {
  1409.             rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1410.             LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1411.             rPeerAddress = buf;
  1412.             delete [] buf;
  1413.         }
  1414.         else if (m_SocketData.nFamily == AF_INET)
  1415.         {
  1416.             rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1417.             rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1418.         }
  1419.         else
  1420.         {
  1421.             delete sockAddr;
  1422.             return FALSE;
  1423.         }
  1424.     }
  1425.     delete sockAddr;
  1426.  
  1427.     return bResult;
  1428. }
  1429. #endif //_AFX
  1430.  
  1431. BOOL CAsyncSocketEx::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1432. {
  1433. #ifndef NOLAYERS
  1434.     if (m_pFirstLayer)
  1435.         return m_pFirstLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
  1436. #endif //NOLAYERS
  1437.  
  1438.     if (!getpeername(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen))
  1439.         return TRUE;
  1440.     else
  1441.         return FALSE;
  1442. }
  1443.  
  1444. #ifdef _AFX
  1445. BOOL CAsyncSocketEx::GetSockName(CString& rSocketAddress, UINT& rSocketPort)
  1446. {
  1447.     SOCKADDR* sockAddr;
  1448.     int nSockAddrLen;
  1449.  
  1450.     if (m_SocketData.nFamily == AF_INET6)
  1451.     {
  1452.         sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1453.         nSockAddrLen = sizeof(SOCKADDR_IN6);
  1454.     }
  1455.     else if (m_SocketData.nFamily == AF_INET)
  1456.     {
  1457.         sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1458.         nSockAddrLen = sizeof(SOCKADDR_IN);
  1459.     }
  1460.  
  1461.     memset(sockAddr, 0, nSockAddrLen);
  1462.  
  1463.     BOOL bResult = GetSockName(sockAddr, &nSockAddrLen);
  1464.  
  1465.     if (bResult)
  1466.     {
  1467.         if (m_SocketData.nFamily == AF_INET6)
  1468.         {
  1469.             rSocketPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1470.             LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1471.             rSocketAddress = buf;
  1472.             delete [] buf;
  1473.         }
  1474.         else if (m_SocketData.nFamily == AF_INET)
  1475.         {
  1476.             rSocketPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1477.             rSocketAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1478.         }
  1479.         else
  1480.         {
  1481.             delete sockAddr;
  1482.             return FALSE;
  1483.         }
  1484.     }
  1485.     delete sockAddr;
  1486.  
  1487.     return bResult;
  1488. }
  1489. #endif //_AFX
  1490.  
  1491. BOOL CAsyncSocketEx::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1492. {
  1493.     if ( !getsockname(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
  1494.         return TRUE;
  1495.     else
  1496.         return FALSE;
  1497. }
  1498.  
  1499. BOOL CAsyncSocketEx::ShutDown(int nHow /*=sends*/)
  1500. {
  1501. #ifndef NOLAYERS
  1502.     if (m_pFirstLayer)
  1503.     {
  1504.         return m_pFirstLayer->ShutDown();
  1505.     }
  1506.     else
  1507. #endif //NOLAYERS
  1508.     {
  1509.         if (!shutdown(m_SocketData.hSocket, nHow))
  1510.             return TRUE;
  1511.         else
  1512.             return FALSE;
  1513.     }
  1514. }
  1515.  
  1516. SOCKET CAsyncSocketEx::Detach()
  1517. {
  1518.     SOCKET socket = m_SocketData.hSocket;
  1519.     DetachHandle(socket);
  1520.     m_SocketData.hSocket = INVALID_SOCKET;
  1521.     m_SocketData.nFamily = AF_UNSPEC;
  1522.     return socket;
  1523. }
  1524.  
  1525. BOOL CAsyncSocketEx::Attach(SOCKET hSocket, long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/)
  1526. {
  1527.     if (hSocket==INVALID_SOCKET || !hSocket)
  1528.         return FALSE;
  1529.  
  1530.     VERIFY(InitAsyncSocketExInstance());
  1531.     m_SocketData.hSocket=hSocket;
  1532.     AttachHandle(hSocket);
  1533.  
  1534. #ifndef NOLAYERS
  1535.     if (m_pFirstLayer)
  1536.     {
  1537.         m_lEvent = lEvent;
  1538.         return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
  1539.     }
  1540.     else
  1541. #endif //NOLAYERS
  1542.     {
  1543.         return AsyncSelect(lEvent);
  1544.     }        
  1545. }
  1546.  
  1547. BOOL CAsyncSocketEx::AsyncSelect( long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
  1548. {
  1549.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1550.     m_lEvent = lEvent;
  1551. #ifndef NOLAYERS
  1552.     if (m_pFirstLayer)
  1553.         return TRUE;
  1554.     else
  1555. #endif //NOLAYERS
  1556.     {
  1557.         if (m_SocketData.hSocket == INVALID_SOCKET && m_SocketData.nFamily == AF_UNSPEC)
  1558.             return true;
  1559.  
  1560.         if ( !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent) )
  1561.             return TRUE;
  1562.         else
  1563.             return FALSE;
  1564.     }
  1565.     return TRUE;
  1566. }
  1567.  
  1568. BOOL CAsyncSocketEx::Listen( int nConnectionBacklog /*=5*/ )
  1569. {
  1570. #ifndef NOLAYERS
  1571.     if (m_pFirstLayer)
  1572.         return m_pFirstLayer->Listen(nConnectionBacklog);
  1573. #endif //NOLAYERS
  1574.  
  1575.     if (!listen(m_SocketData.hSocket, nConnectionBacklog))
  1576.     {
  1577. #ifndef NOSOCKETSTATES
  1578.         SetState(listening);
  1579. #endif //NOSOCKETSTATES
  1580.         return TRUE;
  1581.     }
  1582.     else
  1583.         return FALSE;
  1584. }
  1585.  
  1586. BOOL CAsyncSocketEx::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1587. {
  1588.     ASSERT(rConnectedSocket.m_SocketData.hSocket == INVALID_SOCKET);
  1589. #ifndef NOLAYERS
  1590.     if (m_pFirstLayer)
  1591.     {
  1592.         return m_pFirstLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1593.     }
  1594.     else
  1595. #endif //NOLAYERS
  1596.     {
  1597.         SOCKET hTemp = accept(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);
  1598.  
  1599.         if (hTemp == INVALID_SOCKET)
  1600.             return FALSE;
  1601.         VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
  1602.         rConnectedSocket.m_SocketData.hSocket=hTemp;
  1603.         rConnectedSocket.AttachHandle(hTemp);
  1604.         rConnectedSocket.SetFamily(GetFamily());
  1605. #ifndef NOSOCKETSTATES
  1606.         rConnectedSocket.SetState(connected);
  1607. #endif //NOSOCKETSTATES
  1608.     }
  1609.     return TRUE;
  1610. }
  1611.  
  1612. BOOL CAsyncSocketEx::IOCtl( long lCommand, DWORD* lpArgument )
  1613. {
  1614.     return ioctlsocket(m_SocketData.hSocket, lCommand, lpArgument) != SOCKET_ERROR;
  1615. }
  1616.  
  1617. int CAsyncSocketEx::GetLastError()
  1618. {
  1619.     return WSAGetLastError();
  1620. }
  1621.  
  1622. BOOL CAsyncSocketEx::TriggerEvent(long lEvent)
  1623. {
  1624.     if (m_SocketData.hSocket==INVALID_SOCKET)
  1625.         return FALSE;
  1626.  
  1627.     ASSERT(m_pLocalAsyncSocketExThreadData);
  1628.     ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  1629.     ASSERT(m_SocketData.nSocketIndex!=-1);
  1630.  
  1631. #ifndef NOLAYERS
  1632.     if (m_pFirstLayer)
  1633.     {
  1634.         CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = new CAsyncSocketExLayer::t_LayerNotifyMsg;
  1635.         pMsg->hSocket = m_SocketData.hSocket;
  1636.         pMsg->lEvent=lEvent%0xFFFF;
  1637.         pMsg->pLayer=0;
  1638.         BOOL res=PostMessage(GetHelperWindowHandle(), WM_USER, (WPARAM)m_SocketData.nSocketIndex, (LPARAM)pMsg);
  1639.         if (!res)
  1640.             delete pMsg;
  1641.         return res;
  1642.     }
  1643.     else
  1644. #endif //NOLAYERS
  1645.         return PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, lEvent%0xFFFF);
  1646.  
  1647. }
  1648.  
  1649. SOCKET CAsyncSocketEx::GetSocketHandle()
  1650. {
  1651.     return m_SocketData.hSocket;
  1652. }
  1653.  
  1654. HWND CAsyncSocketEx::GetHelperWindowHandle()
  1655. {
  1656.     if (!m_pLocalAsyncSocketExThreadData)
  1657.         return 0;
  1658.     if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1659.         return 0;
  1660.     return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd();
  1661. }
  1662.  
  1663. #ifndef NOLAYERS
  1664. BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer)
  1665. {
  1666.     ASSERT(pLayer);
  1667.  
  1668.     if (m_pFirstLayer)
  1669.     {
  1670.         ASSERT(m_pLastLayer);
  1671.         m_pLastLayer=m_pLastLayer->AddLayer(pLayer, this);
  1672.         return m_pLastLayer?TRUE:FALSE;
  1673.     }
  1674.     else
  1675.     {
  1676.         ASSERT(!m_pLastLayer);
  1677.         pLayer->Init(0, this);
  1678.         m_pFirstLayer=pLayer;
  1679.         m_pLastLayer=m_pFirstLayer;
  1680.         if (m_SocketData.hSocket != INVALID_SOCKET)
  1681.             if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1682.                 return FALSE;
  1683.     }
  1684.  
  1685.     return TRUE;
  1686. }
  1687.  
  1688. void CAsyncSocketEx::RemoveAllLayers()
  1689. {
  1690.     for (std::list<t_callbackMsg>::iterator iter = m_pendingCallbacks.begin(); iter != m_pendingCallbacks.end(); iter++)
  1691.         delete [] iter->str;
  1692.     m_pendingCallbacks.clear();
  1693.  
  1694.     m_pFirstLayer = 0;
  1695.     m_pLastLayer = 0;
  1696. }
  1697.  
  1698. int CAsyncSocketEx::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1699. {
  1700.     for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1701.     {
  1702.         delete [] iter->str;
  1703.     }
  1704.     return 0;
  1705. }
  1706.  
  1707. BOOL CAsyncSocketEx::IsLayerAttached() const
  1708. {
  1709.     return m_pFirstLayer ? TRUE : FALSE;
  1710. }
  1711. #endif //NOLAYERS
  1712.  
  1713. BOOL CAsyncSocketEx::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel /*=SOL_SOCKET*/)
  1714. {
  1715.     return (SOCKET_ERROR != getsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen));
  1716. }
  1717.  
  1718. BOOL CAsyncSocketEx::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel /*=SOL_SOCKET*/)
  1719. {
  1720.     return (SOCKET_ERROR != setsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, nOptionLen));
  1721. }
  1722.  
  1723. #ifndef NOSOCKETSTATES
  1724.  
  1725. int CAsyncSocketEx::GetState() const
  1726. {
  1727.     return m_nState;
  1728. }
  1729.  
  1730. void CAsyncSocketEx::SetState(int nState)
  1731. {
  1732.     m_nState = nState;
  1733. }
  1734.  
  1735. #endif //NOSOCKETSTATES
  1736.  
  1737. int CAsyncSocketEx::GetFamily() const
  1738. {
  1739.     return m_SocketData.nFamily;
  1740. }
  1741.  
  1742. bool CAsyncSocketEx::SetFamily(int nFamily)
  1743. {
  1744.     if (m_SocketData.nFamily != AF_UNSPEC)
  1745.         return false;
  1746.  
  1747.     m_SocketData.nFamily = nFamily;
  1748.     return true;    
  1749. }
  1750.  
  1751. bool CAsyncSocketEx::TryNextProtocol()
  1752. {
  1753.     DetachHandle(m_SocketData.hSocket);
  1754.     closesocket(m_SocketData.hSocket);
  1755.     m_SocketData.hSocket = INVALID_SOCKET;
  1756.  
  1757.     BOOL ret = FALSE;
  1758.     for (; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1759.     {
  1760.         m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1761.  
  1762.         if (m_SocketData.hSocket == INVALID_SOCKET)
  1763.             continue;
  1764.  
  1765.         AttachHandle(m_SocketData.hSocket);
  1766.         m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1767.         if (!AsyncSelect(m_lEvent))
  1768.         {
  1769.             DetachHandle(m_SocketData.hSocket);
  1770.             closesocket(m_SocketData.hSocket);
  1771.             m_SocketData.hSocket = INVALID_SOCKET;
  1772.             continue;
  1773.         }
  1774.  
  1775. #ifndef NOLAYERS
  1776.         if (m_pFirstLayer)
  1777.         {
  1778.             if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1779.             {
  1780.                 DetachHandle(m_SocketData.hSocket);
  1781.                 closesocket(m_SocketData.hSocket);
  1782.                 m_SocketData.hSocket = INVALID_SOCKET;
  1783.                 continue;
  1784.             }
  1785.         }
  1786. #endif //NOLAYERS
  1787.  
  1788.         if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1789.         { 
  1790.             DetachHandle(m_SocketData.hSocket);
  1791.             closesocket(m_SocketData.hSocket);
  1792.             m_SocketData.hSocket = INVALID_SOCKET;
  1793.             continue; 
  1794.         }
  1795.  
  1796.         ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen);
  1797.         if (!ret && GetLastError() != WSAEWOULDBLOCK)
  1798.         {
  1799.             DetachHandle(m_SocketData.hSocket);
  1800.             closesocket(m_SocketData.hSocket);
  1801.             m_SocketData.hSocket = INVALID_SOCKET;
  1802.             continue;
  1803.         }
  1804.  
  1805.         ret = true;
  1806.         break;
  1807.     }
  1808.  
  1809.     if (m_SocketData.nextAddr)
  1810.         m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1811.  
  1812.     if (!m_SocketData.nextAddr)
  1813.     {
  1814.         p_freeaddrinfo(m_SocketData.addrInfo);
  1815.         m_SocketData.nextAddr = 0;
  1816.         m_SocketData.addrInfo = 0;
  1817.     }
  1818.  
  1819.     if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1820.         return FALSE;
  1821.     else
  1822.         return TRUE;
  1823. }
  1824.  
  1825. #ifndef NOLAYERS
  1826.  
  1827. void CAsyncSocketEx::AddCallbackNotification(const t_callbackMsg& msg)
  1828. {
  1829.     m_pendingCallbacks.push_back(msg);
  1830.  
  1831.     if(m_pendingCallbacks.size() == 1)
  1832.         PostMessage(GetHelperWindowHandle(), WM_USER + 2, (WPARAM)m_SocketData.nSocketIndex, 0);
  1833. }
  1834.  
  1835. #endif //NOLAYERS
  1836.  
  1837. void CAsyncSocketEx::ResendCloseNotify()
  1838. {
  1839.     for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1840.     {
  1841.         if (*iter == this)
  1842.             return;
  1843.     }
  1844.     m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this);
  1845.     if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1)
  1846.     {
  1847.         SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, 0);
  1848.     }
  1849. }
  1850.