home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / SOCKCORE.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-04  |  31.2 KB  |  1,363 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12. #include <stddef.h>
  13.  
  14. #ifdef AFX_SOCK_SEG
  15. #pragma code_seg(AFX_SOCK_SEG)
  16. #endif
  17.  
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. #define new DEBUG_NEW
  24.  
  25. #define _afxSockThreadState AfxGetModuleThreadState()
  26. #define _AFX_SOCK_THREAD_STATE AFX_MODULE_THREAD_STATE
  27.  
  28. #ifdef _AFXDLL
  29.  
  30. inline HINSTANCE AfxLoadSock(FARPROC* proc, LPCSTR lpsz)
  31. #ifndef _MAC
  32.     { return AfxLoadDll(&_afxSockState->m_hInstSOCK, "WSOCK32.DLL", proc, lpsz); }
  33. #elif defined(_DEBUG)
  34.     { return AfxLoadDll(&_afxSockState->m_hInstSOCK, "DebugMicrosoftSocketsLib", proc, lpsz); }
  35. #else
  36.     { return AfxLoadDll(&_afxSockState->m_hInstSOCK, "MicrosoftSocketsLib", proc, lpsz); }
  37. #endif
  38.  
  39. #define SOCKLOAD(x) \
  40.     AfxLoadSock((FARPROC*)&_afxSOCK.pfn##x, #x);
  41.  
  42. SOCKET PASCAL AfxThunkaccept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen)
  43. {
  44.     SOCKLOAD(accept);
  45.     return _afxSOCK.pfnaccept(s, addr, addrlen);
  46. }
  47.  
  48. u_short PASCAL AfxThunkhtons(u_short hostshort)
  49. {
  50.     SOCKLOAD(htons);
  51.     return _afxSOCK.pfnhtons(hostshort);
  52. }
  53.  
  54. unsigned long PASCAL AfxThunkinet_addr(const char FAR * cp)
  55. {
  56.     SOCKLOAD(inet_addr);
  57.     return _afxSOCK.pfninet_addr(cp);
  58. }
  59.  
  60. int PASCAL AfxThunkclosesocket(SOCKET s)
  61. {
  62.     SOCKLOAD(closesocket);
  63.     return _afxSOCK.pfnclosesocket(s);
  64. }
  65.  
  66. int PASCAL AfxThunkgetsockname(SOCKET s, struct sockaddr FAR *name, int FAR * namelen)
  67. {
  68.     SOCKLOAD(getsockname);
  69.     return _afxSOCK.pfngetsockname(s, name, namelen);
  70. }
  71.  
  72. int PASCAL AfxThunkgetpeername(SOCKET s, struct sockaddr FAR *name, int FAR * namelen)
  73. {
  74.     SOCKLOAD(getpeername);
  75.     return _afxSOCK.pfngetpeername(s, name, namelen);
  76. }
  77.  
  78. u_short PASCAL AfxThunkntohs(u_short netshort)
  79. {
  80.     SOCKLOAD(ntohs);
  81.     return _afxSOCK.pfnntohs(netshort);
  82. }
  83.  
  84. char* PASCAL AfxThunkinet_ntoa(struct in_addr in)
  85. {
  86.     SOCKLOAD(inet_ntoa);
  87.     return _afxSOCK.pfninet_ntoa(in);
  88. }
  89.  
  90. int PASCAL AfxThunkWSAGetLastError(void)
  91. {
  92.     SOCKLOAD(WSAGetLastError);
  93.     return _afxSOCK.pfnWSAGetLastError();
  94. }
  95.  
  96. void PASCAL AfxThunkWSASetLastError(int iError)
  97. {
  98.     SOCKLOAD(WSASetLastError);
  99.     _afxSOCK.pfnWSASetLastError(iError);
  100. }
  101.  
  102. int PASCAL AfxThunkWSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData)
  103. {
  104.     SOCKLOAD(WSAStartup);
  105.     return _afxSOCK.pfnWSAStartup(wVersionRequired, lpWSAData);
  106. }
  107.  
  108. int PASCAL AfxThunkWSACleanup(void)
  109. {
  110.     SOCKLOAD(WSACleanup);
  111.     return _afxSOCK.pfnWSACleanup();
  112. }
  113.  
  114. u_long PASCAL AfxThunkhtonl(u_long hostlong)
  115. {
  116.     SOCKLOAD(htonl);
  117.     return _afxSOCK.pfnhtonl(hostlong);
  118. }
  119.  
  120. SOCKET PASCAL AfxThunksocket(int af, int type, int protocol)
  121. {
  122.     SOCKLOAD(socket);
  123.     return _afxSOCK.pfnsocket(af, type, protocol);
  124. }
  125.  
  126. struct hostent* PASCAL AfxThunkgethostbyname(const char FAR * name)
  127. {
  128.     SOCKLOAD(gethostbyname);
  129.     return _afxSOCK.pfngethostbyname(name);
  130. }
  131.  
  132. int PASCAL AfxThunkrecv(SOCKET s, char FAR * buf, int len, int flags)
  133. {
  134.     SOCKLOAD(recv);
  135.     return _afxSOCK.pfnrecv(s, buf, len, flags);
  136. }
  137.  
  138. int PASCAL AfxThunksend(SOCKET s, const char FAR * buf, int len, int flags)
  139. {
  140.     SOCKLOAD(send);
  141.     return _afxSOCK.pfnsend(s, buf, len, flags);
  142. }
  143.  
  144. int PASCAL AfxThunkWSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent)
  145. {
  146.     SOCKLOAD(WSAAsyncSelect);
  147.     return _afxSOCK.pfnWSAAsyncSelect(s, hWnd, wMsg, lEvent);
  148. }
  149.  
  150. int PASCAL AfxThunkrecvfrom(SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR *from, int FAR * fromlen)
  151. {
  152.     SOCKLOAD(recvfrom);
  153.     return _afxSOCK.pfnrecvfrom(s, buf, len, flags, from, fromlen);
  154. }
  155.  
  156. int PASCAL AfxThunksendto(SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen)
  157. {
  158.     SOCKLOAD(sendto);
  159.     return _afxSOCK.pfnsendto(s, buf, len, flags, to, tolen);
  160. }
  161.  
  162. int PASCAL AfxThunkconnect(SOCKET s, const struct sockaddr FAR *name, int namelen)
  163. {
  164.     SOCKLOAD(connect);
  165.     return _afxSOCK.pfnconnect(s, name, namelen);
  166. }
  167.  
  168. int PASCAL AfxThunkbind(SOCKET s, const struct sockaddr FAR *addr, int namelen)
  169. {
  170.     SOCKLOAD(bind);
  171.     return _afxSOCK.pfnbind(s, addr, namelen);
  172. }
  173.  
  174. int PASCAL AfxThunksetsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen)
  175. {
  176.     SOCKLOAD(setsockopt);
  177.     return _afxSOCK.pfnsetsockopt(s, level, optname, optval, optlen);
  178. }
  179.  
  180. int PASCAL AfxThunkgetsockopt(SOCKET s, int level, int optname, char FAR * optval, int FAR *optlen)
  181. {
  182.     SOCKLOAD(getsockopt);
  183.     return _afxSOCK.pfngetsockopt(s, level, optname, optval, optlen);
  184. }
  185.  
  186. int PASCAL AfxThunkioctlsocket(SOCKET s, long cmd, u_long FAR *argp)
  187. {
  188.     SOCKLOAD(ioctlsocket);
  189.     return _afxSOCK.pfnioctlsocket(s, cmd, argp);
  190. }
  191.  
  192. int PASCAL AfxThunklisten(SOCKET s, int backlog)
  193. {
  194.     SOCKLOAD(listen);
  195.     return _afxSOCK.pfnlisten(s, backlog);
  196. }
  197.  
  198. int PASCAL AfxThunkshutdown(SOCKET s, int how)
  199. {
  200.     SOCKLOAD(shutdown);
  201.     return _afxSOCK.pfnshutdown(s, how);
  202. }
  203.  
  204. AFX_DATADEF AFX_SOCK_CALL _afxSOCK =
  205. {
  206.     AfxThunkaccept,
  207.     AfxThunkhtons,
  208.     AfxThunkinet_addr,
  209.     AfxThunkclosesocket,
  210.     AfxThunkgetsockname,
  211.     AfxThunkgetpeername,
  212.     AfxThunkntohs,
  213.     AfxThunkinet_ntoa,
  214.     AfxThunkWSAGetLastError,
  215.     AfxThunkWSASetLastError,
  216.     AfxThunkWSAStartup,
  217.     AfxThunkWSACleanup,
  218.     AfxThunkhtonl,
  219.     AfxThunksocket,
  220.     AfxThunkgethostbyname,
  221.     AfxThunkrecv,
  222.     AfxThunksend,
  223.     AfxThunkWSAAsyncSelect,
  224.     AfxThunkrecvfrom,
  225.     AfxThunksendto,
  226.     AfxThunkconnect,
  227.     AfxThunkbind,
  228.     AfxThunksetsockopt,
  229.     AfxThunkgetsockopt,
  230.     AfxThunkioctlsocket,
  231.     AfxThunklisten,
  232.     AfxThunkshutdown,
  233. };
  234.  
  235. #endif
  236.  
  237. _AFX_SOCK_STATE::~_AFX_SOCK_STATE()
  238. {
  239.     if (m_pfnSockTerm != NULL)
  240.         m_pfnSockTerm();
  241. }
  242.  
  243. /////////////////////////////////////////////////////////////////////////////
  244. // sockets globals and implementation helpers
  245.  
  246. void AFXAPI AfxSocketTerm()
  247. {
  248.     _AFX_SOCK_STATE* pState = _afxSockState.GetData();
  249.     if (pState->m_hInstSOCK != NULL)
  250.     {
  251.         if (pState->m_pfnSockTerm != NULL)
  252.             WSACleanup();
  253.         FreeLibrary(pState->m_hInstSOCK);// handle of WSOCK32.DLL
  254.         pState->m_hInstSOCK = NULL;
  255.     }
  256. }
  257.  
  258. BOOL AFXAPI AfxSocketInit(WSADATA* lpwsaData)
  259. {
  260.     _AFX_SOCK_STATE* pState = _afxSockState.GetData();
  261.     if (pState->m_pfnSockTerm == NULL)
  262.     {
  263.         WSADATA wsaData;
  264.         if (lpwsaData == NULL)
  265.             lpwsaData = &wsaData;
  266.  
  267.         WORD wVersionRequested = MAKEWORD(1, 1);
  268.         int nResult = WSAStartup(wVersionRequested, lpwsaData);
  269.         if (nResult != 0)
  270.             return FALSE;
  271.  
  272.         if (LOBYTE(lpwsaData->wVersion) != 1 || HIBYTE(lpwsaData->wVersion) != 1)
  273.         {
  274.             WSACleanup();
  275.             return FALSE;
  276.         }
  277.         pState->m_pfnSockTerm = &AfxSocketTerm;
  278.     }
  279.  
  280.     return TRUE;
  281. }
  282.  
  283. /////////////////////////////////////////////////////////////////////////////
  284. // CAsyncSocket Construction
  285.  
  286. CAsyncSocket::CAsyncSocket()
  287. {
  288.     m_hSocket = INVALID_SOCKET;
  289. }
  290.  
  291. BOOL CAsyncSocket::Create(UINT nSocketPort, int nSocketType,
  292.     long lEvent, LPCTSTR lpszSocketAddress)
  293. {
  294.     if (Socket(nSocketType, lEvent))
  295.     {
  296.         if (Bind(nSocketPort,lpszSocketAddress))
  297.             return TRUE;
  298.         int nResult = GetLastError();
  299.         Close();
  300.         WSASetLastError(nResult);
  301.     }
  302.     return FALSE;
  303. }
  304.  
  305. /////////////////////////////////////////////////////////////////////////////
  306. // CAsyncSocket Attributes
  307.  
  308. BOOL CAsyncSocket::Attach(SOCKET hSocket, long lEvent)
  309. {
  310.     ASSERT(hSocket != INVALID_SOCKET);
  311.  
  312.     m_hSocket = hSocket;
  313.     CAsyncSocket::AttachHandle(hSocket, this);
  314.  
  315.     return AsyncSelect(lEvent);
  316. }
  317.  
  318. SOCKET CAsyncSocket::Detach()
  319. {
  320.     SOCKET hSocket = m_hSocket;
  321.     if (AsyncSelect(0))
  322.     {
  323.         CAsyncSocket::KillSocket(hSocket, this);
  324.         m_hSocket = INVALID_SOCKET;
  325.         return hSocket;
  326.     }
  327.     return INVALID_SOCKET;
  328. }
  329.  
  330. BOOL CAsyncSocket::GetPeerName(CString& rPeerAddress, UINT& rPeerPort)
  331. {
  332.     SOCKADDR_IN sockAddr;
  333.     memset(&sockAddr, 0, sizeof(sockAddr));
  334.  
  335.     int nSockAddrLen = sizeof(sockAddr);
  336.     BOOL bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  337.     if (bResult)
  338.     {
  339.         rPeerPort = ntohs(sockAddr.sin_port);
  340.         rPeerAddress = inet_ntoa(sockAddr.sin_addr);
  341.     }
  342.     return bResult;
  343. }
  344.  
  345. BOOL CAsyncSocket::GetSockName(CString& rSocketAddress, UINT& rSocketPort)
  346. {
  347.     SOCKADDR_IN sockAddr;
  348.     memset(&sockAddr, 0, sizeof(sockAddr));
  349.  
  350.     int nSockAddrLen = sizeof(sockAddr);
  351.     BOOL bResult = GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
  352.     if (bResult)
  353.     {
  354.         rSocketPort = ntohs(sockAddr.sin_port);
  355.         rSocketAddress = inet_ntoa(sockAddr.sin_addr);
  356.     }
  357.     return bResult;
  358. }
  359.  
  360. /////////////////////////////////////////////////////////////////////////////
  361. // CAscynSocket Operations
  362.  
  363. BOOL CAsyncSocket::Accept(CAsyncSocket& rConnectedSocket,
  364.     SOCKADDR* lpSockAddr, int* lpSockAddrLen)
  365. {
  366.     ASSERT(rConnectedSocket.m_hSocket == INVALID_SOCKET);
  367.     ASSERT(CAsyncSocket::FromHandle(INVALID_SOCKET) == NULL);
  368.  
  369.     CAsyncSocket::AttachHandle(INVALID_SOCKET, &rConnectedSocket);
  370.  
  371.     SOCKET hTemp = accept(m_hSocket, lpSockAddr, lpSockAddrLen);
  372.  
  373.     if (hTemp == INVALID_SOCKET)
  374.     {
  375.         DWORD dwProblem = GetLastError();
  376.         CAsyncSocket::DetachHandle(rConnectedSocket.m_hSocket, FALSE);
  377.         rConnectedSocket.m_hSocket = INVALID_SOCKET;
  378.         SetLastError(dwProblem);
  379.     }
  380.     else if (CAsyncSocket::FromHandle(INVALID_SOCKET) != NULL)
  381.     {
  382.         rConnectedSocket.m_hSocket = hTemp;
  383.         CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
  384.         CAsyncSocket::AttachHandle(hTemp, &rConnectedSocket);
  385.     }
  386.  
  387.     return (hTemp != INVALID_SOCKET);
  388. }
  389.  
  390. BOOL CAsyncSocket::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
  391. {
  392.     USES_CONVERSION;
  393.  
  394.     SOCKADDR_IN sockAddr;
  395.     memset(&sockAddr,0,sizeof(sockAddr));
  396.  
  397.     LPSTR lpszAscii = T2A((LPTSTR)lpszSocketAddress);
  398.     sockAddr.sin_family = AF_INET;
  399.  
  400.     if (lpszAscii == NULL)
  401.         sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
  402.     else
  403.     {
  404.         DWORD lResult = inet_addr(lpszAscii);
  405.         if (lResult == INADDR_NONE)
  406.         {
  407.             WSASetLastError(WSAEINVAL);
  408.             return FALSE;
  409.         }
  410.         sockAddr.sin_addr.s_addr = lResult;
  411.     }
  412.  
  413.     sockAddr.sin_port = htons((u_short)nSocketPort);
  414.  
  415.     return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  416. }
  417.  
  418. void CAsyncSocket::Close()
  419. {
  420.     if (m_hSocket != INVALID_SOCKET)
  421.     {
  422.         VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
  423.         CAsyncSocket::KillSocket(m_hSocket, this);
  424.         m_hSocket = INVALID_SOCKET;
  425.     }
  426. }
  427.  
  428. BOOL CAsyncSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  429. {
  430.     USES_CONVERSION;
  431.  
  432.     ASSERT(lpszHostAddress != NULL);
  433.  
  434.     SOCKADDR_IN sockAddr;
  435.     memset(&sockAddr,0,sizeof(sockAddr));
  436.  
  437.     LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  438.     sockAddr.sin_family = AF_INET;
  439.     sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  440.  
  441.     if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  442.     {
  443.         LPHOSTENT lphost;
  444.         lphost = gethostbyname(lpszAscii);
  445.         if (lphost != NULL)
  446.             sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  447.         else
  448.         {
  449.             WSASetLastError(WSAEINVAL);
  450.             return FALSE;
  451.         }
  452.     }
  453.  
  454.     sockAddr.sin_port = htons((u_short)nHostPort);
  455.  
  456.     return Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  457. }
  458.  
  459. int CAsyncSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
  460. {
  461.     return recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  462. }
  463.  
  464. int CAsyncSocket::ReceiveFrom(void* lpBuf, int nBufLen, CString& rSocketAddress, UINT& rSocketPort, int nFlags)
  465. {
  466.     SOCKADDR_IN sockAddr;
  467.  
  468.     memset(&sockAddr, 0, sizeof(sockAddr));
  469.  
  470.     int nSockAddrLen = sizeof(sockAddr);
  471.     int nResult = ReceiveFrom(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
  472.     if(nResult != SOCKET_ERROR)
  473.     {
  474.         rSocketPort = ntohs(sockAddr.sin_port);
  475.         rSocketAddress = inet_ntoa(sockAddr.sin_addr);
  476.     }
  477.     return nResult;
  478. }
  479.  
  480. int CAsyncSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
  481. {
  482.     return send(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  483. }
  484.  
  485. int CAsyncSocket::SendTo(const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress, int nFlags)
  486. {
  487.     USES_CONVERSION;
  488.  
  489.     SOCKADDR_IN sockAddr;
  490.  
  491.     memset(&sockAddr,0,sizeof(sockAddr));
  492.  
  493.     LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  494.     sockAddr.sin_family = AF_INET;
  495.  
  496.     if (lpszAscii == NULL)
  497.         sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  498.     else
  499.     {
  500.         sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  501.         if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  502.         {
  503.             LPHOSTENT lphost;
  504.             lphost = gethostbyname(lpszAscii);
  505.             if (lphost != NULL)
  506.                 sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  507.             else
  508.             {
  509.                 WSASetLastError(WSAEINVAL);
  510.                 return FALSE;
  511.             }
  512.         }
  513.     }
  514.  
  515.     sockAddr.sin_port = htons((u_short)nHostPort);
  516.  
  517.     return SendTo(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, sizeof(sockAddr), nFlags);
  518. }
  519.  
  520. BOOL CAsyncSocket::AsyncSelect(long lEvent)
  521. {
  522.     ASSERT(m_hSocket != INVALID_SOCKET);
  523.  
  524.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  525.     ASSERT(pState->m_hSocketWindow != NULL);
  526.  
  527.     return WSAAsyncSelect(m_hSocket, pState->m_hSocketWindow,
  528.         WM_SOCKET_NOTIFY, lEvent) != SOCKET_ERROR;
  529. }
  530.  
  531. /////////////////////////////////////////////////////////////////////////////
  532. // CAsyncSocket Overridable callbacks
  533.  
  534. void CAsyncSocket::OnReceive(int /*nErrorCode*/)
  535. {
  536. }
  537.  
  538. void CAsyncSocket::OnSend(int /*nErrorCode*/)
  539. {
  540. }
  541.  
  542. void CAsyncSocket::OnOutOfBandData(int /*nErrorCode*/)
  543. {
  544. }
  545.  
  546. void CAsyncSocket::OnAccept(int /*nErrorCode*/)
  547. {
  548. }
  549.  
  550. void CAsyncSocket::OnConnect(int /*nErrorCode*/)
  551. {
  552. }
  553.  
  554. void CAsyncSocket::OnClose(int /*nErrorCode*/)
  555. {
  556. }
  557.  
  558. /////////////////////////////////////////////////////////////////////////////
  559. // CAsyncSocket Implementation
  560.  
  561. CAsyncSocket::~CAsyncSocket()
  562. {
  563.     if (m_hSocket != INVALID_SOCKET)
  564.         Close();
  565. }
  566.  
  567. CAsyncSocket* PASCAL CAsyncSocket::LookupHandle(SOCKET hSocket, BOOL bDead)
  568. {
  569.     CAsyncSocket* pSocket;
  570.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  571.     if (!bDead)
  572.     {
  573.         pSocket = (CAsyncSocket*)
  574.             pState->m_mapSocketHandle.GetValueAt((void*)hSocket);
  575.         if (pSocket != NULL)
  576.             return pSocket;
  577.     }
  578.     else
  579.     {
  580.         pSocket = (CAsyncSocket*)
  581.             pState->m_mapDeadSockets.GetValueAt((void*)hSocket);
  582.         if (pSocket != NULL)
  583.             return pSocket;
  584.     }
  585.     return NULL;
  586. }
  587.  
  588. void PASCAL CAsyncSocket::AttachHandle(
  589.     SOCKET hSocket, CAsyncSocket* pSocket, BOOL bDead)
  590. {
  591.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  592.  
  593.     BOOL bEnable = AfxEnableMemoryTracking(FALSE);
  594.     if (!bDead)
  595.     {
  596.         ASSERT(CAsyncSocket::LookupHandle(hSocket, bDead) == NULL);
  597.         if (pState->m_mapSocketHandle.IsEmpty())
  598.         {
  599.             ASSERT(pState->m_mapDeadSockets.IsEmpty());
  600.             ASSERT(pState->m_hSocketWindow == NULL);
  601.  
  602.             CSocketWnd* pWnd = new CSocketWnd;
  603.             pWnd->m_hWnd = NULL;
  604.             if (!pWnd->CreateEx(0, AfxRegisterWndClass(0),
  605.                 _T("Socket Notification Sink"),
  606.                 WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL))
  607.             {
  608.                 TRACE0("Warning: unable to create socket notify window!\n");
  609.                 AfxThrowResourceException();
  610.             }
  611.             ASSERT(pWnd->m_hWnd != NULL);
  612.             ASSERT(CWnd::FromHandlePermanent(pWnd->m_hWnd) == pWnd);
  613.             pState->m_hSocketWindow = pWnd->m_hWnd;
  614.         }
  615.         pState->m_mapSocketHandle.SetAt((void*)hSocket, pSocket);
  616.     }
  617.     else
  618.     {
  619.         int nCount;
  620.         if (pState->m_mapDeadSockets.Lookup((void*)hSocket, (void*&)nCount))
  621.             nCount++;
  622.         else
  623.             nCount = 1;
  624.         pState->m_mapDeadSockets.SetAt((void*)hSocket, (void*)nCount);
  625.     }
  626.     AfxEnableMemoryTracking(bEnable);
  627. }
  628.  
  629. void PASCAL CAsyncSocket::DetachHandle(SOCKET hSocket, BOOL bDead)
  630. {
  631.     ASSERT(CAsyncSocket::LookupHandle(hSocket, bDead) != NULL);
  632.  
  633.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  634.     if (!bDead)
  635.     {
  636.         pState->m_mapSocketHandle.RemoveKey((void*)hSocket);
  637.         if (pState->m_mapSocketHandle.IsEmpty())
  638.         {
  639.             ASSERT(pState->m_hSocketWindow != NULL);
  640.             CWnd* pWnd =
  641.                 CWnd::FromHandlePermanent(pState->m_hSocketWindow);
  642.             ASSERT_VALID(pWnd);
  643.  
  644.             pWnd->DestroyWindow();
  645.             delete pWnd;
  646.  
  647.             pState->m_hSocketWindow = NULL;
  648.  
  649.             pState->m_mapDeadSockets.RemoveAll();
  650.  
  651.             while (!pState->m_listSocketNotifications.IsEmpty())
  652.                 delete pState->m_listSocketNotifications.RemoveHead();
  653.         }
  654.     }
  655.     else
  656.     {
  657.         int nCount;
  658.         if (pState->m_mapDeadSockets.Lookup((void*)hSocket, (void*&)nCount))
  659.         {
  660.             nCount--;
  661.             if (nCount == 0)
  662.                 pState->m_mapDeadSockets.RemoveKey((void*)hSocket);
  663.             else
  664.                 pState->m_mapDeadSockets.SetAt((void*)hSocket, (void*)nCount);
  665.         }
  666.     }
  667. }
  668.  
  669. void PASCAL CAsyncSocket::KillSocket(SOCKET hSocket, CAsyncSocket* pSocket)
  670. {
  671.     ASSERT(CAsyncSocket::LookupHandle(hSocket, FALSE) != NULL);
  672.  
  673.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  674.  
  675.     CAsyncSocket::DetachHandle(hSocket, FALSE);
  676.     if (pState->m_hSocketWindow != NULL)
  677.     {
  678.         ::PostMessage(pState->m_hSocketWindow, WM_SOCKET_DEAD,
  679.             (WPARAM)hSocket, 0L);
  680.         CAsyncSocket::AttachHandle(hSocket, pSocket, TRUE);
  681.     }
  682. }
  683.  
  684. void PASCAL CAsyncSocket::DoCallBack(WPARAM wParam, LPARAM lParam)
  685. {
  686.     if (wParam == 0 && lParam == 0)
  687.         return;
  688.  
  689.     // Has the socket be closed?
  690.     CAsyncSocket* pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, TRUE);
  691.  
  692.     // If yes ignore message
  693.     if (pSocket != NULL)
  694.         return;
  695.  
  696.     pSocket = CAsyncSocket::LookupHandle((SOCKET)wParam, FALSE);
  697.     if (pSocket == NULL)
  698.     {
  699.         // Must be in the middle of an Accept call
  700.         pSocket = CAsyncSocket::LookupHandle(INVALID_SOCKET, FALSE);
  701.         ASSERT(pSocket != NULL);
  702.         pSocket->m_hSocket = (SOCKET)wParam;
  703.         CAsyncSocket::DetachHandle(INVALID_SOCKET, FALSE);
  704.         CAsyncSocket::AttachHandle(pSocket->m_hSocket, pSocket, FALSE);
  705.     }
  706.  
  707.     int nErrorCode = WSAGETSELECTERROR(lParam);
  708.     switch (WSAGETSELECTEVENT(lParam))
  709.     {
  710.     case FD_READ:
  711.         {
  712.             DWORD nBytes;
  713.             if (!pSocket->IOCtl(FIONREAD, &nBytes))
  714.                 nErrorCode = WSAGetLastError();
  715.             if (nBytes != 0 || nErrorCode != 0)
  716.                 pSocket->OnReceive(nErrorCode);
  717.         }
  718.         break;
  719.     case FD_WRITE:
  720.         pSocket->OnSend(nErrorCode);
  721.         break;
  722.     case FD_OOB:
  723.         pSocket->OnOutOfBandData(nErrorCode);
  724.         break;
  725.     case FD_ACCEPT:
  726.         pSocket->OnAccept(nErrorCode);
  727.         break;
  728.     case FD_CONNECT:
  729.         pSocket->OnConnect(nErrorCode);
  730.         break;
  731.     case FD_CLOSE:
  732.         pSocket->OnClose(nErrorCode);
  733.         break;
  734.     }
  735. }
  736.  
  737. BOOL CAsyncSocket::Socket(int nSocketType, long lEvent,
  738.     int nProtocolType, int nAddressFormat)
  739. {
  740.     ASSERT(m_hSocket == INVALID_SOCKET);
  741.  
  742.     m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
  743.     if (m_hSocket != INVALID_SOCKET)
  744.     {
  745.         CAsyncSocket::AttachHandle(m_hSocket, this, FALSE);
  746.         return AsyncSelect(lEvent);
  747.     }
  748.     return FALSE;
  749. }
  750.  
  751. #ifdef _DEBUG
  752. void CAsyncSocket::AssertValid() const
  753. {
  754.     CObject::AssertValid();
  755.     ASSERT(m_hSocket == INVALID_SOCKET || CAsyncSocket::FromHandle(m_hSocket) != NULL);
  756. }
  757.  
  758. void CAsyncSocket::Dump(CDumpContext& dc) const
  759. {
  760.     CObject::Dump(dc);
  761.  
  762.     dc << "m_hSocket = ";
  763.     if (m_hSocket == INVALID_SOCKET)
  764.         dc << "INVALID_SOCKET\n";
  765.     else
  766.         dc << m_hSocket << "\n";
  767. }
  768. #endif //_DEBUG
  769.  
  770. int CAsyncSocket::ReceiveFromHelper(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
  771. {
  772.     return recvfrom(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen);
  773. }
  774.  
  775. int CAsyncSocket::SendToHelper(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
  776. {
  777.     return sendto(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen);
  778. }
  779.  
  780. BOOL CAsyncSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  781. {
  782.     return connect(m_hSocket, lpSockAddr, nSockAddrLen) != SOCKET_ERROR;
  783. }
  784.  
  785. /////////////////////////////////////////////////////////////////////////////
  786. // CSocket Construction
  787.  
  788. CSocket::CSocket()
  789. {
  790.     m_pbBlocking = NULL;
  791.     m_nConnectError = -1;
  792.     m_nTimeOut = 2000;
  793. }
  794.  
  795. /////////////////////////////////////////////////////////////////////////////
  796. // CSocket Operations
  797.  
  798. void CSocket::CancelBlockingCall()
  799. {
  800.     if (m_pbBlocking != NULL)
  801.     {
  802.         *m_pbBlocking = FALSE;
  803.         m_pbBlocking = NULL;
  804.     }
  805. }
  806.  
  807. /////////////////////////////////////////////////////////////////////////////
  808. // CSocket Overridable callbacks
  809.  
  810. BOOL CSocket::OnMessagePending()
  811. {
  812.     MSG msg;
  813.     if (::PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE))
  814.     {
  815.         ::DispatchMessage(&msg);
  816.         return FALSE;   // usually return TRUE, but OnIdle usually causes WM_PAINTs
  817.     }
  818.     return FALSE;
  819. }
  820.  
  821. /////////////////////////////////////////////////////////////////////////////
  822. // CSocket Implementation
  823.  
  824. CSocket::~CSocket()
  825. {
  826.     if (m_hSocket != INVALID_SOCKET)
  827.         Close();
  828. }
  829.  
  830. BOOL CSocket::Accept(CAsyncSocket& rConnectedSocket, SOCKADDR* lpSockAddr, int* lpSockAddrLen)
  831. {
  832.     if (m_pbBlocking != NULL)
  833.     {
  834.         WSASetLastError(WSAEINPROGRESS);
  835.         return FALSE;
  836.     }
  837.     while (!CAsyncSocket::Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen))
  838.     {
  839.         if (GetLastError() == WSAEWOULDBLOCK)
  840.         {
  841.             if (!PumpMessages(FD_ACCEPT))
  842.                 return FALSE;
  843.         }
  844.         else
  845.             return FALSE;
  846.     }
  847.     return TRUE;
  848. }
  849.  
  850. void CSocket::Close()
  851. {
  852.     if (m_hSocket != INVALID_SOCKET)
  853.     {
  854.         CancelBlockingCall();
  855.  
  856.         VERIFY(AsyncSelect(0));
  857.         CAsyncSocket::Close();
  858.         m_hSocket = INVALID_SOCKET;
  859.     }
  860. }
  861.  
  862. int CSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
  863. {
  864.     if (m_pbBlocking != NULL)
  865.     {
  866.         WSASetLastError(WSAEINPROGRESS);
  867.         return  FALSE;
  868.     }
  869.     int nResult;
  870.     while ((nResult = CAsyncSocket::Receive(lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
  871.     {
  872.         if (GetLastError() == WSAEWOULDBLOCK)
  873.         {
  874.             if (!PumpMessages(FD_READ))
  875.                 return SOCKET_ERROR;
  876.         }
  877.         else
  878.             return SOCKET_ERROR;
  879.     }
  880.     return nResult;
  881. }
  882.  
  883. int CSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
  884. {
  885.     if (m_pbBlocking != NULL)
  886.     {
  887.         WSASetLastError(WSAEINPROGRESS);
  888.         return  FALSE;
  889.     }
  890.  
  891.     int nLeft, nWritten;
  892.     PBYTE pBuf = (PBYTE)lpBuf;
  893.     nLeft = nBufLen;
  894.  
  895.     while (nLeft > 0)
  896.     {
  897.         nWritten = SendChunk(pBuf, nLeft, nFlags);
  898.         if (nWritten == SOCKET_ERROR)
  899.             return nWritten;
  900.  
  901.         nLeft -= nWritten;
  902.         pBuf += nWritten;
  903.     }
  904.     return nBufLen - nLeft;
  905. }
  906.  
  907. int CSocket::SendChunk(const void* lpBuf, int nBufLen, int nFlags)
  908. {
  909.     int nResult;
  910.     while ((nResult = CAsyncSocket::Send(lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
  911.     {
  912.         if (GetLastError() == WSAEWOULDBLOCK)
  913.         {
  914.             if (!PumpMessages(FD_WRITE))
  915.                 return SOCKET_ERROR;
  916.         }
  917.         else
  918.             return SOCKET_ERROR;
  919.     }
  920.     return nResult;
  921. }
  922.  
  923. BOOL CSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  924. {
  925.     if (m_pbBlocking != NULL)
  926.     {
  927.         WSASetLastError(WSAEINPROGRESS);
  928.         return  FALSE;
  929.     }
  930.  
  931.     m_nConnectError = -1;
  932.  
  933.     if (!CAsyncSocket::ConnectHelper(lpSockAddr, nSockAddrLen))
  934.     {
  935.         if (GetLastError() == WSAEWOULDBLOCK)
  936.         {
  937.             while (PumpMessages(FD_CONNECT))
  938.             {
  939.                 if (m_nConnectError != -1)
  940.                 {
  941.                     WSASetLastError(m_nConnectError);
  942.                     return (m_nConnectError == 0);
  943.                 }
  944.             }
  945.         }
  946.         return FALSE;
  947.     }
  948.     return TRUE;
  949. }
  950.  
  951. int CSocket::ReceiveFromHelper(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
  952. {
  953.     if (m_pbBlocking != NULL)
  954.     {
  955.         WSASetLastError(WSAEINPROGRESS);
  956.         return  FALSE;
  957.     }
  958.     int nResult;
  959.     while ((nResult = CAsyncSocket::ReceiveFromHelper(lpBuf, nBufLen, lpSockAddr, lpSockAddrLen, nFlags)) == SOCKET_ERROR)
  960.     {
  961.         if (GetLastError() == WSAEWOULDBLOCK)
  962.         {
  963.             if (!PumpMessages(FD_READ))
  964.                 return SOCKET_ERROR;
  965.         }
  966.         else
  967.             return SOCKET_ERROR;
  968.     }
  969.     return nResult;
  970. }
  971.  
  972. int CSocket::SendToHelper(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
  973. {
  974.     if (m_pbBlocking != NULL)
  975.     {
  976.         WSASetLastError(WSAEINPROGRESS);
  977.         return  FALSE;
  978.     }
  979.     int nResult;
  980.     while ((nResult = CAsyncSocket::SendToHelper(lpBuf, nBufLen, lpSockAddr, nSockAddrLen, nFlags)) == SOCKET_ERROR)
  981.     {
  982.         if (GetLastError() == WSAEWOULDBLOCK)
  983.         {
  984.             if (!PumpMessages(FD_WRITE))
  985.                 return SOCKET_ERROR;
  986.         }
  987.         else
  988.             return SOCKET_ERROR;
  989.     }
  990.     return nResult;
  991. }
  992.  
  993. int PASCAL CSocket::ProcessAuxQueue()
  994. {
  995.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  996.  
  997.     if (pState->m_listSocketNotifications.IsEmpty())
  998.         return 0;
  999.  
  1000.     int nCount = 0;
  1001.     while(!pState->m_listSocketNotifications.IsEmpty())
  1002.     {
  1003.         nCount++;
  1004.  
  1005.         MSG* pMsg = (MSG*)pState->m_listSocketNotifications.RemoveHead();
  1006.         ASSERT(pMsg != NULL);
  1007.         if (pMsg->message == WM_SOCKET_NOTIFY)
  1008.         {
  1009.             CAsyncSocket::DoCallBack(pMsg->wParam, pMsg->lParam);
  1010.         }
  1011.         else
  1012.         {
  1013.             ASSERT(CAsyncSocket::LookupHandle((SOCKET)pMsg->wParam, TRUE) != NULL);
  1014.             CAsyncSocket::DetachHandle((SOCKET)pMsg->wParam, TRUE);
  1015.         }
  1016.         delete pMsg;
  1017.     }
  1018.     return nCount;
  1019. }
  1020.  
  1021. void PASCAL CSocket::AuxQueueAdd(UINT message, WPARAM wParam, LPARAM lParam)
  1022. {
  1023.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  1024.  
  1025.     MSG* pMsg = new MSG;
  1026.     pMsg->message = message;
  1027.     pMsg->wParam = wParam;
  1028.     pMsg->lParam = lParam;
  1029.     pState->m_listSocketNotifications.AddTail(pMsg);
  1030. }
  1031.  
  1032. BOOL CSocket::PumpMessages(UINT uStopFlag)
  1033. {
  1034.     // The same socket better not be blocking in more than one place.
  1035.     ASSERT(m_pbBlocking == NULL);
  1036.  
  1037.     _AFX_SOCK_THREAD_STATE* pState = _afxSockThreadState;
  1038.  
  1039.     ASSERT(pState->m_hSocketWindow != NULL);
  1040.  
  1041.     BOOL bBlocking = TRUE;
  1042.     m_pbBlocking = &bBlocking;
  1043.     CWinThread* pThread = AfxGetThread();
  1044.  
  1045.     // This is not a timeout in the WinSock sense, but more
  1046.     // like a WM_KICKIDLE to keep message pumping alive
  1047.     UINT nTimerID = ::SetTimer(pState->m_hSocketWindow, 1, m_nTimeOut, NULL);
  1048.  
  1049.     if (nTimerID == 0)
  1050.         AfxThrowResourceException();
  1051.  
  1052.     BOOL bPeek = TRUE;
  1053.  
  1054.     while (bBlocking)
  1055.     {
  1056.         TRY
  1057.         {
  1058.             MSG msg;
  1059.             if (::PeekMessage(&msg, pState->m_hSocketWindow,
  1060.                 WM_SOCKET_NOTIFY, WM_SOCKET_DEAD, PM_REMOVE))
  1061.             {
  1062.                 if (msg.message == WM_SOCKET_NOTIFY && (SOCKET)msg.wParam == m_hSocket)
  1063.                 {
  1064.                     if (WSAGETSELECTEVENT(msg.lParam) == FD_CLOSE)
  1065.                     {
  1066.                         break;
  1067.                     }
  1068.                     if (WSAGETSELECTEVENT(msg.lParam) == uStopFlag)
  1069.                     {
  1070.                         if (uStopFlag == FD_CONNECT)
  1071.                             m_nConnectError = WSAGETSELECTERROR(msg.lParam);
  1072.                         break;
  1073.                     }
  1074.                 }
  1075.                 if (msg.wParam != 0 || msg.lParam != 0)
  1076.                     CSocket::AuxQueueAdd(msg.message, msg.wParam, msg.lParam);
  1077.  
  1078.                 bPeek = TRUE;
  1079.             }
  1080.             else if (::PeekMessage(&msg, pState->m_hSocketWindow,
  1081.                         WM_TIMER, WM_TIMER, PM_REMOVE))
  1082.             {
  1083.             break;
  1084.             }
  1085.  
  1086.             if (bPeek && ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
  1087.             {
  1088.                 if (OnMessagePending())
  1089.                 {
  1090.                     // allow user-interface updates
  1091.                     pThread->OnIdle(-1);
  1092.                 }
  1093.                 else
  1094.                 {
  1095.                     bPeek = FALSE;
  1096.                 }
  1097.             }
  1098.             else
  1099.             {
  1100.                 // no work to do -- allow CPU to sleep
  1101.                 WaitMessage();
  1102.                 bPeek = TRUE;
  1103.             }
  1104.         }
  1105.         CATCH_ALL(e)
  1106.         {
  1107.             TRACE0("Error: caught exception in PumpMessage - continuing.\n");
  1108.             DELETE_EXCEPTION(e);
  1109.             bPeek = TRUE;
  1110.         }
  1111.         END_CATCH_ALL
  1112.     }
  1113.  
  1114.     ::KillTimer(pState->m_hSocketWindow, nTimerID);
  1115.  
  1116.     if (!bBlocking)
  1117.     {
  1118.         WSASetLastError(WSAEINTR);
  1119.         return FALSE;
  1120.     }
  1121.     m_pbBlocking = NULL;
  1122.  
  1123.     ::PostMessage(pState->m_hSocketWindow, WM_SOCKET_NOTIFY, 0, 0);
  1124.  
  1125.     return TRUE;
  1126. }
  1127.  
  1128. #ifdef _DEBUG
  1129. void CSocket::AssertValid() const
  1130. {
  1131.     CAsyncSocket::AssertValid();
  1132. }
  1133.  
  1134. void CSocket::Dump(CDumpContext& dc) const
  1135. {
  1136.     CAsyncSocket::Dump(dc);
  1137.     dc << "m_pbBlocking = " << m_pbBlocking <<"\n";
  1138.     dc << "m_nConnectError = " << m_nConnectError <<"\n";
  1139. }
  1140. #endif //_DEBUG
  1141.  
  1142.  
  1143. /////////////////////////////////////////////////////////////////////////////
  1144. // CSocketFile Construction
  1145.  
  1146. CSocketFile::CSocketFile(CSocket* pSocket, BOOL bArchiveCompatible)
  1147. {
  1148.     m_pSocket = pSocket;
  1149.     m_bArchiveCompatible = bArchiveCompatible;
  1150.  
  1151. #ifdef _DEBUG
  1152.     ASSERT(m_pSocket != NULL);
  1153.     ASSERT(m_pSocket->m_hSocket != INVALID_SOCKET);
  1154.  
  1155.     int nType = 0;
  1156.     int nTypeLen = sizeof(int);
  1157.     ASSERT(m_pSocket->GetSockOpt(SO_TYPE,&nType,&nTypeLen));
  1158.     ASSERT(nType == SOCK_STREAM);
  1159. #endif // _DEBUG
  1160. }
  1161.  
  1162. /////////////////////////////////////////////////////////////////////////////
  1163. // CSocketFile Implementation
  1164.  
  1165. CSocketFile::~CSocketFile()
  1166. {
  1167. }
  1168.  
  1169. UINT CSocketFile::Read(void* lpBuf, UINT nCount)
  1170. {
  1171.     ASSERT(m_pSocket != NULL);
  1172.  
  1173.     int nRead;
  1174.  
  1175.     if (!m_bArchiveCompatible)
  1176.     {
  1177.         int nLeft = nCount;
  1178.         PBYTE pBuf = (PBYTE)lpBuf;
  1179.  
  1180.         while(nLeft > 0)
  1181.         {
  1182.             nRead = m_pSocket->Receive(pBuf, nLeft);
  1183.             if (nRead == SOCKET_ERROR)
  1184.             {
  1185.                 int nError = m_pSocket->GetLastError();
  1186.                 AfxThrowFileException(CFileException::generic, nError);
  1187.                 ASSERT(FALSE);
  1188.             }
  1189.             else if (nRead == 0)
  1190.             {
  1191.                 return nCount - nLeft;
  1192.             }
  1193.  
  1194.             nLeft -= nRead;
  1195.             pBuf += nRead;
  1196.         }
  1197.         return nCount - nLeft;
  1198.     }
  1199.  
  1200.     nRead = m_pSocket->Receive(lpBuf, nCount, 0);
  1201.     if (nRead == SOCKET_ERROR)
  1202.     {
  1203.         int nError = m_pSocket->GetLastError();
  1204.         AfxThrowFileException(CFileException::generic, nError);
  1205.         ASSERT(FALSE);
  1206.     }
  1207.     return nRead;
  1208. }
  1209.  
  1210. void CSocketFile::Write(const void* lpBuf, UINT nCount)
  1211. {
  1212.     ASSERT (m_pSocket!=NULL);
  1213.  
  1214.     int nWritten = m_pSocket->Send(lpBuf, nCount);
  1215.     if (nWritten == SOCKET_ERROR)
  1216.     {
  1217.         int nError = m_pSocket->GetLastError();
  1218.         AfxThrowFileException(CFileException::generic, nError);
  1219.     }
  1220. }
  1221.  
  1222. void CSocketFile::Close()
  1223. {
  1224.     m_pSocket = NULL;
  1225. }
  1226.  
  1227. BOOL CSocketFile::Open(
  1228.     LPCTSTR /*lpszFileName*/, UINT /*nOpenFlags*/, CFileException* /*pError*/)
  1229. {
  1230.     AfxThrowNotSupportedException();
  1231.     return FALSE;
  1232. }
  1233.  
  1234. CFile* CSocketFile::Duplicate() const
  1235. {
  1236.     AfxThrowNotSupportedException();
  1237.     return NULL;
  1238. }
  1239.  
  1240. DWORD CSocketFile::GetPosition() const
  1241. {
  1242.     AfxThrowNotSupportedException();
  1243.     return 0;
  1244. }
  1245.  
  1246. LONG CSocketFile::Seek(LONG lOff, UINT nFrom)
  1247. {
  1248.     if (lOff != 0L || nFrom != current)
  1249.         TRACE0("Warning - Attempt made to seek on a CSocketFile\n");
  1250.     return 0;
  1251. }
  1252.  
  1253. void CSocketFile::SetLength(DWORD /*dwNewLen*/)
  1254. {
  1255.     AfxThrowNotSupportedException();
  1256. }
  1257.  
  1258. DWORD CSocketFile::GetLength() const
  1259. {
  1260.     AfxThrowNotSupportedException();
  1261.     return 0;
  1262. }
  1263.  
  1264. void CSocketFile::LockRange(DWORD /*dwPos*/, DWORD /*dwCount*/)
  1265. {
  1266.     AfxThrowNotSupportedException();
  1267. }
  1268.  
  1269. void CSocketFile::UnlockRange(DWORD /*dwPos*/, DWORD /*dwCount*/)
  1270. {
  1271.     AfxThrowNotSupportedException();
  1272. }
  1273.  
  1274. void CSocketFile::Flush()
  1275. {
  1276. }
  1277.  
  1278. void CSocketFile::Abort()
  1279. {
  1280.     AfxThrowNotSupportedException();
  1281. }
  1282.  
  1283. #ifdef _DEBUG
  1284. void CSocketFile::AssertValid() const
  1285. {
  1286.     CFile::AssertValid();
  1287.     if (m_pSocket != NULL)
  1288.         ASSERT_VALID(m_pSocket);
  1289. }
  1290.  
  1291. void CSocketFile::Dump(CDumpContext& dc) const
  1292. {
  1293.     CFile::Dump(dc);
  1294.     if (dc.GetDepth() > 0)
  1295.     {
  1296.         if (m_pSocket != NULL)
  1297.             dc << "with no socket\n";
  1298.         else
  1299.             dc << "with socket: " << m_pSocket;
  1300.     }
  1301. }
  1302. #endif //_DEBUG
  1303.  
  1304. /////////////////////////////////////////////////////////////////////////////
  1305. // CSocketWnd implementation
  1306.  
  1307. CSocketWnd::CSocketWnd()
  1308. {
  1309. }
  1310.  
  1311. LRESULT CSocketWnd::OnSocketNotify(WPARAM wParam, LPARAM lParam)
  1312. {
  1313.     CSocket::AuxQueueAdd(WM_SOCKET_NOTIFY, wParam, lParam);
  1314.     CSocket::ProcessAuxQueue();
  1315.     return 0L;
  1316. }
  1317.  
  1318. LRESULT CSocketWnd::OnSocketDead(WPARAM wParam, LPARAM lParam)
  1319. {
  1320.     CSocket::AuxQueueAdd(WM_SOCKET_DEAD, wParam, lParam);
  1321.     CSocket::ProcessAuxQueue();
  1322.     return 0L;
  1323. }
  1324.  
  1325. /////////////////////////////////////////////////////////////////////////////
  1326. // Message table implementation
  1327.  
  1328. BEGIN_MESSAGE_MAP(CSocketWnd, CWnd)
  1329.     //{{AFX_MSG_MAP(CWnd)
  1330.     ON_MESSAGE(WM_SOCKET_NOTIFY, OnSocketNotify)
  1331.     ON_MESSAGE(WM_SOCKET_DEAD, OnSocketDead)
  1332.     //}}AFX_MSG_MAP
  1333. END_MESSAGE_MAP()
  1334.  
  1335. //////////////////////////////////////////////////////////////////////////////
  1336. // Inline function declarations expanded out-of-line
  1337.  
  1338. #ifndef _AFX_ENABLE_INLINES
  1339.  
  1340. static char _szAfxSockInl[] = "afxsock.inl";
  1341. #undef THIS_FILE
  1342. #define THIS_FILE _szAfxSockInl
  1343. #define _AFXSOCK_INLINE
  1344. #include "afxsock.inl"
  1345. #undef _AFXSOCK_INLINE
  1346.  
  1347. #endif
  1348.  
  1349. #ifdef AFX_INIT_SEG
  1350. #pragma code_seg(AFX_INIT_SEG)
  1351. #endif
  1352.  
  1353. IMPLEMENT_DYNAMIC(CAsyncSocket, CObject)
  1354. IMPLEMENT_DYNAMIC(CSocket, CAsyncSocket)
  1355. IMPLEMENT_DYNAMIC(CSocketFile, CFile)
  1356.  
  1357. #pragma warning(disable: 4074)
  1358. #pragma init_seg(lib)
  1359.  
  1360. PROCESS_LOCAL(_AFX_SOCK_STATE, _afxSockState)
  1361.  
  1362. /////////////////////////////////////////////////////////////////////////////
  1363.