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.

872 lines
23 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\ipx\adptif\watcher.c
  5. Abstract:
  6. Debug mode code that display adapter information reported
  7. by the stack. It also provides UI mechanism to manually
  8. "disable" (make invisible to clients) and "reenable" adapters
  9. Author:
  10. Vadim Eydelman
  11. Revision History:
  12. --*/
  13. // State information maintained for UI dialog
  14. typedef struct _ADAPTER_STATE {
  15. USHORT AdapterId; // Nic ID
  16. BOOLEAN Status; // Status as supplied by the stack
  17. BOOLEAN Enabled; // User settable status
  18. } ADAPTER_STATE, *PADAPTER_STATE;
  19. DWORD WINAPI
  20. WatcherThread (
  21. LPVOID param
  22. );
  23. BOOL CALLBACK
  24. WatcherDlgProc (
  25. HWND hDlg,
  26. UINT uMsg,
  27. WPARAM wParam,
  28. LPARAM lParam
  29. );
  30. VOID
  31. NotifyClients (
  32. INT i,
  33. BOOLEAN Status
  34. );
  35. VOID
  36. UpdateAdapterList (
  37. HWND AdapterLB
  38. );
  39. HWND WatcherDlg=NULL; // UI dialog handle
  40. PADAPTER_STATE AdapterArray=NULL; // Current adapter info
  41. ULONG AdapterArraySize=0; // Number of adapters in array
  42. PVOID AdapterDataBuffer=NULL; // Buffer to receive nic info from driver
  43. HANDLE DebugWatchEvent=NULL; // Event to be nofified when nic info changes
  44. DWORD DbgFlags=0; // Debug flags
  45. #define DEBUG_SHOW_DIALOG 0x00000001 // Display UI dialog if set
  46. HINSTANCE HDLLInstance; // Dll instance handle
  47. HANDLE WatcherThreadHdl=NULL; // UI thread handle
  48. DWORD WatcherThreadID=0; // Its id
  49. /*++
  50. *******************************************************************
  51. I n i t i a l i z e W a t c h e r
  52. Routine Description:
  53. Initializes UI resorces and starts watcher thread
  54. Arguments:
  55. hinstDLL, handle of DLL module
  56. Return Value:
  57. None
  58. Remarks:
  59. *******************************************************************
  60. --*/
  61. VOID
  62. InitializeWatcher (
  63. HINSTANCE hinstDLL
  64. ) {
  65. HDLLInstance = hinstDLL;
  66. InitCommonControls ();
  67. DebugWatchEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  68. ASSERT (DebugWatchEvent!=NULL);
  69. EnterCriticalSection (&ConfigInfoLock);
  70. if (IpxDriverHandle==NULL) {
  71. DWORD status = OpenAdapterConfigPort ();
  72. ASSERTMSG ("Could not open adapter config port", status==NO_ERROR);
  73. if (!InRouter ())
  74. PostAdapterConfigRequest (DebugWatchEvent);
  75. }
  76. LeaveCriticalSection (&ConfigInfoLock);
  77. WatcherThreadHdl = CreateThread (NULL, // default security
  78. 0, // default stack
  79. &WatcherThread,
  80. (LPVOID)NULL,
  81. 0, // default flags
  82. &WatcherThreadID);
  83. ASSERTMSG ("Could not create watcher thread ",
  84. WatcherThreadHdl!=NULL);
  85. }
  86. /*++
  87. *******************************************************************
  88. C l e a n u p W a t c h e r
  89. Routine Description:
  90. Disposes of resources allocated for UI
  91. Arguments:
  92. None
  93. Return Value:
  94. None
  95. Remarks:
  96. *******************************************************************
  97. --*/
  98. VOID
  99. CleanupWatcher (
  100. void
  101. ) {
  102. PostThreadMessage (WatcherThreadID, WM_QUIT, 0, 0);
  103. WaitForSingleObject (WatcherThreadHdl, INFINITE);
  104. if (IpxDriverHandle!=NULL)
  105. CloseAdapterConfigPort ();
  106. CloseHandle (WatcherThreadHdl);
  107. CloseHandle (DebugWatchEvent);
  108. }
  109. /*++
  110. *******************************************************************
  111. W a t c h e r T h r e a d
  112. Routine Description:
  113. Event loop for Watcher Dialog
  114. Arguments:
  115. param - Not used
  116. Return Value:
  117. None
  118. *******************************************************************
  119. --*/
  120. DWORD WINAPI
  121. WatcherThread (
  122. LPVOID param
  123. ) {
  124. DWORD status;
  125. HANDLE WaitObjects[2];
  126. #define RegChangeEvt (WaitObjects[0])
  127. HKEY regHdl;
  128. DWORD length, disposition, value;
  129. BOOL Done=FALSE;
  130. RegChangeEvt = CreateEvent (NULL, FALSE, TRUE, NULL);
  131. ASSERT (RegChangeEvt!=NULL);
  132. WaitObjects[1] = DebugWatchEvent;
  133. // Create registry key that controls dialog display
  134. status = RegCreateKeyEx (HKEY_LOCAL_MACHINE,
  135. InRouter()
  136. ? TEXT ("System\\CurrentControlSet\\Services\\RemoteAccess\\Adptif")
  137. : TEXT ("System\\CurrentControlSet\\Services\\NwSapAgent\\Adptif"),
  138. 0,
  139. NULL,
  140. REG_OPTION_NON_VOLATILE,
  141. KEY_READ,
  142. NULL,
  143. &regHdl,
  144. &disposition
  145. );
  146. ASSERTMSG ("Can't create registry key. ", status==NO_ERROR);
  147. while (!Done) {
  148. status = MsgWaitForMultipleObjects (2, WaitObjects,
  149. FALSE, INFINITE, QS_ALLINPUT);
  150. if (status==(WAIT_OBJECT_0+2)) {
  151. MSG msg;
  152. while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  153. if (msg.message==WM_QUIT) {
  154. Done = TRUE;
  155. break;
  156. }
  157. else if (!IsWindow(WatcherDlg)
  158. || !IsDialogMessage(WatcherDlg, &msg)) {
  159. TranslateMessage (&msg);
  160. DispatchMessage (&msg);
  161. }
  162. }
  163. }
  164. else if (status==WAIT_OBJECT_0) {
  165. // Registry change event signalled
  166. EnterCriticalSection (&ConfigInfoLock);
  167. length = sizeof (DWORD);
  168. status = RegQueryValueEx (regHdl, TEXT ("DbgFlags"), NULL, NULL,
  169. (PUCHAR)&value, &length);
  170. if (status==NO_ERROR)
  171. DbgFlags = value;
  172. if (DbgFlags & DEBUG_SHOW_DIALOG) {
  173. if (!IsWindow(WatcherDlg)) {
  174. WatcherDlg = CreateDialog (HDLLInstance,
  175. MAKEINTRESOURCE (IDD_WATCHER),
  176. NULL,
  177. &WatcherDlgProc);
  178. ASSERT (WatcherDlg!=NULL);
  179. }
  180. }
  181. else {
  182. if (IsWindow (WatcherDlg)) {
  183. DestroyWindow (WatcherDlg);
  184. WatcherDlg = NULL;
  185. }
  186. }
  187. status = RegNotifyChangeKeyValue (regHdl,
  188. FALSE,
  189. REG_NOTIFY_CHANGE_LAST_SET,
  190. RegChangeEvt,
  191. TRUE);
  192. ASSERTMSG ("Can't start registry notifications. ",
  193. status==NO_ERROR);
  194. LeaveCriticalSection (&ConfigInfoLock);
  195. }
  196. else if (status==WAIT_OBJECT_0+1) {
  197. // Adapter change IRP has completed
  198. EnterCriticalSection (&ConfigInfoLock);
  199. if (WatcherDlg!=NULL) // Update dialog
  200. UpdateAdapterList (GetDlgItem (WatcherDlg, IDL_ADAPTERS));
  201. if (!InRouter ()) { // Inform clients and repost IRP
  202. ProcessAdapterConfigInfo ();
  203. PostAdapterConfigRequest (DebugWatchEvent);
  204. } // When in router, IRP is processed
  205. // by APC routine and new one is immediately
  206. // posted
  207. LeaveCriticalSection (&ConfigInfoLock);
  208. }
  209. }
  210. if (IsWindow (WatcherDlg)) {
  211. DestroyWindow (WatcherDlg);
  212. WatcherDlg = NULL;
  213. }
  214. RegCloseKey (regHdl);
  215. CloseHandle (RegChangeEvt);
  216. return 0;
  217. #undef RegChangeEvent
  218. }
  219. /*++
  220. *******************************************************************
  221. W a t c h e r D i a l o g P r o c
  222. Routine Description:
  223. Window Proc for watcher dialog.
  224. Implements UI for adapter info changes
  225. Arguments:
  226. hDlg - handle of dialog box
  227. uMsg - message
  228. wParam - first message parameter
  229. lParam - second message parameter
  230. Return Value:
  231. TRUE if procedure processed tne message
  232. FALSE if default procedure is to process the message
  233. *******************************************************************
  234. --*/
  235. BOOL CALLBACK
  236. WatcherDlgProc (
  237. HWND hDlg,
  238. UINT uMsg,
  239. WPARAM wParam,
  240. LPARAM lParam
  241. ) {
  242. UINT i,aa;
  243. CHAR buffer[60]; // Buffer to print adapter info to
  244. HWND hLB; // Adapter listbox window handle
  245. BOOL res=FALSE; // Return value
  246. DWORD status;
  247. LV_COLUMN lvc;
  248. HICON hIcon;
  249. HIMAGELIST hIml;
  250. RECT rect;
  251. static RECT lbPos;
  252. static LPTSTR Headers[]={TEXT(" Nic Name"), TEXT("NicId"), TEXT("ItfId"),
  253. TEXT("Network#"), TEXT("Local Node #"), TEXT("Remote Node#"),
  254. TEXT("Ln.Spd"), TEXT("MaxSz"), TEXT("Type"), TEXT("Medium"),
  255. TEXT("State"), NULL};
  256. switch (uMsg) {
  257. case WM_INITDIALOG: // Dialog is being created
  258. hLB = GetDlgItem (hDlg, IDL_ADAPTERS);
  259. GetWindowRect (hLB, &lbPos);
  260. MapWindowPoints (HWND_DESKTOP, hDlg,
  261. (POINT *)&lbPos, 2);
  262. GetClientRect (hDlg, &rect);
  263. lbPos.bottom = rect.bottom - lbPos.bottom;
  264. lbPos.right = rect.right - lbPos.right;
  265. hIml = ImageList_Create(GetSystemMetrics(SM_CXSMICON),
  266. GetSystemMetrics(SM_CYSMICON), TRUE, 2, 2);
  267. hIcon = LoadIcon(HDLLInstance,
  268. MAKEINTRESOURCE(ID_ICON_DOWN));
  269. ImageList_AddIcon(hIml, hIcon);
  270. DeleteObject(hIcon);
  271. hIcon = LoadIcon(HDLLInstance,
  272. MAKEINTRESOURCE(ID_ICON_UP));
  273. ImageList_AddIcon(hIml, hIcon);
  274. DeleteObject(hIcon);
  275. ListView_SetImageList(hLB, hIml, LVSIL_STATE);
  276. // Initialize the LV_COLUMN structure.
  277. lvc.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  278. lvc.fmt = LVCFMT_LEFT;
  279. aa = ListView_GetStringWidth (hLB, TEXT("MM"));
  280. for (i=0; Headers[i]!=NULL; i++) {
  281. lvc.pszText = Headers[i];
  282. lvc.iSubItem = i;
  283. lvc.cx = ListView_GetStringWidth (hLB, lvc.pszText)+aa;
  284. status = ListView_InsertColumn(hLB, i, &lvc);
  285. ASSERTMSG ("Could not insert list column ", status!=-1);
  286. }
  287. EnterCriticalSection (&ConfigInfoLock);
  288. UpdateAdapterList (GetDlgItem (hDlg, IDL_ADAPTERS));
  289. // Disable all buttons (nothing selected)
  290. LeaveCriticalSection (&ConfigInfoLock);
  291. break;
  292. case WM_COMMAND: // Process child window messages only
  293. switch (LOWORD(wParam)) {
  294. case IDCANCEL: // Do not allow to close the Dialog Box
  295. MessageBeep (MB_ICONHAND);
  296. res = TRUE;
  297. break;
  298. }
  299. break;
  300. case WM_NOTIFY:
  301. #define pnmv ((NM_LISTVIEW *)lParam)
  302. if ((pnmv->hdr.code==LVN_ITEMCHANGED)
  303. && (pnmv->uChanged&LVIF_STATE)
  304. && (pnmv->uNewState&LVIS_SELECTED)
  305. && (pnmv->iItem>0)) {
  306. }
  307. else if (pnmv->hdr.code==NM_DBLCLK) {
  308. LV_HITTESTINFO hit;
  309. status = GetMessagePos ();
  310. hit.pt.x = LOWORD(status);
  311. hit.pt.y = HIWORD(status);
  312. ScreenToClient (pnmv->hdr.hwndFrom, &hit.pt);
  313. ListView_HitTest(pnmv->hdr.hwndFrom, &hit);
  314. if ((hit.iItem>0)
  315. && (hit.flags&LVHT_ONITEMSTATEICON)) {
  316. i = hit.iItem - 1;
  317. EnterCriticalSection (&ConfigInfoLock);
  318. if (!AdapterArray[i].Enabled) {
  319. AdapterArray[i].Enabled = TRUE;
  320. if ((AdapterArray[i].Status==NIC_CONFIGURED)
  321. ||(AdapterArray[i].Status==NIC_LINE_UP))
  322. NotifyClients (i, NIC_LINE_UP);
  323. }
  324. else {
  325. AdapterArray[i].Enabled = FALSE;
  326. if ((AdapterArray[i].Status==NIC_CONFIGURED)
  327. ||(AdapterArray[i].Status==NIC_LINE_UP))
  328. NotifyClients (i, NIC_LINE_DOWN);
  329. }
  330. ListView_SetItemState (pnmv->hdr.hwndFrom, hit.iItem,
  331. INDEXTOSTATEIMAGEMASK (
  332. AdapterArray[i].Enabled
  333. ? (((AdapterArray[i].Status==NIC_CONFIGURED)
  334. || (AdapterArray[i].Status==NIC_LINE_UP))
  335. ? 2 : 1)
  336. : 0),
  337. LVIS_STATEIMAGEMASK);
  338. LeaveCriticalSection (&ConfigInfoLock);
  339. ListView_Update(pnmv->hdr.hwndFrom, hit.iItem);
  340. }
  341. }
  342. break;
  343. #undef pnmw
  344. case WM_SIZE:
  345. hLB = GetDlgItem (hDlg, IDL_ADAPTERS);
  346. MoveWindow (hLB, lbPos.left, lbPos.top,
  347. LOWORD (lParam)-lbPos.right-lbPos.left,
  348. HIWORD (lParam)-lbPos.bottom-lbPos.top,
  349. TRUE);
  350. break;
  351. case WM_DESTROY:
  352. EnterCriticalSection (&ConfigInfoLock);
  353. if (AdapterDataBuffer!=NULL) {
  354. RtlFreeHeap (RtlProcessHeap (), 0, AdapterDataBuffer);
  355. AdapterDataBuffer = NULL;
  356. }
  357. if (AdapterArray!=NULL) {
  358. RtlFreeHeap (RtlProcessHeap (), 0, AdapterArray);
  359. AdapterArray = NULL;
  360. }
  361. LeaveCriticalSection (&ConfigInfoLock);
  362. break;
  363. }
  364. return res;
  365. }
  366. /*++
  367. *******************************************************************
  368. N o t i f y C l i e n t s
  369. Routine Description:
  370. Notifies clients of adapter status changes made through UI
  371. Arguments:
  372. i - index of the adapter that was modified
  373. Status - new state of the adapter
  374. Return Value:
  375. None
  376. *******************************************************************
  377. --*/
  378. VOID
  379. NotifyClients (
  380. INT i,
  381. BOOLEAN Status
  382. ) {
  383. PLIST_ENTRY cur;
  384. PIPX_NIC_INFO NicPtr =
  385. &((PIPX_NIC_INFO)
  386. ((PIPX_NICS)
  387. ((PNWLINK_ACTION)AdapterDataBuffer)
  388. ->Data)
  389. ->Data)[i];
  390. PADAPTER_MSG msg = (PADAPTER_MSG)RtlAllocateHeap (
  391. RtlProcessHeap (), 0,
  392. sizeof (ADAPTER_MSG));
  393. ASSERTMSG ("Could not allocate adapter message ",
  394. msg!=NULL);
  395. RtlCopyMemory (&msg->info, NicPtr, sizeof (IPX_NIC_INFO));
  396. msg->info.Status = Status;
  397. msg->refcnt = 0;
  398. cur = PortListHead.Flink;
  399. while (cur!=&PortListHead) {
  400. PCONFIG_PORT config = CONTAINING_RECORD (cur,
  401. CONFIG_PORT, link);
  402. msg->refcnt += 1;;
  403. if (config->curmsg==NULL) {
  404. BOOL res = SetEvent (config->event);
  405. ASSERTMSG ("Can't set client event ", res);
  406. config->curmsg = &msg->info;
  407. }
  408. cur = cur->Flink;
  409. }
  410. InsertTailList (&MessageListHead, &msg->link);
  411. }
  412. /*++
  413. *******************************************************************
  414. U p d a t e A d a p t e r L i s t
  415. Routine Description:
  416. Updates adapter info displayed in the list
  417. Arguments:
  418. AdapterLB - list view control window handle
  419. Return Value:
  420. None
  421. *******************************************************************
  422. --*/
  423. VOID
  424. UpdateAdapterList (
  425. HWND AdapterLB
  426. ) {
  427. PNWLINK_ACTION action;
  428. PIPX_NICS request;
  429. IO_STATUS_BLOCK IoStatus;
  430. PIPX_NIC_INFO NicPtr;
  431. PISN_ACTION_GET_DETAILS details;
  432. CHAR IoctlBuffer[
  433. sizeof (NWLINK_ACTION)
  434. +sizeof (ISN_ACTION_GET_DETAILS)];
  435. ULONG i, j;
  436. PADAPTER_STATE newArray;
  437. WCHAR namebuf[64];
  438. char buf[128];
  439. ULONG length;
  440. DWORD status;
  441. LV_ITEM lvi;
  442. status = ListView_DeleteAllItems(AdapterLB);
  443. ASSERTMSG ("Could not all list items ", status);
  444. action = (PNWLINK_ACTION)IoctlBuffer;
  445. action->Header.TransportId = ISN_ACTION_TRANSPORT_ID;
  446. action->OptionType = NWLINK_OPTION_CONTROL;
  447. action->BufferLength = sizeof (action->Option)
  448. +sizeof (ISN_ACTION_GET_DETAILS);
  449. action->Option = MIPX_CONFIG;
  450. details = (PISN_ACTION_GET_DETAILS)action->Data;
  451. details->NicId = 0;
  452. status = NtDeviceIoControlFile(
  453. IpxDriverHandle,
  454. NULL,
  455. NULL,
  456. NULL,
  457. &IoStatus,
  458. IOCTL_TDI_ACTION,
  459. NULL,
  460. 0,
  461. action,
  462. sizeof(NWLINK_ACTION)
  463. +sizeof (ISN_ACTION_GET_DETAILS));
  464. if (status==STATUS_PENDING){
  465. status = NtWaitForSingleObject (IpxDriverHandle, FALSE, NULL);
  466. if (NT_SUCCESS (status))
  467. status = IoStatus.Status;
  468. }
  469. ASSERTMSG ("Ioclt MIPX_CONFIG failed ", NT_SUCCESS (status));
  470. ListView_SetItemCount(AdapterLB, details->NicId);
  471. lvi.mask = LVIF_TEXT;
  472. lvi.pszText = buf;
  473. lvi.iItem = 0;
  474. lvi.iSubItem = 0;
  475. sprintf (buf, "%ls", L"Internal");
  476. status = ListView_InsertItem (AdapterLB, &lvi);
  477. ASSERTMSG ("Could not insert list item ", status!=-1);
  478. lvi.iSubItem = 1;
  479. sprintf (buf, "%d", 0);
  480. status = ListView_SetItem (AdapterLB, &lvi);
  481. ASSERTMSG ("Could not set list subitem ", status);
  482. lvi.iSubItem = 2;
  483. sprintf (buf, "%d", 0);
  484. status = ListView_SetItem (AdapterLB, &lvi);
  485. ASSERTMSG ("Could not set list subitem ", status);
  486. lvi.iSubItem = 3;
  487. sprintf (buf,"%08x", GETLONG2ULONGdirect(&details->NetworkNumber));
  488. status = ListView_SetItem (AdapterLB, &lvi);
  489. ASSERTMSG ("Could not set list subitem ", status);
  490. lvi.iSubItem = 4;
  491. sprintf (buf, "%02x%02x%02x%02x%02x%02x",
  492. INTERNAL_NODE_ADDRESS[0], INTERNAL_NODE_ADDRESS[1],
  493. INTERNAL_NODE_ADDRESS[2], INTERNAL_NODE_ADDRESS[3],
  494. INTERNAL_NODE_ADDRESS[4], INTERNAL_NODE_ADDRESS[5]);
  495. status = ListView_SetItem (AdapterLB, &lvi);
  496. ASSERTMSG ("Could not set list subitem ", status);
  497. newArray = (PADAPTER_STATE)RtlAllocateHeap (RtlProcessHeap (), 0,
  498. sizeof (ADAPTER_STATE)*details->NicId);
  499. ASSERTMSG ("Could not allocate Adapter state array ", newArray!=NULL);
  500. if (AdapterDataBuffer!=NULL)
  501. RtlFreeHeap (RtlProcessHeap (), 0, AdapterDataBuffer);
  502. AdapterDataBuffer = RtlAllocateHeap (RtlProcessHeap (), 0,
  503. FIELD_OFFSET (NWLINK_ACTION, Data)
  504. +FIELD_OFFSET (IPX_NICS, Data)
  505. +sizeof (IPX_NIC_INFO)*details->NicId);
  506. ASSERTMSG ("Could not allocate request buffer ", action!=NULL);
  507. action = (PNWLINK_ACTION)AdapterDataBuffer;
  508. action->Header.TransportId = ISN_ACTION_TRANSPORT_ID;
  509. action->OptionType = NWLINK_OPTION_CONTROL;
  510. action->BufferLength = sizeof (action->Option)
  511. +FIELD_OFFSET(IPX_NICS,Data)
  512. +sizeof (IPX_NIC_INFO)*details->NicId;
  513. action->Option = MIPX_GETNEWNICINFO;
  514. request = (PIPX_NICS)action->Data;
  515. request->NoOfNics = 0;
  516. request->TotalNoOfNics = 0;
  517. request->fAllNicsDesired = TRUE;
  518. status = NtDeviceIoControlFile(
  519. IpxDriverHandle,
  520. NULL,
  521. NULL,
  522. NULL,
  523. &IoStatus,
  524. IOCTL_TDI_ACTION,
  525. NULL,
  526. 0,
  527. action,
  528. FIELD_OFFSET(NWLINK_ACTION, Data)
  529. +FIELD_OFFSET(IPX_NICS,Data)
  530. +sizeof (IPX_NIC_INFO)*details->NicId);
  531. if (status==STATUS_PENDING) {
  532. status = NtWaitForSingleObject (IpxDriverHandle, FALSE, NULL);
  533. if (NT_SUCCESS (status))
  534. status = IoStatus.Status;
  535. }
  536. ASSERTMSG ("Ioctl MIPX_GETNEWNICINFO failed ", NT_SUCCESS (status));
  537. NicPtr = (PIPX_NIC_INFO)request->Data;
  538. NumAdapters = request->TotalNoOfNics;
  539. for (i=0; i<NumAdapters; i++, NicPtr++) {
  540. UINT j;
  541. for (j=0; (j<AdapterArraySize)
  542. && (AdapterArray[j].AdapterId
  543. !=NicPtr->NicId); j++);
  544. newArray[i].AdapterId = NicPtr->NicId;
  545. newArray[i].Status = NicPtr->Status;
  546. if (j<AdapterArraySize)
  547. newArray[i].Enabled = AdapterArray[j].Enabled;
  548. else
  549. newArray[i].Enabled = TRUE;
  550. length = sizeof (namebuf);
  551. GetAdapterNameW (newArray[i].AdapterId, &length, namebuf);
  552. lvi.iItem = i+1;
  553. lvi.mask |= LVIF_STATE;
  554. lvi.iSubItem = 0;
  555. lvi.stateMask = LVIS_STATEIMAGEMASK;
  556. lvi.state = INDEXTOSTATEIMAGEMASK (
  557. newArray[i].Enabled
  558. ? (((NicPtr->Status==NIC_CONFIGURED)
  559. || (NicPtr->Status==NIC_LINE_UP))
  560. ? 2 : 1)
  561. : 0);
  562. sprintf (buf, "%ls", namebuf);
  563. status = ListView_InsertItem (AdapterLB, &lvi);
  564. ASSERTMSG ("Could not insert list item ", status!=-1);
  565. lvi.mask &= (~LVIF_STATE);
  566. sprintf (buf, "%d", newArray[i].AdapterId);
  567. lvi.iSubItem = 1;
  568. status = ListView_SetItem (AdapterLB, &lvi);
  569. ASSERTMSG ("Could not set list subitem ", status);
  570. sprintf (buf, "%d",
  571. (NicPtr->NdisMediumType==NdisMediumWan)
  572. && (newArray[i].Status==NIC_LINE_UP)
  573. ? NicPtr->InterfaceIndex
  574. : -1);
  575. lvi.iSubItem = 2;
  576. status = ListView_SetItem (AdapterLB, &lvi);
  577. ASSERTMSG ("Could not set list subitem ", status);
  578. sprintf (buf, "%08x", GETLONG2ULONGdirect(&NicPtr->NetworkAddress));
  579. lvi.iSubItem = 3;
  580. status = ListView_SetItem (AdapterLB, &lvi);
  581. ASSERTMSG ("Could not set list subitem ", status);
  582. sprintf (buf, "%02x%02x%02x%02x%02x%02x",
  583. NicPtr->LocalNodeAddress[0], NicPtr->LocalNodeAddress[1],
  584. NicPtr->LocalNodeAddress[2], NicPtr->LocalNodeAddress[3],
  585. NicPtr->LocalNodeAddress[4], NicPtr->LocalNodeAddress[5]);
  586. lvi.iSubItem = 4;
  587. status = ListView_SetItem (AdapterLB, &lvi);
  588. ASSERTMSG ("Could not set list subitem ", status);
  589. sprintf (buf, "%02x%02x%02x%02x%02x%02x",
  590. NicPtr->RemoteNodeAddress[0], NicPtr->RemoteNodeAddress[1],
  591. NicPtr->RemoteNodeAddress[2], NicPtr->RemoteNodeAddress[3],
  592. NicPtr->RemoteNodeAddress[4], NicPtr->RemoteNodeAddress[5]);
  593. lvi.iSubItem = 5;
  594. status = ListView_SetItem (AdapterLB, &lvi);
  595. ASSERTMSG ("Could not set list subitem ", status);
  596. sprintf (buf, "%d", NicPtr->LinkSpeed);
  597. lvi.iSubItem = 6;
  598. status = ListView_SetItem (AdapterLB, &lvi);
  599. ASSERTMSG ("Could not set list subitem ", status);
  600. sprintf (buf, "%d", NicPtr->MaxPacketSize);
  601. lvi.iSubItem = 7;
  602. status = ListView_SetItem (AdapterLB, &lvi);
  603. ASSERTMSG ("Could not set list subitem ", status);
  604. sprintf (buf, "%d", NicPtr->PacketType);
  605. lvi.iSubItem = 8;
  606. status = ListView_SetItem (AdapterLB, &lvi);
  607. ASSERTMSG ("Could not set list subitem ", status);
  608. switch (NicPtr->NdisMediumType) {
  609. case NdisMedium802_3:
  610. sprintf (buf, "%s", "802.3");
  611. break;
  612. case NdisMedium802_5:
  613. sprintf (buf, "%s", "802.5");
  614. break;
  615. case NdisMediumFddi:
  616. sprintf (buf, "%s", "FDDI");
  617. break;
  618. case NdisMediumWan:
  619. sprintf (buf, "%s", "Wan");
  620. break;
  621. case NdisMediumLocalTalk:
  622. sprintf (buf, "%s", "LTalk");
  623. break;
  624. case NdisMediumDix:
  625. sprintf (buf, "%s", "Dix");
  626. break;
  627. case NdisMediumArcnetRaw:
  628. sprintf (buf, "%s", "ArcnetRaw");
  629. break;
  630. case NdisMediumArcnet878_2:
  631. sprintf (buf, "%s", "Arcnet878.2");
  632. break;
  633. }
  634. lvi.iSubItem = 9;
  635. status = ListView_SetItem (AdapterLB, &lvi);
  636. ASSERTMSG ("Could not set list subitem ", status);
  637. switch (NicPtr->Status) {
  638. case NIC_CREATED:
  639. sprintf (buf, "%s", "Created");
  640. break;
  641. case NIC_DELETED:
  642. sprintf (buf, "%s", "Deleted");
  643. break;
  644. case NIC_CONFIGURED:
  645. sprintf (buf, "%s", "Configured");
  646. break;
  647. case NIC_LINE_UP:
  648. sprintf (buf, "%s", "Up");
  649. break;
  650. case NIC_LINE_DOWN:
  651. sprintf (buf, "%s", "Down");
  652. break;
  653. default:
  654. ASSERTMSG ("Unknown nic status ", FALSE);
  655. break;
  656. }
  657. lvi.iSubItem = 10;
  658. status = ListView_SetItem (AdapterLB, &lvi);
  659. ASSERTMSG ("Could not set list subitem ", status);
  660. }
  661. if (AdapterArray!=NULL)
  662. RtlFreeHeap (RtlProcessHeap (), 0, AdapterArray);
  663. AdapterArray = newArray;
  664. AdapterArraySize = NumAdapters;
  665. }
  666. /*++
  667. *******************************************************************
  668. I p x R e c v C o m p l e t i o n W a t c h
  669. Routine Description:
  670. Substitute completion routine that filters out packets
  671. received on the adapters disabled by the UI
  672. Arguments:
  673. Context - Pointer to client completion routine
  674. IoStatus - status of completed io operation (clients overlapped
  675. structure is used as the buffer)
  676. Reserved - ???
  677. Return Value:
  678. None
  679. --*/
  680. VOID
  681. IpxRecvCompletionWatch (
  682. IN PVOID Context,
  683. IN PIO_STATUS_BLOCK IoStatus,
  684. IN ULONG Reserved
  685. ) {
  686. LPOVERLAPPED ovrp = (LPOVERLAPPED)IoStatus;
  687. if (NT_SUCCESS(IoStatus->Status)) {
  688. // Check if adapter is disabled through the UI and repost recv if so
  689. USHORT NicId = GetNicId (ovrp->OffsetHigh);
  690. UINT i;
  691. EnterCriticalSection (&ConfigInfoLock);
  692. if (AdapterArray!=NULL) {
  693. for (i=0; (i<AdapterArraySize) && (AdapterArray[i].AdapterId!=NicId); i++);
  694. ASSERTMSG ("Invalid Nic id ", i<AdapterArraySize);
  695. if (!AdapterArray[i].Enabled) {
  696. LeaveCriticalSection (&ConfigInfoLock);
  697. IoStatus->Status = NtDeviceIoControlFile(
  698. (HANDLE)ovrp->hEvent,
  699. NULL,
  700. IpxRecvCompletionWatch,
  701. Context, // APC Context
  702. IoStatus,
  703. MIPX_RCV_DATAGRAM,
  704. NULL,
  705. 0,
  706. (PVOID)ovrp->OffsetHigh,
  707. FIELD_OFFSET (IPX_DATAGRAM_OPTIONS2,Data)
  708. + ovrp->Offset
  709. );
  710. if (NT_SUCCESS (IoStatus->Status))
  711. return;
  712. }
  713. else
  714. LeaveCriticalSection (&ConfigInfoLock);
  715. }
  716. else
  717. LeaveCriticalSection (&ConfigInfoLock);
  718. }
  719. ovrp->hEvent = NULL;
  720. IpxRecvCompletion (Context, IoStatus, Reserved);
  721. }
  722. /*++
  723. *******************************************************************
  724. I s A d a p t e r D i s a b l e d
  725. Routine Description:
  726. Chacks if adapter with given id is disabled by the UI (it wont be
  727. reported to the clients)
  728. Arguments:
  729. NicId - id of the adapter to check
  730. Return Value:
  731. TRUE - adapter is disabled
  732. FALSE - adapter is not disabled
  733. --*/
  734. BOOL
  735. IsAdapterDisabled (
  736. USHORT NicId
  737. ) {
  738. if (AdapterArray!=NULL) {
  739. UINT j;
  740. for (j=0; j<AdapterArraySize; j++) {
  741. if (AdapterArray[j].AdapterId==NicId)
  742. break;
  743. }
  744. ASSERTMSG ("Nic not in the array ", j<AdapterArraySize);
  745. if (!AdapterArray[j].Enabled)
  746. return TRUE;
  747. }
  748. return FALSE;
  749. }
  750. /*++
  751. *******************************************************************
  752. I n f o r m W a t c h e r
  753. Routine Description:
  754. Signals event to inform let watcher dialog update its adapter
  755. configuration info
  756. Arguments:
  757. None
  758. Return Value:
  759. None
  760. --*/
  761. VOID
  762. InformWatcher (
  763. void
  764. ) {
  765. if (WatcherDlg!=NULL) {
  766. BOOL res = SetEvent (DebugWatchEvent);
  767. ASSERTMSG ("Could not set debug watch event ", res);
  768. }
  769. }