Source code of Windows XP (NT5)
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.

496 lines
11 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\rtm\rtmdlg.c
  5. Abstract:
  6. Routing Table Manager DLL. Debugging code to display table entries
  7. in dialog box
  8. Author:
  9. Vadim Eydelman
  10. Revision History:
  11. --*/
  12. #include "pchrtm.h"
  13. #pragma hdrstop
  14. #if DBG
  15. #define IP_PROTOCOL RR_RoutingProtocol
  16. #define IP_INTERFACE RR_InterfaceID
  17. #define IP_METRIC RR_FamilySpecificData.FSD_Metric1
  18. #define IP_TIMESTAMP RR_TimeStamp
  19. #define IP_NET_NUM RR_Network.N_NetNumber
  20. #define IP_NET_MSK RR_Network.N_NetMask
  21. #define IP_NEXT_HOP_NUM RR_NextHopAddress.N_NetNumber
  22. #define IP_NEXT_HOP_MSK RR_NextHopAddress.N_NetMask
  23. #define IP_ADPTER_INDEX RR_FamilySpecificData.FSD_AdapterIndex
  24. #define IP_PROTOCOL_METRIC RR_FamilySpecificData.FSD_ProtocolMetric
  25. #define IP_PSD RR_ProtocolSpecificData
  26. #define IPX_PROTOCOL RR_RoutingProtocol
  27. #define IPX_INTERFACE RR_InterfaceID
  28. #define IPX_METRIC RR_FamilySpecificData.FSD_TickCount
  29. #define IPX_TIMESTAMP RR_TimeStamp
  30. #define IPX_NET_NUM RR_Network.N_NetNumber
  31. #define IPX_NEXT_HOP_MAC RR_NextHopAddress.NHA_Mac
  32. #define IPX_HOP_COUNT RR_FamilySpecificData.FSD_HopCount
  33. #define IPX_PSD RR_ProtocolSpecificData
  34. // Make table accessible to debugging code
  35. extern RTM_TABLE Tables[RTM_NUM_OF_PROTOCOL_FAMILIES];
  36. // Define protype internal to rtm.c
  37. VOID
  38. ConsolidateNetNumberLists (
  39. PRTM_TABLE Table // Table for which operation is performed
  40. );
  41. DWORD DbgLevel = 0;
  42. DWORD MaxTicks = MAXULONG;
  43. DWORD MaxMessages=10000;
  44. HANDLE RTDlgThreadHdl;
  45. ULONG DisplayedTableIdx = 0xFFFFFFFF;
  46. HWND RTDlg=NULL;
  47. // Internal function prototypes
  48. INT_PTR CALLBACK
  49. RTDlgProc (
  50. HWND hDlg,
  51. UINT uMsg,
  52. WPARAM wParam,
  53. LPARAM lParam
  54. );
  55. INT
  56. PrintRoute (
  57. char *buffer,
  58. PRTM_ROUTE_NODE node,
  59. BOOLEAN full
  60. );
  61. VOID
  62. FillUpRouteLB (
  63. );
  64. #define DLLInstanceHdl ((HANDLE)param)
  65. DWORD WINAPI
  66. RTDialogThread (
  67. LPVOID param
  68. ) {
  69. MSG msg;
  70. DWORD status;
  71. BOOLEAN Done = FALSE;
  72. HANDLE RegChangeEvt;
  73. HKEY regHdl;
  74. DWORD length, disposition, value;
  75. RegChangeEvt = CreateEvent (NULL, FALSE, TRUE, NULL);
  76. ASSERTERR (RegChangeEvt!=NULL);
  77. status = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
  78. TEXT ("System\\CurrentControlSet\\Services\\RemoteAccess\\RTM"),
  79. 0,
  80. NULL,
  81. REG_OPTION_NON_VOLATILE,
  82. KEY_READ,
  83. NULL,
  84. &regHdl,
  85. &disposition
  86. );
  87. ASSERTMSG ("Can't create registry key. ", status==NO_ERROR);
  88. length = sizeof (DWORD);
  89. status = RegQueryValueEx (regHdl, TicksWrapAroundValueName, NULL, NULL,
  90. (PUCHAR)&value, &length);
  91. if (status==NO_ERROR)
  92. MaxTicks = value;
  93. length = sizeof (DWORD);
  94. status = RegQueryValueEx (regHdl, MaxMessagesValueName, NULL, NULL,
  95. (PUCHAR)&value, &length);
  96. if (status==NO_ERROR)
  97. MaxMessages = value;
  98. while (!Done) {
  99. status = MsgWaitForMultipleObjects (1, &RegChangeEvt,
  100. FALSE, INFINITE, QS_ALLINPUT);
  101. if (status==(WAIT_OBJECT_0+1)) {
  102. while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  103. if (msg.message==WM_QUIT) {
  104. Done = TRUE;
  105. break;
  106. }
  107. else if (!IsWindow(RTDlg)
  108. || !IsDialogMessage(RTDlg, &msg)) {
  109. TranslateMessage (&msg);
  110. DispatchMessage (&msg);
  111. }
  112. }
  113. }
  114. else if (status==WAIT_OBJECT_0) {
  115. length = sizeof (DWORD);
  116. status = RegQueryValueEx (regHdl, DbgLevelValueName, NULL, NULL,
  117. (PUCHAR)&DbgLevel, &length);
  118. if (status!=NO_ERROR)
  119. DbgLevel = 0;
  120. IF_DEBUG (DISPLAY_TABLE) {
  121. if (!IsWindow(RTDlg)) {
  122. RTDlg = CreateDialog (DLLInstanceHdl,
  123. MAKEINTRESOURCE (IDD_RTM_TABLE),
  124. NULL,
  125. &RTDlgProc);
  126. ASSERTERR (RTDlg!=NULL);
  127. }
  128. }
  129. else {
  130. if (IsWindow (RTDlg)) {
  131. DestroyWindow (RTDlg);
  132. RTDlg = NULL;
  133. }
  134. }
  135. status = RegNotifyChangeKeyValue (regHdl,
  136. FALSE,
  137. REG_NOTIFY_CHANGE_LAST_SET,
  138. RegChangeEvt,
  139. TRUE);
  140. ASSERTMSG ("Can't start registry notifications. ",
  141. status==NO_ERROR);
  142. }
  143. }
  144. if (IsWindow (RTDlg)) {
  145. DestroyWindow (RTDlg);
  146. RTDlg = NULL;
  147. }
  148. RegCloseKey (regHdl);
  149. return 0;
  150. }
  151. #undef DLLInstanceHdl
  152. // Dialog box procedure
  153. INT_PTR CALLBACK
  154. RTDlgProc (
  155. HWND hDlg,
  156. UINT uMsg,
  157. WPARAM wParam,
  158. LPARAM lParam
  159. ) {
  160. BOOL res = FALSE;
  161. char buf[32];
  162. int idx;
  163. TIMER_BASIC_INFORMATION TimerInfo;
  164. DWORD status;
  165. switch (uMsg) {
  166. case WM_INITDIALOG: // Dialog is being created
  167. // Fill in protocol family combo box
  168. SendDlgItemMessage (hDlg,
  169. IDC_PROTOCOL_FAMILY,
  170. CB_INSERTSTRING,
  171. RTM_PROTOCOL_FAMILY_IPX,
  172. (LPARAM)"IPX"
  173. );
  174. SendDlgItemMessage (hDlg,
  175. IDC_PROTOCOL_FAMILY,
  176. CB_INSERTSTRING,
  177. RTM_PROTOCOL_FAMILY_IP,
  178. (LPARAM)"IP"
  179. );
  180. DisplayedTableIdx = RTM_PROTOCOL_FAMILY_IPX;
  181. SendDlgItemMessage (hDlg,
  182. IDC_PROTOCOL_FAMILY,
  183. CB_SETCURSEL,
  184. DisplayedTableIdx,
  185. 0
  186. );
  187. // Start timer (updates improvized clock)
  188. SetTimer (hDlg, 0, 1000, NULL);
  189. res = TRUE;
  190. break;
  191. case WM_COMMAND: // Process child window messages only
  192. switch (LOWORD(wParam)) {
  193. case IDCANCEL:
  194. res = FALSE;
  195. break;
  196. case IDC_PROTOCOL_FAMILY:
  197. if (HIWORD(wParam)==CBN_SELENDOK) {
  198. DWORD newFamily = (DWORD)SendMessage (
  199. (HWND)lParam,
  200. CB_GETCURSEL,
  201. 0, 0);
  202. if ((newFamily!=CB_ERR)
  203. && (newFamily!=DisplayedTableIdx)) {
  204. // Change the displayed table if
  205. // user makes different selection
  206. DisplayedTableIdx = newFamily;
  207. SendDlgItemMessage (hDlg,
  208. IDL_ROUTES,
  209. LB_RESETCONTENT,
  210. 0, 0);
  211. if (Tables[DisplayedTableIdx].RT_Heap!=NULL) {
  212. ConsolidateNetNumberLists (&Tables[DisplayedTableIdx]);
  213. FillUpRouteLB ();
  214. }
  215. }
  216. }
  217. break;
  218. // case IDL_ROUTES:
  219. // // Update entry on which user double clicks
  220. // if (HIWORD(wParam)==LBN_SELCHANGE)
  221. // UpdateLBSelections ();
  222. // break;
  223. case IDB_RESYNC:
  224. SendDlgItemMessage (hDlg,
  225. IDL_ROUTES,
  226. LB_RESETCONTENT,
  227. 0, 0);
  228. if (Tables[DisplayedTableIdx].RT_Heap!=NULL) {
  229. ConsolidateNetNumberLists (&Tables[DisplayedTableIdx]);
  230. FillUpRouteLB ();
  231. }
  232. break;
  233. }
  234. break;
  235. case WM_TIMER:
  236. // Update improvised clock
  237. sprintf (buf, "%08d", GetTickCount ()/1000);
  238. SendDlgItemMessage (hDlg, IDT_TICK_COUNT, WM_SETTEXT,
  239. 0, (LPARAM)buf);
  240. status = NtQueryTimer (
  241. Tables[DisplayedTableIdx].RT_ExpirationTimer,
  242. TimerBasicInformation,
  243. &TimerInfo,
  244. sizeof (TimerInfo),
  245. NULL);
  246. if (NT_SUCCESS (status)) {
  247. if (!TimerInfo.TimerState)
  248. sprintf (buf, "%08d",
  249. (ULONG)((LONGLONG)TimerInfo.RemainingTime.QuadPart
  250. /(10000*1000)));
  251. else
  252. sprintf (buf, "Not set");
  253. }
  254. else
  255. sprintf (buf, "error");
  256. SendDlgItemMessage (hDlg, IDT_EXPIRATION, WM_SETTEXT,
  257. 0, (LPARAM)buf);
  258. status = NtQueryTimer (
  259. Tables[DisplayedTableIdx].RT_UpdateTimer,
  260. TimerBasicInformation,
  261. &TimerInfo,
  262. sizeof (TimerInfo),
  263. NULL);
  264. if (NT_SUCCESS (status)) {
  265. if (!TimerInfo.TimerState)
  266. sprintf (buf, "%08d",
  267. (ULONG)((LONGLONG)TimerInfo.RemainingTime.QuadPart
  268. /(10000*1000)));
  269. else
  270. sprintf (buf, "Not set");
  271. }
  272. else
  273. sprintf (buf, "error");
  274. SendDlgItemMessage (hDlg, IDT_UPDATE, WM_SETTEXT,
  275. 0, (LPARAM)buf);
  276. res = TRUE;
  277. break;
  278. case RT_ADDROUTE:
  279. SendDlgItemMessage (hDlg, IDL_ROUTES,
  280. LB_INSERTSTRING, wParam, lParam);
  281. // Trace2 (ANY, "%2d - %s added\n", wParam, lParam);
  282. GlobalFree ((VOID *)lParam);
  283. res = TRUE;
  284. break;
  285. case RT_DELETEROUTE:
  286. idx = (int) SendDlgItemMessage (hDlg, IDL_ROUTES,
  287. LB_FINDSTRING, (WPARAM)0, lParam);
  288. if (idx!=LB_ERR)
  289. SendDlgItemMessage (hDlg, IDL_ROUTES,
  290. LB_DELETESTRING, (WPARAM)idx, 0);
  291. // Trace2 (ANY, "%2d - %s deleted\n", idx, lParam);
  292. GlobalFree ((VOID *)lParam);
  293. res = TRUE;
  294. break;
  295. case WM_DESTROY:
  296. DisplayedTableIdx = 0xFFFFFFFF;
  297. break;
  298. }
  299. return res;
  300. }
  301. // Prints route information
  302. INT
  303. PrintRoute (
  304. char *buf, // Buffer to print to
  305. PRTM_ROUTE_NODE node, // Route to print
  306. BOOLEAN full // Print everything (including variable part)
  307. ) {
  308. INT res;
  309. switch (DisplayedTableIdx) {
  310. case RTM_PROTOCOL_FAMILY_IPX:
  311. res = sprintf (buf,
  312. " %08x ",
  313. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NET_NUM
  314. );
  315. break;
  316. case RTM_PROTOCOL_FAMILY_IP:
  317. res = sprintf (buf,
  318. "%08x-%08x",
  319. ((PRTM_IP_ROUTE)&node->RN_Route)->IP_NET_NUM,
  320. ((PRTM_IP_ROUTE)&node->RN_Route)->IP_NET_MSK
  321. );
  322. break;
  323. }
  324. res += sprintf (&buf[res],
  325. " %4d %4d",
  326. node->RN_Route.XX_INTERFACE,
  327. node->RN_Route.XX_PROTOCOL);
  328. switch (DisplayedTableIdx) {
  329. case RTM_PROTOCOL_FAMILY_IPX:
  330. res += sprintf (&buf[res],
  331. " %02x%02x%02x%02x%02x%02x ",
  332. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[0],
  333. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[1],
  334. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[2],
  335. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[3],
  336. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[4],
  337. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_NEXT_HOP_MAC[5]
  338. );
  339. break;
  340. case RTM_PROTOCOL_FAMILY_IP:
  341. res += sprintf (&buf[res],
  342. " %08x-%08x",
  343. ((PRTM_IP_ROUTE)&node->RN_Route)->IP_NEXT_HOP_NUM,
  344. ((PRTM_IP_ROUTE)&node->RN_Route)->IP_NEXT_HOP_MSK
  345. );
  346. break;
  347. }
  348. if (full) {
  349. switch (DisplayedTableIdx) {
  350. case RTM_PROTOCOL_FAMILY_IPX:
  351. res += sprintf (&buf[res],
  352. " %6d %08d %1d %1d",
  353. ((PRTM_IPX_ROUTE)&node->RN_Route)->IPX_METRIC,
  354. node->RN_ExpirationTime/1000,
  355. IsBest (node),
  356. IsEnabled (node));
  357. break;
  358. case RTM_PROTOCOL_FAMILY_IP:
  359. res += sprintf (&buf[res],
  360. " %6d %08d %1d %1d",
  361. ((PRTM_IP_ROUTE)&node->RN_Route)->IP_METRIC,
  362. node->RN_ExpirationTime/1000,
  363. IsBest (node),
  364. IsEnabled (node));
  365. break;
  366. }
  367. }
  368. return res;
  369. }
  370. // Fills list box with all routes in the current table
  371. VOID
  372. FillUpRouteLB (
  373. void
  374. ) {
  375. PLIST_ENTRY cur;
  376. INT idx=0;
  377. PRTM_TABLE Table = &Tables[DisplayedTableIdx];
  378. // Make sure we own the table while printing
  379. EnterSyncList (Table, &Table->RT_NetNumberMasterList, TRUE);
  380. cur = Table->RT_NetNumberMasterList.RSL_Head.Flink;
  381. while (cur!=&Table->RT_NetNumberMasterList.RSL_Head) {
  382. PRTM_ROUTE_NODE node = CONTAINING_RECORD (cur,
  383. RTM_ROUTE_NODE,
  384. RN_Links[RTM_NET_NUMBER_LIST_LINK]);
  385. if (!IsEnumerator (node))
  386. AddRouteToLB (Table, node, idx++);
  387. cur = cur->Flink;
  388. }
  389. LeaveSyncList (Table, &Table->RT_NetNumberMasterList);
  390. }
  391. // Insert line with item data at specified position in the list box
  392. VOID
  393. AddRouteToLB (
  394. PRTM_TABLE Table,
  395. PRTM_ROUTE_NODE node,
  396. INT idx
  397. ) {
  398. char *buf;
  399. if (IsWindow (RTDlg)
  400. && (Table==&Tables[DisplayedTableIdx])) {
  401. buf = (char *)GlobalAlloc (GMEM_FIXED, 80);
  402. // Print node
  403. PrintRoute (buf, node, TRUE);
  404. // Insert at specified position
  405. SendNotifyMessage (RTDlg, RT_ADDROUTE, (WPARAM)idx, (LPARAM)buf);
  406. }
  407. }
  408. // Deletes route line from the list box
  409. VOID
  410. DeleteRouteFromLB (
  411. PRTM_TABLE Table,
  412. PRTM_ROUTE_NODE node
  413. ) {
  414. char *buf;
  415. if (IsWindow (RTDlg)
  416. && (Table==&Tables[DisplayedTableIdx])) {
  417. buf = (char *)GlobalAlloc (GMEM_FIXED, 80);
  418. // Print route info
  419. PrintRoute (buf, node, FALSE);
  420. // Find corresponding line in the list
  421. SendNotifyMessage (RTDlg, RT_DELETEROUTE, 0, (LPARAM)buf);
  422. }
  423. }
  424. #endif