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

Visual C++

  1. //PassThruUserIo.cpp
  2. //提供有关PassThru与应用程序交互的支持函数
  3. #include "stdafx.h"
  4. #include <winioctl.h>
  5. #include <ntddndis.h>
  6. #include <stdio.h>
  7. #include <tchar.h>
  8. #include "PassThruUserIo.h"
  9. extern ARPRule *pARPRuleList;
  10. HANDLE PtOpenControlDevice()
  11. {
  12. // 打开到驱动程序所控制设备的句柄
  13. HANDLE hFile = ::CreateFile(
  14. _T("\\.\PassThru"),
  15. GENERIC_READ | GENERIC_WRITE,
  16. 0,
  17. NULL,
  18. OPEN_EXISTING,
  19. FILE_ATTRIBUTE_NORMAL,
  20. NULL);
  21. return hFile;
  22. }
  23. HANDLE PtOpenAdapter(PWSTR pszAdapterName)
  24. {
  25. // 打开控制设备对象句柄
  26. HANDLE hAdapter = PtOpenControlDevice();
  27. if(hAdapter == INVALID_HANDLE_VALUE)
  28. return INVALID_HANDLE_VALUE;
  29. // 确定适配器名称的长度
  30. int nBufferLength = wcslen((PWSTR)pszAdapterName) * sizeof(WCHAR);
  31. // 发送IOCTL_PTUSERIO_OPEN_ADAPTER控制代码,打开适配器上下文
  32. DWORD dwBytesReturn;
  33. BOOL bOK = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_OPEN_ADAPTER, 
  34. pszAdapterName, nBufferLength, NULL, 0, &dwBytesReturn, NULL);
  35. // 检查结果
  36. if(!bOK)
  37. {
  38. ::CloseHandle(hAdapter);
  39. return INVALID_HANDLE_VALUE;
  40. }
  41. return hAdapter;
  42. }
  43. BOOL PtAdapterRequest(HANDLE hAdapter, PPTUSERIO_OID_DATA pOidData, BOOL bQuery)
  44. {
  45. if(hAdapter == INVALID_HANDLE_VALUE)
  46. return FALSE;
  47. // 发送IOCTL
  48. DWORD dw;
  49. int bRet = ::DeviceIoControl(
  50. hAdapter, bQuery ? IOCTL_PTUSERIO_QUERY_OID : IOCTL_PTUSERIO_SET_OID,
  51. pOidData, sizeof(PTUSERIO_OID_DATA) -1 + pOidData->Length,
  52. pOidData, sizeof(PTUSERIO_OID_DATA) -1 + pOidData->Length, &dw, NULL);
  53. return bRet;
  54. }
  55. //
  56. // 设置工作模式
  57. BOOL PtSetWorkMode(int *pWorkMode)
  58. {
  59. BOOL bRet = TRUE;
  60. // 打开PassThruEx驱动的控制设备对象,枚举下层绑定
  61. HANDLE hControlDevice = PtOpenControlDevice();
  62. CIMAdapters adapters;
  63. if(!adapters.EnumAdapters(hControlDevice))
  64. {
  65. AfxMessageBox(L"枚举适配器失败!");
  66. return FALSE;
  67. }
  68. // 将工作模式设置到每个下层适配器
  69. HANDLE hAdapter;
  70. for(int i=0; i<adapters.m_nAdapters; i++)
  71. {
  72. // 打开下层适配器
  73. hAdapter = PtOpenAdapter(adapters.m_pwszAdapterName[i]);
  74. if(hAdapter != INVALID_HANDLE_VALUE)
  75. {
  76. ULONG nLen = sizeof(int);
  77. BOOL bRet = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_SET_WORKMODE, pWorkMode, nLen, NULL, 0, &nLen, NULL);
  78. ::CloseHandle(hAdapter);
  79. }
  80. else
  81. {
  82. bRet = FALSE;
  83. break;
  84. }
  85. }
  86. ::CloseHandle(hControlDevice);
  87. return bRet;
  88. }
  89. // 设Ping
  90. BOOL PtSetPing(int *pPing)
  91. {
  92. BOOL bRet = TRUE;
  93. // 打开PassThruEx驱动的控制设备对象,枚举下层绑定
  94. HANDLE hControlDevice = PtOpenControlDevice();
  95. CIMAdapters adapters;
  96. if(!adapters.EnumAdapters(hControlDevice))
  97. {
  98. AfxMessageBox(L"枚举适配器失败!");
  99. return FALSE;
  100. }
  101. // 将工作模式设置到每个下层适配器
  102. HANDLE hAdapter;
  103. for(int i=0; i<adapters.m_nAdapters; i++)
  104. {
  105. // 打开下层适配器
  106. hAdapter = PtOpenAdapter(adapters.m_pwszAdapterName[i]);
  107. if(hAdapter != INVALID_HANDLE_VALUE)
  108. {
  109. ULONG nLen = sizeof(int); // 需要设置的是两个BOOL值,一个表示Ping入,另一个表示Ping出
  110. BOOL bRet = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_SET_PING, pPing, nLen, NULL, 0, &nLen, NULL);
  111. ::CloseHandle(hAdapter);
  112. }
  113. else
  114. {
  115. bRet = FALSE;
  116. break;
  117. }
  118. }
  119. ::CloseHandle(hControlDevice);
  120. return bRet;
  121. }
  122. // 设置ARP过滤规则
  123. BOOL PtSetARPRules(BOOL bIsARPRuleOpened)
  124. {
  125. BOOL bRet = TRUE;
  126. // 打开PassThruEx驱动的控制设备对象,枚举下层绑定
  127. HANDLE hControlDevice = PtOpenControlDevice();
  128. CIMAdapters adapters;
  129. if(!adapters.EnumAdapters(hControlDevice))
  130. {
  131. AfxMessageBox(L"枚举适配器失败!");
  132. return FALSE;
  133. }
  134. // 将工作模式设置到每个下层适配器
  135. HANDLE hAdapter;
  136. for(int i=0; i<adapters.m_nAdapters; i++)
  137. {
  138. // 打开下层适配器
  139. hAdapter = PtOpenAdapter(adapters.m_pwszAdapterName[i]);
  140. if(hAdapter != INVALID_HANDLE_VALUE)
  141. {
  142. if (bIsARPRuleOpened == FALSE)
  143. {
  144. // 删除ARP过滤规则
  145. DWORD dwBytes;
  146. bRet = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_CLEAR_ARP_RULE, NULL, 0, NULL, 0, &dwBytes, NULL);
  147. }
  148. else
  149. {
  150. // 增加ARP过滤规则
  151. for (ARPRule *p=pARPRuleList; p!=NULL; p=p->pNext)
  152. {
  153. ULONG nLen = sizeof(ARPRule);
  154. bRet = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_SET_ARP_RULE, p, nLen, NULL, 0, &nLen, NULL);
  155. }
  156. }
  157. ::CloseHandle(hAdapter);
  158. }
  159. else
  160. {
  161. bRet = FALSE;
  162. break;
  163. }
  164. }
  165. ::CloseHandle(hControlDevice);
  166. return bRet;
  167. }
  168. // 查询网络活动状态
  169. BOOL PtQueryStatistics(HANDLE hAdapter, PPassthruStatistics pStats)
  170. {
  171. ULONG nStatsLen = sizeof(PassthruStatistics);
  172. BOOL bRet = ::DeviceIoControl(hAdapter, 
  173. IOCTL_PTUSERIO_QUERY_STATISTICS, NULL, 0, pStats, nStatsLen, &nStatsLen, NULL);
  174. return bRet;
  175. }
  176. // 重置统计数字
  177. BOOL PtResetStatistics(HANDLE hAdapter)
  178. {
  179. DWORD dwBytes;
  180. BOOL bRet = ::DeviceIoControl(hAdapter, 
  181. IOCTL_PTUSERIO_RESET_STATISTICS, NULL, 0, NULL, 0, &dwBytes, NULL);
  182. return bRet;
  183. }
  184. // 向适配器添加一个过滤规则
  185. BOOL PtAddFilter(HANDLE hAdapter, PPassthruFilter pFilter)
  186. {
  187. ULONG nFilterLen = sizeof(PassthruFilter);
  188. BOOL bRet = ::DeviceIoControl(hAdapter, IOCTL_PTUSERIO_ADD_FILTER, 
  189. pFilter, nFilterLen, NULL, 0, &nFilterLen, NULL);
  190. return bRet;
  191. }
  192. // 清除适配器上的过滤规则
  193. BOOL PtClearFilter(HANDLE hAdapter)
  194. {
  195. DWORD dwBytes;
  196. BOOL bRet = ::DeviceIoControl(hAdapter, 
  197. IOCTL_PTUSERIO_CLEAR_FILTER, NULL, 0, NULL, 0, &dwBytes, NULL);
  198. return bRet;
  199. }
  200. //////////////////////////////////////////////////////////
  201. BOOL CIMAdapters::EnumAdapters(HANDLE hControlDevice)
  202. {
  203. DWORD dwBufferLength = sizeof(m_buffer);
  204. BOOL bRet = ::DeviceIoControl(hControlDevice, IOCTL_PTUSERIO_ENUMERATE, 
  205. NULL, 0, m_buffer, dwBufferLength, &dwBufferLength, NULL);
  206. if(!bRet)
  207. {
  208. AfxMessageBox(L"::DeviceIoControl失败!");
  209. return FALSE;
  210. }
  211. // 保存适配器数量
  212. m_nAdapters = (ULONG)((ULONG*)m_buffer)[0];
  213. // 下面从m_buffer中获取适配器名称和符号连接名称
  214. // 指向设备名称
  215. WCHAR *pwsz = (WCHAR *)((ULONG *)m_buffer + 1);
  216. int i = 0;
  217. m_pwszVirtualName[i] = pwsz;
  218. while(*(pwsz++) != NULL)
  219. {
  220. while(*(pwsz++) != NULL)
  221. { ; }
  222. m_pwszAdapterName[i] = pwsz;
  223. while(*(pwsz++) != NULL)
  224. { ; }
  225. if(++i >= MAX_ADAPTERS)
  226. break;
  227. m_pwszVirtualName[i] = pwsz;
  228. }
  229. return TRUE;
  230. }
  231. // 设置IM驱动的过滤规则
  232. BOOL IMSetRules(PPassthruFilter pRules, int nRuleCount)
  233. {
  234. BOOL bRet = TRUE;
  235. // 打开PassThruEx驱动的控制设备对象,枚举下层绑定
  236. HANDLE hControlDevice = PtOpenControlDevice();
  237. CIMAdapters adapters;
  238. if(!adapters.EnumAdapters(hControlDevice))
  239. {
  240. AfxMessageBox(L"枚举适配器失败!");
  241. return FALSE;
  242. }
  243. // 将过滤规则设置到每个下层适配器
  244. HANDLE hAdapter;
  245. int i, j;
  246. for(i=0; i<adapters.m_nAdapters; i++)
  247. {
  248. // 打开下层适配器
  249. hAdapter = PtOpenAdapter(adapters.m_pwszAdapterName[i]);
  250. if(hAdapter != INVALID_HANDLE_VALUE)
  251. {
  252. for(j=0; j<nRuleCount; j++)
  253. {
  254. PassthruFilter rule = pRules[j];
  255. // 注意在这里转化字节顺序
  256. rule.sourcePort = htons(rule.sourcePort);
  257. rule.sourceIP = htonl(rule.sourceIP);
  258. rule.sourceMask = htonl(rule.sourceMask);
  259. rule.destinationPort = htons(rule.destinationPort);
  260. rule.destinationIP = htonl(rule.destinationIP);
  261. rule.destinationMask = htonl(rule.destinationMask);
  262. // 添加过滤规则
  263. if(!PtAddFilter(hAdapter, &rule))
  264. {
  265. bRet = FALSE;
  266. break;
  267. }
  268. }
  269. ::CloseHandle(hAdapter);
  270. }
  271. else
  272. {
  273. bRet = FALSE;
  274. break;
  275. }
  276. }
  277. ::CloseHandle(hControlDevice);
  278. return bRet;
  279. }
  280. // 清除IM驱动的过滤规则
  281. BOOL IMClearRules()
  282. {
  283. BOOL bRet = TRUE;
  284. // 打开PassThruEx驱动的控制设备对象,枚举下层绑定
  285. HANDLE hControlDevice = PtOpenControlDevice();
  286. CIMAdapters adapters;
  287. if(!adapters.EnumAdapters(hControlDevice))
  288. return FALSE;
  289. // 将过滤规则设置到每个下层适配器
  290. HANDLE hAdapter;
  291. for(int i=0; i<adapters.m_nAdapters; i++)
  292. {
  293. // 打开下层适配器
  294. hAdapter = PtOpenAdapter(adapters.m_pwszAdapterName[i]);
  295. if(hAdapter != INVALID_HANDLE_VALUE)
  296. {
  297. // 清除过滤规则
  298. PtClearFilter(hAdapter);
  299. ::CloseHandle(hAdapter);
  300. }
  301. else
  302. {
  303. bRet = FALSE;
  304. break;
  305. }
  306. }
  307. ::CloseHandle(hControlDevice);
  308. return bRet;
  309. }