Leaked source code of windows server 2003
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.

774 lines
23 KiB

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // tdipnp.cpp
  7. //
  8. // Abstract:
  9. // This module contains the tdi pnp functions called from the tdilib.sys
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. #include "sysvars.h"
  13. extern "C"
  14. {
  15. #pragma warning(disable: NAMELESS_STRUCT_UNION)
  16. #include "tdiinfo.h"
  17. #pragma warning(default: NAMELESS_STRUCT_UNION)
  18. }
  19. ////////////////////////////////////////////////////////
  20. // private defines and prototypes
  21. ////////////////////////////////////////////////////////
  22. VOID
  23. TSPrintTdiContext(
  24. PTDI_PNP_CONTEXT Context
  25. );
  26. VOID
  27. TSRemoveFromDeviceList(
  28. PTA_ADDRESS pTaAddress,
  29. PCWSTR pDeviceName,
  30. ULONG ulNameLength
  31. );
  32. VOID
  33. TSAddToDeviceList(
  34. PTA_ADDRESS pTaAddress,
  35. PCWSTR pDeviceName,
  36. ULONG ulNameLength
  37. );
  38. const PCHAR strFunc1 = "TSPnpBindCallback";
  39. const PCHAR strFunc2 = "TSPnpPowerHandler";
  40. const PCHAR strFunc3 = "TSPnpAddAddressCallback";
  41. const PCHAR strFunc4 = "TSPnpDelAddressCallback";
  42. const PCHAR strFunc5 = "TSGetNumDevices";
  43. const PCHAR strFunc6 = "TSGetDevice";
  44. const PCHAR strFunc7 = "TSGetAddress";
  45. //const PCHAR strFuncP1 = "TSPrintTdiContext";
  46. const PCHAR strFuncP2 = "TSAddToDeviceList";
  47. //const PCHAR strFuncP3 = "TSRemoveFromDeviceList";
  48. ///////////////////////////////////////////////////////
  49. // public functions
  50. ///////////////////////////////////////////////////////
  51. // ---------------------------------------
  52. //
  53. // Function: TSPnpBindCallback
  54. //
  55. // Arguments: TdiPnpOpcode -- callback type
  56. // pusDeviceName -- name of device to deal with
  57. // pwstrBindingList -- information from registry Linkage key
  58. // (if appropriate)
  59. //
  60. // Returns: none
  61. //
  62. // Descript: This function is called by tdi.sys when tdisample.sys
  63. // registers its PnpCallbackHandlers. It is called several
  64. // times, with the reason for each call in TdiPnpOpcode
  65. //
  66. // Currently, it just writes the information passed in to the
  67. // debugger
  68. //
  69. // ---------------------------------------
  70. VOID
  71. TSPnpBindCallback(TDI_PNP_OPCODE TdiPnpOpcode,
  72. PUNICODE_STRING pusDeviceName,
  73. PWSTR pwstrBindingList)
  74. {
  75. if (ulDebugLevel & ulDebugShowHandlers)
  76. {
  77. if (pusDeviceName)
  78. {
  79. DebugPrint1("DeviceName: %wZ\r\n", pusDeviceName);
  80. }
  81. else
  82. {
  83. DebugPrint0("DeviceName: NULL\n");
  84. }
  85. DebugPrint0("OPCODE: ");
  86. switch (TdiPnpOpcode)
  87. {
  88. case TDI_PNP_OP_MIN:
  89. DebugPrint0("TDI_PNP_OP_MIN\n");
  90. break;
  91. case TDI_PNP_OP_ADD:
  92. DebugPrint0("TDI_PNP_OP_ADD\n");
  93. break;
  94. case TDI_PNP_OP_DEL:
  95. DebugPrint0("TDI_PNP_OP_DEL\n");
  96. break;
  97. case TDI_PNP_OP_UPDATE:
  98. DebugPrint0("TDI_PNP_OP_UPDATE\n");
  99. break;
  100. case TDI_PNP_OP_PROVIDERREADY:
  101. DebugPrint0("TDI_PNP_OP_PROVIDERREADY\n");
  102. break;
  103. case TDI_PNP_OP_NETREADY:
  104. DebugPrint0("TDI_PNP_OP_NETREADY\n");
  105. break;
  106. default:
  107. DebugPrint1("INCORRECT OPCODE FROM TDI!! [0x%08x]\n",
  108. TdiPnpOpcode);
  109. DbgBreakPoint();
  110. break;
  111. }
  112. //
  113. // this is the information from the registry under
  114. // HKLM/SYSTEM/CurrentControlSet/Services/clientname/Linkage/Bind
  115. //
  116. if( pwstrBindingList == NULL )
  117. {
  118. DebugPrint0("Bindinglist is NULL\n");
  119. }
  120. else
  121. {
  122. ULONG_PTR ulStrLen;
  123. DebugPrint0("BindingList:\n");
  124. while (*pwstrBindingList)
  125. {
  126. DebugPrint1("%ws\n", pwstrBindingList);
  127. ulStrLen = 1 + wcslen(pwstrBindingList);
  128. pwstrBindingList += ulStrLen;
  129. }
  130. DebugPrint0("\n");
  131. }
  132. }
  133. }
  134. // --------------------------------------
  135. //
  136. // Function: TSPnpPowerHandler
  137. //
  138. // Arguments: pusDeviceName -- device name to deal with
  139. // pNetPnpEvent -- power event to deal with
  140. // pTdiPnpContext1
  141. // pTdiPnpContext2
  142. //
  143. // Returns: status of operation
  144. //
  145. // Descript: This function deals with pnp and power management issues
  146. //
  147. // Currently, it just outputs information to the debugger
  148. //
  149. // --------------------------------------
  150. NTSTATUS
  151. TSPnpPowerHandler(PUNICODE_STRING pusDeviceName,
  152. PNET_PNP_EVENT pNetPnpEvent,
  153. PTDI_PNP_CONTEXT pTdiPnpContext1,
  154. PTDI_PNP_CONTEXT pTdiPnpContext2)
  155. {
  156. if (ulDebugLevel & ulDebugShowHandlers)
  157. {
  158. if (pusDeviceName)
  159. {
  160. DebugPrint1("DeviceName: %wZ\r\n", pusDeviceName);
  161. }
  162. else
  163. {
  164. DebugPrint0("DeviceName: NULL\n");
  165. }
  166. switch (pNetPnpEvent->NetEvent)
  167. {
  168. case NetEventSetPower:
  169. case NetEventQueryPower:
  170. {
  171. if (pNetPnpEvent->NetEvent == NetEventSetPower)
  172. {
  173. DebugPrint1("%s: NetEventSetPower--", strFunc2);
  174. }
  175. else
  176. {
  177. DebugPrint1("%s: NetEventQueryPower -- ", strFunc2);
  178. }
  179. NET_DEVICE_POWER_STATE NetDevicePowerState
  180. = *(PNET_DEVICE_POWER_STATE)pNetPnpEvent->Buffer;
  181. switch (NetDevicePowerState)
  182. {
  183. case NetDeviceStateUnspecified:
  184. DebugPrint0("PowerStateUnspecified\n");
  185. break;
  186. case NetDeviceStateD0:
  187. DebugPrint0("PowerUp\n");
  188. break;
  189. case NetDeviceStateD1:
  190. case NetDeviceStateD2:
  191. case NetDeviceStateD3:
  192. DebugPrint0("PowerDown\n");
  193. break;
  194. }
  195. break;
  196. }
  197. case NetEventQueryRemoveDevice:
  198. DebugPrint1("%s: NetEventQueryRemoveDevice\n", strFunc2);
  199. break;
  200. case NetEventCancelRemoveDevice:
  201. DebugPrint1("%s: NetEventCancelRemoveDevice\n", strFunc2);
  202. break;
  203. case NetEventReconfigure:
  204. DebugPrint1("%s: NetEventReconfigure\n", strFunc2);
  205. break;
  206. case NetEventBindList:
  207. DebugPrint1("%s: NetEventBindList\n", strFunc2);
  208. break;
  209. case NetEventBindsComplete:
  210. DebugPrint1("%s: NetEventBindsComplete\n", strFunc2);
  211. break;
  212. case NetEventPnPCapabilities:
  213. DebugPrint1("%s: NetEventPnPCapabilities\n", strFunc2);
  214. break;
  215. }
  216. if (pTdiPnpContext1)
  217. {
  218. DebugPrint0("TdiPnpContext1:\n");
  219. TSPrintTdiContext(pTdiPnpContext1);
  220. }
  221. if (pTdiPnpContext2)
  222. {
  223. DebugPrint0("TdiPnpContext2:\n");
  224. TSPrintTdiContext(pTdiPnpContext2);
  225. }
  226. }
  227. return STATUS_SUCCESS;
  228. }
  229. // -----------------------------------------------
  230. //
  231. // Function: TSPnpAddAddressCallback
  232. //
  233. // Arguments: pTaAddress -- address to register
  234. // pusDeviceName -- device name associated with address
  235. // pTdiPnpContext
  236. //
  237. // Returns: none
  238. //
  239. // Descript: called by tdi.sys. When called, tdisample adds this device
  240. // to its registered list, if it recognizes the address format
  241. //
  242. // -----------------------------------------------
  243. VOID
  244. TSPnpAddAddressCallback(PTA_ADDRESS pTaAddress,
  245. PUNICODE_STRING pusDeviceName,
  246. PTDI_PNP_CONTEXT pTdiPnpContext)
  247. {
  248. if (ulDebugLevel & ulDebugShowHandlers)
  249. {
  250. //
  251. // write info to debugger
  252. //
  253. DebugPrint1("DeviceName: %wZ\r\n", pusDeviceName);
  254. TSPrintTaAddress(pTaAddress);
  255. if (pTdiPnpContext)
  256. {
  257. DebugPrint0("TdiPnpContext:\n");
  258. TSPrintTdiContext(pTdiPnpContext);
  259. }
  260. }
  261. //
  262. // add this to our list of devices/addresses, if appropriate
  263. //
  264. TSAddToDeviceList(pTaAddress,
  265. pusDeviceName->Buffer,
  266. pusDeviceName->Length);
  267. }
  268. // -----------------------------------------------
  269. //
  270. // Function: TSDelAddAddressCallback
  271. //
  272. // Arguments: pTaAddress -- address to de-register
  273. // pusDeviceName -- device name associated with address
  274. // pTdiPnpContext
  275. //
  276. // Returns: none
  277. //
  278. // Descript: called by tdi.sys. When called, tdisample removes this device
  279. // to its registered list, if it recognizes the address format
  280. //
  281. // -----------------------------------------------
  282. VOID
  283. TSPnpDelAddressCallback(PTA_ADDRESS pTaAddress,
  284. PUNICODE_STRING pusDeviceName,
  285. PTDI_PNP_CONTEXT pTdiPnpContext)
  286. {
  287. if (ulDebugLevel & ulDebugShowHandlers)
  288. {
  289. DebugPrint1("DeviceName: %wZ\r\n", pusDeviceName);
  290. TSPrintTaAddress(pTaAddress);
  291. if (pTdiPnpContext)
  292. {
  293. DebugPrint0("TdiPnpContext:\n");
  294. TSPrintTdiContext(pTdiPnpContext);
  295. }
  296. }
  297. //
  298. // remove this from our list of devices/addresses, if appropriate
  299. //
  300. TSRemoveFromDeviceList(pTaAddress,
  301. pusDeviceName->Buffer,
  302. pusDeviceName->Length);
  303. }
  304. // ----------------------------------------
  305. //
  306. // Function: TSGetNumDevices
  307. //
  308. // Arguments: pSendBuffer
  309. // pReceiveBuffer
  310. //
  311. // Returns: none
  312. //
  313. // Descript: Finds the number of devices in tdidevicelist,
  314. // and returns that value..
  315. //
  316. // ----------------------------------------
  317. VOID
  318. TSGetNumDevices(PSEND_BUFFER pSendBuffer,
  319. PRECEIVE_BUFFER pReceiveBuffer)
  320. {
  321. ULONG ulSlot = 0;
  322. ULONG ulAddressType = pSendBuffer->COMMAND_ARGS.GetDevArgs.ulAddressType;
  323. if (ulDebugLevel & ulDebugShowCommand)
  324. {
  325. DebugPrint1("\nCommand = ulGETNUMDEVICES\n"
  326. "AddressType = 0x%08x\n",
  327. ulAddressType);
  328. }
  329. TSAcquireSpinLock(&pTdiDevnodeList->TdiSpinLock);
  330. for (ULONG ulCount = 0; ulCount < ulMAX_DEVICE_NODES; ulCount++)
  331. {
  332. PTDI_DEVICE_NODE pTdiDeviceNode = &(pTdiDevnodeList->TdiDeviceNode[ulCount]);
  333. if ((pTdiDeviceNode->ulState != ulDEVSTATE_UNUSED) &&
  334. (pTdiDeviceNode->pTaAddress->AddressType == (USHORT)ulAddressType))
  335. {
  336. ++ulSlot;
  337. }
  338. }
  339. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  340. pReceiveBuffer->RESULTS.ulReturnValue = ulSlot;
  341. }
  342. // ----------------------------------------
  343. //
  344. // Function: TSGetDevice
  345. //
  346. // Arguments: pSendBuffer -- arguments
  347. // pReceiveBuffer -- where to put result
  348. //
  349. // Returns: NTSTATUS (success if finds slot, else false)
  350. //
  351. // Descript: Finds the device name indicated, and returns
  352. // the string for that value
  353. //
  354. // ----------------------------------------
  355. NTSTATUS
  356. TSGetDevice(PSEND_BUFFER pSendBuffer,
  357. PRECEIVE_BUFFER pReceiveBuffer)
  358. {
  359. ULONG ulSlot = 0;
  360. ULONG ulAddressType = pSendBuffer->COMMAND_ARGS.GetDevArgs.ulAddressType;
  361. ULONG ulSlotNum = pSendBuffer->COMMAND_ARGS.GetDevArgs.ulSlotNum;
  362. if (ulDebugLevel & ulDebugShowCommand)
  363. {
  364. DebugPrint2("\nCommand = ulGETDEVICE\n"
  365. "AddressType = 0x%08x\n"
  366. "SlotNum = %d\n",
  367. ulAddressType,
  368. ulSlotNum);
  369. }
  370. TSAcquireSpinLock(&pTdiDevnodeList->TdiSpinLock);
  371. for (ULONG ulCount = 0; ulCount < ulMAX_DEVICE_NODES; ulCount++)
  372. {
  373. PTDI_DEVICE_NODE pTdiDeviceNode = &(pTdiDevnodeList->TdiDeviceNode[ulCount]);
  374. if ((pTdiDeviceNode->ulState != ulDEVSTATE_UNUSED) &&
  375. (pTdiDeviceNode->pTaAddress->AddressType == (USHORT)ulAddressType))
  376. {
  377. if (ulSlot == ulSlotNum)
  378. {
  379. if (pTdiDeviceNode->ustrDeviceName.MaximumLength > (ulMAX_CNTSTRING_LENGTH * sizeof(WCHAR)))
  380. {
  381. DebugPrint0("string length problem!\n");
  382. DbgBreakPoint();
  383. }
  384. RtlZeroMemory(&pReceiveBuffer->RESULTS.ucsStringReturn.wcBuffer,
  385. ulMAX_CNTSTRING_LENGTH * sizeof(WCHAR));
  386. pReceiveBuffer->RESULTS.ucsStringReturn.usLength
  387. = pTdiDeviceNode->ustrDeviceName.Length;
  388. RtlCopyMemory(pReceiveBuffer->RESULTS.ucsStringReturn.wcBuffer,
  389. pTdiDeviceNode->ustrDeviceName.Buffer,
  390. pTdiDeviceNode->ustrDeviceName.Length);
  391. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  392. if (pTdiDeviceNode->ulState == ulDEVSTATE_INUSE)
  393. {
  394. return STATUS_SUCCESS;
  395. }
  396. else
  397. {
  398. return STATUS_UNSUCCESSFUL;
  399. }
  400. }
  401. ++ulSlot;
  402. }
  403. }
  404. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  405. return STATUS_UNSUCCESSFUL;
  406. }
  407. // ----------------------------------------
  408. //
  409. // Function: TSGetAddress
  410. //
  411. // Arguments: pSendBuffer -- arguments
  412. // pReceiveBuffer -- where to put result
  413. //
  414. // Returns: NTSTATUS (success if finds slot, else false)
  415. //
  416. // Descript: Finds the device name indicated, and returns
  417. // the string for that value
  418. //
  419. // ----------------------------------------
  420. NTSTATUS
  421. TSGetAddress(PSEND_BUFFER pSendBuffer,
  422. PRECEIVE_BUFFER pReceiveBuffer)
  423. {
  424. ULONG ulSlot = 0;
  425. ULONG ulAddressType = pSendBuffer->COMMAND_ARGS.GetDevArgs.ulAddressType;
  426. ULONG ulSlotNum = pSendBuffer->COMMAND_ARGS.GetDevArgs.ulSlotNum;
  427. if (ulDebugLevel & ulDebugShowCommand)
  428. {
  429. DebugPrint2("\nCommand = ulGETADDRESS\n"
  430. "AddressType = 0x%08x\n"
  431. "SlotNum = %d\n",
  432. ulAddressType,
  433. ulSlotNum);
  434. }
  435. TSAcquireSpinLock(&pTdiDevnodeList->TdiSpinLock);
  436. for (ULONG ulCount = 0; ulCount < ulMAX_DEVICE_NODES; ulCount++)
  437. {
  438. PTDI_DEVICE_NODE pTdiDeviceNode = &(pTdiDevnodeList->TdiDeviceNode[ulCount]);
  439. if ((pTdiDeviceNode->ulState != ulDEVSTATE_UNUSED) &&
  440. (pTdiDeviceNode->pTaAddress->AddressType == (USHORT)ulAddressType))
  441. {
  442. if (ulSlot == ulSlotNum)
  443. {
  444. ULONG ulLength = FIELD_OFFSET(TA_ADDRESS, Address)
  445. + pTdiDeviceNode->pTaAddress->AddressLength;
  446. pReceiveBuffer->RESULTS.TransAddr.TAAddressCount = 1;
  447. RtlCopyMemory(&pReceiveBuffer->RESULTS.TransAddr.TaAddress,
  448. pTdiDeviceNode->pTaAddress,
  449. ulLength);
  450. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  451. if (pTdiDeviceNode->ulState == ulDEVSTATE_INUSE)
  452. {
  453. return STATUS_SUCCESS;
  454. }
  455. else
  456. {
  457. return STATUS_UNSUCCESSFUL;
  458. }
  459. }
  460. ++ulSlot;
  461. }
  462. }
  463. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  464. return STATUS_UNSUCCESSFUL;
  465. }
  466. //////////////////////////////////////////////////////
  467. // private functions
  468. //////////////////////////////////////////////////////
  469. // ---------------------------------
  470. //
  471. // Function: TSPrintTdiContext
  472. //
  473. // Arguments: pTdiPnpContext -- context to dump
  474. //
  475. // Returns: none
  476. //
  477. // Descript: prints out information in pTdiPnpContext structure
  478. //
  479. // ---------------------------------
  480. VOID
  481. TSPrintTdiContext(PTDI_PNP_CONTEXT pTdiPnpContext)
  482. {
  483. if (pTdiPnpContext)
  484. {
  485. PUCHAR pucTemp = pTdiPnpContext->ContextData;
  486. DebugPrint2("TdiPnpContextSize: %u\n"
  487. "TdiPnpContextType: %u\n"
  488. "TdiPnpContextData: ",
  489. pTdiPnpContext->ContextSize,
  490. pTdiPnpContext->ContextType);
  491. for (ULONG ulCount = 0; ulCount < pTdiPnpContext->ContextSize; ulCount++)
  492. {
  493. DebugPrint1("%02x ", *pucTemp);
  494. ++pucTemp;
  495. }
  496. DebugPrint0("\n");
  497. }
  498. }
  499. // ------------------------------------------
  500. //
  501. // Function: TSAddToDeviceList
  502. //
  503. // Arguments: pTaAddress -- current address structure
  504. // pusDeviceName -- actual name of device
  505. //
  506. // Returns: none
  507. //
  508. // Descript: Adds this device to our device list, if appropriate
  509. //
  510. // ------------------------------------------
  511. VOID
  512. TSAddToDeviceList(PTA_ADDRESS pTaAddress,
  513. PCWSTR pDeviceName,
  514. ULONG ulNameLength)
  515. {
  516. //
  517. // scan list for first available slot. For any slot before the first
  518. // available whose entry has been deleted, check to see if this is the
  519. // same device coming back
  520. //
  521. ULONG ulLengthNeeded = FIELD_OFFSET(TA_ADDRESS, Address)
  522. + pTaAddress->AddressLength;
  523. ULONG ulAddressType = pTaAddress->AddressType;
  524. TSAcquireSpinLock(&pTdiDevnodeList->TdiSpinLock);
  525. for (ULONG ulCount = 0; ulCount < ulMAX_DEVICE_NODES; ulCount++)
  526. {
  527. PTDI_DEVICE_NODE pTdiDeviceNode = &(pTdiDevnodeList->TdiDeviceNode[ulCount]);
  528. switch (pTdiDeviceNode->ulState)
  529. {
  530. //
  531. // this is first unused slot
  532. // allocate buffers and set
  533. //
  534. case ulDEVSTATE_UNUSED:
  535. if ((TSAllocateMemory((PVOID *)&pTdiDeviceNode->pTaAddress,
  536. ulLengthNeeded,
  537. strFuncP2,
  538. "TaAddress")) == STATUS_SUCCESS)
  539. {
  540. if ((TSAllocateMemory((PVOID *)&pTdiDeviceNode->ustrDeviceName.Buffer,
  541. ulNameLength+2,
  542. strFuncP2,
  543. "Buffer")) == STATUS_SUCCESS)
  544. {
  545. RtlCopyMemory(pTdiDeviceNode->pTaAddress,
  546. pTaAddress,
  547. ulLengthNeeded);
  548. pTdiDeviceNode->ustrDeviceName.MaximumLength = (USHORT)(ulNameLength + 2);
  549. pTdiDeviceNode->ustrDeviceName.Length = (USHORT)ulNameLength;
  550. RtlCopyMemory(pTdiDeviceNode->ustrDeviceName.Buffer,
  551. pDeviceName,
  552. ulNameLength);
  553. pTdiDeviceNode->ulState = ulDEVSTATE_INUSE;
  554. }
  555. else
  556. {
  557. TSFreeMemory(pTdiDeviceNode->pTaAddress);
  558. }
  559. }
  560. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  561. return;
  562. //
  563. // device in slot has been removed. See if this is the same
  564. // device coming back
  565. //
  566. case ulDEVSTATE_DELETED:
  567. {
  568. //
  569. // check for correct name
  570. //
  571. ULONG_PTR ulCompareLength = RtlCompareMemory(pTdiDeviceNode->ustrDeviceName.Buffer,
  572. pDeviceName,
  573. ulNameLength);
  574. if (ulCompareLength == ulNameLength)
  575. {
  576. //
  577. // for tcpip, netbios, and appletalk this is enough
  578. // for ipx/spx, need to check address as well
  579. //
  580. if (ulAddressType == TDI_ADDRESS_TYPE_IPX)
  581. {
  582. ulCompareLength = RtlCompareMemory(pTdiDeviceNode->pTaAddress,
  583. pTaAddress,
  584. pTaAddress->AddressLength + sizeof(ULONG));
  585. //
  586. // if address is incorrect, not right ipx
  587. //
  588. if (ulCompareLength != pTaAddress->AddressLength + sizeof(ULONG))
  589. {
  590. break;
  591. }
  592. }
  593. else
  594. {
  595. //
  596. // copy address info over in case it changed..
  597. //
  598. RtlCopyMemory(pTdiDeviceNode->pTaAddress,
  599. pTaAddress,
  600. ulLengthNeeded);
  601. }
  602. pTdiDeviceNode->ulState = ulDEVSTATE_INUSE;
  603. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  604. return;
  605. }
  606. }
  607. break;
  608. //
  609. // device in slot is in used. Leave it alone
  610. //
  611. case ulDEVSTATE_INUSE:
  612. break;
  613. }
  614. }
  615. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  616. }
  617. // ------------------------------------------
  618. //
  619. // Function: TSRemoveFromDeviceList
  620. //
  621. // Arguments: pTaAddress -- current address structure
  622. // pusDeviceName -- actual name of device
  623. //
  624. // Returns: none
  625. //
  626. // Descript: Remove this device from our device list, if is it
  627. // on it..
  628. //
  629. // ------------------------------------------
  630. VOID
  631. TSRemoveFromDeviceList(PTA_ADDRESS pTaAddress,
  632. PCWSTR pDeviceName,
  633. ULONG ulNameLength)
  634. {
  635. //
  636. // search list for the item to remove..
  637. //
  638. TSAcquireSpinLock(&pTdiDevnodeList->TdiSpinLock);
  639. for (ULONG ulCount = 0; ulCount < ulMAX_DEVICE_NODES; ulCount++)
  640. {
  641. PTDI_DEVICE_NODE pTdiDeviceNode = &(pTdiDevnodeList->TdiDeviceNode[ulCount]);
  642. //
  643. // check to see that it is the right node...
  644. // first check to see if the address is correct
  645. //
  646. ULONG_PTR ulCompareLength = RtlCompareMemory(pTdiDeviceNode->pTaAddress,
  647. pTaAddress,
  648. pTaAddress->AddressLength + sizeof(ULONG));
  649. //
  650. // if address is correct, check for correct name
  651. //
  652. if (ulCompareLength == pTaAddress->AddressLength + sizeof(ULONG))
  653. {
  654. ulCompareLength = RtlCompareMemory(pTdiDeviceNode->ustrDeviceName.Buffer,
  655. pDeviceName,
  656. ulNameLength);
  657. //
  658. // if this matches, it's the right node. Delete it!
  659. //
  660. if (ulCompareLength == ulNameLength)
  661. {
  662. pTdiDeviceNode->ulState = ulDEVSTATE_DELETED;
  663. break;
  664. }
  665. }
  666. }
  667. TSReleaseSpinLock(&pTdiDevnodeList->TdiSpinLock);
  668. }
  669. /////////////////////////////////////////////////////////////////
  670. // end of file tdipnp.cpp
  671. /////////////////////////////////////////////////////////////////