MFNetTraffic.cpp
上传用户:tintim
上传日期:2022-05-14
资源大小:1573k
文件大小:9k
源码类别:

网络截获/分析

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "MFNetTraffic.h"
  3. #include "float.h"
  4. #ifdef _DEBUG
  5. #undef THIS_FILE
  6. static char THIS_FILE[]=__FILE__;
  7. #define new DEBUG_NEW
  8. #endif
  9. #include "winperf.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. MFNetTraffic::MFNetTraffic()
  14. {
  15. lasttraffic = 0.0;
  16. CurrentInterface = -1;
  17. CurrentTrafficType = AllTraffic;
  18. GetInterfaces();
  19. }
  20. MFNetTraffic::~MFNetTraffic()
  21. {
  22. }
  23. PERF_OBJECT_TYPE *FirstObject(PERF_DATA_BLOCK *dataBlock)
  24. {
  25.   return (PERF_OBJECT_TYPE *) ((BYTE *)dataBlock + dataBlock->HeaderLength);
  26. }
  27. PERF_OBJECT_TYPE *NextObject(PERF_OBJECT_TYPE *act)
  28. {
  29.   return (PERF_OBJECT_TYPE *) ((BYTE *)act + act->TotalByteLength);
  30. }
  31. PERF_COUNTER_DEFINITION *FirstCounter(PERF_OBJECT_TYPE *perfObject)
  32. {
  33.   return (PERF_COUNTER_DEFINITION *) ((BYTE *) perfObject + perfObject->HeaderLength);
  34. }
  35. PERF_COUNTER_DEFINITION *NextCounter(PERF_COUNTER_DEFINITION *perfCounter)
  36. {
  37.   return (PERF_COUNTER_DEFINITION *) ((BYTE *) perfCounter + perfCounter->ByteLength);
  38. }
  39. PERF_COUNTER_BLOCK *GetCounterBlock(PERF_INSTANCE_DEFINITION *pInstance)
  40. {
  41.   return (PERF_COUNTER_BLOCK *) ((BYTE *)pInstance + pInstance->ByteLength);
  42. }
  43. PERF_INSTANCE_DEFINITION *FirstInstance (PERF_OBJECT_TYPE *pObject)
  44. {
  45.   return (PERF_INSTANCE_DEFINITION *)  ((BYTE *) pObject + pObject->DefinitionLength);
  46. }
  47. PERF_INSTANCE_DEFINITION *NextInstance (PERF_INSTANCE_DEFINITION *pInstance)
  48. {
  49.   PERF_COUNTER_BLOCK  *pCtrBlk = GetCounterBlock(pInstance);
  50.   return (PERF_INSTANCE_DEFINITION *) ((BYTE *)pInstance + pInstance->ByteLength + pCtrBlk->ByteLength);
  51. }
  52. char *WideToMulti(wchar_t *source, char *dest, int size)
  53. {
  54.   WideCharToMultiByte(CP_ACP, 0, source, -1, dest, size, 0, 0);
  55.   return dest;
  56. }
  57. /*
  58. Window NT/2000: When calling the RegQueryValueEx function with hKey set to the 
  59. HKEY_PERFORMANCE_DATA handle and a value string of a specified object, the 
  60. returned data structure sometimes has unrequested objects. Don't be surprised;
  61. this is normal behavior. When calling the RegQueryValueEx function, you should 
  62. always expect to walk the returned data structure to look for the requested object. 
  63. */
  64. //得到接口号为interfaceNumber的接口流量
  65. double MFNetTraffic::GetTraffic(int interfaceNumber)
  66. {
  67. try
  68. {
  69. #define DEFAULT_BUFFER_SIZE 40960L
  70. POSITION pos;
  71. CString InterfaceName;
  72. pos = Interfaces.FindIndex(interfaceNumber);
  73. if(pos==NULL)
  74. return 0.0;
  75. //得到当前的接口名字
  76. InterfaceName = Interfaces.GetAt(pos);
  77. //为性能数据缓冲
  78. unsigned char *data = new unsigned char [DEFAULT_BUFFER_SIZE];
  79. // 从RegQueryValueEx返回的值:本例中忽略改变量
  80. DWORD type;
  81. // 缓冲的尺寸
  82. DWORD size = DEFAULT_BUFFER_SIZE;
  83. // RegQueryValueEx返回的值
  84. DWORD ret;
  85. // 从网络对象(索引是510)查询性能数据
  86. /*
  87. HKEY_PERFORMANCE_DATA:
  88. Windows NT/2000/XP: Registry entries subordinate to this key allow you to 
  89. access performance data. The data is not actually stored in the registry; 
  90. the registry functions cause the system to collect the data from its source.
  91. */
  92. /*
  93. */
  94. while((ret = RegQueryValueEx(
  95. HKEY_PERFORMANCE_DATA, "510", NULL, &type, data, &size)) != ERROR_SUCCESS) 
  96. {
  97. if(ret == ERROR_MORE_DATA) 
  98. {
  99. // 缓冲尺寸太小,增加内存分配
  100. size += DEFAULT_BUFFER_SIZE;
  101. delete [] data;
  102. data = new unsigned char [size];
  103. else 
  104. {
  105. // 未定义的错误
  106. return 1;
  107. }
  108. }
  109. //性能数据块
  110. PERF_DATA_BLOCK *dataBlockPtr = (PERF_DATA_BLOCK *)data;
  111. //枚举链表中第一个对象
  112. PERF_OBJECT_TYPE *objectPtr = FirstObject(dataBlockPtr);
  113. //遍历链表 
  114. for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++) 
  115. {
  116. char nameBuffer[255];
  117. // 判断是否是网络对象索引号是510
  118. if(objectPtr->ObjectNameTitleIndex == 510) 
  119. {
  120. // 偏移变量
  121. DWORD processIdOffset = ULONG_MAX;
  122. // 找到第一个计数器
  123. PERF_COUNTER_DEFINITION *counterPtr = FirstCounter(objectPtr);
  124. // 遍历链表
  125. for(int b=0 ; b<(int)objectPtr->NumCounters ; b++) 
  126. {
  127. // 判断接收的数据类型是否是我们需要的
  128. if((int)counterPtr->CounterNameTitleIndex == CurrentTrafficType)
  129. processIdOffset = counterPtr->CounterOffset;
  130. // 下一个计数器
  131. counterPtr = NextCounter(counterPtr);
  132. }
  133. //数据类型不是我们需要的
  134. if(processIdOffset == ULONG_MAX) {
  135. delete [] data;
  136. return 1;
  137. }
  138. // 找到第一个实列(instance)
  139. PERF_INSTANCE_DEFINITION *instancePtr = FirstInstance(objectPtr);
  140. DWORD fullTraffic;
  141. DWORD traffic;
  142. //遍历整个实列
  143. for(b=0 ; b<objectPtr->NumInstances ; b++) 
  144. {
  145. wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);
  146. // 得到这个实列的PERF_COUNTER_BLOCK
  147. PERF_COUNTER_BLOCK *counterBlockPtr = GetCounterBlock(instancePtr);
  148. // 现在我们得到了接口的名字
  149. char *pName = WideToMulti(namePtr, nameBuffer, sizeof(nameBuffer));
  150. CString iName;
  151. iName.Format("%s",pName);
  152. POSITION pos = TotalTraffics.FindIndex(b);
  153. if(pos!=NULL)
  154. {
  155. fullTraffic = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));
  156. TotalTraffics.SetAt(pos,fullTraffic);
  157. }
  158. // 如果当前的接口就是我们选择的接口
  159. if(InterfaceName == iName)
  160. {
  161. traffic = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));
  162. double acttraffic = (double)traffic;
  163. double trafficdelta;
  164. // 判断处理的接口是否是新的
  165. if(CurrentInterface != interfaceNumber)
  166. {
  167. lasttraffic = acttraffic;
  168. trafficdelta = 0.0;
  169. CurrentInterface = interfaceNumber;
  170. }
  171. else
  172. {
  173. trafficdelta = acttraffic - lasttraffic;
  174. lasttraffic = acttraffic;
  175. }
  176. delete [] data;
  177. return(trafficdelta);
  178. }
  179. //下一个实列
  180. instancePtr = NextInstance(instancePtr);
  181. }
  182. }
  183. // 下一个对象
  184. objectPtr = NextObject(objectPtr);
  185. }
  186. delete [] data;
  187. return 0;
  188. }
  189. catch(...)
  190. {
  191. return 0;
  192. }
  193. }
  194. //枚举安装的接口
  195. BOOL MFNetTraffic::GetInterfaces()
  196. {
  197. try
  198. {
  199.         #define DEFAULT_BUFFER_SIZE 40960L
  200. Interfaces.RemoveAll();
  201. unsigned char *data = (unsigned char*)malloc(DEFAULT_BUFFER_SIZE);
  202. DWORD type;
  203. DWORD size = DEFAULT_BUFFER_SIZE;
  204. DWORD ret;
  205. char s_key[4096];
  206. sprintf( s_key , "%d" , 510 );
  207. //RegQueryValueEx的固定调用格式
  208. while((ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, s_key, 0, &type, data, &size)) != ERROR_SUCCESS) {
  209. while(ret == ERROR_MORE_DATA) 
  210. {
  211. size += DEFAULT_BUFFER_SIZE;
  212. data = (unsigned char*) realloc(data, size);
  213. if(ret != ERROR_SUCCESS)
  214. {
  215. return FALSE;
  216. }
  217. }
  218. //得到数据块
  219. PERF_DATA_BLOCK  *dataBlockPtr = (PERF_DATA_BLOCK *)data;
  220. //得到第一个对象
  221. PERF_OBJECT_TYPE *objectPtr = FirstObject(dataBlockPtr);
  222. for(int a=0 ; a<(int)dataBlockPtr->NumObjectTypes ; a++) 
  223. {
  224. char nameBuffer[255];
  225. if(objectPtr->ObjectNameTitleIndex == 510) 
  226. {
  227. DWORD processIdOffset = ULONG_MAX;
  228. PERF_COUNTER_DEFINITION *counterPtr = FirstCounter(objectPtr);
  229. for(int b=0 ; b<(int)objectPtr->NumCounters ; b++) 
  230. {
  231. if(counterPtr->CounterNameTitleIndex == 520)
  232. processIdOffset = counterPtr->CounterOffset;
  233. counterPtr = NextCounter(counterPtr);
  234. }
  235. if(processIdOffset == ULONG_MAX) {
  236. free(data);
  237. return 1;
  238. }
  239. PERF_INSTANCE_DEFINITION *instancePtr = FirstInstance(objectPtr);
  240. for(b=0 ; b<objectPtr->NumInstances ; b++) 
  241. {
  242. wchar_t *namePtr = (wchar_t *) ((BYTE *)instancePtr + instancePtr->NameOffset);
  243. PERF_COUNTER_BLOCK *counterBlockPtr = GetCounterBlock(instancePtr);
  244. char *pName = WideToMulti(namePtr, nameBuffer, sizeof(nameBuffer));
  245. DWORD bandwith = *((DWORD *) ((BYTE *)counterBlockPtr + processIdOffset));
  246. DWORD tottraff = 0;
  247. Interfaces.AddTail(CString(pName));
  248. Bandwidths.AddTail(bandwith);
  249. TotalTraffics.AddTail(tottraff);  // initial 0, just for creating the list
  250. instancePtr = NextInstance(instancePtr);
  251. }
  252. }
  253. objectPtr = NextObject(objectPtr);
  254. }
  255. free(data);
  256. return TRUE;
  257. }
  258. catch(...)
  259. {
  260. return FALSE;
  261. }
  262. }
  263. //返回安装的接口数
  264. int MFNetTraffic::GetNetworkInterfacesCount()
  265. {
  266. return Interfaces.GetCount()-1;
  267. }
  268. //返回接口名称
  269. BOOL MFNetTraffic::GetNetworkInterfaceName(CString *InterfaceName, int index)
  270. {
  271. POSITION pos = Interfaces.FindIndex(index);
  272. if(pos==NULL)
  273. return FALSE;
  274. InterfaceName->Format("%s",Interfaces.GetAt(pos));
  275. return TRUE;
  276. }
  277. //返回接口带宽
  278. DWORD MFNetTraffic::GetInterfaceBandwidth(int index)
  279. {
  280. POSITION pos = Bandwidths.FindIndex(index);
  281. if(pos==NULL)
  282. return 0;
  283. else 
  284. return Bandwidths.GetAt(pos) / 8;
  285. }
  286. //具体接口接收和发送的数据量
  287. DWORD MFNetTraffic::GetInterfaceTotalTraffic(int index)
  288. {
  289. DWORD totaltraffic = 0;
  290. POSITION pos;
  291. pos= TotalTraffics.FindIndex(index);
  292. if(pos!=NULL)
  293. {
  294. totaltraffic = TotalTraffics.GetAt(pos); 
  295. if(totaltraffic == 0.0)
  296. {
  297. GetTraffic(index);
  298. pos= TotalTraffics.FindIndex(index);
  299. if(pos!=NULL)
  300. {
  301. totaltraffic = TotalTraffics.GetAt(pos); 
  302. }
  303. }
  304. }
  305. return(totaltraffic);
  306. }
  307. void MFNetTraffic::SetTrafficType(int trafficType)
  308. {
  309. CurrentTrafficType = trafficType;
  310. }