Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

266 lines
6.3 KiB

  1. /*************************************************************************************************\
  2. *
  3. * SOCKETS.C
  4. *
  5. * This file contains routines used for establishing Sockets connections.
  6. *
  7. \*************************************************************************************************/
  8. #include <windows.h>
  9. #include <winsock.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "gutils.h"
  13. /* ---- Local variables and #defines ----
  14. */
  15. WSADATA WSAData;
  16. #define MAX_PENDING_CONNECTS 4 /* The backlog allowed for listen() */
  17. static PCHAR DBG_WSAERRORTEXT = "%s failed at line %d in %s: Error %d\n";
  18. #define WSAERROR(func) \
  19. // ERROR(( DBG_WSAERRORTEXT, func, __LINE__, __FILE__, WSAGetLastError() ))
  20. /* Error message macro:
  21. */
  22. #ifdef SOCKETS
  23. #undef SOCKETS
  24. #endif
  25. #define SOCKETS( args ) DBGMSG( DBG_SOCKETS, args )
  26. /* ---- Local function prototypes ----
  27. */
  28. /* ---- Function definitions ----
  29. */
  30. /****************************************************************************\
  31. *
  32. * FUNCTION: FillAddr(HWND, PSOCKADDR_IN, LPSTR)
  33. *
  34. * PURPOSE: Retrieves the IP address and port number.
  35. *
  36. * COMMENTS:
  37. * This function is called in two conditions.
  38. * 1.) When a client is preparing to call connect(), or
  39. * 2.) When a server host is going to call bind(), listen() and
  40. * accept().
  41. * In both situations, a SOCKADDR_IN structure is filled.
  42. * However, different fields are filled depending on the condition.
  43. *
  44. * ASSUMPTION:
  45. * bConnect determines if the socket address is being set up for a listen()
  46. * (bConnect == TRUE) or a connect() (bConnect == FALSE)
  47. *
  48. *
  49. *\***************************************************************************/
  50. BOOL
  51. FillAddr(
  52. HWND hWnd,
  53. PSOCKADDR_IN psin,
  54. LPSTR pServerName
  55. )
  56. {
  57. DWORD dwSize;
  58. PHOSTENT phe;
  59. char szTemp[200];
  60. CHAR szBuff[80];
  61. psin->sin_family = AF_INET;
  62. /*
  63. ** If we are setting up for a listen() call (pServerName == NULL),
  64. ** fill servent with our address.
  65. */
  66. if (!pServerName)
  67. {
  68. /*
  69. ** Retrieve my ip address. Assuming the hosts file in
  70. ** in %systemroot%/system/drivers/etc/hosts contains my computer name.
  71. */
  72. dwSize = sizeof(szBuff);
  73. GetComputerName(szBuff, &dwSize);
  74. CharLowerBuff( szBuff, dwSize );
  75. }
  76. /* gethostbyname() fails if the remote name is in upper-case characters!
  77. */
  78. else
  79. {
  80. strcpy( szBuff, pServerName );
  81. CharLowerBuff( szBuff, strlen( szBuff ) );
  82. }
  83. phe = gethostbyname(szBuff);
  84. if (phe == NULL) {
  85. wsprintf( szTemp, "%d is the error. Make sure '%s' is"
  86. " listed in the hosts file.", WSAGetLastError(), szBuff );
  87. MessageBox(hWnd, szTemp, "gethostbyname() failed.", MB_OK);
  88. return FALSE;
  89. }
  90. memcpy((char FAR *)&(psin->sin_addr), phe->h_addr, phe->h_length);
  91. return TRUE;
  92. }
  93. /* SocketConnect
  94. *
  95. * The counterpart to SocketListen.
  96. * Creates a socket and initializes it with the supplied TCP/IP
  97. * port address, then connects to a listening server.
  98. * The returned socket can be used to send() and recv() data.
  99. *
  100. * Parameters: TCPPort - The port to use.
  101. * pSocket - A pointer to a SOCKET, which will be filled in
  102. * if the call succeeds.
  103. *
  104. * Returns: TRUE if successful.
  105. *
  106. *
  107. * Created 16 November 1993 (andrewbe)
  108. *
  109. */
  110. BOOL SocketConnect( LPSTR pstrServerName, u_short TCPPort, SOCKET *pSocket )
  111. {
  112. SOCKET Socket;
  113. SOCKADDR_IN dest_sin; /* DESTination Socket INternet */
  114. /* Create a socket:
  115. */
  116. Socket = socket( AF_INET, SOCK_STREAM, 0);
  117. if (Socket == INVALID_SOCKET)
  118. {
  119. WSAERROR( "socket()");
  120. return FALSE;
  121. }
  122. if (!FillAddr( NULL, &dest_sin, pstrServerName ) )
  123. {
  124. return FALSE;
  125. }
  126. dest_sin.sin_port = htons( TCPPort );
  127. /* Someone must be listen()ing for this to succeed:
  128. */
  129. if (connect( Socket, (PSOCKADDR)&dest_sin, sizeof( dest_sin)) == SOCKET_ERROR)
  130. {
  131. closesocket( Socket );
  132. WSAERROR("connect()");
  133. MessageBox(NULL,
  134. "ERROR: Could not connect the socket. "
  135. "It may be that the hardcoded Sleep() value "
  136. "on the caller's side is not long enough.",
  137. "Video Conferencing Prototype", MB_OK);
  138. return FALSE;
  139. }
  140. *pSocket = Socket;
  141. return TRUE;
  142. }
  143. /* SocketListen
  144. *
  145. * The counterpart to SocketConnect.
  146. * Creates a socket and initializes it with the supplied TCP/IP
  147. * port address, then listens for a connecting client.
  148. * The returned socket can be used to send() and recv() data.
  149. *
  150. * Parameters: TCPPort - The port to use.
  151. * pSocket - A pointer to a SOCKET, which will be filled in
  152. * if the call succeeds.
  153. *
  154. * Returns: TRUE if successful.
  155. *
  156. *
  157. * Created 16 November 1993 (andrewbe)
  158. *
  159. */
  160. BOOL SocketListen( u_short TCPPort, SOCKET *pSocket )
  161. {
  162. SOCKET Socket;
  163. SOCKADDR_IN local_sin; /* Local socket - internet style */
  164. SOCKADDR_IN acc_sin; /* Accept socket address - internet style */
  165. int acc_sin_len; /* Accept socket address length */
  166. /* Create a socket:
  167. */
  168. Socket = socket( AF_INET, SOCK_STREAM, 0);
  169. if (Socket == INVALID_SOCKET)
  170. {
  171. WSAERROR( "socket()");
  172. return FALSE;
  173. }
  174. /*
  175. ** Retrieve the IP address and TCP Port number
  176. */
  177. if (!FillAddr(NULL, &local_sin, NULL ))
  178. {
  179. return FALSE;
  180. }
  181. /*
  182. ** Associate an address with a socket. (bind)
  183. */
  184. local_sin.sin_port = htons( TCPPort );
  185. if (bind( Socket, (struct sockaddr FAR *)&local_sin, sizeof(local_sin)) == SOCKET_ERROR)
  186. {
  187. WSAERROR( "bind()" );
  188. return FALSE;
  189. }
  190. if (listen( Socket, MAX_PENDING_CONNECTS ) == SOCKET_ERROR)
  191. {
  192. WSAERROR( "listen()" );
  193. return FALSE;
  194. }
  195. acc_sin_len = sizeof(acc_sin);
  196. Socket = accept( Socket, (struct sockaddr *)&acc_sin, (int *)&acc_sin_len );
  197. if (Socket == INVALID_SOCKET)
  198. {
  199. WSAERROR( "accept()" );
  200. return FALSE;
  201. }
  202. *pSocket = Socket;
  203. return TRUE;
  204. }