/private/net/sockets/winsock2/dll/ws2_rp/msrlsp/rsocket.cpp

https://github.com/pustladi/Windows-2000 · C++ · 366 lines · 214 code · 59 blank · 93 comment · 21 complexity · 5939607cf0f22f8070485ee6e96de1d1 MD5 · raw file

  1. //---------------------------------------------------------------------------
  2. // Copyright (c) 1997 Microsoft Corporation
  3. // Copyright (c) 1996 Intel Corporation
  4. //
  5. // rsocket.cpp
  6. //
  7. // Implementation of the RSOCKET class used by the restricted processes for
  8. // a TCP/IP sockets.
  9. //
  10. // Revision History:
  11. //
  12. // edwardr 11-05-97 Initial version. Modeled after dsocket.cpp
  13. // example code.
  14. //
  15. //---------------------------------------------------------------------------
  16. #include "precomp.h"
  17. #include "globals.h"
  18. // Variables to keep track of the sockets we have open
  19. LIST_ENTRY g_SocketList;
  20. RTL_CRITICAL_SECTION g_csSocketList;
  21. //---------------------------------------------------------------------------
  22. // RSOCKET::RSOCKET()
  23. //
  24. // RSOCKET object constructor. Note: RSOCKET::Initialize() does all of the
  25. // real initialization.
  26. //---------------------------------------------------------------------------
  27. RSOCKET::RSOCKET()
  28. {
  29. // Set our data members to known values
  30. m_Provider = NULL;
  31. m_SocketHandle = (SOCKET)SOCKET_ERROR;
  32. m_dwCatalogEntryId = 0;
  33. m_dwContext = INVALID_SOCKET;
  34. m_lAsyncEvents = 0;
  35. m_hAsyncWindow = NULL;
  36. m_AsyncSocket = INVALID_SOCKET;
  37. m_uiAsyncMessage = 0;
  38. m_hNetEvent = 0;
  39. m_pIRestrictedProcess = 0;
  40. }
  41. //---------------------------------------------------------------------------
  42. // RSOCKET::Initialize()
  43. //
  44. // Completes the initialization of the RSOCKET object. This must be the
  45. // first member function called for the RSOCKET object. This procedure
  46. // should be called only once for the object.
  47. //
  48. // Provider - Supplies a reference to the RPROVIDER object associated with
  49. // this RSOCKET instance.
  50. //
  51. // ProviderSocket - The socket handle returned from the lower level provider.
  52. //
  53. // CatalogEntryId - The CatalogEntryId for the provider referenced by
  54. // m_Provider.
  55. //
  56. // Context - The socket handle returned from WPUCreateSocketHandle().
  57. //
  58. // The function returns NO_ERROR if successful. Otherwise it
  59. // returns an appropriate Winsock error code if the initialization
  60. // cannot be completed.
  61. //---------------------------------------------------------------------------
  62. INT RSOCKET::Initialize( IN PRPROVIDER Provider,
  63. IN SOCKET ProviderSocket,
  64. IN DWORD dwCatalogEntryId,
  65. IN ULONG_PTR dwContext,
  66. IN IRestrictedProcess *pIRestrictedProcess )
  67. {
  68. // Store the provider and process object.
  69. m_Provider = Provider;
  70. m_SocketHandle = ProviderSocket;
  71. m_dwCatalogEntryId = dwCatalogEntryId;
  72. m_dwContext = dwContext;
  73. m_pIRestrictedProcess = pIRestrictedProcess;
  74. DEBUGF( DBG_TRACE,
  75. ("Initializing socket %X\n",this));
  76. return NO_ERROR;
  77. }
  78. //---------------------------------------------------------------------------
  79. // RSOCKET::~RSOCKET()
  80. //
  81. // RSOCKET destructor. Cleanup before the RSOCKET instance is deleted.
  82. //---------------------------------------------------------------------------
  83. RSOCKET::~RSOCKET()
  84. {
  85. gWorkerThread->UnregisterSocket( this );
  86. if (m_pIRestrictedProcess)
  87. {
  88. m_pIRestrictedProcess->Release(); // Shouldn't need a loop...
  89. m_pIRestrictedProcess = 0;
  90. }
  91. DEBUGF( DBG_TRACE, ("Destroying socket %X\n",this));
  92. }
  93. //---------------------------------------------------------------------------
  94. // RSOCKET::RegisterAsyncOperation()
  95. //
  96. // Registers an event mask that will signal the specified window with the
  97. // specified message when one of the events occurs.
  98. //
  99. // Returns NO_ERROR on success, or a Winsock error code.
  100. //---------------------------------------------------------------------------
  101. INT RSOCKET::RegisterAsyncOperation( HWND Window,
  102. UINT Message,
  103. LONG lEvents )
  104. {
  105. INT ReturnCode;
  106. ReturnCode = WSAENOBUFS;
  107. if (lEvents)
  108. {
  109. //Create a WIN32 event to hand to the worker thread.
  110. if (NULL == m_hNetEvent)
  111. {
  112. m_hNetEvent = CreateEvent( NULL,
  113. TRUE,
  114. FALSE,
  115. NULL);
  116. }
  117. // Write down the user request
  118. if (m_hNetEvent)
  119. {
  120. m_hAsyncWindow = Window;
  121. m_AsyncSocket = m_dwContext;
  122. m_uiAsyncMessage= Message;
  123. m_lAsyncEvents = lEvents;
  124. // Register this socket with the worker thread.
  125. ReturnCode = gWorkerThread->RegisterSocket( this );
  126. }
  127. }
  128. else
  129. {
  130. DEBUGF( DBG_TRACE,
  131. ("Unegistering socket %X\n",this));
  132. m_hAsyncWindow = NULL;
  133. m_AsyncSocket = INVALID_SOCKET;
  134. m_uiAsyncMessage= 0;
  135. m_lAsyncEvents = 0;
  136. ReturnCode = gWorkerThread->UnregisterSocket( this );
  137. }
  138. return ReturnCode;
  139. }
  140. //---------------------------------------------------------------------------
  141. // RSOCKET::SignalAsyncEvent()
  142. //
  143. // This is the notification function called by the worker thread to
  144. // signal network events using a Windows Message.
  145. //---------------------------------------------------------------------------
  146. VOID RSOCKET::SignalAsyncEvent()
  147. {
  148. WSANETWORKEVENTS Events;
  149. INT ErrorCode;
  150. ErrorCode = NO_ERROR;
  151. assert(this != NULL);
  152. // Find out what happend.
  153. m_Provider->WSPEnumNetworkEvents( m_SocketHandle,
  154. m_hNetEvent,
  155. &Events,
  156. &ErrorCode );
  157. if (NO_ERROR == ErrorCode)
  158. {
  159. //
  160. // Signal all the valid events
  161. //
  162. if (Events.lNetworkEvents & FD_READ & m_lAsyncEvents)
  163. {
  164. PostMessage( m_hAsyncWindow,
  165. m_uiAsyncMessage,
  166. m_dwContext,
  167. MAKELONG( FD_READ,Events.iErrorCode[FD_READ_BIT] ));
  168. }
  169. if (Events.lNetworkEvents & FD_WRITE & m_lAsyncEvents)
  170. {
  171. PostMessage( m_hAsyncWindow,
  172. m_uiAsyncMessage,
  173. m_dwContext,
  174. MAKELONG( FD_WRITE,Events.iErrorCode[FD_WRITE_BIT] ));
  175. }
  176. if (Events.lNetworkEvents & FD_OOB & m_lAsyncEvents)
  177. {
  178. PostMessage( m_hAsyncWindow,
  179. m_uiAsyncMessage,
  180. m_dwContext,
  181. MAKELONG( FD_OOB,Events.iErrorCode[FD_OOB_BIT] ));
  182. }
  183. if (Events.lNetworkEvents & FD_ACCEPT & m_lAsyncEvents)
  184. {
  185. PostMessage( m_hAsyncWindow,
  186. m_uiAsyncMessage,
  187. m_dwContext,
  188. MAKELONG( FD_ACCEPT,Events.iErrorCode[FD_ACCEPT_BIT] ));
  189. }
  190. if (Events.lNetworkEvents & FD_CONNECT & m_lAsyncEvents)
  191. {
  192. PostMessage( m_hAsyncWindow,
  193. m_uiAsyncMessage,
  194. m_dwContext,
  195. MAKELONG( FD_CONNECT,Events.iErrorCode[FD_CONNECT_BIT] ));
  196. }
  197. if (Events.lNetworkEvents & FD_CLOSE & m_lAsyncEvents)
  198. {
  199. PostMessage( m_hAsyncWindow,
  200. m_uiAsyncMessage,
  201. m_dwContext,
  202. MAKELONG( FD_CLOSE,Events.iErrorCode[FD_CLOSE_BIT] ));
  203. }
  204. if (Events.lNetworkEvents & FD_QOS & m_lAsyncEvents)
  205. {
  206. PostMessage( m_hAsyncWindow,
  207. m_uiAsyncMessage,
  208. m_dwContext,
  209. MAKELONG( FD_QOS,Events.iErrorCode[FD_QOS_BIT] ));
  210. }
  211. if (Events.lNetworkEvents & FD_GROUP_QOS & m_lAsyncEvents)
  212. {
  213. PostMessage( m_hAsyncWindow,
  214. m_uiAsyncMessage,
  215. m_dwContext,
  216. MAKELONG( FD_GROUP_QOS,Events.iErrorCode[FD_GROUP_QOS_BIT] ));
  217. }
  218. }
  219. }
  220. //---------------------------------------------------------------------------
  221. // RSOCKET::AddListDSocket()
  222. //
  223. //---------------------------------------------------------------------------
  224. BOOL RSOCKET::InitListDSocket()
  225. {
  226. NTSTATUS NtStatus;
  227. InitializeListHead(&g_SocketList);
  228. NtStatus = RtlInitializeCriticalSection(&g_csSocketList);
  229. return TRUE;
  230. }
  231. //---------------------------------------------------------------------------
  232. // RSOCKET::FindListDSocket()
  233. //
  234. // Search the list of currently open sockets to find the RSOCKET object
  235. // that is associated with the specified socket handle.
  236. //---------------------------------------------------------------------------
  237. RSOCKET *RSOCKET::FindListDSocket( SOCKET s )
  238. {
  239. NTSTATUS NtStatus;
  240. RSOCKET *pRSocket;
  241. LIST_ENTRY *pListEntry;
  242. NtStatus = RtlEnterCriticalSection(&g_csSocketList);
  243. pListEntry = g_SocketList.Flink;
  244. while ( pListEntry != &g_SocketList)
  245. {
  246. pRSocket = CONTAINING_RECORD( pListEntry,
  247. RSOCKET,
  248. m_SocketListLinkage );
  249. if (pRSocket->m_dwContext == s)
  250. {
  251. NtStatus = RtlLeaveCriticalSection(&g_csSocketList);
  252. return pRSocket;
  253. }
  254. pListEntry = pListEntry->Flink;
  255. }
  256. NtStatus = RtlLeaveCriticalSection(&g_csSocketList);
  257. return 0;
  258. }
  259. //---------------------------------------------------------------------------
  260. // RSOCKET::AddListDSocket()
  261. //
  262. //---------------------------------------------------------------------------
  263. BOOL RSOCKET::AddListDSocket( RSOCKET *pRSocket )
  264. {
  265. NTSTATUS NtStatus;
  266. NtStatus = RtlEnterCriticalSection(&g_csSocketList);
  267. InsertHeadList( &g_SocketList,
  268. &pRSocket->m_SocketListLinkage );
  269. NtStatus = RtlLeaveCriticalSection(&g_csSocketList);
  270. return TRUE;
  271. }
  272. //---------------------------------------------------------------------------
  273. // RSOCKET::RemoveListDSocket()
  274. //
  275. //---------------------------------------------------------------------------
  276. BOOL RSOCKET::RemoveListDSocket( RSOCKET *pRSocket )
  277. {
  278. NTSTATUS NtStatus;
  279. NtStatus = RtlEnterCriticalSection(&g_csSocketList);
  280. RemoveEntryList( &pRSocket->m_SocketListLinkage );
  281. NtStatus = RtlLeaveCriticalSection(&g_csSocketList);
  282. return TRUE;
  283. }
  284. //---------------------------------------------------------------------------
  285. // RSOCKET::RemoveHeadListDSocket()
  286. //
  287. //---------------------------------------------------------------------------
  288. RSOCKET *RSOCKET::RemoveHeadListDSocket()
  289. {
  290. NTSTATUS NtStatus;
  291. RSOCKET *pRSocket;
  292. LIST_ENTRY *pListEntry;
  293. NtStatus = RtlEnterCriticalSection(&g_csSocketList);
  294. if (IsListEmpty(&g_SocketList))
  295. {
  296. pRSocket = 0;
  297. }
  298. else
  299. {
  300. pListEntry = RemoveHeadList(&g_SocketList);
  301. pRSocket = CONTAINING_RECORD( pListEntry,
  302. RSOCKET,
  303. m_SocketListLinkage );
  304. }
  305. NtStatus = RtlLeaveCriticalSection(&g_csSocketList);
  306. return pRSocket;
  307. }