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.

576 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. buffsock.cxx
  5. Abstract:
  6. Implements the BUFFERED_SOCKET class.
  7. Author:
  8. Keith Moore (keithmo) 02-Dec-1996
  9. Revision History:
  10. --*/
  11. #include "precomp.hxx"
  12. #pragma hdrstop
  13. //
  14. // Private constants.
  15. //
  16. #define BUFFER_LENGTH 4096 // bytes
  17. #define ALLOC_MEM(cb) (PVOID)::LocalAlloc(LPTR, (cb))
  18. #define FREE_MEM(p) (VOID)::LocalFree((HLOCAL)(p))
  19. //
  20. // Private types.
  21. //
  22. //
  23. // Private globals.
  24. //
  25. LONG BUFFERED_SOCKET::m_InitCount = -1;
  26. //
  27. // Private prototypes.
  28. //
  29. //
  30. // Public functions.
  31. //
  32. BUFFERED_SOCKET::BUFFERED_SOCKET()
  33. {
  34. m_Socket = INVALID_SOCKET;
  35. m_Buffer = NULL;
  36. m_BufferLength = 0;
  37. m_BytesAvailable = NULL;
  38. m_Offset = 0;
  39. m_Initialized = FALSE;
  40. } // BUFFERED_SOCKET::BUFFERED_SOCKET()
  41. BUFFERED_SOCKET::~BUFFERED_SOCKET()
  42. {
  43. if( m_Socket != INVALID_SOCKET ) {
  44. ::closesocket( m_Socket );
  45. }
  46. if( m_Buffer != NULL ) {
  47. FREE_MEM( m_Buffer );
  48. }
  49. if( ::InterlockedDecrement( &BUFFERED_SOCKET::m_InitCount ) == -1 ) {
  50. ::WSACleanup();
  51. }
  52. } // BUFFERED_SOCKET::~BUFFERED_SOCKET()
  53. INT
  54. BUFFERED_SOCKET::InitializeClient(
  55. LPSTR HostName,
  56. USHORT Port
  57. )
  58. {
  59. LPHOSTENT hostent;
  60. INT result;
  61. SOCKADDR_IN addr;
  62. result = CommonInitialize();
  63. if( result != 0 ) {
  64. return result;
  65. }
  66. addr.sin_family = AF_INET;
  67. addr.sin_port = htons( Port );
  68. addr.sin_addr.s_addr = ::inet_addr( HostName );
  69. if( addr.sin_addr.s_addr == INADDR_NONE ) {
  70. hostent = ::gethostbyname( HostName );
  71. if( hostent == NULL ) {
  72. return ::WSAGetLastError();
  73. }
  74. addr.sin_addr.s_addr = *(PULONG)hostent->h_addr_list[0];
  75. }
  76. return InitializeClient( &addr );
  77. } // BUFFERED_SOCKET::InitializeClient
  78. INT
  79. BUFFERED_SOCKET::InitializeClient(
  80. LPSOCKADDR_IN HostAddress
  81. )
  82. {
  83. INT result;
  84. result = CommonInitialize();
  85. if( result != 0 ) {
  86. return result;
  87. }
  88. if( m_Socket == INVALID_SOCKET ) {
  89. m_Socket = ::socket(
  90. AF_INET,
  91. SOCK_STREAM,
  92. 0
  93. );
  94. if( m_Socket == INVALID_SOCKET ) {
  95. return ::WSAGetLastError();
  96. }
  97. }
  98. if( ::connect(
  99. m_Socket,
  100. (SOCKADDR *)HostAddress,
  101. sizeof(*HostAddress)
  102. ) == SOCKET_ERROR ) {
  103. return ::WSAGetLastError();
  104. }
  105. return InitializeClient( m_Socket );
  106. } // BUFFERED_SOCKET::InitializeClient
  107. INT
  108. BUFFERED_SOCKET::InitializeClient(
  109. SOCKET Socket
  110. )
  111. {
  112. INT result;
  113. result = CommonInitialize();
  114. if( result != 0 ) {
  115. return result;
  116. }
  117. m_Socket = Socket;
  118. return 0;
  119. } // BUFFERED_SOCKET::InitializeClient
  120. INT
  121. BUFFERED_SOCKET::InitializeServer(
  122. USHORT Port
  123. )
  124. {
  125. INT result;
  126. SOCKET tmpSocket;
  127. SOCKADDR_IN addr;
  128. result = CommonInitialize();
  129. if( result != 0 ) {
  130. return result;
  131. }
  132. tmpSocket = ::socket(
  133. AF_INET,
  134. SOCK_STREAM,
  135. 0
  136. );
  137. if( tmpSocket == INVALID_SOCKET ) {
  138. return ::WSAGetLastError();
  139. }
  140. addr.sin_family = AF_INET;
  141. addr.sin_port = htons( Port );
  142. addr.sin_addr.s_addr = INADDR_ANY;
  143. result = ::bind(
  144. tmpSocket,
  145. (SOCKADDR *)&addr,
  146. sizeof(addr)
  147. );
  148. if( result == SOCKET_ERROR ) {
  149. result = ::WSAGetLastError();
  150. ::closesocket( tmpSocket );
  151. return result;
  152. }
  153. result = ::listen(
  154. tmpSocket,
  155. 1
  156. );
  157. if( result == SOCKET_ERROR ) {
  158. result = ::WSAGetLastError();
  159. ::closesocket( tmpSocket );
  160. return result;
  161. }
  162. m_Socket = ::accept(
  163. tmpSocket,
  164. NULL,
  165. NULL
  166. );
  167. if( m_Socket == INVALID_SOCKET ) {
  168. result = ::WSAGetLastError();
  169. ::closesocket( tmpSocket );
  170. return result;
  171. }
  172. ::closesocket( tmpSocket );
  173. return 0;
  174. } // BUFFERED_SOCKET::InitializeClient
  175. INT
  176. BUFFERED_SOCKET::Send(
  177. PVOID Buffer,
  178. LPDWORD BufferLength
  179. )
  180. {
  181. INT result;
  182. result = ::send(
  183. m_Socket,
  184. (CHAR *)Buffer,
  185. (INT)*BufferLength,
  186. 0
  187. );
  188. if( result == SOCKET_ERROR ) {
  189. return ::WSAGetLastError();
  190. }
  191. *BufferLength = (DWORD)result;
  192. return 0;
  193. } // BUFFERED_SOCKET::Send
  194. INT
  195. BUFFERED_SOCKET::Recv(
  196. PVOID Buffer,
  197. LPDWORD BufferLength
  198. )
  199. {
  200. INT result;
  201. result = ::recv(
  202. m_Socket,
  203. (CHAR *)Buffer,
  204. (INT)*BufferLength,
  205. 0
  206. );
  207. if( result == SOCKET_ERROR ) {
  208. return ::WSAGetLastError();
  209. }
  210. *BufferLength = (DWORD)result;
  211. return 0;
  212. } // BUFFERED_SOCKET::Recv
  213. INT
  214. BUFFERED_SOCKET::SendFrame(
  215. PVOID Buffer,
  216. LPDWORD BufferLength
  217. )
  218. {
  219. INT result;
  220. WSABUF buffers[2];
  221. buffers[0].len = sizeof(DWORD);
  222. buffers[0].buf = (CHAR *)BufferLength;
  223. buffers[1].len = *BufferLength;
  224. buffers[1].buf = (CHAR *)Buffer;
  225. result = ::WSASend(
  226. m_Socket,
  227. buffers,
  228. 2,
  229. BufferLength,
  230. 0,
  231. NULL,
  232. NULL
  233. );
  234. if( result == SOCKET_ERROR ) {
  235. return ::WSAGetLastError();
  236. }
  237. *BufferLength -= sizeof(DWORD);
  238. return 0;
  239. } // BUFFERED_SOCKET::SendFrame
  240. INT
  241. BUFFERED_SOCKET::RecvFrame(
  242. PVOID Buffer,
  243. LPDWORD BufferLength
  244. )
  245. {
  246. INT result;
  247. DWORD frameLength;
  248. result = BufferedRecv( &frameLength, sizeof(frameLength) );
  249. if( result != 0 ) {
  250. return result;
  251. }
  252. if( frameLength > *BufferLength ) {
  253. return WSAEMSGSIZE;
  254. }
  255. result = BufferedRecv( Buffer, frameLength );
  256. if( result != 0 ) {
  257. return result;
  258. }
  259. *BufferLength = frameLength;
  260. return 0;
  261. } // BUFFERED_SOCKET::RecvFrom
  262. INT
  263. BUFFERED_SOCKET::SendBlob(
  264. PIIS_CRYPTO_BLOB Blob
  265. )
  266. {
  267. DWORD length;
  268. length = IISCryptoGetBlobLength( Blob );
  269. return SendFrame(
  270. (PVOID)Blob,
  271. &length
  272. );
  273. } // BUFFERED_SOCKET::SendFrame
  274. INT
  275. BUFFERED_SOCKET::RecvBlob(
  276. PIIS_CRYPTO_BLOB * ppBlob
  277. )
  278. {
  279. INT result;
  280. DWORD blobLength;
  281. PIIS_CRYPTO_BLOB blob;
  282. result = BufferedRecv( &blobLength, sizeof(blobLength) );
  283. if( result != 0 ) {
  284. return result;
  285. }
  286. blob = (PIIS_CRYPTO_BLOB)ALLOC_MEM(blobLength);
  287. if( blob == NULL ) {
  288. return WSAENOBUFS;
  289. }
  290. result = BufferedRecv( blob, blobLength );
  291. if( result != 0 ) {
  292. return result;
  293. }
  294. *ppBlob = blob;
  295. return 0;
  296. } // BUFFERED_SOCKET::RecvFrom
  297. //
  298. // Private functions.
  299. //
  300. INT
  301. BUFFERED_SOCKET::BufferedRecv(
  302. PVOID Buffer,
  303. DWORD BufferLength
  304. )
  305. {
  306. PCHAR buffer = (PCHAR)Buffer;
  307. DWORD bytesToCopy;
  308. INT result;
  309. while( BufferLength > 0 ) {
  310. if( m_BytesAvailable == 0 ) {
  311. m_BytesAvailable = m_BufferLength;
  312. result = Recv( m_Buffer, &m_BytesAvailable );
  313. if( result != 0 ) {
  314. return result;
  315. }
  316. if( m_BytesAvailable == 0 ) {
  317. return WSAEMSGSIZE;
  318. }
  319. m_Offset = 0;
  320. }
  321. bytesToCopy = min( m_BytesAvailable, BufferLength );
  322. memcpy(
  323. buffer,
  324. (PCHAR)m_Buffer + m_Offset,
  325. bytesToCopy
  326. );
  327. m_Offset += bytesToCopy;
  328. m_BytesAvailable -= bytesToCopy;
  329. BufferLength -= bytesToCopy;
  330. }
  331. return 0;
  332. } // BUFFERED_SOCKET::BufferedRecv
  333. INT
  334. BUFFERED_SOCKET::CommonInitialize()
  335. {
  336. INT result = 0;
  337. WSADATA data;
  338. if( m_Initialized ) {
  339. return 0;
  340. }
  341. if( m_Buffer == NULL ) {
  342. m_Buffer = ALLOC_MEM( BUFFER_LENGTH );
  343. if( m_Buffer == NULL ) {
  344. return WSAENOBUFS;
  345. }
  346. }
  347. m_BufferLength = BUFFER_LENGTH;
  348. m_BytesAvailable = 0;
  349. m_Offset = 0;
  350. if( ::InterlockedIncrement( &BUFFERED_SOCKET::m_InitCount ) == 0 ) {
  351. result = ::WSAStartup( 0x0202, &data );
  352. }
  353. m_Initialized = ( result == 0 );
  354. return result;
  355. } // BUFFERED_SOCKET::CommonInitialize