MyLsp.cpp
上传用户:zhuzhu0204
上传日期:2020-07-13
资源大小:13165k
文件大小:8k
开发平台:

Visual C++

  1. // MyLsp.cpp : Defines the entry point for the DLL application.
  2. //
  3. // 声明要使用UNICODE字符串
  4. #define UNICODE
  5. #define _UNICODE
  6. #include <Winsock2.h>
  7. #include <Ws2spi.h>
  8. #include <Sporder.h>
  9. #include <Windows.h>
  10. #include <stdio.h>
  11. #include <tchar.h>
  12. #include "MyLsp.h"
  13. #include "Acl.h"
  14. #include "../common/Debug.h"
  15. #include "../common/PMacRes.h"
  16. #pragma comment(lib, "Ws2_32.lib")
  17. CAcl g_Acl; // 访问列表,用来检查会话的访问权限
  18. WSPUPCALLTABLE g_pUpCallTable; // 上层函数列表。如果LSP创建了自己的伪句柄,才使用这个函数列表
  19. WSPPROC_TABLE g_NextProcTable; // 下层函数列表
  20. TCHAR g_szCurrentApp[MAX_PATH]; // 当前调用本DLL的程序的名称
  21. BOOL APIENTRY DllMain( HANDLE hModule, 
  22.                        DWORD  ul_reason_for_call, 
  23.                        LPVOID lpReserved
  24.  )
  25. {
  26. switch (ul_reason_for_call)
  27. {
  28. case DLL_PROCESS_ATTACH:
  29. {
  30. // 取得主模块的名称
  31. ::GetModuleFileName(NULL, g_szCurrentApp, MAX_PATH);
  32. }
  33. break;
  34. }
  35. return TRUE;
  36. }
  37. int WSPAPI WSPStartup(
  38.   WORD wVersionRequested,
  39.   LPWSPDATA lpWSPData,
  40.   LPWSAPROTOCOL_INFO lpProtocolInfo,
  41.   WSPUPCALLTABLE UpcallTable,
  42.   LPWSPPROC_TABLE lpProcTable
  43. )
  44. {
  45. if(lpProtocolInfo->ProtocolChain.ChainLen <= 1)
  46. {
  47. return WSAEPROVIDERFAILEDINIT;
  48. }
  49. // 保存向上调用的函数表指针(这里我们不使用它)
  50. g_pUpCallTable = UpcallTable;
  51. // 枚举协议,找到下层协议的WSAPROTOCOL_INFOW结构
  52. WSAPROTOCOL_INFOW NextProtocolInfo;
  53. int nTotalProtos;
  54. LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtos);
  55. // 下层入口ID
  56. DWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries[1];
  57. for(int i=0; i<nTotalProtos; i++)
  58. {
  59. if(pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId)
  60. {
  61. memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(NextProtocolInfo));
  62. break;
  63. }
  64. }
  65. if(i >= nTotalProtos)
  66. {
  67. return WSAEPROVIDERFAILEDINIT;
  68. }
  69. // 加载下层协议的DLL
  70. int nError;
  71. TCHAR szBaseProviderDll[MAX_PATH];
  72. int nLen = MAX_PATH;
  73. // 取得下层提供程序DLL路径
  74. if(::WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR)
  75. {
  76. return WSAEPROVIDERFAILEDINIT;
  77. }
  78. if(!::ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH))
  79. {
  80. return WSAEPROVIDERFAILEDINIT;
  81. }
  82. // 加载下层提供程序
  83. HMODULE hModule = ::LoadLibrary(szBaseProviderDll);
  84. if(hModule == NULL)
  85. {
  86. return WSAEPROVIDERFAILEDINIT;
  87. }
  88. // 导入下层提供程序的WSPStartup函数
  89. LPWSPSTARTUP  pfnWSPStartup = NULL;
  90. pfnWSPStartup = (LPWSPSTARTUP)::GetProcAddress(hModule, "WSPStartup");
  91. if(pfnWSPStartup == NULL)
  92. {
  93. return WSAEPROVIDERFAILEDINIT;
  94. }
  95. // 调用下层提供程序的WSPStartup函数
  96. LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo;
  97. if(NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL)
  98. pInfo = &NextProtocolInfo;
  99. int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, pInfo, UpcallTable, lpProcTable);
  100. if(nRet != ERROR_SUCCESS)
  101. {
  102. return nRet;
  103. }
  104. // 保存下层提供者的函数表
  105. g_NextProcTable = *lpProcTable;
  106. // 传给上层,截获对以下函数的调用
  107. lpProcTable->lpWSPSocket = WSPSocket;
  108. lpProcTable->lpWSPCloseSocket = WSPCloseSocket;
  109. lpProcTable->lpWSPBind = WSPBind;
  110. lpProcTable->lpWSPAccept = WSPAccept;
  111. lpProcTable->lpWSPConnect = WSPConnect;
  112. lpProcTable->lpWSPSendTo = WSPSendTo;
  113. lpProcTable->lpWSPRecvFrom = WSPRecvFrom; 
  114. FreeProvider(pProtoInfo);
  115. return nRet;
  116. }
  117. SOCKET WSPAPI WSPSocket(
  118. int af,                               
  119. int type,                             
  120. int protocol,                         
  121. LPWSAPROTOCOL_INFOW lpProtocolInfo,   
  122. GROUP g,                              
  123. DWORD dwFlags,                        
  124. LPINT lpErrno
  125. )
  126. {
  127. // 首先调用下层函数创建套节字
  128. SOCKET s = g_NextProcTable.lpWSPSocket(af, type, protocol, lpProtocolInfo, g, dwFlags, lpErrno);
  129. if(s == INVALID_SOCKET)
  130. {
  131. return s;
  132. }
  133. // 调用CAcl类的CheckSocket函数,设置会话属性
  134. if (af == FROM_PROTOCOL_INFO)
  135. af = lpProtocolInfo->iAddressFamily;
  136. if (type == FROM_PROTOCOL_INFO)
  137. type = lpProtocolInfo->iSocketType;
  138. if (protocol == FROM_PROTOCOL_INFO)
  139. protocol = lpProtocolInfo->iProtocol;
  140. g_Acl.CheckSocket(s, af, type, protocol);
  141. return s;
  142. }
  143. int WSPAPI WSPCloseSocket(
  144. SOCKET s,
  145. LPINT lpErrno
  146. )
  147. {
  148. // 调用CAcl类的CheckCloseSocket函数,删除对应的会话
  149. g_Acl.CheckCloseSocket(s);
  150. return g_NextProcTable.lpWSPCloseSocket(s, lpErrno);
  151. }
  152. int WSPAPI WSPBind(SOCKET s, const struct sockaddr* name, int namelen, LPINT lpErrno)
  153. {
  154. // 调用CAcl类的CheckBind函数,设置会话属性
  155. g_Acl.CheckBind(s, name);
  156. return g_NextProcTable.lpWSPBind(s, name, namelen, lpErrno);
  157. }
  158. int WSPAPI WSPConnect(
  159. SOCKET s,
  160. const struct sockaddr FAR * name,
  161. int namelen,
  162. LPWSABUF lpCallerData,
  163. LPWSABUF lpCalleeData,
  164. LPQOS lpSQOS,
  165. LPQOS lpGQOS,
  166. LPINT lpErrno
  167. )
  168. {
  169. // 检查是否允许连接到远程主机
  170. if(g_Acl.CheckConnect(s, name) != PF_PASS)
  171. {
  172. *lpErrno = WSAECONNREFUSED;
  173. return SOCKET_ERROR;
  174. return g_NextProcTable.lpWSPConnect(s, name, namelen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno);
  175. }
  176. SOCKET WSPAPI WSPAccept(
  177. SOCKET s,
  178. struct sockaddr FAR *addr,
  179. LPINT addrlen,
  180. LPCONDITIONPROC lpfnCondition,
  181. DWORD dwCallbackData,
  182. LPINT lpErrno
  183. )
  184. {
  185. // 首先调用下层函数接收到来的连接
  186. SOCKET sNew = g_NextProcTable.lpWSPAccept(s, addr, addrlen, lpfnCondition, dwCallbackData, lpErrno);
  187. // 检查是否允许,如果不允许,关闭新接收的连接
  188. if (sNew != INVALID_SOCKET && g_Acl.CheckAccept(s, sNew, addr) != PF_PASS)
  189. {
  190. int iError;
  191. g_NextProcTable.lpWSPCloseSocket(sNew, &iError);
  192. *lpErrno = WSAECONNREFUSED;
  193. return SOCKET_ERROR;
  194. }
  195. return sNew;
  196. }
  197. int WSPAPI WSPSendTo(
  198. SOCKET s,
  199. LPWSABUF lpBuffers,
  200. DWORD dwBufferCount,
  201. LPDWORD lpNumberOfBytesSent,
  202. DWORD dwFlags,
  203. const struct sockaddr FAR * lpTo,
  204. int iTolen,
  205. LPWSAOVERLAPPED lpOverlapped,
  206. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  207. LPWSATHREADID lpThreadId,
  208. LPINT lpErrno
  209. )
  210. {
  211. // 检查是否允许发送数据
  212. if (g_Acl.CheckSendTo(s, lpTo) != PF_PASS)
  213. {
  214. int iError;
  215. g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);
  216. *lpErrno = WSAECONNABORTED;
  217. return SOCKET_ERROR;
  218. }
  219. // 调用下层发送函数
  220. return g_NextProcTable.lpWSPSendTo(s, lpBuffers, dwBufferCount, 
  221. lpNumberOfBytesSent, dwFlags, lpTo, iTolen, 
  222. lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
  223. }
  224. int WSPAPI WSPRecvFrom (
  225. SOCKET s,
  226. LPWSABUF lpBuffers,
  227. DWORD dwBufferCount,
  228. LPDWORD lpNumberOfBytesRecvd,
  229. LPDWORD lpFlags,
  230. struct sockaddr FAR * lpFrom,
  231. LPINT lpFromlen,
  232. LPWSAOVERLAPPED lpOverlapped,
  233. LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
  234. LPWSATHREADID lpThreadId,
  235. LPINT lpErrno
  236. )
  237. {
  238. // 首先检查是否允许接收数据
  239. if(g_Acl.CheckRecvFrom(s, lpFrom) != PF_PASS)
  240. {
  241. int iError;
  242. g_NextProcTable.lpWSPShutdown(s, SD_BOTH, &iError);
  243. *lpErrno = WSAECONNABORTED;
  244. return SOCKET_ERROR;
  245. }
  246. // 调用下层接收函数
  247. return g_NextProcTable.lpWSPRecvFrom(s, lpBuffers, dwBufferCount, lpNumberOfBytesRecvd, 
  248. lpFlags, lpFrom, lpFromlen, lpOverlapped, lpCompletionRoutine, lpThreadId, lpErrno);
  249. }
  250. LPWSAPROTOCOL_INFOW GetProvider(LPINT lpnTotalProtocols)
  251. {
  252. DWORD dwSize = 0;
  253. int nError;
  254. LPWSAPROTOCOL_INFOW pProtoInfo = NULL;
  255. // 取得需要的长度
  256. if(::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR)
  257. {
  258. if(nError != WSAENOBUFS)
  259. return NULL;
  260. }
  261. pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize);
  262. *lpnTotalProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError);
  263. return pProtoInfo;
  264. }
  265. void FreeProvider(LPWSAPROTOCOL_INFOW pProtoInfo)
  266. {
  267. ::GlobalFree(pProtoInfo);
  268. }