win_net.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:49k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxtypes.h"
  36. #ifdef _WIN16
  37. #include <stdlib.h>
  38. #endif _WIN16
  39. #include <stdio.h>
  40. #include <string.h>
  41. /* mcast_multiple_if test */
  42. #ifndef _WINCE
  43. #include <iostream.h>
  44. #include <winsock2.h>
  45. #include <ws2tcpip.h>
  46. #endif /* _WINCE */
  47. #include "hxslist.h"
  48. #include "platform/win/sock.h"
  49. #include "platform/win/hxsock.h" //  Low level socket calls
  50. #include "hxthread.h"
  51. #include "hxcom.h"
  52. #include "hxengin.h"
  53. #include "threngin.h"
  54. #include "platform/win/win_net.h"      //  Our declaration
  55. #include "platform/win/casynnet.h"     //  Declaration of async socket notifier
  56. #include "netbyte.h"
  57. #include "hxbuffer.h"
  58. #include "timebuff.h"
  59. #include "hxtick.h"
  60. #include "debugout.h" //  Debug macros
  61. #include "hxstrutl.h"
  62. #include "hxheap.h"
  63. #include "thrdconn.h"
  64. #ifdef _DEBUG
  65. #undef HX_THIS_FILE
  66. static const char HX_THIS_FILE[] = __FILE__;
  67. #endif  
  68. static WinsockManager OnlyOneOfThisInTheWholeProgram;
  69. //#define _LOGSMIL    1
  70. win_net::win_net()       // PostThreadMessage
  71. {
  72.     set_sock( INVALID_SOCKET );
  73.     mLastError     = HXR_OK;
  74.     callRaConnect   = 1;    
  75.     bReadyToWrite   = 0;
  76.     m_SocketState   = CONN_CLOSED;
  77. #ifndef WIN32_PLATFORM_PSPC
  78.     m_hAsyncHandle  = NULL;
  79. #endif
  80.     m_AsyncAddress  = NULL;
  81.     CurrentAddr     = 0;
  82.     m_DNSOnly     = FALSE;
  83.     m_pAsyncHost    = NULL;
  84.     InBlockingMode  = 0;
  85.     m_lRefCount     = 0;
  86.     m_pInBuffer = new char[TCP_BUF_SIZE];
  87.     m_bReuseAddr = FALSE;
  88.     m_bReusePort = FALSE;
  89.     m_bIgnoreWSAECONNRESET = FALSE;
  90. }
  91. win_net::~win_net() 
  92. {
  93. #ifndef WIN32_PLATFORM_PSPC
  94.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , FALSE);
  95.     if (m_AsyncNotifier)
  96.     {
  97. m_AsyncNotifier->CancelSelect( this );
  98.     }
  99. #endif
  100.     m_SocketState = CONN_CLOSING;
  101.     if ((get_sock() != INVALID_SOCKET) && sockObj)       
  102.     {       
  103. if (sockObj->HXclosesocket(get_sock()))
  104. {
  105.     int code = 0;
  106.     code = sockObj->HXWSAGetLastError();
  107. }    
  108.     }
  109.     set_sock( INVALID_SOCKET );
  110.     m_SocketState = CONN_CLOSED;
  111.     mConnectionOpen = 0;
  112.     if (m_AsyncAddress)
  113.     {
  114. delete [] m_AsyncAddress;
  115. m_AsyncAddress = NULL;
  116.     }
  117.     HX_VECTOR_DELETE(m_pAsyncHost);
  118.     delete[] m_pInBuffer;
  119. }
  120. win_net * win_net::new_socket(UINT16 type)
  121. {
  122.     win_net* c = NULL;
  123.     if (sockObj)
  124.     { 
  125. switch(type)
  126. {
  127. case HX_TCP_SOCKET:
  128.     c = new win_TCP;
  129.     break;
  130. case HX_UDP_SOCKET:
  131.     c = new win_UDP;
  132.     break;
  133. }
  134.     }
  135.     return(c);
  136. }
  137. // init_drivers() should do any network driver initialization here
  138. // params is a pointer to a platform specfic defined struct that 
  139. // contains an required initialization data
  140. HX_RESULT win_net::init_drivers(void *params)
  141. {
  142.     if(!sockObj)
  143.       sockObj = new CHXSock;  
  144.     if(!sockObj)
  145.       return(HXR_OUTOFMEMORY);
  146.     return(HXR_OK);
  147. }
  148. /*  close_drivers() should close any network drivers used by the program
  149.   NOTE: The program MUST not make any other calls to the network drivers
  150.   until init_drivers() has been called */
  151. HX_RESULT win_net::close_drivers(void *params)
  152. {
  153.     if(sockObj)
  154.     {
  155. sockObj->HXWSACleanup();
  156. delete sockObj;
  157. sockObj = NULL;
  158.     }  
  159.     return(HXR_OK);
  160. }
  161. HX_RESULT win_net::host_to_ip_str( char *host, char *ip, UINT32 ulIPBufLen)
  162. {
  163.     ULONG32 dwAddress;
  164.     IN_ADDR rInAddress;
  165.     HX_RESULT theErr;
  166.     PHOSTENT pHostEntry;
  167.     theErr = HXR_OK;
  168.     // Let's look for this in the cache first
  169.     if (conn::is_cached( host, &dwAddress))
  170.     {
  171. // Found it, copy the 32bit address into rInAddress w/o calling memcpy()
  172. rInAddress = *(IN_ADDR *)&dwAddress;
  173.     }
  174.     else
  175.     {
  176. // Do DNS on the host name
  177. if (!(pHostEntry = sockObj->HXgethostbyname( host )))
  178. {
  179.     // Error
  180.     theErr = HXR_DNR;
  181. }
  182. // Return w/o attempting any copies if there's an error
  183. if (HXR_OK != theErr)
  184. {
  185.     goto FuncExit;
  186. }
  187. // copy the ip address into rInAddress w/o calling memcpy()
  188. rInAddress = *(IN_ADDR *)(pHostEntry->h_addr);
  189.     }
  190.     // Convert the ULONG32 IP address into a string and copy it into ip
  191.     SafeStrCpy( ip, sockObj->HXinet_ntoa( rInAddress ) , ulIPBufLen);
  192.     // Single exit point
  193. FuncExit:
  194.     return( theErr );
  195. }
  196. ULONG32 win_net::AddRef()
  197. {
  198.     return InterlockedIncrement(&m_lRefCount);
  199. }
  200. ULONG32 win_net::Release()
  201. {
  202.     if (InterlockedDecrement(&m_lRefCount) > 0)
  203.     {
  204.         return m_lRefCount;
  205.     }
  206.     delete this;
  207.     return 0;
  208. }
  209. HX_RESULT win_net::init_win(UINT16 type, UINT32 local_addr, 
  210.     UINT16 port, UINT16 blocking)
  211. {                                        
  212.     int            s;
  213.     s = sockObj->HXsocket(PF_INET, type, 0);
  214.     if (s == INVALID_SOCKET) 
  215.     {
  216. mLastError = HXR_NET_SOCKET_INVALID;
  217. return mLastError;
  218.     }
  219.     InBlockingMode = 1;
  220.      
  221.     {
  222. struct linger Ling;
  223. Ling.l_onoff = 0;
  224. Ling.l_linger = 0;
  225. if (callRaConnect && sockObj->HXsetsockopt(s, SOL_SOCKET, SO_LINGER, 
  226.      (char *)&Ling, sizeof(Ling)) != 0)
  227. {                 
  228.     if(!InBlockingMode)
  229. return HXR_BLOCK_CANCELED;                      
  230.     int code;
  231.     code = sockObj->HXWSAGetLastError(); 
  232.     mLastError = HXR_NET_SOCKET_INVALID;
  233.     InBlockingMode = 0;
  234.     return mLastError;
  235. }
  236.     }
  237.     if(!InBlockingMode)
  238. return HXR_BLOCK_CANCELED;
  239.     
  240.     InBlockingMode = 0;
  241.  
  242.     { 
  243. if (sockObj->HXsetsockopt(s, SOL_SOCKET, SO_REUSEADDR, 
  244.                       (const char *)&m_bReuseAddr, sizeof(m_bReuseAddr)) != 0)
  245. {
  246.         int code;
  247.     code = sockObj->HXWSAGetLastError(); 
  248.     mLastError = HXR_NET_SOCKET_INVALID;
  249.     return mLastError;
  250. }
  251. // Reuse port is not supported on win's right now...
  252. /*
  253. if (sockObj->HXsetsockopt(s, SOL_SOCKET, SO_REUSEPORT, 
  254.                       (const char *)&m_bReusePort, sizeof(m_bReusePort)) != 0)
  255. {
  256.         int code;
  257.     code = sockObj->HXWSAGetLastError(); 
  258.     mLastError = HXR_NET_SOCKET_INVALID;
  259.     return mLastError;
  260. }
  261. */
  262.     }    
  263.     
  264.     struct sockaddr_in SockAddr;
  265.     memset(&SockAddr, 0, sizeof(SockAddr));
  266.     SockAddr.sin_family = AF_INET;
  267.     
  268.     SockAddr.sin_addr.s_addr = sockObj->HXhtonl(local_addr);
  269.     SockAddr.sin_port = sockObj->HXhtons(port);
  270.     if (sockObj->HXbind(s, (sockaddr*)&SockAddr, sizeof(SockAddr)) < 0) 
  271.     {
  272. //perror("bind");
  273. goto err;
  274.     } 
  275.     {
  276. unsigned long lMode = 1;                                                            
  277. if (!blocking && sockObj->HXioctlsocket(s, FIONBIO, &lMode) < 0) 
  278. {
  279.     goto err;
  280. }    
  281.     }
  282.     if (!callRaConnect)
  283.     {
  284. m_SocketState = CONN_OPEN;
  285.     }
  286.     else
  287.     {
  288. m_SocketState = CONN_NO_CONN;
  289.     }
  290.     set_sock( s );
  291.     return HXR_OK;
  292. err:
  293.     sockObj->HXclosesocket(s);
  294.     mLastError = HXR_NET_CONNECT;
  295.     return mLastError;
  296. }
  297. HX_RESULT win_net::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform)
  298. {   
  299.     DEBUGOUTSTR( "win_net::connect()rn" );
  300.     m_hInst = (HINSTANCE)ulPlatform;
  301.     if (!blocking)
  302.     {
  303. #ifndef WIN32_PLATFORM_PSPC
  304. return( ConnectAsync( host, port ) );
  305. #else
  306. HX_ASSERT(0 && "No Async connect");
  307. #endif
  308.     }
  309.     else
  310.     {
  311. bReadyToWrite = 0;
  312. if(!host)                 
  313. {
  314.     mLastError = HXR_DNR;
  315.     return mLastError;
  316. }
  317.     
  318. if(get_sock() < 0)                 
  319. {
  320.     mLastError = HXR_NET_SOCKET_INVALID;
  321.     return mLastError;
  322. }
  323.     
  324. struct in_addr addr;
  325.         char* pTemp = strrchr(host, '.');
  326.         if (pTemp && isdigit(*(pTemp + 1)))
  327. {   /* IP address. */
  328.     InBlockingMode = 1;
  329.     addr.s_addr = sockObj->HXinet_addr(host);
  330.     
  331.     if(!InBlockingMode)
  332. return HXR_BLOCK_CANCELED;
  333.     
  334.     InBlockingMode = 0;
  335.     
  336.     if ((UINT)addr.s_addr == (UINT)-1) 
  337.     {
  338. mLastError = HXR_DNR;
  339. return mLastError;
  340.     }
  341.     m_SocketState = CONN_CONNECT_INPROG;
  342. else
  343. {   /* Host name. */
  344.     InBlockingMode = 1;
  345.     struct hostent *h = sockObj->HXgethostbyname(host);
  346.     
  347.     if(!InBlockingMode)
  348. return HXR_BLOCK_CANCELED;
  349.     InBlockingMode = 0;
  350.     if (!h || !h->h_addr ) 
  351.     {
  352. mLastError = HXR_DNR;
  353. return mLastError;
  354.     }
  355.     memcpy(&addr, h->h_addr, sizeof(struct in_addr)); /* Flawfinder: ignore */
  356.     
  357.     // Rahul
  358.     m_AsyncPort = port;
  359.     if (m_pAsyncHost != host)
  360.     {
  361. HX_VECTOR_DELETE(m_pAsyncHost);
  362. m_pAsyncHost = ::new_string(host);
  363.     }
  364. }                    
  365.     
  366. struct sockaddr_in SockAddr;
  367. memset(&SockAddr, 0, sizeof(SockAddr));
  368. SockAddr.sin_family = AF_INET;
  369. SockAddr.sin_addr.s_addr = *(long*)&addr;
  370. SockAddr.sin_port = sockObj->HXhtons(port);
  371. // this stores info about current addr 
  372. CurrentAddr = *(ULONG32*)&addr;
  373.             
  374. InBlockingMode = 1;                
  375. if(callRaConnect && sockObj->HXconnect(get_sock(), (sockaddr*)&SockAddr, sizeof(SockAddr)))
  376. {   
  377.     if(!InBlockingMode)
  378. return HXR_BLOCK_CANCELED;
  379.     InBlockingMode = 0;
  380.     int code;
  381.     code = sockObj->HXWSAGetLastError(); 
  382.     if(!blocking && (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS))
  383.     {  
  384.        mConnectionOpen = 1;
  385.        return HXR_OK;
  386.     }   
  387.     mLastError = HXR_NET_CONNECT;
  388.     return mLastError;
  389. }       
  390.     
  391. if(!InBlockingMode)
  392.     return HXR_BLOCK_CANCELED;
  393.            
  394. InBlockingMode = 0;
  395.           
  396. mConnectionOpen = 1;
  397. m_SocketState = CONN_OPEN; 
  398. bReadyToWrite = 1;
  399. #ifdef WIN32_PLATFORM_PSPC 
  400. // Without asyncronous notification we cannot tolerate Asyncronous connect
  401. // so set non-blocking here rather than at connect
  402. ULONG lMode = 1;
  403. sockObj->HXioctlsocket(get_sock(), FIONBIO, &lMode);
  404. if (mCallBack)
  405. {
  406.     mCallBack->Func(CONNECT_NOTIFICATION);
  407. }
  408. #endif
  409.   return HXR_OK;
  410.     }
  411. }
  412. //-------------------------------------------------
  413. #if defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  414. HX_RESULT 
  415. win_net::WaitforSelect(void *pE,void *pC)
  416. {
  417.     ThreadEngine *pEngine = (ThreadEngine *)pE;
  418.     ThreadedConn *pProcessConn = (ThreadedConn*) pC;
  419.     if (!pEngine)
  420. return HXR_FAIL;
  421.     CHXMapPtrToPtr::Iterator ndxConn;
  422.     CHXMapPtrToPtr* pSockMap = pEngine->GetSockMap();
  423.     fd_set readfds,exceptfds;
  424.     BOOL bHaveSock = FALSE;
  425.     HX_RESULT theErr = HXR_OK;
  426.     FD_ZERO(&readfds);
  427.     FD_ZERO(&exceptfds);
  428.     
  429.     for (ndxConn = pSockMap->Begin(); 
  430.  ndxConn != pSockMap->End(); ++ndxConn)
  431.     {
  432. ThreadedConn* pConn = (ThreadedConn*) (*ndxConn);
  433. if (pProcessConn &&
  434.     pConn != pProcessConn)
  435.     continue; // dont process other connections while closing
  436. if (!pConn->connection_really_open())
  437.     continue;
  438. if (!pConn->GetActualConn())
  439.     continue;
  440. unsigned int s = pConn->get_sock();
  441. if (s != INVALID_SOCKET)
  442. {
  443.     FD_SET(s,&readfds);
  444.     FD_SET(s,&exceptfds);
  445.     bHaveSock = TRUE;
  446. }
  447.     }
  448.     if (!bHaveSock)
  449. return HXR_FAIL;
  450.     theErr = sockObj->HXselect(NULL,&readfds,NULL,NULL/*&exceptfds*/,NULL);
  451.     if (theErr == SOCKET_ERROR)
  452.     {
  453. theErr = sockObj->HXWSAGetLastError();
  454.     }
  455.     else
  456.     {
  457. theErr = HXR_OK;
  458.     }
  459.     // check for read ready
  460.     for (ndxConn = pSockMap->Begin(); 
  461.  ndxConn != pSockMap->End(); ++ndxConn)
  462.     {
  463. ThreadedConn* pConn = (ThreadedConn*) (*ndxConn);
  464. if (pProcessConn &&
  465.     pConn != pProcessConn)
  466.     continue; // dont process other connections while closing
  467. if (!pConn->GetActualConn())
  468.     continue;
  469. int s = pConn->get_sock();
  470. if (s != INVALID_SOCKET)
  471. {
  472.     if (FD_ISSET(s,&readfds))
  473.        pConn->DoRead(TRUE);
  474. }
  475.      }
  476.     return theErr;
  477. }
  478. HX_RESULT  
  479. win_net::CheckForConnection()
  480. {
  481.     HX_ASSERT(m_SocketState == CONN_LISTENNING);
  482.     if (m_SocketState != CONN_LISTENNING)
  483. return HXR_FAIL;
  484.     sockaddr_in addr;
  485.     int len = sizeof(sockaddr_in);
  486.     memset(&addr, 0, len);
  487.     
  488.     SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);
  489.     if ( sock == INVALID_SOCKET )
  490.     {
  491.   int code = sockObj->HXWSAGetLastError();
  492. // igno all errors...  r
  493.     return HXR_WOULD_BLOCK;
  494.     }
  495.     win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
  496.     c->AddRef();
  497.     conn::add_connection_to_list ( c );
  498.     if ( c )
  499.     {
  500. c->set_sock(sock);
  501. c->connect_accept((ULONG32)m_hInst, addr);
  502. if (mCallBack && (m_SocketState == CONN_LISTENNING))
  503. {
  504.     mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
  505. }
  506.     }
  507.     HX_RELEASE(c);
  508.     return HXR_OK;
  509. }
  510. #endif //defined(HELIX_FEATURE_NETWORK_USE_SELECT)
  511. // This function actually starts an async DNS request
  512. // It does it on either the first read or first write after we
  513. #ifndef WIN32_PLATFORM_PSPC
  514. // call ConnectAsync();
  515. HX_RESULT win_net::DoStartAsyncConn()
  516. {
  517.     DEBUGOUTSTR( "win_net::DoStartAsyncConn()rn" );
  518.     
  519.     if (!m_pAsyncHost)
  520.     {
  521. return (mLastError = HXR_FAILED);
  522.     }
  523.     if (!m_AsyncAddress)
  524.     {
  525. m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
  526.     }
  527.     if (!m_AsyncAddress)
  528.     {
  529. return (mLastError = HXR_OUTOFMEMORY);
  530.     }
  531.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , TRUE);
  532.     m_AsyncNotifier->DoAsyncDNS( this, m_pAsyncHost, m_AsyncAddress, MAXGETHOSTSTRUCT );
  533.     m_SocketState = CONN_DNS_INPROG;
  534.     return( mLastError = HXR_WOULD_BLOCK );
  535. }
  536. // This method get's called by connect() in the case of an async request
  537. // It doesn't however actually start the connection.  It just registers
  538. // that we need to do the connection.  DoStartAsyncConn() will really do it.
  539. HX_RESULT win_net::ConnectAsync( LPCSTR host, UINT16 port )
  540. {
  541.     DEBUGOUTSTR( "win_net::ConnectAsync()rn" );
  542.     bReadyToWrite = 0;
  543.     if (!host)                 
  544.     {
  545. mLastError = HXR_DNR;
  546. return mLastError;
  547.     }
  548.     if (get_sock() == INVALID_SOCKET)
  549.     {
  550. mLastError = HXR_NET_SOCKET_INVALID;
  551. return mLastError;
  552.     }
  553.     struct in_addr addr;  
  554.     char* pTemp = strrchr(host, '.');
  555.     if (pTemp && atoi(pTemp + 1))
  556.     {   /* IP address. */
  557. addr.s_addr = sockObj->HXinet_addr(host);
  558. if ((UINT)addr.s_addr == (UINT)-1) 
  559. {
  560.     mLastError = HXR_DNR;
  561.     return mLastError;
  562. }
  563. else
  564. {
  565.     LPSTR pTemp;
  566.     hostent *pHost;
  567.     if (!m_AsyncAddress)
  568.     {
  569. m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
  570.     }
  571.     if (!m_AsyncAddress)
  572.     {
  573. mLastError = HXR_OUTOFMEMORY;
  574. return (mLastError);
  575.     }
  576.     pHost = (hostent *)m_AsyncAddress;
  577.     // this stores info about current addr 
  578.     CurrentAddr = *(ULONG32 *)&addr;
  579.     m_AsyncPort = port;
  580.     pTemp = (LPSTR)&addr.s_addr;
  581.     pHost->h_addr_list = &pTemp;
  582.     CB_DNSComplete( TRUE );
  583. }
  584.     } 
  585.     else if (conn::is_cached((char *)host,(ULONG32 *) &addr))
  586.     {
  587. LPSTR pTemp;
  588. hostent *pHost;
  589. if (!m_AsyncAddress)
  590. {
  591.     m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
  592. }
  593. if (!m_AsyncAddress)
  594. {
  595.     mLastError = HXR_OUTOFMEMORY;
  596.     return (mLastError);
  597. }
  598. pHost = (hostent *)m_AsyncAddress;
  599. // this stores info about current addr 
  600. CurrentAddr = *(ULONG32 *)&addr;
  601. m_AsyncPort = port;
  602. pTemp = (LPSTR)&addr.s_addr;
  603. pHost->h_addr_list = &pTemp;
  604. CB_DNSComplete( TRUE );
  605.     }
  606.     else
  607.     {
  608. // Save the parameters, and tell ourselves we're starting up
  609. m_AsyncPort = port;
  610. if (m_pAsyncHost != host)
  611. {
  612.     HX_VECTOR_DELETE(m_pAsyncHost);
  613.     m_pAsyncHost = ::new_string(host);
  614. }
  615. m_SocketState = CONN_NO_CONN;
  616. return(DoStartAsyncConn());
  617.     }
  618.     return( HXR_OK );
  619. }
  620. // Once async DNS has commpleted then we'll call this guy to do the
  621. // connection (again asynchronously).
  622. void win_net::ContinueAsyncConnect()
  623. {
  624.     hostent *pHost;
  625.     struct in_addr addr;
  626.     DEBUGOUTSTR( "win_net::ContinueAsyncConnect()rn" );
  627.     pHost = (hostent *)m_AsyncAddress;
  628.     if (!pHost)
  629. return;
  630.     memcpy( &(addr.s_addr), pHost->h_addr, sizeof( addr.s_addr ) ); /* Flawfinder: ignore */
  631.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
  632.     m_AsyncNotifier->DoAsyncSelect( this );
  633.     
  634.     struct sockaddr_in SockAddr;
  635.     memset( &SockAddr, 0, sizeof( SockAddr ) );
  636.     SockAddr.sin_family = AF_INET;
  637.     SockAddr.sin_addr.s_addr = *(long*)&(addr.s_addr);
  638.     SockAddr.sin_port = sockObj->HXhtons( m_AsyncPort );
  639.                 
  640.     if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)&SockAddr, sizeof( SockAddr ) ))
  641.     {   
  642. int code;
  643. code = sockObj->HXWSAGetLastError(); 
  644. if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS)
  645. {  
  646.     m_SocketState = CONN_CONNECT_INPROG;
  647.     mConnectionOpen = 1;
  648.     return;
  649. }   
  650. mLastError = HXR_NET_CONNECT;
  651. m_SocketState = CONN_CONNECT_FAILED;
  652. return;
  653.     }       
  654.     m_SocketState = CONN_CONNECT_INPROG;
  655.               
  656.     mConnectionOpen = 1;
  657.     return;
  658. }
  659. // Called by the notifier to tell us that the DNS request completed
  660. void win_net::CB_DNSComplete( int iSuccess )
  661. {
  662.     DEBUGOUTSTR( "CB_DNSComplete()rn" );
  663.     mDNSDone  = TRUE;
  664.     if (iSuccess && m_pAsyncHost)
  665.     {
  666. conn::add_to_cache(m_pAsyncHost, get_addr());
  667.     }
  668.     if (m_DNSOnly)
  669.     {
  670. if (iSuccess)
  671. {
  672.     mHostIPValid = TRUE;
  673.     mHostIPAddr = get_addr();
  674. }
  675. else
  676. {
  677.     mHostIPValid = FALSE;
  678. }
  679.     }
  680.     else
  681.     {
  682. if (iSuccess)
  683. {
  684.     m_SocketState = CONN_CONNECT_INPROG;
  685.     ContinueAsyncConnect();
  686. }
  687. else
  688. {
  689.     m_SocketState = CONN_DNS_FAILED;
  690. }
  691.     }
  692.     if (mCallBack)  
  693.     {
  694. mCallBack->Func(DNS_NOTIFICATION, iSuccess);
  695.     }
  696. }
  697. // Called by the notifier to tell us that the Connection completed
  698. void win_net::CB_ConnectionComplete( int iSuccess )
  699. {
  700.     DEBUGOUTSTR( "CB_ConnectionComplete()rn" );
  701.     if (iSuccess)
  702.     {
  703. m_SocketState = CONN_OPEN;
  704. if (mCallBack)
  705. {
  706.     mCallBack->Func(CONNECT_NOTIFICATION);
  707. }
  708.     }
  709.     else
  710.     {
  711. m_SocketState = CONN_CONNECT_FAILED;
  712. if (mCallBack)  
  713. {
  714.     mCallBack->Func(CONNECT_NOTIFICATION, FALSE);
  715. }
  716.     }
  717. }
  718. // Called by the notifier when data ready for read/write
  719. void win_net::CB_ReadWriteNotification( int iType )
  720. {
  721. #ifndef _DEMPSEY
  722. // noisy output
  723.     DEBUGOUTSTR( "CB_ReadWriteNotification()....rn" );
  724. #endif // _DEMPSEY
  725.     // Should do something here....
  726.     if (mCallBack && (m_SocketState == CONN_OPEN))
  727.     {
  728. if (iType == FD_WRITE)
  729. {
  730.     mCallBack->Func(WRITE_NOTIFICATION);
  731. }
  732. else if (iType == FD_READ)
  733. {
  734.     mCallBack->Func(READ_NOTIFICATION);
  735. }
  736. //mCallBack->callback_task( HX_UDP_CALLBACK, NULL );
  737.     }
  738. }
  739. void win_net::CB_AcceptNotification()
  740. {
  741.     DEBUGOUTSTR( "CB_AcceptNotification()....rn" );
  742.     HX_ASSERT(m_SocketState == CONN_LISTENNING);
  743.     
  744.     win_net* c = (win_net*)conn::actual_new_socket(HX_TCP_SOCKET);
  745.     c->AddRef();
  746.     conn::add_connection_to_list ( c );
  747.     if ( c )
  748.     {
  749. sockaddr_in addr;
  750. int len = sizeof(addr);
  751. SOCKET sock = sockObj->HXaccept(get_sock(), (sockaddr*)&addr, &len);
  752. if ( sock != INVALID_SOCKET)
  753. {
  754.     c->set_sock(sock);
  755.     c->connect_accept((ULONG32)m_hInst, addr);
  756.     if (mCallBack && (m_SocketState == CONN_LISTENNING))
  757.     {
  758. mCallBack->Func(ACCEPT_NOTIFICATION, TRUE, (conn*)c);
  759.     }
  760. }
  761.     }
  762.     HX_RELEASE(c);
  763. }
  764. void win_net::CB_CloseNotification()
  765. {
  766.     DEBUGOUTSTR( "CB_CloseNotification()....rn" );
  767.     m_SocketState = CONN_CLOSED;
  768.     if (mCallBack)
  769.     {
  770. mCallBack->Func(CLOSE_NOTIFICATION);
  771.     }
  772. }
  773. #endif
  774. HX_RESULT win_net::connect( sockaddr_in *addr )
  775. {
  776.     if(callRaConnect && sockObj->HXconnect( get_sock(), (sockaddr*)addr, sizeof( addr ) ))
  777.     {
  778. mLastError = HXR_NET_CONNECT;
  779. return mLastError;
  780.     }                   
  781.     
  782.     mConnectionOpen = 1;
  783.     return HXR_OK;     
  784. }
  785. HX_RESULT win_net::write(void * buf, UINT16  *len) 
  786. {
  787.     int got;
  788.     DEBUGOUTSTR( "win_net::write()rn" );
  789.     if (get_sock() == INVALID_SOCKET) 
  790.     {
  791. // Not connected
  792. return( mLastError = HXR_NET_SOCKET_INVALID );
  793.     }
  794.     if (m_SocketState != CONN_OPEN ) //&& m_SocketState != CONN_DNS_INPROG)
  795.     {
  796. // We won't be able to write anything here, so clear this
  797. // we'll return why we didn't write anything.
  798. *len = 0;
  799. switch( m_SocketState )
  800. {
  801. case CONN_DNS_INPROG:
  802. case CONN_CONNECT_INPROG:
  803. case CONN_CLOSING:
  804. return( mLastError = HXR_WOULD_BLOCK );
  805. case CONN_CLOSED:
  806. return( mLastError = HXR_NET_SOCKET_INVALID );
  807. case CONN_NO_CONN:
  808. #ifndef WIN32_PLATFORM_PSPC
  809. return( DoStartAsyncConn() );
  810. #else
  811.         HX_ASSERT(0 && "No Async net");
  812.         return( HXR_NET_READ );
  813. #endif
  814. case CONN_DNS_FAILED:
  815. return( mLastError = HXR_DNR );
  816. case CONN_CONNECT_FAILED:
  817. return( mLastError = HXR_NET_CONNECT );
  818. default:
  819. // HUH???
  820. assert( 0 );
  821. return( mLastError = HXR_NET_READ );
  822. };
  823.     }
  824.     else
  825.     {
  826. got = sockObj->HXsend( get_sock(), (char *)buf, *len, 0 );
  827. if (got == -1)
  828. {
  829.     int code;
  830.     *len = 0;
  831.     code = sockObj->HXWSAGetLastError();
  832.     // Mask the "so what?" errors
  833.     if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS) 
  834.     {
  835. return HXR_WOULD_BLOCK;
  836.     }
  837.     else
  838.     {
  839. mLastError = HXR_NET_WRITE;
  840. return mLastError;
  841.     }
  842. }
  843. //#if defined(_DEBUG) && defined(_LOGSMIL)
  844. // if (::HXDebugOptionEnabled("zLogSMIL"))
  845. //{FILE* f1 = ::fopen("e:\temp\foo.txt", "a+"); ::fwrite(buf, got, 1, f1);::fclose(f1);}
  846. //#endif
  847. *len = got;
  848. return HXR_OK;
  849.     }
  850. }
  851. HX_RESULT win_net::writeto(void * buf, UINT16  *len, ULONG32 addr, UINT16 port) 
  852. {
  853.     //sendto
  854.     int got;
  855.     sockaddr_in resend_addr;
  856.     
  857.     ::memset( &resend_addr, 0, sizeof( resend_addr ) );
  858.     resend_addr.sin_family = AF_INET;
  859.     resend_addr.sin_addr.s_addr = addr;
  860.     resend_addr.sin_port = sockObj->HXhtons(port);
  861.     got = sockObj->HXsendto(get_sock(), (char *) buf, *len, 0, (sockaddr *)&resend_addr, sizeof (resend_addr)); 
  862.     if (got == -1)
  863.     {
  864. int code;
  865. *len = 0;
  866. code = sockObj->HXWSAGetLastError();
  867. // Mask the "so what?" errors
  868. if (code == WSAEWOULDBLOCK || code == WSAEINPROGRESS) 
  869. {
  870.     return HXR_WOULD_BLOCK;
  871. }
  872. else
  873. {
  874.     mLastError = HXR_NET_WRITE;
  875.     return mLastError;
  876. }
  877.     }
  878.     *len = got;
  879.     return HXR_OK;
  880. }
  881. HX_RESULT win_net::WriteComplete   (char * Buffer, int length)
  882. {
  883.     int sent = 0;
  884.     unsigned short cur_sent=0;
  885.     while(sent < length)
  886.     {
  887. cur_sent = length - sent;
  888. HX_RESULT ret = write(Buffer + sent, &cur_sent);
  889. if(ret != HXR_OK && ret != HXR_WOULD_BLOCK)
  890.     break;
  891. sent += cur_sent;
  892.     }
  893. // m_SocketState = CONN_NO_CONN;
  894.     if(sent < length)
  895.     {
  896. mLastError = HXR_NET_WRITE;
  897. return mLastError;
  898.     }
  899.     return HXR_OK;
  900. }
  901. int win_net::ReadyToWrite()
  902. {
  903.     if(get_sock() < 0)
  904.     {
  905. bReadyToWrite = 0;
  906. return bReadyToWrite;
  907.     }
  908.     if(bReadyToWrite)
  909. return 1;
  910.     
  911.     fd_set writefds;
  912.     FD_ZERO(&writefds);
  913.     FD_SET((UINT32)get_sock(), &writefds);
  914.     
  915.     TIMEVAL timeout;
  916.     timeout.tv_sec = 1;
  917.     timeout.tv_usec = 0;
  918.     if(sockObj->HXselect(0, NULL, &writefds,NULL, &timeout) == 1)
  919. bReadyToWrite = 1;
  920.     
  921.     return bReadyToWrite;        
  922. }
  923. void win_net::done (void)
  924. {
  925. #ifndef WIN32_PLATFORM_PSPC
  926.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , FALSE);
  927.     if (m_AsyncNotifier)
  928.     {
  929. m_AsyncNotifier->CancelSelect( this );
  930.     }
  931. #endif
  932.     m_SocketState = CONN_CLOSING;
  933.     if ((get_sock() != INVALID_SOCKET) && sockObj)
  934.     {       
  935. if (sockObj->HXclosesocket(get_sock()))
  936. {
  937.     int code = 0;
  938.     code = sockObj->HXWSAGetLastError();
  939. }    
  940.     }
  941.     set_sock( INVALID_SOCKET );
  942.     m_SocketState = CONN_CLOSED;
  943.     mConnectionOpen = 0;
  944. }
  945. inline HX_RESULT win_net::listen(ULONG32 ulLocalAddr, UINT16 port, 
  946.  UINT16 backlog, UINT16 blocking,
  947.  ULONG32 ulPlatform)
  948. {
  949.     m_hInst = (HINSTANCE)ulPlatform;
  950. // accept is polled
  951. #ifndef WIN32_PLATFORM_PSPC
  952.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier(m_hInst ,TRUE);
  953.     m_AsyncNotifier->DoAsyncSelect((win_net*)this );
  954. #endif
  955.     HX_RESULT ret = sockObj->HXlisten(get_sock(), backlog);
  956.     if ( SUCCEEDED(ret) )
  957.     {
  958. m_SocketState = CONN_LISTENNING;
  959. ret = HXR_OK;
  960.     }
  961.     else
  962.     {
  963. ret = HXR_NET_SOCKET_INVALID;
  964.     }
  965.     return ret;
  966. }
  967. inline HX_RESULT win_net::blocking (void)
  968. {
  969.     unsigned long nonblocking = 0;
  970.     return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking); 
  971. }
  972. inline HX_RESULT win_net::nonblocking (void) 
  973. {
  974.     unsigned long nonblocking = 1;
  975.     return sockObj->HXioctlsocket(get_sock(), FIONBIO, &nonblocking); 
  976. }
  977. HX_RESULT win_net::connect_accept(ULONG32 ulPlatform, sockaddr_in addr)
  978. {
  979.     m_hInst = (HINSTANCE)ulPlatform;
  980.     
  981.     CurrentAddr = addr.sin_addr.s_addr;
  982.     // set up the new connection so it will use its own notifier. 
  983.     // now we want to add this so it will recieve messages.
  984. #ifndef WIN32_PLATFORM_PSPC
  985.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst, TRUE);
  986.     m_AsyncNotifier->DoAsyncSelect(this);
  987. #endif
  988.     m_SocketState = CONN_OPEN;
  989.     mConnectionOpen = 1;
  990.     return HXR_OK;
  991. }
  992. CHXMapPtrToPtr win_net::zm_MapObjectsToWinsockTasks;
  993. CHXMapPtrToPtr win_net::zm_WinsockTasksRefCounts;
  994. int win_net::zm_LibRefCount = 0;
  995. BOOL win_net::IsWinsockAvailable(void* pObject)
  996. {
  997.     BOOL bWinSockInitedForTask = FALSE;
  998.     // First check to see that the drivers are loaded...
  999.     //
  1000.     // NOTE: this doesn't include initializing Winsock for 
  1001.     // the object's task...
  1002.     if(!OnlyOneOfThisInTheWholeProgram.IsInitialized())
  1003.     {
  1004. OnlyOneOfThisInTheWholeProgram.Initialize();
  1005.     }
  1006.     if(OnlyOneOfThisInTheWholeProgram.IsInitialized())
  1007.     {
  1008. zm_LibRefCount++;
  1009.     
  1010.     // Make sure Winsock is initialized for the object's task...
  1011. // get current task.
  1012. #if defined( WIN32 )
  1013. void* ulTask = (void*)GetCurrentProcessId();
  1014. #else
  1015. void* ulTask = (void*)GetCurrentTask();
  1016. #endif
  1017. // add map of object (http or session) to task
  1018. zm_MapObjectsToWinsockTasks[pObject] = ulTask;
  1019. // bump up ref count for task
  1020. void* pVoid;
  1021. ULONG32 TaskRefCount = 0;
  1022. if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
  1023. {
  1024. TaskRefCount = (ULONG32)pVoid;
  1025. }
  1026. TaskRefCount++;
  1027. bWinSockInitedForTask = TRUE;
  1028. HX_ASSERT_VALID_PTR(sockObj);
  1029. zm_WinsockTasksRefCounts[ulTask] = (void*)TaskRefCount;
  1030.     }
  1031.     return bWinSockInitedForTask;
  1032. }
  1033. BOOL win_net::ReleaseWinsockUsage(void* pObject)
  1034. {
  1035.     // Only do any of this if we've first called IsWinsockAvailable()
  1036.     if (zm_LibRefCount > 0)
  1037.     {
  1038. // get previous task from map of object (http or session) to task
  1039. void* ulTask;
  1040. if (zm_MapObjectsToWinsockTasks.Lookup(pObject,ulTask))
  1041. {
  1042.     zm_MapObjectsToWinsockTasks.RemoveKey(pObject);
  1043.     // bump up ref count for task
  1044.     void* pVoid;
  1045.     ULONG32 TaskRefCount = 0;
  1046.     if (zm_WinsockTasksRefCounts.Lookup(ulTask,pVoid))
  1047.     {
  1048. TaskRefCount = (ULONG32)pVoid;
  1049.     }
  1050.     TaskRefCount--;
  1051.     // if 0 then call WSACleanup
  1052.     if (TaskRefCount == 0)
  1053.     {
  1054. zm_WinsockTasksRefCounts.RemoveKey(ulTask);
  1055.     }
  1056. }
  1057. // Decerement total ref count
  1058. zm_LibRefCount--;
  1059.     }
  1060.     return TRUE;
  1061. }
  1062. HX_RESULT win_net::read(void * buf, UINT16 *len) 
  1063. {
  1064.     int  got;
  1065.     static int breakpoint = 0;
  1066.     assert( buf );
  1067.     assert( len );
  1068. // This DEBUGOUTSTR is noisy.
  1069. #ifndef _DEMPSEY
  1070.     DEBUGOUTSTR( "win_net::read()rn" );
  1071. #endif // !_DEMPSEY
  1072.     if (get_sock() == INVALID_SOCKET || !callRaConnect) 
  1073.     {
  1074. // Not connected
  1075. return( mLastError = HXR_NET_SOCKET_INVALID );
  1076.     }
  1077.     // Is the TCP socket actually connected yet?
  1078.     /* We want to read data even if we have received CloseNotification. 
  1079.      * This is because some unread data may be still be in the pipe
  1080.      * - RA 10/01/1997
  1081.      */
  1082.     if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
  1083.     {
  1084. // No
  1085. // We won't be able to write anything here, so clear this
  1086. // we'll return why we didn't write anything.
  1087. *len = 0;
  1088. switch( m_SocketState )
  1089. {
  1090. case CONN_DNS_INPROG:
  1091. case CONN_CONNECT_INPROG:
  1092. case CONN_CLOSING:
  1093. return( mLastError = HXR_WOULD_BLOCK );
  1094. case CONN_CLOSED:
  1095. return( mLastError = HXR_NET_SOCKET_INVALID );
  1096. case CONN_NO_CONN:
  1097. #ifndef WIN32_PLATFORM_PSPC
  1098. return( DoStartAsyncConn() );
  1099. #else
  1100.         HX_ASSERT(0 && "No Async net");
  1101.         return( HXR_NET_READ );
  1102. #endif
  1103. case CONN_DNS_FAILED:
  1104. return( mLastError = HXR_DNR );
  1105. case CONN_CONNECT_FAILED:
  1106. return( mLastError = HXR_NET_CONNECT );
  1107. default:
  1108. // HUH???
  1109. HX_ASSERT (FALSE);
  1110. return( mLastError = HXR_NET_READ );
  1111. };
  1112.     }
  1113.     else
  1114.     {
  1115. // Now we can actually do the read
  1116. if (callRaConnect)
  1117. {
  1118.     got = sockObj->HXrecv( get_sock(), (char *)buf, *len, 0 );
  1119. }
  1120. else
  1121. {
  1122.     int  fromlen;
  1123.     struct sockaddr  from;
  1124.     fromlen = sizeof( from );
  1125.     got = sockObj->HXrecvfrom( get_sock(), (char *)buf, *len, 0, &from, &fromlen );
  1126.     if (got > 0) breakpoint++;
  1127. }
  1128. // Did we get an error?
  1129. if (got == SOCKET_ERROR) 
  1130. {   
  1131.     *len = 0;
  1132.     if (m_SocketState == CONN_CLOSED)
  1133.     {
  1134. return( mLastError = HXR_NET_SOCKET_INVALID );
  1135.     }
  1136.     int code;
  1137.     code = sockObj->HXWSAGetLastError();
  1138.     // Translate the error
  1139.     switch (code)
  1140.     {
  1141.     case WSAEWOULDBLOCK:
  1142.     case WSAEINPROGRESS:
  1143.     return( mLastError = HXR_WOULD_BLOCK );
  1144.     case WSAEFAULT:
  1145.     case WSAENOTCONN:
  1146.     case WSAENOTSOCK:
  1147.     return( mLastError = HXR_NET_SOCKET_INVALID );
  1148.     case WSAENETDOWN:
  1149.     return( mLastError = HXR_GENERAL_NONET );
  1150.     case WSAEINTR:
  1151.     return( mLastError = HXR_BLOCK_CANCELED );
  1152.     case WSAEMSGSIZE:
  1153.     return( mLastError = HXR_MSG_TOOLARGE);
  1154.     case WSAETIMEDOUT:
  1155.     case WSAESHUTDOWN:
  1156.     case WSAECONNABORTED:
  1157.     return( mLastError = HXR_SERVER_DISCONNECTED );
  1158.     case WSAECONNRESET:
  1159. /*
  1160.  * WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
  1161.  * workaround
  1162.  */
  1163. if (!m_bIgnoreWSAECONNRESET)
  1164. {
  1165.     return( mLastError = HXR_SERVER_DISCONNECTED );
  1166. }
  1167. else
  1168. {
  1169.     return( mLastError = HXR_WOULD_BLOCK );
  1170. }
  1171.     default:
  1172.     return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
  1173.     }
  1174.     // Shouldn't really get here
  1175.     return( mLastError );
  1176. }
  1177. else if (got == 0 && *len != 0)
  1178. {
  1179.     *len = 0;
  1180.     if (m_SocketState == CONN_CLOSED)
  1181.     {
  1182. return( mLastError = HXR_NET_SOCKET_INVALID );
  1183.     }
  1184.     else
  1185.     {
  1186. return( mLastError = HXR_SERVER_DISCONNECTED );
  1187.     }
  1188. }
  1189. else
  1190. {
  1191.     // This should be our exit point for successful read
  1192.     *len = got;
  1193.     return( HXR_OK );
  1194. }
  1195.     }
  1196. }
  1197. HX_RESULT
  1198. win_net::readfrom (REF(IHXBuffer*) pBuffer,
  1199.    REF(UINT32)     ulAddress,
  1200.    REF(UINT16)     ulPort)
  1201. {
  1202.     int  got = 0;
  1203.     UINT16 size = 0;
  1204. #ifndef _DEMPSEY
  1205.     DEBUGOUTSTR( "win_net::readfrom()rn" );
  1206. #endif // !_DEMPSEY
  1207.     pBuffer = NULL;
  1208.     ulAddress = 0;
  1209.     ulPort = 0;
  1210.     if (get_sock() == INVALID_SOCKET || callRaConnect) 
  1211.     {
  1212. // Not connected
  1213. return( mLastError = HXR_NET_SOCKET_INVALID );
  1214.     }
  1215.     /* We want to read data even if we have received CloseNotification. 
  1216.      * This is because some unread data may be still be in the pipe
  1217.      * - RA 10/01/1997
  1218.      */
  1219.     if (m_SocketState != CONN_OPEN && m_SocketState != CONN_CLOSED)
  1220.     {
  1221. // No
  1222. // We won't be able to write anything here, so clear this
  1223. // we'll return why we didn't write anything.
  1224. switch( m_SocketState )
  1225. {
  1226. case CONN_DNS_INPROG:
  1227. case CONN_CONNECT_INPROG:
  1228. case CONN_CLOSING:
  1229. return( mLastError = HXR_WOULD_BLOCK );
  1230. case CONN_CLOSED:
  1231. return( mLastError = HXR_NET_SOCKET_INVALID );
  1232. case CONN_NO_CONN:
  1233. #ifndef WIN32_PLATFORM_PSPC
  1234. return( DoStartAsyncConn() );
  1235. #else
  1236.         HX_ASSERT(0 && "No Async net");
  1237.         return( HXR_NET_READ );
  1238. #endif
  1239. case CONN_DNS_FAILED:
  1240. return( mLastError = HXR_DNR );
  1241. case CONN_CONNECT_FAILED:
  1242. return( mLastError = HXR_NET_CONNECT );
  1243. default:
  1244. // HUH???
  1245. HX_ASSERT (FALSE);
  1246. return( mLastError = HXR_NET_READ );
  1247. };
  1248.     }
  1249.     else
  1250.     {
  1251. int  fromlen;
  1252. struct sockaddr_in  from;
  1253.     
  1254. fromlen = sizeof( from );
  1255. got = sockObj->HXrecvfrom( get_sock(), m_pInBuffer, TCP_BUF_SIZE, 0, (struct sockaddr*)&from, &fromlen );
  1256. // Did we get an error?
  1257. if (got == SOCKET_ERROR) 
  1258. {   
  1259.     if (m_SocketState == CONN_CLOSED)
  1260.     {
  1261. return( mLastError = HXR_NET_SOCKET_INVALID );
  1262.     }
  1263.     int code;
  1264.     code = sockObj->HXWSAGetLastError();
  1265.     // Translate the error
  1266.     switch (code)
  1267.     {
  1268.     case WSAEWOULDBLOCK:
  1269.     case WSAEINPROGRESS:
  1270.     return( mLastError = HXR_WOULD_BLOCK );
  1271.     case WSAEFAULT:
  1272.     case WSAENOTCONN:
  1273.     case WSAENOTSOCK:
  1274.     return( mLastError = HXR_NET_SOCKET_INVALID );
  1275.     case WSAENETDOWN:
  1276.     return( mLastError = HXR_GENERAL_NONET );
  1277.     case WSAEINTR:
  1278.     return( mLastError = HXR_BLOCK_CANCELED );
  1279.     case WSAEMSGSIZE:
  1280.     return( mLastError = HXR_MSG_TOOLARGE);
  1281.     case WSAETIMEDOUT:
  1282.     case WSAESHUTDOWN:
  1283.     case WSAECONNABORTED:
  1284.     return( mLastError = HXR_SERVER_DISCONNECTED );
  1285.     case WSAECONNRESET:
  1286. /*
  1287.  * WinSock Recvfrom() Now Returns WSAECONNRESET Instead of Blocking or Timing Out (Q263823)
  1288.  * workaround
  1289.  */
  1290. if (!m_bIgnoreWSAECONNRESET)
  1291. {
  1292.     return( mLastError = HXR_SERVER_DISCONNECTED );
  1293. }
  1294. else
  1295. {
  1296.     return( mLastError = HXR_WOULD_BLOCK );
  1297. }
  1298.     
  1299.     default:
  1300.     return( mLastError = HXR_NET_READ );   // Error we don't know what to do about
  1301.     }
  1302.     // Shouldn't really get here
  1303.     return( mLastError );
  1304. }
  1305. else if (got == 0)
  1306. {
  1307.     if (m_SocketState == CONN_CLOSED)
  1308.     {
  1309. return( mLastError = HXR_NET_SOCKET_INVALID );
  1310.     }
  1311.     else
  1312.     {
  1313. return( mLastError = HXR_SERVER_DISCONNECTED );
  1314.     }
  1315. }
  1316. else
  1317. {
  1318.     // This should be our exit point for successful read
  1319.     CHXTimeStampedBuffer* pTimeBuffer = new CHXTimeStampedBuffer;
  1320.     pTimeBuffer->AddRef();
  1321.     pTimeBuffer->SetTimeStamp(HX_GET_TICKCOUNT());
  1322.     pTimeBuffer->Set((UCHAR*)m_pInBuffer, got);
  1323.     pBuffer = (IHXBuffer*) pTimeBuffer;
  1324.     ulAddress = DwToHost(from.sin_addr.s_addr);
  1325.     ulPort = WToHost(from.sin_port);
  1326.     
  1327.     return( HXR_OK );
  1328. }
  1329.     }
  1330. }
  1331.     
  1332. ULONG32 win_net::get_addr()
  1333. {
  1334.     hostent *pHost = (hostent *)m_AsyncAddress;
  1335.     ULONG32 addr = 0;
  1336.     
  1337.     // if CurrentAddr is set, we must have passed
  1338.     // a dotted IP address...
  1339.     if (CurrentAddr)
  1340.     {
  1341. addr = CurrentAddr;
  1342.     }
  1343.     else if (pHost)
  1344.     {
  1345. addr = (ULONG32) (*(ULONG32*)pHost->h_addr);
  1346.     }
  1347.     return addr;
  1348. }
  1349. UINT16 win_net::get_local_port()
  1350. {
  1351.     sockaddr_in addr;
  1352.     int addr_len = sizeof addr;
  1353.     memset(&addr, 0, HX_SAFESIZE_T(addr_len));
  1354.     int ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);
  1355.  
  1356.     return (ret < 0) ? -1: WToHost(addr.sin_port);
  1357. }
  1358. // we need it for dns_find_ip_addr since async stuff needs a window handle...
  1359. HX_RESULT win_net::SetWindowHandle(ULONG32 handle) 
  1360. {
  1361.     m_hInst = (HINSTANCE)handle; 
  1362.     return HXR_OK;
  1363. }
  1364. HX_RESULT win_net::dns_find_ip_addr(const char * host, UINT16 blocking)
  1365. {
  1366.     if(!host)                 
  1367.     {
  1368. mLastError = HXR_DNR;
  1369. return mLastError;
  1370.     }
  1371.     if(get_sock() < 0)                 
  1372.     {
  1373. mLastError = HXR_NET_SOCKET_INVALID;
  1374. return mLastError;
  1375.     }
  1376.     if (conn::is_cached((char *) host, &mHostIPAddr))
  1377.     {
  1378. mHostIPValid = TRUE;
  1379. mDNSDone = TRUE;
  1380. mLastError = HXR_OK;
  1381. if (mCallBack)  
  1382. {
  1383.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  1384. }
  1385. return mLastError;
  1386.     }
  1387.     char* pTemp = strrchr(host, '.');
  1388.     if (pTemp && atoi(pTemp + 1))
  1389.     {   /* IP address. */
  1390. struct in_addr addr;  
  1391. mHostIPValid = FALSE;
  1392. mHostIPAddr = 0;
  1393. mDNSDone = TRUE;
  1394. addr.s_addr = sockObj->HXinet_addr(host);
  1395. if ((UINT)addr.s_addr == (UINT)-1) 
  1396. {
  1397.     mLastError = HXR_DNR;
  1398.     return mLastError;
  1399. }
  1400. mHostIPValid = TRUE;
  1401. mHostIPAddr = *(ULONG32 *) &addr;
  1402. conn::add_to_cache((char *) host, mHostIPAddr);
  1403. if (mCallBack)  
  1404. {
  1405.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  1406. }
  1407. return HXR_OK;
  1408.     } 
  1409.     if (blocking)
  1410.     {
  1411. struct in_addr addr;  
  1412.             
  1413. mHostIPValid = FALSE;
  1414. mHostIPAddr = 0;
  1415. mDNSDone = TRUE;
  1416. struct hostent *h = sockObj->HXgethostbyname(host);
  1417. if (!h || !h->h_addr ) 
  1418. {
  1419.     mLastError = HXR_DNR;
  1420.     return mLastError;
  1421. }
  1422. memcpy(&addr, h->h_addr, sizeof(struct in_addr)); /* Flawfinder: ignore */
  1423. mHostIPValid = TRUE;
  1424. mHostIPAddr = *(ULONG32 *) &addr;
  1425. conn::add_to_cache((char *) host, mHostIPAddr);
  1426. if (mCallBack)  
  1427. {
  1428.     mCallBack->Func(DNS_NOTIFICATION, TRUE);
  1429. }
  1430. return( mLastError = HXR_OK);
  1431.     }
  1432.     else
  1433.     {
  1434. if (m_pAsyncHost != host)
  1435. {
  1436.     // Save the parameters, and tell ourselves we're starting up
  1437.     HX_VECTOR_DELETE(m_pAsyncHost);
  1438.     m_pAsyncHost = ::new_string(host);
  1439. }
  1440. if (!m_AsyncAddress)
  1441. {
  1442.     m_AsyncAddress = new char[MAXGETHOSTSTRUCT];
  1443. }
  1444. if (!m_AsyncAddress)
  1445. {
  1446.     return (mLastError = HXR_OUTOFMEMORY);
  1447. }
  1448. // set the boolean variable that we are only doing async DNs and
  1449. // do not intend to connect
  1450. #ifndef WIN32_PLATFORM_PSPC
  1451. m_DNSOnly   = TRUE;
  1452. m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst , TRUE);
  1453. m_AsyncNotifier->DoAsyncDNS( this, m_pAsyncHost, m_AsyncAddress, MAXGETHOSTSTRUCT );
  1454. m_SocketState = CONN_DNS_INPROG;
  1455. #else 
  1456. m_DNSOnly   = FALSE;
  1457. #endif
  1458. return( mLastError = HXR_WOULD_BLOCK );
  1459.     }
  1460. }
  1461. BOOL win_net::dns_ip_addr_found(BOOL * valid, ULONG32 *addr)
  1462. {
  1463.     if (mDNSDone)
  1464.     {
  1465. // reset DNS only flag...
  1466. m_DNSOnly   = FALSE;
  1467. *valid = mHostIPValid;
  1468. *addr  = mHostIPAddr;
  1469. return TRUE;
  1470.     }
  1471.     else
  1472. return FALSE;
  1473. }
  1474. BOOL win_net::set_receive_buf_size(int DesiredSize)
  1475. {
  1476.     int s = get_sock();
  1477.     if (s == INVALID_SOCKET) 
  1478.     {
  1479. mLastError = HXR_NET_SOCKET_INVALID;
  1480. return FALSE;
  1481.     }
  1482.     int RcvBufSize = 0;
  1483.     int iSize = sizeof(RcvBufSize);
  1484.     if (sockObj->HXgetsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&RcvBufSize, 
  1485.       &iSize))
  1486.     {
  1487. RcvBufSize = 0;
  1488.     }
  1489.     if (RcvBufSize < DesiredSize)
  1490.     {
  1491. RcvBufSize = DesiredSize;
  1492. if(sockObj->HXsetsockopt(s, SOL_SOCKET, SO_RCVBUF, 
  1493. (char *)&RcvBufSize, sizeof(RcvBufSize)))
  1494. {
  1495.     int code;
  1496.     code = sockObj->HXWSAGetLastError(); 
  1497.     return FALSE;
  1498. }
  1499.     }
  1500.     return TRUE;
  1501. }
  1502. /*
  1503. *   reuse_addr/reuse_port has to be called before a sock binds.  however, 
  1504. *   socket is not available until it binds as it is implemented.  So, set a 
  1505. *   flag here and do the actual setsockopt right before a sock binds.
  1506. *   Look in init_win().
  1507. */
  1508. HX_RESULT
  1509. win_net::reuse_addr(BOOL enable)
  1510. {
  1511.     m_bReuseAddr = enable;
  1512.     return HXR_OK;
  1513. }
  1514. HX_RESULT
  1515. win_net::reuse_port(BOOL enable)
  1516. {
  1517.     m_bReusePort = enable;
  1518.     return HXR_OK;
  1519. }
  1520. HX_RESULT
  1521. win_net::get_host_name(char* name, int namelen)
  1522. {
  1523.     HX_ASSERT(sockObj);
  1524.     
  1525.     if (sockObj->HXgethostname(name, namelen) != 0)
  1526.     {
  1527. return HXR_FAILED;
  1528.     }
  1529.     else
  1530.     {
  1531. return HXR_OK;
  1532.     }   
  1533. }
  1534. HX_RESULT
  1535. win_net::get_host_by_name(char* name, REF(struct hostent*) h)
  1536. {
  1537.     HX_ASSERT(sockObj);
  1538.     
  1539.     h = sockObj->HXgethostbyname(name);
  1540.     if (!h || !h->h_addr_list)
  1541.     {
  1542. return HXR_DNR;
  1543.     }
  1544.     else
  1545.     {
  1546. return HXR_OK;
  1547.     }
  1548. }
  1549. HX_RESULT win_UDP::set_broadcast(BOOL enable)
  1550. {
  1551. int ret;
  1552. SOCKET s = get_sock();
  1553. if(s == INVALID_SOCKET)
  1554. {
  1555. return( mLastError = HXR_NET_SOCKET_INVALID );
  1556. }
  1557. ret = sockObj->HXsetsockopt( s, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof(UINT32) );
  1558. if(ret == -1)
  1559. ret = HXR_BIND;
  1560. return ret;
  1561. }
  1562. HX_RESULT 
  1563. win_UDP::set_send_size(UINT32 send_size)
  1564. {
  1565.     int s = get_sock();
  1566.     int ret = 0;
  1567. again:
  1568.     ret = sockObj->HXsetsockopt(s, SOL_SOCKET, SO_SNDBUF,
  1569.      (char*)&send_size, sizeof(INT32));
  1570.     if (ret < 0 && send_size > 8192)
  1571.     {
  1572. send_size >>= 1;
  1573.         goto again;
  1574.     }
  1575.     return ret;
  1576. }
  1577. HX_RESULT win_UDP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
  1578. {
  1579.     HX_RESULT ret;
  1580.     if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
  1581.     {                
  1582. if(ret == HXR_BLOCK_CANCELED)
  1583.     return ret;
  1584.   
  1585. mLastError = HXR_NET_CONNECT;
  1586. return mLastError;
  1587.     }
  1588.     return win_net::connect(host, port, blocking, ulPlatform );
  1589. }
  1590. HX_RESULT win_UDP::SetWindowHandle(ULONG32 handle)
  1591. {
  1592.     m_hInst = (HINSTANCE)handle;
  1593. #ifndef WIN32_PLATFORM_PSPC
  1594.     m_AsyncNotifier = CAsyncSockN::GetCAsyncSockNotifier( m_hInst ,TRUE);
  1595.     m_AsyncNotifier->DoAsyncSelect( this );
  1596. #endif
  1597.     return HXR_OK;
  1598. }
  1599. HX_RESULT win_UDP::connect(sockaddr_in * addr, UINT16 blocking) 
  1600. {                
  1601.     HX_RESULT ret;
  1602.     if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
  1603.     { 
  1604. if(ret == HXR_BLOCK_CANCELED)
  1605.     return ret;                                          
  1606.   
  1607. mLastError = HXR_NET_CONNECT;
  1608. return mLastError;
  1609.     }
  1610.     return win_net::connect(addr);
  1611. }                                  
  1612. HX_RESULT win_TCP::connect(const char* host, UINT16 port, UINT16 blocking, ULONG32 ulPlatform ) 
  1613. {   
  1614.     HX_RESULT ret;
  1615.     if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
  1616.     {    
  1617. if(ret == HXR_BLOCK_CANCELED)
  1618.     return ret;                                          
  1619.       
  1620. mLastError = HXR_NET_CONNECT;
  1621. return mLastError;
  1622.     }
  1623.     return win_net::connect(host, port, blocking, ulPlatform );
  1624. }
  1625. HX_RESULT win_TCP::connect(sockaddr_in * addr, UINT16 blocking) 
  1626. {
  1627.     HX_RESULT ret;
  1628.     if (get_sock() < 0 && (ret = init(INADDR_ANY, 0, blocking)) != HXR_OK)
  1629.     { 
  1630. if(ret == HXR_BLOCK_CANCELED)
  1631.     return ret;                                          
  1632.   
  1633. mLastError = HXR_NET_CONNECT;
  1634. return mLastError;
  1635.     }
  1636.     return win_net::connect(addr);
  1637. }
  1638. inline HX_RESULT win_UDP::listen(ULONG32 ulLocalAddr, UINT16 port, 
  1639.  UINT16 backlog, UINT16 blocking,
  1640.  ULONG32 ulPlatform)
  1641. {
  1642.     return HXR_INVALID_OPERATION;
  1643. }
  1644. inline HX_RESULT win_TCP::listen(ULONG32 ulLocalAddr, UINT16 port, 
  1645.  UINT16 backlog, UINT16 blocking,
  1646.  ULONG32 ulPlatform)
  1647. {
  1648.     HX_RESULT ret = HXR_NET_SOCKET_INVALID;
  1649.     if ( get_sock() < 0 )
  1650.     {
  1651. if ( ulLocalAddr == HX_INADDR_ANY )
  1652.     ret = init(INADDR_ANY, port, blocking);
  1653. else
  1654.     ret = init(ulLocalAddr, port, blocking);
  1655.     }
  1656.     if ( FAILED(ret) )
  1657.     {
  1658. if(ret == HXR_BLOCK_CANCELED)
  1659.     return ret;
  1660. mLastError = HXR_NET_SOCKET_INVALID;
  1661. return mLastError;
  1662.     }
  1663.     return win_net::listen(ulLocalAddr, port, backlog, blocking, ulPlatform);
  1664. }
  1665. HX_RESULT
  1666. win_UDP::set_multicast()
  1667. {
  1668. #ifdef NO_MULTICAST
  1669.     return HXR_MULTICAST_UDP;
  1670. #else
  1671.     INT32          ret;
  1672.     sockaddr_in addr;
  1673.     int addr_len = sizeof addr;
  1674.     if (get_sock() == INVALID_SOCKET) 
  1675.     {
  1676.         // Not connected
  1677.         return( mLastError = HXR_NET_SOCKET_INVALID );
  1678.     }
  1679.     memset(&addr, 0, HX_SAFESIZE_T(addr_len));
  1680.     ret = sockObj->HXgetsockname(get_sock(), (sockaddr*)&addr, &addr_len);
  1681.     if (ret < 0)
  1682.     {
  1683.         return HXR_MULTICAST_UDP;
  1684.     }
  1685.     ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_IF,
  1686.                        (char*) &addr.sin_addr.s_addr,
  1687.                        sizeof (addr.sin_addr.s_addr));
  1688.     if (ret < 0)
  1689.     {
  1690. return HXR_MULTICAST_UDP;
  1691.     }
  1692.     return HXR_OK;
  1693. #endif /* NO_MULTICAST */
  1694. }
  1695. HX_RESULT
  1696. win_UDP::set_multicast_ttl(unsigned char ttl)
  1697. {
  1698. #ifdef NO_MULTICAST
  1699.     return HXR_MULTICAST_UDP;
  1700. #else
  1701.     if (get_sock() == INVALID_SOCKET) 
  1702.     {
  1703.         // Not connected
  1704.         return( mLastError = HXR_NET_SOCKET_INVALID );
  1705.     }
  1706.     
  1707.     INT32         ret;
  1708.     INT32         ttl_proxy = ttl;
  1709.     ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_MULTICAST_TTL,
  1710.                        (char*) &ttl_proxy, sizeof (ttl_proxy));
  1711.     if (ret < 0)
  1712.     {
  1713.         return HXR_MULTICAST_UDP;
  1714.     }
  1715.     return HXR_OK;
  1716. #endif /* ! NO_MULTICAST */
  1717. }
  1718. HX_RESULT win_UDP::join_multicast_group(ULONG32 addr, ULONG32 if_addr)
  1719. {
  1720.     int ret;
  1721.     ip_mreq multicast_group;
  1722.     if (get_sock() == INVALID_SOCKET) 
  1723.     {
  1724. // Not connected
  1725. return( mLastError = HXR_NET_SOCKET_INVALID );
  1726.     }
  1727.     
  1728.     multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
  1729.     multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
  1730.     
  1731.     ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
  1732.     if (ret == -1)
  1733.     {
  1734. int err;
  1735. err = sockObj->HXWSAGetLastError();
  1736. return HXR_MULTICAST_JOIN;
  1737.     }
  1738.     return HXR_OK;
  1739. }
  1740. HX_RESULT win_UDP::leave_multicast_group(ULONG32 addr, ULONG32 if_addr)
  1741. {
  1742.     int ret;
  1743.     ip_mreq multicast_group;
  1744.     if (get_sock() == INVALID_SOCKET) 
  1745.     {
  1746. // Not connected
  1747. return( mLastError = HXR_NET_SOCKET_INVALID );
  1748.     }
  1749.     multicast_group.imr_multiaddr.s_addr = sockObj->HXhtonl(addr);
  1750. // multicast_group.imr_multiaddr.s_addr = sockObj->HXinet_addr("226.0.0.8");
  1751.     multicast_group.imr_interface.s_addr = sockObj->HXhtonl(if_addr);
  1752.     
  1753.     ret = sockObj->HXsetsockopt(get_sock(), IPPROTO_IP, IP_DROP_MEMBERSHIP, (char*)&multicast_group , sizeof (multicast_group) );
  1754.     if (ret == -1)
  1755.     {
  1756. return HXR_GENERAL_MULTICAST;
  1757.     }
  1758.     return HXR_OK;
  1759. }
  1760. HX_RESULT 
  1761. win_UDP::set_multicast_if(ULONG32 ulInterface)
  1762. {
  1763.     int ret;
  1764.     int s = get_sock();
  1765.     if(s == INVALID_SOCKET)
  1766.     {
  1767. return( mLastError = HXR_NET_SOCKET_INVALID );
  1768.     }
  1769.     unsigned long addr = sockObj->HXhtonl(ulInterface);    
  1770.     ret = sockObj->HXsetsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, 
  1771. (char*)&addr, sizeof(addr));
  1772.     if(ret == -1)
  1773. ret = HXR_GENERAL_MULTICAST;
  1774.     return ret;
  1775. }
  1776. HX_RESULT
  1777. win_UDP::GetFromInfo(ULONG32& ulAddr, UINT16& nPort)
  1778. {
  1779.     return HXR_OK;
  1780. }
  1781. WinsockManager::WinsockManager()
  1782. {
  1783.     bInitialized = FALSE;
  1784.     Initialize();
  1785. }
  1786. WinsockManager::~WinsockManager()
  1787. {
  1788.     conn::close_drivers(NULL);
  1789.     bInitialized = FALSE;
  1790. }
  1791. void
  1792. WinsockManager::Initialize()
  1793. {
  1794.     bInitialized = FALSE;
  1795.     HX_ASSERT(!sockObj);
  1796.     if(!sockObj)
  1797. sockObj = new CHXSock;  
  1798.     if(conn::init_drivers(NULL) != HXR_OK)
  1799.     return;
  1800.     if(sockObj && sockObj->WinSockAvail() && sockObj->InitWinsock())
  1801.     {
  1802. bInitialized = TRUE;
  1803.     }
  1804.     UINT8 nWinSockVersion = sockObj->HXGetVersion();
  1805.     /*
  1806.      * Check to see what platform we are on
  1807.      */
  1808.     OSVERSIONINFO winver;
  1809.     winver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  1810. #ifndef WIN32_PLATFORM_PSPC
  1811.     if(GetVersionEx(&winver))
  1812.     {
  1813. if(nWinSockVersion == 2 &&
  1814.    winver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS &&
  1815.    winver.dwMinorVersion == 0)
  1816. {
  1817.     /*
  1818.      * Async lookup in Win 95 with WinSock2.0 installed returns the same handle for
  1819.      * multiple requests. If there are multiple outstanding requests, there is
  1820.      * no way to map the handle in the response to the outstansing request since
  1821.      * all replies get mapped to one request. NT 4.0 returns different handles so
  1822.      * name resolution works fine.
  1823.      *
  1824.      * We workaround this by queueing up the DNS requests.
  1825.      */
  1826.     sockGlobals.m_bWinSock2Suck = TRUE;
  1827. }
  1828.     }
  1829. #endif
  1830. }
  1831. BOOL    
  1832. WinsockManager::IsInitialized()
  1833. {
  1834.     return bInitialized && sockObj;
  1835. }