MSocketSupport.bas
上传用户:bcdefg2008
上传日期:2013-02-28
资源大小:144k
文件大小:44k
源码类别:

Email服务器

开发平台:

Visual Basic

  1. Attribute VB_Name = "MSocketSupport"
  2. Option Explicit
  3. '
  4. Public Const INADDR_NONE = &HFFFF
  5. '
  6. Public Const SOCKET_ERROR = -1
  7. Public Const INVALID_SOCKET = -1
  8. Public Const INADDR_ANY = &H0
  9. '
  10. Public Const FD_SETSIZE = 64
  11. '
  12. '/*
  13. ' * Define constant based on rfc883, used by gethostbyxxxx() calls.
  14. ' */
  15. Public Const MAXGETHOSTSTRUCT = 1024
  16. '
  17. '/*
  18. ' * WinSock 2 extension -- manifest constants for shutdown()
  19. ' */
  20. Public Const SD_RECEIVE = &H0
  21. Public Const SD_SEND = &H1
  22. Public Const SD_BOTH = &H2
  23. '
  24. Public Const MSG_OOB = &H1         '/* process out-of-band data */
  25. Public Const MSG_PEEK = &H2        '/* peek at incoming message */
  26. Public Const MSG_DONTROUTE = &H4   '/* send without using routing tables */
  27. Public Const MSG_PARTIAL = &H8000  '/* partial send or recv for message xport */
  28. '
  29. Public Const FD_READ = &H1&
  30. Public Const FD_WRITE = &H2&
  31. Public Const FD_OOB = &H4&
  32. Public Const FD_ACCEPT = &H8&
  33. Public Const FD_CONNECT = &H10&
  34. Public Const FD_CLOSE = &H20&
  35. '
  36. Public Const SOL_SOCKET = 65535
  37. '
  38. ' option flags per socket
  39. Public Const SO_DEBUG = &H0&         ' Turn on debugging info recording
  40. Public Const SO_ACCEPTCONN = &H2&    ' Socket has had listen() - READ-ONLY.
  41. Public Const SO_REUSEADDR = &H4&     ' Allow local address reuse.
  42. Public Const SO_KEEPALIVE = &H8&     ' Keep connections alive.
  43. Public Const SO_DONTROUTE = &H10&    ' Just use interface addresses.
  44. Public Const SO_BROADCAST = &H20&    ' Permit sending of broadcast msgs.
  45. Public Const SO_USELOOPBACK = &H40&  ' Bypass hardware when possible.
  46. Public Const SO_LINGER = &H80&       ' Linger on close if data present.
  47. Public Const SO_OOBINLINE = &H100&   ' Leave received OOB data in line.
  48. Public Const SO_DONTLINGER = Not SO_LINGER
  49. Public Const SO_EXCLUSIVEADDRUSE = Not SO_REUSEADDR ' Disallow local address reuse.
  50. ' Additional options.
  51. Public Const SO_SNDBUF = &H1001&     ' Send buffer size.
  52. Public Const SO_RCVBUF = &H1002&     ' Receive buffer size.
  53. Public Const SO_ERROR = &H1007&      ' Get error status and clear.
  54. Public Const SO_TYPE = &H1008&       ' Get socket type - READ-ONLY.
  55. '
  56. Public Const WSADESCRIPTION_LEN = 257
  57. Public Const WSASYS_STATUS_LEN = 129
  58. '
  59. Public Type WSADATA
  60.     wVersion As Integer
  61.     wHighVersion As Integer
  62.     szDescription As String * WSADESCRIPTION_LEN
  63.     szSystemStatus As String * WSASYS_STATUS_LEN
  64.     iMaxSockets As Integer
  65.     iMaxUdpDg As Integer
  66.     lpVendorInfo As Long
  67. End Type
  68. '
  69. Public Type sockaddr_in
  70.     sin_family       As Integer
  71.     sin_port         As Integer
  72.     sin_addr         As Long
  73.     sin_zero(1 To 8) As Byte
  74. End Type
  75. Public Type fd_set
  76.   fd_count                  As Long '// how many are SET?
  77.   fd_array(1 To FD_SETSIZE) As Long '// an array of SOCKETs
  78. End Type
  79. '
  80. '/*
  81. ' * All Windows Sockets error constants are biased by WSABASEERR from
  82. ' * the "normal"
  83. ' */
  84. Public Const WSABASEERR = 10000
  85. '/*
  86. ' * Windows Sockets definitions of regular Microsoft C error constants
  87. ' */
  88. Public Const WSAEINTR = (WSABASEERR + 4)
  89. Public Const WSAEBADF = (WSABASEERR + 9)
  90. Public Const WSAEACCES = (WSABASEERR + 13)
  91. Public Const WSAEFAULT = (WSABASEERR + 14)
  92. Public Const WSAEINVAL = (WSABASEERR + 22)
  93. Public Const WSAEMFILE = (WSABASEERR + 24)
  94. '/*
  95. ' * Windows Sockets definitions of regular Berkeley error constants
  96. ' */
  97. Public Const WSAEWOULDBLOCK = (WSABASEERR + 35)
  98. Public Const WSAEINPROGRESS = (WSABASEERR + 36)
  99. Public Const WSAEALREADY = (WSABASEERR + 37)
  100. Public Const WSAENOTSOCK = (WSABASEERR + 38)
  101. Public Const WSAEDESTADDRREQ = (WSABASEERR + 39)
  102. Public Const WSAEMSGSIZE = (WSABASEERR + 40)
  103. Public Const WSAEPROTOTYPE = (WSABASEERR + 41)
  104. Public Const WSAENOPROTOOPT = (WSABASEERR + 42)
  105. Public Const WSAEPROTONOSUPPORT = (WSABASEERR + 43)
  106. Public Const WSAESOCKTNOSUPPORT = (WSABASEERR + 44)
  107. Public Const WSAEOPNOTSUPP = (WSABASEERR + 45)
  108. Public Const WSAEPFNOSUPPORT = (WSABASEERR + 46)
  109. Public Const WSAEAFNOSUPPORT = (WSABASEERR + 47)
  110. Public Const WSAEADDRINUSE = (WSABASEERR + 48)
  111. Public Const WSAEADDRNOTAVAIL = (WSABASEERR + 49)
  112. Public Const WSAENETDOWN = (WSABASEERR + 50)
  113. Public Const WSAENETUNREACH = (WSABASEERR + 51)
  114. Public Const WSAENETRESET = (WSABASEERR + 52)
  115. Public Const WSAECONNABORTED = (WSABASEERR + 53)
  116. Public Const WSAECONNRESET = (WSABASEERR + 54)
  117. Public Const WSAENOBUFS = (WSABASEERR + 55)
  118. Public Const WSAEISCONN = (WSABASEERR + 56)
  119. Public Const WSAENOTCONN = (WSABASEERR + 57)
  120. Public Const WSAESHUTDOWN = (WSABASEERR + 58)
  121. Public Const WSAETOOMANYREFS = (WSABASEERR + 59)
  122. Public Const WSAETIMEDOUT = (WSABASEERR + 60)
  123. Public Const WSAECONNREFUSED = (WSABASEERR + 61)
  124. Public Const WSAELOOP = (WSABASEERR + 62)
  125. Public Const WSAENAMETOOLONG = (WSABASEERR + 63)
  126. Public Const WSAEHOSTDOWN = (WSABASEERR + 64)
  127. Public Const WSAEHOSTUNREACH = (WSABASEERR + 65)
  128. Public Const WSAENOTEMPTY = (WSABASEERR + 66)
  129. Public Const WSAEPROCLIM = (WSABASEERR + 67)
  130. Public Const WSAEUSERS = (WSABASEERR + 68)
  131. Public Const WSAEDQUOT = (WSABASEERR + 69)
  132. Public Const WSAESTALE = (WSABASEERR + 70)
  133. Public Const WSAEREMOTE = (WSABASEERR + 71)
  134. '/*
  135. ' * Extended Windows Sockets error constant definitions
  136. ' */
  137. Public Const WSASYSNOTREADY = (WSABASEERR + 91)
  138. Public Const WSAVERNOTSUPPORTED = (WSABASEERR + 92)
  139. Public Const WSANOTINITIALISED = (WSABASEERR + 93)
  140. Public Const WSAEDISCON = (WSABASEERR + 101)
  141. Public Const WSAENOMORE = (WSABASEERR + 102)
  142. Public Const WSAECANCELLED = (WSABASEERR + 103)
  143. Public Const WSAEINVALIDPROCTABLE = (WSABASEERR + 104)
  144. Public Const WSAEINVALIDPROVIDER = (WSABASEERR + 105)
  145. Public Const WSAEPROVIDERFAILEDINIT = (WSABASEERR + 106)
  146. Public Const WSASYSCALLFAILURE = (WSABASEERR + 107)
  147. Public Const WSASERVICE_NOT_FOUND = (WSABASEERR + 108)
  148. Public Const WSATYPE_NOT_FOUND = (WSABASEERR + 109)
  149. Public Const WSA_E_NO_MORE = (WSABASEERR + 110)
  150. Public Const WSA_E_CANCELLED = (WSABASEERR + 111)
  151. Public Const WSAEREFUSED = (WSABASEERR + 112)
  152. '
  153. '/* Authoritative Answer: Host not found */
  154. Public Const WSAHOST_NOT_FOUND = (WSABASEERR + 1001)
  155. '/* Non-Authoritative: Host not found, or SERVERFAIL */
  156. Public Const WSATRY_AGAIN = (WSABASEERR + 1002)
  157. '/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
  158. Public Const WSANO_RECOVERY = (WSABASEERR + 1003)
  159. '/* Valid name, no data record of requested type */
  160. Public Const WSANO_DATA = (WSABASEERR + 1004)
  161. '
  162. '
  163. 'Socket types
  164. '
  165. Public Enum SocketType
  166.     SOCK_STREAM = 1    ' /* stream socket */
  167.     SOCK_DGRAM = 2     ' /* datagram socket */
  168.     SOCK_RAW = 3       ' /* raw-protocol interface */
  169.     SOCK_RDM = 4       ' /* reliably-delivered message */
  170.     SOCK_SEQPACKET = 5 ' /* sequenced packet stream */
  171. End Enum
  172. '
  173. Public Enum AddressFamily
  174.     '
  175.     AF_UNSPEC = 0      '/* unspecified */
  176. '/*
  177. ' * Although  AF_UNSPEC  is  defined for backwards compatibility, using
  178. ' * AF_UNSPEC for the "af" parameter when creating a socket is STRONGLY
  179. ' * DISCOURAGED.    The  interpretation  of  the  "protocol"  parameter
  180. ' * depends  on the actual address family chosen.  As environments grow
  181. ' * to  include  more  and  more  address families that use overlapping
  182. ' * protocol  values  there  is  more  and  more  chance of choosing an
  183. ' * undesired address family when AF_UNSPEC is used.
  184. ' */
  185.     AF_UNIX = 1        '/* local to host (pipes, portals) */
  186.     AF_INET = 2        '/* internetwork: UDP, TCP, etc. */
  187.     AF_IMPLINK = 3     '/* arpanet imp addresses */
  188.     AF_PUP = 4         '/* pup protocols: e.g. BSP */
  189.     AF_CHAOS = 5       '/* mit CHAOS protocols */
  190.     AF_NS = 6          '/* XEROX NS protocols */
  191.     AF_IPX = AF_NS     '/* IPX protocols: IPX, SPX, etc. */
  192.     AF_ISO = 7         '/* ISO protocols */
  193.     AF_OSI = AF_ISO    '/* OSI is ISO */
  194.     AF_ECMA = 8        '/* european computer manufacturers */
  195.     AF_DATAKIT = 9     '/* datakit protocols */
  196.     AF_CCITT = 10      '/* CCITT protocols, X.25 etc */
  197.     AF_SNA = 11        '/* IBM SNA */
  198.     AF_DECnet = 12     '/* DECnet */
  199.     AF_DLI = 13        '/* Direct data link interface */
  200.     AF_LAT = 14        '/* LAT */
  201.     AF_HYLINK = 15     '/* NSC Hyperchannel */
  202.     AF_APPLETALK = 16  '/* AppleTalk */
  203.     AF_NETBIOS = 17    '/* NetBios-style addresses */
  204.     AF_VOICEVIEW = 18  '/* VoiceView */
  205.     AF_FIREFOX = 19    '/* Protocols from Firefox */
  206.     AF_UNKNOWN1 = 20   '/* Somebody is using this! */
  207.     AF_BAN = 21        '/* Banyan */
  208.     AF_ATM = 22        '/* Native ATM Services */
  209.     AF_INET6 = 23      '/* Internetwork Version 6 */
  210.     AF_CLUSTER = 24    '/* Microsoft Wolfpack */
  211.     AF_12844 = 25      '/* IEEE 1284.4 WG AF */
  212.     AF_MAX = 26
  213.     '
  214. End Enum
  215. '
  216. '/*
  217. ' * Protocols
  218. ' */
  219. Public Enum SocketProtocol
  220.     IPPROTO_IP = 0             '/* dummy for IP */
  221.     IPPROTO_ICMP = 1           '/* control message protocol */
  222.     IPPROTO_IGMP = 2           '/* internet group management protocol */
  223.     IPPROTO_GGP = 3            '/* gateway^2 (deprecated) */
  224.     IPPROTO_TCP = 6            '/* tcp */
  225.     IPPROTO_PUP = 12           '/* pup */
  226.     IPPROTO_UDP = 17           '/* user datagram protocol */
  227.     IPPROTO_IDP = 22           '/* xns idp */
  228.     IPPROTO_ND = 77            '/* UNOFFICIAL net disk proto */
  229.     IPPROTO_RAW = 255          '/* raw IP packet */
  230.     IPPROTO_MAX = 256
  231. End Enum
  232. '
  233. Public Type HostEnt
  234.     hName     As Long
  235.     hAliases  As Long
  236.     hAddrType As Integer
  237.     hLength   As Integer
  238.     hAddrList As Long
  239. End Type
  240. '
  241. Public Declare Function gethostbyaddr Lib "ws2_32.dll" (addr As Long, ByVal addr_len As Long, ByVal addr_type As Long) As Long
  242. Public Declare Function gethostbyname Lib "ws2_32.dll" (ByVal host_name As String) As Long
  243. Public Declare Function gethostname Lib "ws2_32.dll" (ByVal host_name As String, ByVal namelen As Long) As Long
  244. Public Declare Function getservbyname Lib "ws2_32.dll" (ByVal serv_name As String, ByVal proto As String) As Long
  245. Public Declare Function getprotobynumber Lib "ws2_32.dll" (ByVal proto As Long) As Long
  246. Public Declare Function getprotobyname Lib "ws2_32.dll" (ByVal proto_name As String) As Long
  247. Public Declare Function getservbyport Lib "ws2_32.dll" (ByVal Port As Integer, ByVal proto As Long) As Long
  248. Public Declare Function inet_addr Lib "ws2_32.dll" (ByVal cp As String) As Long
  249. Public Declare Function inet_ntoa Lib "ws2_32.dll" (ByVal inn As Long) As Long
  250. Public Declare Function htons Lib "ws2_32.dll" (ByVal hostshort As Integer) As Integer
  251. Public Declare Function htonl Lib "ws2_32.dll" (ByVal hostlong As Long) As Long
  252. Public Declare Function ntohl Lib "ws2_32.dll" (ByVal netlong As Long) As Long
  253. Public Declare Function ntohs Lib "ws2_32.dll" (ByVal netshort As Integer) As Integer
  254. Public Declare Function api_socket Lib "ws2_32.dll" Alias "socket" (ByVal af As Long, ByVal s_type As Long, ByVal protocol As Long) As Long
  255. Public Declare Function api_closesocket Lib "ws2_32.dll" Alias "closesocket" (ByVal s As Long) As Long
  256. Public Declare Function api_connect Lib "ws2_32.dll" Alias "connect" (ByVal s As Long, ByRef Name As sockaddr_in, ByVal namelen As Long) As Long
  257. Public Declare Function getsockname Lib "ws2_32.dll" (ByVal s As Long, ByRef Name As sockaddr_in, ByRef namelen As Long) As Long
  258. Public Declare Function getpeername Lib "ws2_32.dll" (ByVal s As Long, ByRef Name As sockaddr_in, ByRef namelen As Long) As Long
  259. Public Declare Function api_bind Lib "ws2_32.dll" Alias "bind" (ByVal s As Long, ByRef Name As sockaddr_in, ByRef namelen As Long) As Long
  260. Public Declare Function api_select Lib "ws2_32.dll" Alias "select" (ByVal nfds As Long, ByRef readfds As Any, ByRef writefds As Any, ByRef exceptfds As Any, ByRef Timeout As Long) As Long
  261. Public Declare Function recv Lib "ws2_32.dll" (ByVal s As Long, ByRef buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
  262. Public Declare Function send Lib "ws2_32.dll" (ByVal s As Long, ByRef buf As Any, ByVal buflen As Long, ByVal flags As Long) As Long
  263. Public Declare Function shutdown Lib "ws2_32.dll" (ByVal s As Long, ByVal how As Long) As Long
  264. Public Declare Function api_listen Lib "ws2_32.dll" Alias "listen" (ByVal s As Long, ByVal backlog As Long) As Long
  265. Public Declare Function api_accept Lib "ws2_32.dll" Alias "accept" (ByVal s As Long, ByRef addr As sockaddr_in, ByRef addrlen As Long) As Long
  266. Public Declare Function setsockopt Lib "ws2_32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, ByVal optlen As Long) As Long
  267. Public Declare Function getsockopt Lib "ws2_32.dll" (ByVal s As Long, ByVal level As Long, ByVal optname As Long, optval As Any, optlen As Long) As Long
  268. Public Declare Function sendto Lib "ws2_32.dll" (ByVal s As Long, ByRef buf As Any, ByVal buflen As Long, ByVal flags As Long, ByRef toaddr As sockaddr_in, ByVal tolen As Long) As Long
  269. Public Declare Function recvfrom Lib "ws2_32.dll" (ByVal s As Long, ByRef buf As Any, ByVal buflen As Long, ByVal flags As Long, ByRef from As sockaddr_in, ByRef fromlen As Long) As Long
  270. Public Declare Function WSAAsyncSelect Lib "ws2_32.dll" (ByVal s As Long, ByVal hwnd As Long, ByVal wMsg As Long, ByVal lEvent As Long) As Long
  271. Public Declare Function WSAAsyncGetHostByAddr Lib "ws2_32.dll" (ByVal hwnd As Long, ByVal wMsg As Long, ByRef lngAddr As Long, ByVal lngLenght As Long, ByVal lngType As Long, buf As Any, ByVal lngBufLen As Long) As Long
  272. Public Declare Function WSAAsyncGetHostByName Lib "ws2_32.dll" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal strHostName As String, buf As Any, ByVal buflen As Long) As Long
  273. Public Declare Function WSAStartup Lib "ws2_32.dll" (ByVal wVR As Long, lpWSAD As WSADATA) As Long
  274. Public Declare Function WSACleanup Lib "ws2_32.dll" () As Long
  275. '
  276. Private Const GWL_WNDPROC = -4
  277. Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
  278. Private Declare Function CreateWindowEx Lib "user32" Alias "CreateWindowExA" (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) As Long
  279. Private Declare Function DestroyWindow Lib "user32" (ByVal hwnd As Long) As Long
  280. 'Added: 04-MAR-2002
  281. Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long
  282. Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal lpString1 As String, ByVal lpString2 As Long) As Long
  283. Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal lpString As Any) As Long
  284. Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
  285. Private Declare Sub RtlMoveMemory Lib "kernel32" (hpvDest As Any, ByVal hpvSource As Long, ByVal cbCopy As Long)
  286. '
  287. Public Const GMEM_FIXED = &H0
  288. Public Const GMEM_MOVEABLE = &H2
  289. '
  290. Public Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
  291. Public Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
  292. Public Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
  293. Public Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
  294. '
  295. Private m_lngWindowHandle   As Long
  296. Private m_colSockets        As Collection
  297. Private m_colResolvers      As Collection
  298. Private m_colMemoryBlocks   As Collection
  299. Private m_lngPreviousValue  As Long
  300. Private m_blnGetHostRecv    As Boolean
  301. Private m_blnWinsockInit    As Boolean
  302. Private m_lngMaxMsgSize     As Long
  303. Private Const WM_USER = &H400
  304. '
  305. 'Private Const RESOLVE_MESSAGE = WM_USER + 1
  306. 'Private Const SOCKET_MESSAGE = WM_USER + 2
  307. '
  308. Private m_lngResolveMessage As Long 'Added: 04-MAR-2002
  309. Private m_lngWinsockMessage As Long 'Added: 04-MAR-2002
  310. '
  311. Private Const OFFSET_4 = 4294967296#
  312. Private Const MAXINT_4 = 2147483647
  313. Private Const OFFSET_2 = 65536
  314. Private Const MAXINT_2 = 32767
  315. Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  316.     '
  317.     'This the callback function of the window created to hook
  318.     'messages sent by the Winsock service. It handles only two
  319.     'types of messages - network events for the sockets the
  320.     'WSAAsyncSelect fucntion was called for, and the messages
  321.     'sent in response to the WSAAsyncGetHostByName and
  322.     'WSAAsyncGetHostByAddress Winsock API functions.
  323.     '
  324.     'Then the message is received, this function creates illegal
  325.     'reference to the instance of the CSocket class and calls
  326.     'either the PostSocketEvent or PostGetHostEvent method of the
  327.     'class to pass that message to the class.
  328.     '
  329.     Dim objSocket           As CSocket  'the illegal reference to an
  330.                                         'instance of the CSocket class
  331.     Dim lngObjPointer       As Long     'pointer to the existing instance
  332.                                         'of the CSocket class
  333.     Dim lngEventID          As Long     'network event
  334.     Dim lngErrorCode        As Long     'code of the error message
  335.     Dim lngMemoryHandle     As Long     'descriptor of the allocated
  336.                                         'memory object
  337.     Dim lngMemoryPointer    As Long     'pointer to the allocated memory
  338.     Dim lngHostAddress      As Long     '32-bit host address
  339.     Dim strHostName         As String   'a host hame
  340.     Dim udtHost             As HostEnt  'structure of the data in the
  341.                                         'allocated memory block
  342.     Dim lngIpAddrPtr        As Long     'pointer to the IP address string
  343.     '
  344.     On Error GoTo ERORR_HANDLER
  345.     '
  346.     If uMsg = m_lngWinsockMessage Then  'Modified: 04-MAR-2002
  347.     
  348.         '
  349.         'All the pointers to the existing instances of the CSocket class
  350.         'are stored in the m_colSockets collection. Key of the collection's
  351.         'item contains a value of the socket handle, and a value of the
  352.         'collection item is the Long value that is a pointer the object,
  353.         'instance of the CSocket class. Since the wParam argument of the
  354.         'callback function contains a value of the socket handle the
  355.         'function has received the network event message for, we can use
  356.         'that value to get the object's pointer. With the pointer value
  357.         'we can create the illegal reference to the object to be able to
  358.         'call any Public or Friend subroutine of that object.
  359.         '
  360.         Set objSocket = SocketObjectFromPointer(CLng(m_colSockets("S" & wParam)))
  361.         '
  362.         'Retrieve the network event ID
  363.         lngEventID = LoWord(lParam)
  364.         'Retrieve the error code
  365.         lngErrorCode = HiWord(lParam)
  366.         '
  367.         'Forward the message to the instance of the CSocket class
  368.         objSocket.PostSocketEvent lngEventID, lngErrorCode
  369.         '
  370.     ElseIf uMsg = m_lngResolveMessage Then  'Modified: 04-MAR-2002
  371.         '
  372.         'A message has been received in response to the call of
  373.         'the WSAAsyncGetHostByName or WSAAsyncGetHostByAddress.
  374.         '
  375.         'Retrieve the error code
  376.         lngErrorCode = HiWord(lParam)
  377.         '
  378.         'The wParam parameter of the callback function contains
  379.         'the task handle returned by the original function call
  380.         '(see the ResolveHost function for more info). This value
  381.         'is used as a key of the m_colResolvers collection item.
  382.         'The item of that collection contains a pointer to the
  383.         'instance of the CSocket class. So, if we know a value
  384.         'of the task handle, we can find out the pointer to the
  385.         'object which called the ResolveHost function in this module.
  386.         '
  387.         'Get the object pointer by the task handle value
  388.         lngObjPointer = CLng(m_colResolvers("R" & wParam))
  389.         '
  390.         'A value of the pointer to the instance of the CSocket class
  391.         'is used also as a key for the m_colMemoryBlocks collection
  392.         'item that contains a handle of the allocated memory block
  393.         'object. That memory block is the buffer where the
  394.         'WSAAsyncGetHostByName and WSAAsyncGetHostByAddress functions
  395.         'store the result HOSTENT structure.
  396.         '
  397.         'Get the handle of the allocated memory block object by the
  398.         'pointer to the instance of the CSocket class.
  399.         lngMemoryHandle = CLng(m_colMemoryBlocks("S" & lngObjPointer))
  400.         '
  401.         'Lock the memory block and get address of the buffer where
  402.         'the HOSTENT structure data is stored.
  403.         lngMemoryPointer = GlobalLock(lngMemoryHandle)
  404.         '
  405.         'Create an illegal reference to the instance of the
  406.         'CSocket class
  407.         Set objSocket = SocketObjectFromPointer(lngObjPointer)
  408.         '
  409.         'Now we can forward the message to that instance.
  410.         '
  411.         If lngErrorCode <> 0 Then
  412.             '
  413.             'If the host was not resolved, pass the error code value
  414.             objSocket.PostGetHostEvent 0, 0, "", lngErrorCode
  415.             '
  416.         Else
  417.             '
  418.             'Move data from the allocated memory block to the
  419.             'HOSTENT structure - udtHost
  420.             CopyMemory udtHost, ByVal lngMemoryPointer, Len(udtHost)
  421.             '
  422.             'Get a 32-bit host address
  423.             CopyMemory lngIpAddrPtr, ByVal udtHost.hAddrList, 4
  424.             CopyMemory lngHostAddress, ByVal lngIpAddrPtr, 4
  425.             '
  426.             'Get a host name
  427.             strHostName = StringFromPointer(udtHost.hName)
  428.             '
  429.             'Call the PostGetHostEvent friend method of the objSocket
  430.             'to forward the retrieved information.
  431.             objSocket.PostGetHostEvent wParam, lngHostAddress, strHostName
  432.             '
  433.         End If
  434.         '
  435.         'The task to resolve the host name is completed, thus we don't
  436.         'need the allocated memory block anymore and corresponding items
  437.         'in the m_colMemoryBlocks and m_colResolvers collections as well.
  438.         '
  439.         'Unlock the memory block
  440.         Call GlobalUnlock(lngMemoryHandle)
  441.         'Free that memory
  442.         Call GlobalFree(lngMemoryHandle)
  443.         '
  444.         'Rremove the items from the collections
  445.         m_colMemoryBlocks.Remove "S" & lngObjPointer
  446.         m_colResolvers.Remove "R" & wParam
  447.         '
  448.         'If there are no more resolving tasks in progress,
  449.         'destroy the collection objects to free resources.
  450.         If m_colResolvers.Count = 0 Then
  451.             Set m_colMemoryBlocks = Nothing
  452.             Set m_colResolvers = Nothing
  453.         End If
  454.         '
  455.     End If
  456.     '
  457. EXIT_LABEL:
  458.     '
  459.     Exit Function
  460.     '
  461. ERORR_HANDLER:
  462.     '
  463.     'Err.Raise Err.Number, "CSocket.WindowProc", Err.Description
  464.     '
  465.     'GoTo EXIT_LABEL
  466.     '
  467. End Function
  468. Public Function RegisterSocket(ByVal lngSocketHandle As Long, ByVal lngObjectPointer As Long) As Boolean
  469. '********************************************************************************
  470. 'Author    :Oleg Gdalevich
  471. 'Date/Time :17-12-2001
  472. 'Purpose   :Adds the socket to the m_colSockets collection, and
  473. '           registers that socket with WSAAsyncSelect Winsock API
  474. '           function to receive network events for the socket.
  475. '           If this socket is the first one to be registered, the
  476. '           window and collection will be created in this function as well.
  477. 'Arguments :lngSocketHandle  - the socket handle
  478. '           lngObjectPointer - pointer to an object, instance of the CSocket class
  479. 'Returns   :If the argument is valid and no error occurred - True.
  480. '********************************************************************************
  481.     '
  482.     Dim lngEvents   As Long
  483.     Dim lngRetValue As Long
  484.     '
  485.     If m_lngWindowHandle = 0 Then
  486.         '
  487.         'We have no window to catch the network events.
  488.         'Create a new one.
  489.         m_lngWindowHandle = CreateWinsockMessageWindow
  490.         '
  491.         If m_lngWindowHandle = 0 Then
  492.             '
  493.             'Can't create a new window. Just exit to return False
  494.             Exit Function
  495.             '
  496.         End If
  497.         '
  498.     End If
  499.     '
  500.     'The m_colSockets collection holds information
  501.     'about all the sockets. If the current socket is
  502.     'the first one, create the collection object.
  503.     If m_colSockets Is Nothing Then
  504.         Set m_colSockets = New Collection
  505.     End If
  506.     '
  507.     'Add a new item to the m_colSockets collection.
  508.     'The item key contains the socket handle, and the item's data
  509.     'is the pointer to the instance of the CSocket class.
  510.     m_colSockets.Add lngObjectPointer, "S" & lngSocketHandle
  511.     '
  512.     'The lngEvents variable contains a bitmask of events we are
  513.     'going to catch with the window callback function.
  514.     lngEvents = FD_CONNECT Or FD_READ Or FD_WRITE Or FD_CLOSE Or FD_ACCEPT
  515.     '
  516.     'Force the Winsock service to send the network event notifications
  517.     'to the window which handle is m_lngWindowHandle.
  518.     lngRetValue = WSAAsyncSelect(lngSocketHandle, m_lngWindowHandle, m_lngWinsockMessage, lngEvents)    'Modified:04-MAR-2002
  519.     '
  520.     'Return value of this function
  521.     RegisterSocket = Not CBool(lngRetValue)
  522.     '
  523.     '
  524. End Function
  525. Public Function UnregisterSocket(ByVal lngSocketHandle As Long) As Boolean
  526. '********************************************************************************
  527. 'Author    :Oleg Gdalevich
  528. 'Date/Time :17-12-2001
  529. 'Purpose   :Removes the socket from the m_colSockets collection
  530. '           If it is the last socket in that collection, the window
  531. '           and colection will be destroyed as well.
  532. 'Returns   :If the argument is valid and no error occurred - True.
  533. '********************************************************************************
  534.     '
  535.     If (lngSocketHandle = INVALID_SOCKET) Or (m_colSockets Is Nothing) Then
  536.         '
  537.         'Something wrong with the caller of this function :)
  538.         'Return False
  539.         Exit Function
  540.         '
  541.     End If
  542.     '
  543.     Call WSAAsyncSelect(lngSocketHandle, m_lngWindowHandle, 0&, 0&)
  544.     '
  545.     'Remove the socket from the collection
  546.     m_colSockets.Remove "S" & lngSocketHandle
  547.     '
  548.     UnregisterSocket = True
  549.     '
  550.     '
  551.     If m_colSockets.Count = 0 Then
  552.         '
  553.         'If there are no more sockets in the collection
  554.         'destroy the collection object and the window
  555.         '
  556.         Set m_colSockets = Nothing
  557.         '
  558.         '
  559.         UnregisterSocket = DestroyWinsockMessageWindow
  560.         '
  561.     End If
  562.     '
  563. End Function
  564. Public Function ResolveHost(strHostAddress As String, ByVal lngObjectPointer As Long) As Long
  565. '********************************************************************************
  566. 'Author    :Oleg Gdalevich
  567. 'Date/Time :17-12-2001
  568. 'Purpose   :Receives requests to resolve a host address from the CSocket class.
  569. 'Returns   :If no errors occurred - ID of the request. Otherwise - 0.
  570. '********************************************************************************
  571.     '
  572.     'Since this module is supposed to serve several instances of the
  573.     'CSocket class, this function can be called to start several
  574.     'resolving tasks that could be executed simultaneously. To
  575.     'distinguish the resolving tasks the m_colResolvers collection
  576.     'is used. The key of the collection's item contains a pointer to
  577.     'the instance of the CSocket class and the item's data is the
  578.     'Request ID, the value returned by the WSAAsyncGetHostByXXXX
  579.     'Winsock API function. So in order to get the pointer to the
  580.     'instance of the CSocket class by the task ID value the following
  581.     'line of code can be used:
  582.     '
  583.     'lngObjPointer = CLng(m_colResolvers("R" & lngTaskID))
  584.     '
  585.     'The WSAAsyncGetHostByXXXX function needs the buffer (the buf argument)
  586.     'where the data received from DNS server will be stored. We cannot use
  587.     'a local byte array for this purpose as this buffer must be available
  588.     'from another subroutine in this module - WindowProc, also we cannot
  589.     'use a module level array as several tasks can be executed simultaneously
  590.     'At least, we need a dynamic module level array of arrays - too complicated.
  591.     'I decided to use Windows API functions for allocation some memory for
  592.     'each resolving task: GlobalAlloc, GlobalLock, GlobalUnlock, and GlobalFree.
  593.     '
  594.     'To distinguish those memory blocks, the m_colMemoryBlocks collection is
  595.     'used. The key of the collection's item contains value of the object
  596.     'pointer, and the item's value is a handle of the allocated memory
  597.     'block object, value returned by the GlobalAlloc function. So in order to
  598.     'get value of the handle of the allocated memory block object by the
  599.     'pointer to the instance of CSocket class we can use the following code:
  600.     '
  601.     'lngMemoryHandle = CLng(m_colMemoryBlocks("S" & lngObjPointer))
  602.     '
  603.     'Why do we need all this stuff?
  604.     '
  605.     'The problem is that the callback function give us only the resolving task
  606.     'ID value, but we need information about:
  607.     '   - where the data returned from the DNS server is stored
  608.     '   - which instance of the CSocket class we need to post the info to
  609.     '
  610.     'So, if we know the task ID value, we can find out the object pointer:
  611.     '   lngObjPointer = CLng(m_colResolvers("R" & lngTaskID))
  612.     '
  613.     'If we know the object pointer value we can find out where the data is strored:
  614.     '   lngMemoryHandle = CLng(m_colMemoryBlocks("S" & lngObjPointer))
  615.     '
  616.     'That's it. :))
  617.     '
  618.     Dim lngAddress          As Long '32-bit host address
  619.     Dim lngRequestID        As Long 'value returned by WSAAsyncGetHostByXXX
  620.     Dim lngMemoryHandle     As Long 'handle of the allocated memory block object
  621.     Dim lngMemoryPointer    As Long 'address of the memory block
  622.     '
  623.     'Allocate some memory
  624.     lngMemoryHandle = GlobalAlloc(GMEM_FIXED, MAXGETHOSTSTRUCT)
  625.     '
  626.     If lngMemoryHandle > 0 Then
  627.         '
  628.         'Lock the memory block just to get the address
  629.         'of that memory into the lngMemoryPointer variable
  630.         lngMemoryPointer = GlobalLock(lngMemoryHandle)
  631.         '
  632.         If lngMemoryPointer = 0 Then
  633.             '
  634.             'Memory allocation error
  635.             Call GlobalFree(lngMemoryHandle)
  636.             Exit Function
  637.             '
  638.         Else
  639.             'Unlock the memory block
  640.             GlobalUnlock (lngMemoryHandle)
  641.             '
  642.         End If
  643.         '
  644.     Else
  645.         '
  646.         'Memory allocation error
  647.         Exit Function
  648.         '
  649.     End If
  650.     '
  651.     'If this request is the first one, create the collections
  652.     If m_colResolvers Is Nothing Then
  653.         Set m_colMemoryBlocks = New Collection
  654.         Set m_colResolvers = New Collection
  655.     End If
  656.     '
  657.     'Remember the memory block location
  658.     m_colMemoryBlocks.Add lngMemoryHandle, "S" & CStr(lngObjectPointer)
  659.     '
  660.     'Try to get 32-bit address
  661.     lngAddress = inet_addr(strHostAddress)
  662.     '
  663.     If lngAddress = INADDR_NONE Then
  664.         '
  665.         'If strHostAddress is not an IP address, try to resolve by name
  666.         lngRequestID = WSAAsyncGetHostByName(m_lngWindowHandle, m_lngResolveMessage, strHostAddress, ByVal lngMemoryPointer, MAXGETHOSTSTRUCT)  'Modified: 04-MAR-2002
  667.         '
  668.     Else
  669.         '
  670.         'strHostAddress contains an IP address, resolve by address to get a host name
  671.         lngRequestID = WSAAsyncGetHostByAddr(m_lngWindowHandle, m_lngResolveMessage, lngAddress, 4&, AF_INET, ByVal lngMemoryPointer, MAXGETHOSTSTRUCT) 'Modified: 04-MAR-2002
  672.         '
  673.     End If
  674.     '
  675.     If lngRequestID <> 0 Then
  676.         '
  677.         'If the call of the WSAAsyncGetHostByXXXX is successful, the
  678.         'lngRequestID variable contains the task ID value.
  679.         'Remember it.
  680.         m_colResolvers.Add lngObjectPointer, "R" & CStr(lngRequestID)
  681.         '
  682.         'Return value
  683.         ResolveHost = lngRequestID
  684.         '
  685.     Else
  686.         '
  687.         'If the call of the WSAAsyncGetHostByXXXX is not successful,
  688.         'remove the item from the m_colMemoryBlocks collection.
  689.         m_colMemoryBlocks.Remove ("S" & CStr(lngObjectPointer))
  690.         '
  691.         'Free allocated memory block
  692.         Call GlobalFree(lngMemoryHandle)
  693.         '
  694.         'If there are no more resolving tasks in progress,
  695.         'destroy the collection objects.
  696.         If m_colResolvers.Count = 0 Then
  697.             Set m_colResolvers = Nothing
  698.             Set m_colMemoryBlocks = Nothing
  699.         End If
  700.         '
  701.     End If
  702.     '
  703. End Function
  704. Private Function CreateWinsockMessageWindow() As Long
  705. '********************************************************************************
  706. 'Author    :Oleg Gdalevich
  707. 'Date/Time :17-12-2001
  708. 'Purpose   :Creates a window to hook the winsock messages
  709. 'Returns   :The window handle
  710. '********************************************************************************
  711.     '
  712.     'Create a window. It will be used for hooking messages for registered
  713.     'sockets, and we'll not see this window as the ShowWindow is never called.
  714.     m_lngWindowHandle = CreateWindowEx(0&, "STATIC", "SOCKET_WINDOW", 0&, 0&, 0&, 0&, 0&, 0&, 0&, App.hInstance, ByVal 0&)
  715.     '
  716.     If m_lngWindowHandle = 0 Then
  717.         '
  718.         'I really don't know - is this possible? Probably - yes,
  719.         'due the lack of the system resources, for example.
  720.         '
  721.         'In this case the function returns 0.
  722.         '
  723.     Else
  724.         '
  725.         'Register a callback function for the window created a moment ago in this function
  726.         'm_lngPreviousValue - stores the returned value that is the pointer to the previous
  727.         'callback window function. We'll need this value to destroy the window.
  728.         m_lngPreviousValue = SetWindowLong(m_lngWindowHandle, GWL_WNDPROC, AddressOf WindowProc)
  729.         '
  730.         'Just to let the caller know that the function was executed successfully
  731.         CreateWinsockMessageWindow = m_lngWindowHandle
  732.         '
  733.         '
  734.     End If
  735.     '
  736. End Function
  737. Private Function DestroyWinsockMessageWindow() As Boolean
  738. '********************************************************************************
  739. 'Author    :Oleg Gdalevich
  740. 'Date/Time :17-12-2001
  741. 'Purpose   :Destroyes the window
  742. 'Returns   :If the window was destroyed successfully - True.
  743. '********************************************************************************
  744.     '
  745.     On Error GoTo ERR_HANDLER
  746.     '
  747.     'Return the previous window procedure
  748.     SetWindowLong m_lngWindowHandle, GWL_WNDPROC, m_lngPreviousValue
  749.     'Destroy the window
  750.     DestroyWindow m_lngWindowHandle
  751.     '
  752.     '
  753.     'Reset the window handle variable
  754.     m_lngWindowHandle = 0
  755.     'If no errors occurred, the function returns True
  756.     DestroyWinsockMessageWindow = True
  757.     '
  758. ERR_HANDLER:
  759. End Function
  760. Private Function SocketObjectFromPointer(ByVal lngPointer As Long) As CSocket
  761.     '
  762.     Dim objSocket As CSocket
  763.     '
  764.     CopyMemory objSocket, lngPointer, 4&
  765.     Set SocketObjectFromPointer = objSocket
  766.     CopyMemory objSocket, 0&, 4&
  767.     '
  768. End Function
  769. Private Function LoWord(lngValue As Long) As Long
  770.    LoWord = (lngValue And &HFFFF&)
  771. End Function
  772. Private Function HiWord(lngValue As Long) As Long
  773.     '
  774.     If (lngValue And &H80000000) = &H80000000 Then
  775.         HiWord = ((lngValue And &H7FFF0000)  &H10000) Or &H8000&
  776.     Else
  777.         HiWord = (lngValue And &HFFFF0000)  &H10000
  778.     End If
  779.     '
  780. End Function
  781. Public Function GetErrorDescription(ByVal lngErrorCode As Long) As String
  782.     '
  783.     Dim strDesc As String
  784.     '
  785.     Select Case lngErrorCode
  786.         '
  787.         Case WSAEACCES
  788.             strDesc = "Permission denied."
  789.         Case WSAEADDRINUSE
  790.             strDesc = "Address already in use."
  791.         Case WSAEADDRNOTAVAIL
  792.             strDesc = "Cannot assign requested address."
  793.         Case WSAEAFNOSUPPORT
  794.             strDesc = "Address family not supported by protocol family."
  795.         Case WSAEALREADY
  796.             strDesc = "Operation already in progress."
  797.         Case WSAECONNABORTED
  798.             strDesc = "Software caused connection abort."
  799.         Case WSAECONNREFUSED
  800.             strDesc = "Connection refused."
  801.         Case WSAECONNRESET
  802.             strDesc = "Connection reset by peer."
  803.         Case WSAEDESTADDRREQ
  804.             strDesc = "Destination address required."
  805.         Case WSAEFAULT
  806.             strDesc = "Bad address."
  807.         Case WSAEHOSTDOWN
  808.             strDesc = "Host is down."
  809.         Case WSAEHOSTUNREACH
  810.             strDesc = "No route to host."
  811.         Case WSAEINPROGRESS
  812.             strDesc = "Operation now in progress."
  813.         Case WSAEINTR
  814.             strDesc = "Interrupted function call."
  815.         Case WSAEINVAL
  816.             strDesc = "Invalid argument."
  817.         Case WSAEISCONN
  818.             strDesc = "Socket is already connected."
  819.         Case WSAEMFILE
  820.             strDesc = "Too many open files."
  821.         Case WSAEMSGSIZE
  822.             strDesc = "Message too long."
  823.         Case WSAENETDOWN
  824.             strDesc = "Network is down."
  825.         Case WSAENETRESET
  826.             strDesc = "Network dropped connection on reset."
  827.         Case WSAENETUNREACH
  828.             strDesc = "Network is unreachable."
  829.         Case WSAENOBUFS
  830.             strDesc = "No buffer space available."
  831.         Case WSAENOPROTOOPT
  832.             strDesc = "Bad protocol option."
  833.         Case WSAENOTCONN
  834.             strDesc = "Socket is not connected."
  835.         Case WSAENOTSOCK
  836.             strDesc = "Socket operation on nonsocket."
  837.         Case WSAEOPNOTSUPP
  838.             strDesc = "Operation not supported."
  839.         Case WSAEPFNOSUPPORT
  840.             strDesc = "Protocol family not supported."
  841.         Case WSAEPROCLIM
  842.             strDesc = "Too many processes."
  843.         Case WSAEPROTONOSUPPORT
  844.             strDesc = "Protocol not supported."
  845.         Case WSAEPROTOTYPE
  846.             strDesc = "Protocol wrong type for socket."
  847.         Case WSAESHUTDOWN
  848.             strDesc = "Cannot send after socket shutdown."
  849.         Case WSAESOCKTNOSUPPORT
  850.             strDesc = "Socket type not supported."
  851.         Case WSAETIMEDOUT
  852.             strDesc = "Connection timed out."
  853.         Case WSATYPE_NOT_FOUND
  854.             strDesc = "Class type not found."
  855.         Case WSAEWOULDBLOCK
  856.             strDesc = "Resource temporarily unavailable."
  857.         Case WSAHOST_NOT_FOUND
  858.             strDesc = "Host not found."
  859.         Case WSANOTINITIALISED
  860.             strDesc = "Successful WSAStartup not yet performed."
  861.         Case WSANO_DATA
  862.             strDesc = "Valid name, no data record of requested type."
  863.         Case WSANO_RECOVERY
  864.             strDesc = "This is a nonrecoverable error."
  865.         Case WSASYSCALLFAILURE
  866.             strDesc = "System call failure."
  867.         Case WSASYSNOTREADY
  868.             strDesc = "Network subsystem is unavailable."
  869.         Case WSATRY_AGAIN
  870.             strDesc = "Nonauthoritative host not found."
  871.         Case WSAVERNOTSUPPORTED
  872.             strDesc = "Winsock.dll version out of range."
  873.         Case WSAEDISCON
  874.             strDesc = "Graceful shutdown in progress."
  875.         Case Else
  876.             strDesc = "Unknown error."
  877.     End Select
  878.     '
  879.     GetErrorDescription = strDesc
  880.     '
  881. End Function
  882. Public Function InitWinsockService() As Long
  883.     '
  884.     'This functon does two things; it initializes the Winsock
  885.     'service and returns value of maximum size of the UDP
  886.     'message. Since this module is supposed to serve multiple
  887.     'instances of the CSocket class, this function can be
  888.     'called several times. But we need to call the WSAStartup
  889.     'Winsock API function only once when the first instance of
  890.     'the CSocket class is created.
  891.     '
  892.     Dim lngRetVal       As Long     'value returned by WSAStartup
  893.     Dim strErrorMsg     As String   'error description string
  894.     Dim udtWinsockData  As WSADATA  'structure to pass to WSAStartup as an argument
  895.     '
  896.     If Not m_blnWinsockInit Then
  897.         '
  898.         'start up winsock service
  899.         lngRetVal = WSAStartup(&H101, udtWinsockData)
  900.         '
  901.         If lngRetVal <> 0 Then
  902.             '
  903.             'The system cannot load the Winsock library.
  904.             '
  905.             Select Case lngRetVal
  906.                 Case WSASYSNOTREADY
  907.                     strErrorMsg = "The underlying network subsystem is not " & _
  908.                                   "ready for network communication."
  909.                 Case WSAVERNOTSUPPORTED
  910.                     strErrorMsg = "The version of Windows Sockets API support " & _
  911.                                   "requested is not provided by this particular " & _
  912.                                   "Windows Sockets implementation."
  913.                 Case WSAEINVAL
  914.                     strErrorMsg = "The Windows Sockets version specified by the " & _
  915.                                   "application is not supported by this DLL."
  916.             End Select
  917.             '
  918.             Err.Raise Err.LastDllError, "MSocketSupport.InitWinsockService", strErrorMsg
  919.             '
  920.         Else
  921.             '
  922.             'The Winsock library is loaded successfully.
  923.             '
  924.             m_blnWinsockInit = True
  925.             '
  926.             'This function returns returns value of
  927.             'maximum size of the UDP message
  928.             m_lngMaxMsgSize = IntegerToUnsigned(udtWinsockData.iMaxUdpDg)
  929.             InitWinsockService = m_lngMaxMsgSize
  930.             '
  931.             m_lngResolveMessage = RegisterWindowMessage(App.EXEName & ".ResolveMessage")    'Added: 04-MAR-2002
  932.             m_lngWinsockMessage = RegisterWindowMessage(App.EXEName & ".WinsockMessage")    'Added: 04-MAR-2002
  933.             '
  934.             '
  935.         End If
  936.         '
  937.     Else
  938.         '
  939.         'If this function has been called before by another
  940.         'instance of the CSocket class, the code to init the
  941.         'Winsock service must not be executed, but the function
  942.         'returns maximum size of the UDP message anyway.
  943.         InitWinsockService = m_lngMaxMsgSize
  944.         '
  945.     End If
  946.     '
  947. End Function
  948. Public Sub CleanupWinsock()
  949. '********************************************************************************
  950. 'This subroutine is called from the Class_Terminate() event
  951. 'procedure of any instance of the CSocket class. But the WSACleanup
  952. 'Winsock API function is called only if the calling object is the
  953. 'last instance of the CSocket class within the current process.
  954. '********************************************************************************
  955.     '
  956.     'If the Winsock library was loaded
  957.     'before and there are no more sockets.
  958.     If m_blnWinsockInit And m_colSockets Is Nothing Then
  959.         '
  960.         'Unload library and free the system resources
  961.         Call WSACleanup
  962.         '
  963.         'Turn off the m_blnWinsockInit flag variable
  964.         m_blnWinsockInit = False
  965.         '
  966.     End If
  967.     '
  968. End Sub
  969. Public Function StringFromPointer(ByVal lPointer As Long) As String
  970.     '
  971.     Dim strTemp As String
  972.     Dim lRetVal As Long
  973.     '
  974.     'prepare the strTemp buffer
  975.     strTemp = String$(lstrlen(ByVal lPointer), 0)
  976.     '
  977.     'copy the string into the strTemp buffer
  978.     lRetVal = lstrcpy(ByVal strTemp, ByVal lPointer)
  979.     '
  980.     'return a string
  981.     If lRetVal Then StringFromPointer = strTemp
  982.     '
  983. End Function
  984. Public Function UnsignedToLong(Value As Double) As Long
  985.     '
  986.     'The function takes a Double containing a value in the