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.

1104 lines
32 KiB

  1. ////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // utils.cpp
  7. //
  8. // Abstract:
  9. // This module contains some utility functions for the tdi sample driver
  10. //
  11. /////////////////////////////////////////////////////////////////////
  12. #include "sysvars.h"
  13. /////////////////////////////////////////////////////
  14. // private constants
  15. /////////////////////////////////////////////////////
  16. //const PCHAR strFunc1 = "TSAllocateMemory";
  17. const PCHAR strFunc2 = "TSFreeMemory";
  18. const PCHAR strFunc3 = "TSScanMemoryPool";
  19. //const PCHAR strFunc4 = "TSInsertNode";
  20. const PCHAR strFunc5 = "TSRemoveNode";
  21. const PCHAR strFunc6 = "TSGetObjectFromHandle";
  22. //const PCHAR strFunc6 = "TSAllocateIrp";
  23. //const PCHAR strFunc7 = "TSFreeIrp";
  24. //const PCHAR strFunc8 = "TSPrintTaAddress";
  25. const PCHAR strFunc9 = "TSllocateIrpPool";
  26. const PCHAR strFuncA = "TSFreeIrpPool";
  27. ////////////////////////////////////////////////////
  28. // public functions
  29. ////////////////////////////////////////////////////
  30. // --------------------------------------------------------------------
  31. //
  32. // Function: TSAllocateMemory
  33. //
  34. // Arguments: ppvVirtualAddress -- addr of pointer to set to allocated block
  35. // ulLength -- length of memory to allocate
  36. // strFunction -- ptr to function name string
  37. // strTitle -- ptr to title of this allocation
  38. //
  39. // Returns: lStatus
  40. //
  41. // Descript: This function acts as a wrapper for the ExAllocatePoolWithTag
  42. // function. It also stores info for each memory block that can
  43. // identify them in case of "memory leaks"
  44. //
  45. // ---------------------------------------------------------------------
  46. //
  47. // this structure store information about this memory block to allow
  48. // us to track memory blocks, and verify that they are freed properly, that
  49. // we don't write beyond the end of them, etc
  50. //
  51. struct PRIVATE_MEMORY
  52. {
  53. ULONG ulSignature; // ulMEMORY_BLOCK
  54. PCHAR strFunction; // name of function doing allocate
  55. PCHAR strTitle; // Title for specific allocate
  56. ULONG ulLength; // ulong index of trailer (=(length/4)-1
  57. PRIVATE_MEMORY *pLastMemPtr; // ptr to last allocated block
  58. PRIVATE_MEMORY *pNextMemPtr; // ptr to next allocated block
  59. };
  60. const ULONG ulTRAIL_PATTERN = 0x0f1e2d3c;
  61. const ULONG ulMEMORY_BLOCK = 0x4b5a6978;
  62. #define TDISAMPLE_TAG 'aSDT'
  63. NTSTATUS
  64. TSAllocateMemory(PVOID *ppvVirtualAddress,
  65. ULONG ulLength,
  66. CONST PCHAR strFunction,
  67. CONST PCHAR strTitle)
  68. {
  69. PVOID pvBaseMemory; // base -- where actual memory allocated
  70. //
  71. // allocate for length plus header plus trailer, rounded up to next dword
  72. //
  73. ulLength += (sizeof(PRIVATE_MEMORY) + sizeof(ULONG) + 3);
  74. ulLength &= 0xfffffffc;
  75. //
  76. // allocate it
  77. //
  78. pvBaseMemory = ExAllocatePoolWithTag(NonPagedPool,
  79. ulLength,
  80. TDISAMPLE_TAG);
  81. //
  82. // things to do if allocation was successful
  83. //
  84. if (pvBaseMemory)
  85. {
  86. //
  87. // zero the memory
  88. //
  89. RtlZeroMemory(pvBaseMemory, ulLength);
  90. //
  91. // set up our header and trailer info
  92. //
  93. PRIVATE_MEMORY *pPrivateMemory // our header information
  94. = (PRIVATE_MEMORY *)pvBaseMemory;
  95. PULONG pulBase
  96. = (PULONG)pvBaseMemory;
  97. //
  98. // adjust the ptr we return to allocated memory
  99. //
  100. *ppvVirtualAddress = (PUCHAR)pvBaseMemory + sizeof(PRIVATE_MEMORY);
  101. //
  102. // set up our header information
  103. //
  104. ulLength /= sizeof(ULONG); // set ulLength to ulong index of trailer
  105. --ulLength;
  106. pPrivateMemory->ulSignature = ulMEMORY_BLOCK;
  107. pPrivateMemory->strFunction = strFunction;
  108. pPrivateMemory->strTitle = strTitle;
  109. pPrivateMemory->ulLength = ulLength;
  110. //
  111. // set up the trailer information
  112. //
  113. pulBase[ulLength] = ulTRAIL_PATTERN;
  114. //
  115. // insert at head of linked list..
  116. // (note that memory is already initialized to null)
  117. //
  118. TSAcquireSpinLock(&MemTdiSpinLock);
  119. if (pvMemoryList)
  120. {
  121. ((PRIVATE_MEMORY *)pvMemoryList)->pLastMemPtr = pPrivateMemory;
  122. pPrivateMemory->pNextMemPtr = (PRIVATE_MEMORY *)pvMemoryList;
  123. }
  124. pvMemoryList = pPrivateMemory;
  125. TSReleaseSpinLock(&MemTdiSpinLock);
  126. return STATUS_SUCCESS;
  127. }
  128. else
  129. {
  130. DebugPrint3("%s: unable to allocate %u bytes for %s\n",
  131. strFunction, ulLength, strTitle);
  132. *ppvVirtualAddress = NULL;
  133. return STATUS_INSUFFICIENT_RESOURCES;
  134. }
  135. }
  136. // -------------------------------------------------------------------
  137. //
  138. // Function: TSFreeMemory
  139. //
  140. // Arguments: pvVirtualAddress -- address of memory block to free
  141. //
  142. // Returns: None
  143. //
  144. // Descript: This function is a wrapper around the ExFreePool
  145. // function. it helps track memory
  146. // to make sure that we cleanup up everything...
  147. //
  148. // --------------------------------------------------------------------
  149. VOID
  150. TSFreeMemory(PVOID pvVirtualAddress)
  151. {
  152. if (pvVirtualAddress == NULL)
  153. {
  154. DebugPrint1("%s: memory block already freed!\n", strFunc2);
  155. DbgBreakPoint();
  156. return;
  157. }
  158. //
  159. // back up to start of header information
  160. //
  161. pvVirtualAddress = (PVOID)((PUCHAR)pvVirtualAddress - sizeof(PRIVATE_MEMORY));
  162. PRIVATE_MEMORY *pPrivateMemory // ptr to our header block
  163. = (PRIVATE_MEMORY *)pvVirtualAddress;
  164. PULONG pulTemp // temp ptr into allocated block
  165. = (PULONG)pvVirtualAddress;
  166. ULONG ulLength
  167. = pPrivateMemory->ulLength;
  168. //
  169. // is this a valid memory block?
  170. //
  171. if (pPrivateMemory->ulSignature != ulMEMORY_BLOCK)
  172. {
  173. DebugPrint2("%s: invalid memory block at %p!\n",
  174. strFunc2,
  175. pPrivateMemory);
  176. DbgBreakPoint();
  177. return;
  178. }
  179. //
  180. // check that the trailer is still ok
  181. //
  182. if (pulTemp[ulLength] != ulTRAIL_PATTERN)
  183. {
  184. DebugPrint2("%s: trailer overwritten for block staring at %p\n",
  185. strFunc2,
  186. pPrivateMemory);
  187. DbgBreakPoint();
  188. return;
  189. }
  190. //
  191. // remove it from the linked list..
  192. //
  193. TSAcquireSpinLock(&MemTdiSpinLock);
  194. //
  195. // is it first block in list?
  196. //
  197. if (pPrivateMemory->pLastMemPtr == (PRIVATE_MEMORY *)NULL)
  198. {
  199. pvMemoryList = pPrivateMemory->pNextMemPtr;
  200. }
  201. else
  202. {
  203. PRIVATE_MEMORY *pLastPrivateMemory
  204. = pPrivateMemory->pLastMemPtr;
  205. pLastPrivateMemory->pNextMemPtr = pPrivateMemory->pNextMemPtr;
  206. }
  207. //
  208. // fix ptr of next memory block if necessary
  209. //
  210. if (pPrivateMemory->pNextMemPtr != (PVOID)NULL)
  211. {
  212. PRIVATE_MEMORY *pNextPrivateMemory
  213. = pPrivateMemory->pNextMemPtr;
  214. pNextPrivateMemory->pLastMemPtr = pPrivateMemory->pLastMemPtr;
  215. }
  216. TSReleaseSpinLock(&MemTdiSpinLock);
  217. //
  218. // zero memory and free--make sure we adjust ulLength to be the true length
  219. //
  220. RtlZeroMemory(pvVirtualAddress, sizeof(ULONG) * (ulLength + 1));
  221. ExFreePool(pvVirtualAddress);
  222. }
  223. // -------------------------------------------------------------------
  224. //
  225. // Function: TSScanMemoryPool
  226. //
  227. // Arguments: none
  228. //
  229. // Returns: none
  230. //
  231. // Descript: Scans to see if any tdi sample owned memory blocks have
  232. // not been freed
  233. //
  234. // -------------------------------------------------------------------
  235. VOID
  236. TSScanMemoryPool(VOID)
  237. {
  238. TSAcquireSpinLock(&MemTdiSpinLock);
  239. if (pvMemoryList)
  240. {
  241. PRIVATE_MEMORY *pPrivateMemory // our header information
  242. = (PRIVATE_MEMORY *)pvMemoryList;
  243. PULONG pulTemp;
  244. DebugPrint0("The following memory blocks have not been freed!\n");
  245. while (pPrivateMemory)
  246. {
  247. //
  248. // is this a valid memory block?
  249. //
  250. if (pPrivateMemory->ulSignature != ulMEMORY_BLOCK)
  251. {
  252. DebugPrint1("Memory block at %p has an invalid signature!\n",
  253. pPrivateMemory);
  254. DbgBreakPoint();
  255. }
  256. DebugPrint2("Memory block at %p: total length = %d bytes\n",
  257. pPrivateMemory,
  258. sizeof(ULONG) * (pPrivateMemory->ulLength + 1));
  259. DebugPrint2("Block '%s' was allocated by function %s\n",
  260. pPrivateMemory->strTitle,
  261. pPrivateMemory->strFunction);
  262. pulTemp = (PULONG)pPrivateMemory;
  263. //
  264. // check that the trailer is still ok
  265. //
  266. if (pulTemp[pPrivateMemory->ulLength] != ulTRAIL_PATTERN)
  267. {
  268. DebugPrint0("The trailer for this memory block has been overwritten\n");
  269. DbgBreakPoint();
  270. }
  271. DebugPrint0("\n");
  272. pPrivateMemory = pPrivateMemory->pNextMemPtr;
  273. }
  274. DebugPrint0("\n\n\n");
  275. }
  276. else
  277. {
  278. DebugPrint0("All Tdi Sample memory blocks freed properly!\n");
  279. }
  280. TSReleaseSpinLock(&MemTdiSpinLock);
  281. }
  282. // --------------------------------------------
  283. //
  284. // Function: TSInsertNode
  285. //
  286. // Arguments: pNewNode -- node to insert into list
  287. //
  288. // Returns: Handle where we put things
  289. //
  290. // Descript: insert the object at the first empty slot in the
  291. // table. Return Handle for it (NULL if error)
  292. //
  293. // --------------------------------------------
  294. ULONG
  295. TSInsertNode(PGENERIC_HEADER pNewNode)
  296. {
  297. ULONG ulTdiHandle = 0;
  298. for (ULONG ulCount = 0; ulCount < ulMAX_OBJ_HANDLES; ulCount++)
  299. {
  300. if (pObjectList->GenHead[ulCount] == NULL)
  301. {
  302. pObjectList->GenHead[ulCount] = pNewNode;
  303. ulTdiHandle = (ulCount + pNewNode->ulSignature);
  304. break;
  305. }
  306. }
  307. return ulTdiHandle;
  308. }
  309. // ---------------------------------------------
  310. //
  311. // Function: TSRemoveNode
  312. //
  313. // Arguments: pOldNode -- node to remove from it's linked list..
  314. //
  315. // Returns: none
  316. //
  317. // Descript: remove from appropriate linked list
  318. //
  319. // ---------------------------------------------
  320. VOID
  321. TSRemoveNode(ULONG ulTdiHandle)
  322. {
  323. ULONG ulType;
  324. ULONG ulSlot;
  325. PGENERIC_HEADER pGenericHeader;
  326. ulType = ulTdiHandle & usOBJ_TYPE_MASK;
  327. if ((ulType == ulControlChannelObject) ||
  328. (ulType == ulAddressObject) ||
  329. (ulType == ulEndpointObject))
  330. {
  331. ulSlot = ulTdiHandle & usOBJ_HANDLE_MASK;
  332. pGenericHeader = pObjectList->GenHead[ulSlot];
  333. if (pGenericHeader)
  334. {
  335. if (pGenericHeader->ulSignature == ulType)
  336. {
  337. pObjectList->GenHead[ulSlot] = NULL;
  338. return;
  339. }
  340. //
  341. // from here down, error cases
  342. //
  343. else
  344. {
  345. DebugPrint1("%s: wrong type for node!\n", strFunc5);
  346. }
  347. }
  348. else
  349. {
  350. DebugPrint1("%s: node is null!\n", strFunc5);
  351. }
  352. }
  353. else
  354. {
  355. DebugPrint1("%s: Bad handle type value\n", strFunc5);
  356. }
  357. }
  358. // ---------------------------------------------
  359. //
  360. // Function: TSGetObjectFromHandle
  361. //
  362. // Arguments: TdiHandle -- the handle passed in to us
  363. // ulType -- the type the handle needs to have
  364. //
  365. // Returns: pGenericHeader of object (NULL if error)
  366. //
  367. // Descript: fetch object from list via handle
  368. //
  369. // ---------------------------------------------
  370. PGENERIC_HEADER
  371. TSGetObjectFromHandle(ULONG ulTdiHandle,
  372. ULONG ulType)
  373. {
  374. ULONG ulHandleType = ulTdiHandle & usOBJ_TYPE_MASK;
  375. if ((ulHandleType & ulType) == ulHandleType)
  376. {
  377. ULONG ulHandleSlot = ulTdiHandle & usOBJ_HANDLE_MASK;
  378. PGENERIC_HEADER pGenericHeader = pObjectList->GenHead[ulHandleSlot];
  379. if (pGenericHeader)
  380. {
  381. if (pGenericHeader->ulSignature == ulHandleType)
  382. {
  383. return pGenericHeader;
  384. }
  385. //
  386. // from here down, error conditions
  387. //
  388. else
  389. {
  390. DebugPrint1("%s: wrong type for node!\n", strFunc6);
  391. }
  392. }
  393. else
  394. {
  395. DebugPrint1("%s: node is null!\n", strFunc6);
  396. }
  397. }
  398. else
  399. {
  400. DebugPrint1("%s: Bad handle type value\n", strFunc6);
  401. }
  402. // DbgBreakPoint();
  403. return NULL;
  404. }
  405. // ----------------------------------------------------
  406. //
  407. // Function: TSAllocateIrp
  408. //
  409. // Arguments: pDeviceObject -- device object to call with this irp
  410. // pIrpPool -- irp pool to allocate from (may be NULL)
  411. //
  412. // Returns: IRP that was allocated (NULL if error)
  413. //
  414. // Descript: allocates a single IRP for use in calling the
  415. // lower level driver (TdiProvider)
  416. //
  417. // NOTE: much of this code taken from ntos\io\iosubs.c\IoBuildDeviceIoRequest
  418. // see TSAllocateIrpPool for how we cheat
  419. //
  420. // ----------------------------------------------------
  421. PIRP
  422. TSAllocateIrp(PDEVICE_OBJECT pDeviceObject,
  423. PIRP_POOL pIrpPool)
  424. {
  425. PIRP pNewIrp = NULL;
  426. if (pIrpPool)
  427. {
  428. pNewIrp = pIrpPool->pAvailIrpList;
  429. if (!pNewIrp)
  430. {
  431. TSAcquireSpinLock(&pIrpPool->TdiSpinLock);
  432. pIrpPool->pAvailIrpList = pIrpPool->pUsedIrpList;
  433. pIrpPool->pUsedIrpList = NULL;
  434. TSReleaseSpinLock(&pIrpPool->TdiSpinLock);
  435. pNewIrp = pIrpPool->pAvailIrpList;
  436. }
  437. if (pNewIrp)
  438. {
  439. pIrpPool->pAvailIrpList = pNewIrp->AssociatedIrp.MasterIrp;
  440. pNewIrp->AssociatedIrp.MasterIrp = NULL;
  441. }
  442. }
  443. else
  444. {
  445. pNewIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
  446. pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();;
  447. }
  448. if (pNewIrp)
  449. {
  450. PIO_STACK_LOCATION pIrpSp = IoGetNextIrpStackLocation(pNewIrp);
  451. pIrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
  452. pIrpSp->Parameters.DeviceIoControl.OutputBufferLength = 0;
  453. pIrpSp->Parameters.DeviceIoControl.InputBufferLength = 0;
  454. pIrpSp->Parameters.DeviceIoControl.IoControlCode = 0x00000003;
  455. pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer = NULL;
  456. pNewIrp->UserBuffer = NULL;
  457. pNewIrp->UserIosb = NULL;
  458. pNewIrp->UserEvent = NULL;
  459. pNewIrp->RequestorMode = KernelMode;
  460. }
  461. return pNewIrp;
  462. }
  463. // ----------------------------------------------------
  464. //
  465. // Function: TSFreeIrp
  466. //
  467. // Arguments: IRP to free
  468. // pIrpPool -- pool to free to (may be NULL)
  469. //
  470. // Returns: none
  471. //
  472. // Descript: Frees the IRP passed in
  473. // See TSAllocateIrpPool for how we cheat..
  474. //
  475. // ----------------------------------------------------
  476. VOID
  477. TSFreeIrp(PIRP pIrp,
  478. PIRP_POOL pIrpPool)
  479. {
  480. if (pIrpPool)
  481. {
  482. TSAcquireSpinLock(&pIrpPool->TdiSpinLock);
  483. pIrp->AssociatedIrp.MasterIrp = pIrpPool->pUsedIrpList;
  484. pIrpPool->pUsedIrpList = pIrp;
  485. TSReleaseSpinLock(&pIrpPool->TdiSpinLock);
  486. if (pIrpPool->fMustFree)
  487. {
  488. TSFreeIrpPool(pIrpPool);
  489. }
  490. }
  491. else
  492. {
  493. IoFreeIrp(pIrp);
  494. }
  495. }
  496. // ---------------------------------
  497. //
  498. // Function: TSPrintTaAddress
  499. //
  500. // Arguments: pTaAddress -- address to print out info for
  501. //
  502. // Returns: none
  503. //
  504. // Descript: prints out information in pTaAddress structure
  505. //
  506. // ---------------------------------
  507. VOID
  508. TSPrintTaAddress(PTA_ADDRESS pTaAddress)
  509. {
  510. BOOLEAN fShowAddress = TRUE;
  511. DebugPrint0("AddressType = TDI_ADDRESS_TYPE_");
  512. switch (pTaAddress->AddressType)
  513. {
  514. case TDI_ADDRESS_TYPE_UNSPEC:
  515. DebugPrint0("UNSPEC\n");
  516. break;
  517. case TDI_ADDRESS_TYPE_UNIX:
  518. DebugPrint0("UNIX\n");
  519. break;
  520. case TDI_ADDRESS_TYPE_IP:
  521. DebugPrint0("IP\n");
  522. fShowAddress = FALSE;
  523. {
  524. PTDI_ADDRESS_IP pTdiAddressIp = (PTDI_ADDRESS_IP)pTaAddress->Address;
  525. PUCHAR pucTemp = (PUCHAR)&pTdiAddressIp->in_addr;
  526. DebugPrint5("sin_port = 0x%04x\n"
  527. "in_addr = %u.%u.%u.%u\n",
  528. pTdiAddressIp->sin_port,
  529. pucTemp[0], pucTemp[1],
  530. pucTemp[2], pucTemp[3]);
  531. }
  532. break;
  533. case TDI_ADDRESS_TYPE_IMPLINK:
  534. DebugPrint0("IMPLINK\n");
  535. break;
  536. case TDI_ADDRESS_TYPE_PUP:
  537. DebugPrint0("PUP\n");
  538. break;
  539. case TDI_ADDRESS_TYPE_CHAOS:
  540. DebugPrint0("CHAOS\n");
  541. break;
  542. case TDI_ADDRESS_TYPE_IPX:
  543. DebugPrint0("IPX\n");
  544. fShowAddress = FALSE;
  545. {
  546. PTDI_ADDRESS_IPX pTdiAddressIpx = (PTDI_ADDRESS_IPX)pTaAddress->Address;
  547. DebugPrint8("NetworkAddress = 0x%08x\n"
  548. "NodeAddress = %u.%u.%u.%u.%u.%u\n"
  549. "Socket = 0x%04x\n",
  550. pTdiAddressIpx->NetworkAddress,
  551. pTdiAddressIpx->NodeAddress[0],
  552. pTdiAddressIpx->NodeAddress[1],
  553. pTdiAddressIpx->NodeAddress[2],
  554. pTdiAddressIpx->NodeAddress[3],
  555. pTdiAddressIpx->NodeAddress[4],
  556. pTdiAddressIpx->NodeAddress[5],
  557. pTdiAddressIpx->Socket);
  558. }
  559. break;
  560. case TDI_ADDRESS_TYPE_NBS:
  561. DebugPrint0("NBS\n");
  562. break;
  563. case TDI_ADDRESS_TYPE_ECMA:
  564. DebugPrint0("ECMA\n");
  565. break;
  566. case TDI_ADDRESS_TYPE_DATAKIT:
  567. DebugPrint0("DATAKIT\n");
  568. break;
  569. case TDI_ADDRESS_TYPE_CCITT:
  570. DebugPrint0("CCITT\n");
  571. break;
  572. case TDI_ADDRESS_TYPE_SNA:
  573. DebugPrint0("SNA\n");
  574. break;
  575. case TDI_ADDRESS_TYPE_DECnet:
  576. DebugPrint0("DECnet\n");
  577. break;
  578. case TDI_ADDRESS_TYPE_DLI:
  579. DebugPrint0("DLI\n");
  580. break;
  581. case TDI_ADDRESS_TYPE_LAT:
  582. DebugPrint0("LAT\n");
  583. break;
  584. case TDI_ADDRESS_TYPE_HYLINK:
  585. DebugPrint0("HYLINK\n");
  586. break;
  587. case TDI_ADDRESS_TYPE_APPLETALK:
  588. DebugPrint0("APPLETALK\n");
  589. fShowAddress = FALSE;
  590. {
  591. PTDI_ADDRESS_APPLETALK pTdiAddressAppleTalk = (PTDI_ADDRESS_APPLETALK)pTaAddress->Address;
  592. DebugPrint3("Network = 0x%04x\n"
  593. "Node = 0x%02x\n"
  594. "Socket = 0x%02x\n",
  595. pTdiAddressAppleTalk->Network,
  596. pTdiAddressAppleTalk->Node,
  597. pTdiAddressAppleTalk->Socket);
  598. }
  599. break;
  600. case TDI_ADDRESS_TYPE_NETBIOS:
  601. DebugPrint0("NETBIOS\n");
  602. fShowAddress = FALSE;
  603. {
  604. PTDI_ADDRESS_NETBIOS pTdiAddressNetbios = (PTDI_ADDRESS_NETBIOS)pTaAddress->Address;
  605. UCHAR pucName[17];
  606. //
  607. // make sure we have a zero-terminated name to print...
  608. //
  609. RtlCopyMemory(pucName, pTdiAddressNetbios->NetbiosName, 16);
  610. pucName[16] = 0;
  611. DebugPrint0("NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_");
  612. switch (pTdiAddressNetbios->NetbiosNameType)
  613. {
  614. case TDI_ADDRESS_NETBIOS_TYPE_UNIQUE:
  615. DebugPrint0("UNIQUE\n");
  616. break;
  617. case TDI_ADDRESS_NETBIOS_TYPE_GROUP:
  618. DebugPrint0("GROUP\n");
  619. break;
  620. case TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE:
  621. DebugPrint0("QUICK_UNIQUE\n");
  622. break;
  623. case TDI_ADDRESS_NETBIOS_TYPE_QUICK_GROUP:
  624. DebugPrint0("QUICK_GROUP\n");
  625. break;
  626. default:
  627. DebugPrint1("INVALID [0x%04x]\n",
  628. pTdiAddressNetbios->NetbiosNameType);
  629. break;
  630. }
  631. DebugPrint1("NetbiosName = %s\n", pucName);
  632. }
  633. break;
  634. case TDI_ADDRESS_TYPE_8022:
  635. DebugPrint0("8022\n");
  636. fShowAddress = FALSE;
  637. {
  638. PTDI_ADDRESS_8022 pTdiAddress8022 = (PTDI_ADDRESS_8022)pTaAddress->Address;
  639. DebugPrint6("Address = %02x-%02x-%02x-%02x-%02x-%02x\n",
  640. pTdiAddress8022->MACAddress[0],
  641. pTdiAddress8022->MACAddress[1],
  642. pTdiAddress8022->MACAddress[2],
  643. pTdiAddress8022->MACAddress[3],
  644. pTdiAddress8022->MACAddress[4],
  645. pTdiAddress8022->MACAddress[5]);
  646. }
  647. break;
  648. case TDI_ADDRESS_TYPE_OSI_TSAP:
  649. DebugPrint0("OSI_TSAP\n");
  650. fShowAddress = FALSE;
  651. {
  652. PTDI_ADDRESS_OSI_TSAP pTdiAddressOsiTsap = (PTDI_ADDRESS_OSI_TSAP)pTaAddress->Address;
  653. ULONG ulSelectorLength;
  654. ULONG ulAddressLength;
  655. PUCHAR pucTemp = pTdiAddressOsiTsap->tp_addr;
  656. DebugPrint0("TpAddrType = ISO_");
  657. switch (pTdiAddressOsiTsap->tp_addr_type)
  658. {
  659. case ISO_HIERARCHICAL:
  660. DebugPrint0("HIERARCHICAL\n");
  661. ulSelectorLength = pTdiAddressOsiTsap->tp_tsel_len;
  662. ulAddressLength = pTdiAddressOsiTsap->tp_taddr_len;
  663. break;
  664. case ISO_NON_HIERARCHICAL:
  665. DebugPrint0("NON_HIERARCHICAL\n");
  666. ulSelectorLength = 0;
  667. ulAddressLength = pTdiAddressOsiTsap->tp_taddr_len;
  668. break;
  669. default:
  670. DebugPrint1("INVALID [0x%04x]\n",
  671. pTdiAddressOsiTsap->tp_addr_type);
  672. ulSelectorLength = 0;
  673. ulAddressLength = 0;
  674. break;
  675. }
  676. if (ulSelectorLength)
  677. {
  678. ULONG ulCount;
  679. DebugPrint0("TransportSelector: ");
  680. for (ulCount = 0; ulCount < ulSelectorLength; ulCount++)
  681. {
  682. DebugPrint1("%02x ", *pucTemp);
  683. ++pucTemp;
  684. }
  685. DebugPrint0("\n");
  686. }
  687. if (ulAddressLength)
  688. {
  689. ULONG ulCount;
  690. DebugPrint0("TransportAddress: ");
  691. for (ulCount = 0; ulCount < ulAddressLength; ulCount++)
  692. {
  693. DebugPrint1("%02x ", *pucTemp);
  694. ++pucTemp;
  695. }
  696. DebugPrint0("\n");
  697. }
  698. }
  699. break;
  700. case TDI_ADDRESS_TYPE_NETONE:
  701. DebugPrint0("NETONE\n");
  702. fShowAddress = FALSE;
  703. {
  704. PTDI_ADDRESS_NETONE pTdiAddressNetone = (PTDI_ADDRESS_NETONE)pTaAddress->Address;
  705. UCHAR pucName[21];
  706. //
  707. // make sure have 0-terminated name
  708. //
  709. RtlCopyMemory(pucName,
  710. pTdiAddressNetone->NetoneName,
  711. 20);
  712. pucName[20] = 0;
  713. DebugPrint0("NetoneNameType = TDI_ADDRESS_NETONE_TYPE_");
  714. switch (pTdiAddressNetone->NetoneNameType)
  715. {
  716. case TDI_ADDRESS_NETONE_TYPE_UNIQUE:
  717. DebugPrint0("UNIQUE\n");
  718. break;
  719. case TDI_ADDRESS_NETONE_TYPE_ROTORED:
  720. DebugPrint0("ROTORED\n");
  721. break;
  722. default:
  723. DebugPrint1("INVALID [0x%04x]\n",
  724. pTdiAddressNetone->NetoneNameType);
  725. break;
  726. }
  727. DebugPrint1("NetoneName = %s\n",
  728. pucName);
  729. }
  730. break;
  731. case TDI_ADDRESS_TYPE_VNS:
  732. DebugPrint0("VNS\n");
  733. fShowAddress = FALSE;
  734. {
  735. PTDI_ADDRESS_VNS pTdiAddressVns = (PTDI_ADDRESS_VNS)pTaAddress->Address;
  736. DebugPrint4("NetAddress: %02x-%02x-%02x-%02x\n",
  737. pTdiAddressVns->net_address[0],
  738. pTdiAddressVns->net_address[1],
  739. pTdiAddressVns->net_address[2],
  740. pTdiAddressVns->net_address[3]);
  741. DebugPrint5("SubnetAddr: %02x-%02x\n"
  742. "Port: %02x-%02x\n"
  743. "Hops: %u\n",
  744. pTdiAddressVns->subnet_addr[0],
  745. pTdiAddressVns->subnet_addr[1],
  746. pTdiAddressVns->port[0],
  747. pTdiAddressVns->port[1],
  748. pTdiAddressVns->hops);
  749. }
  750. break;
  751. case TDI_ADDRESS_TYPE_NETBIOS_EX:
  752. DebugPrint0("NETBIOS_EX\n");
  753. fShowAddress = FALSE;
  754. {
  755. PTDI_ADDRESS_NETBIOS_EX pTdiAddressNetbiosEx = (PTDI_ADDRESS_NETBIOS_EX)pTaAddress->Address;
  756. UCHAR pucEndpointName[17];
  757. UCHAR pucNetbiosName[17];
  758. //
  759. // make sure we have zero-terminated names to print...
  760. //
  761. RtlCopyMemory(pucEndpointName,
  762. pTdiAddressNetbiosEx->EndpointName,
  763. 16);
  764. pucEndpointName[16] = 0;
  765. RtlCopyMemory(pucNetbiosName,
  766. pTdiAddressNetbiosEx->NetbiosAddress.NetbiosName,
  767. 16);
  768. pucNetbiosName[16] = 0;
  769. DebugPrint1("EndpointName = %s\n"
  770. "NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_",
  771. pucEndpointName);
  772. switch (pTdiAddressNetbiosEx->NetbiosAddress.NetbiosNameType)
  773. {
  774. case TDI_ADDRESS_NETBIOS_TYPE_UNIQUE:
  775. DebugPrint0("UNIQUE\n");
  776. break;
  777. case TDI_ADDRESS_NETBIOS_TYPE_GROUP:
  778. DebugPrint0("GROUP\n");
  779. break;
  780. case TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE:
  781. DebugPrint0("QUICK_UNIQUE\n");
  782. break;
  783. case TDI_ADDRESS_NETBIOS_TYPE_QUICK_GROUP:
  784. DebugPrint0("QUICK_GROUP\n");
  785. break;
  786. default:
  787. DebugPrint1("INVALID [0x%04x]\n",
  788. pTdiAddressNetbiosEx->NetbiosAddress.NetbiosNameType);
  789. break;
  790. }
  791. DebugPrint1("NetbiosName = %s\n", pucNetbiosName);
  792. }
  793. break;
  794. case TDI_ADDRESS_TYPE_IP6:
  795. DebugPrint0("IPv6\n");
  796. fShowAddress = FALSE;
  797. {
  798. PTDI_ADDRESS_IP6 pTdiAddressIp6 = (PTDI_ADDRESS_IP6)pTaAddress->Address;
  799. PUCHAR pucTemp = (PUCHAR)&pTdiAddressIp6->sin6_addr;
  800. DebugPrint3("SinPort6 = 0x%04x\n"
  801. "FlowInfo = 0x%08x\n"
  802. "ScopeId = 0x%08x\n",
  803. pTdiAddressIp6->sin6_port,
  804. pTdiAddressIp6->sin6_flowinfo,
  805. pTdiAddressIp6->sin6_scope_id);
  806. DebugPrint8("In6_addr = %x%02x:%x%02x:%x%02x:%x%02x:",
  807. pucTemp[0], pucTemp[1],
  808. pucTemp[2], pucTemp[3],
  809. pucTemp[4], pucTemp[5],
  810. pucTemp[6], pucTemp[7]);
  811. DebugPrint8("%x%02x:%x%02x:%x%02x:%x%02x\n",
  812. pucTemp[8], pucTemp[9],
  813. pucTemp[10], pucTemp[11],
  814. pucTemp[12], pucTemp[13],
  815. pucTemp[14], pucTemp[15]);
  816. }
  817. break;
  818. default:
  819. DebugPrint1("UNKNOWN [0x%08x]\n", pTaAddress->AddressType);
  820. break;
  821. }
  822. if (fShowAddress)
  823. {
  824. PUCHAR pucTemp = pTaAddress->Address;
  825. DebugPrint1("AddressLength = %d\n"
  826. "Address = ",
  827. pTaAddress->AddressLength);
  828. for (ULONG ulCount = 0; ulCount < pTaAddress->AddressLength; ulCount++)
  829. {
  830. DebugPrint1("%02x ", *pucTemp);
  831. pucTemp++;
  832. }
  833. DebugPrint0("\n");
  834. }
  835. }
  836. // ----------------------------------------------------
  837. //
  838. // Function: TSAllocateIrpPool
  839. //
  840. // Arguments: device object
  841. //
  842. // Returns: ptr to irp pool
  843. //
  844. // Descript: allocates an IRP pool when the driver starts, so
  845. // we don't have to worry about being in an inappropriate
  846. // IRQL when we need one...
  847. //
  848. // NOTE: we cheat a little in maintaining our list of available Irps
  849. // We use the AssociatedIrp.MasterIrp field to point to the
  850. // next IRP in our list. Because of this, we need to explicitly
  851. // set this field to NULL whenever we remove one of the IRPs from our
  852. // list..
  853. //
  854. // ----------------------------------------------------
  855. PIRP_POOL
  856. TSAllocateIrpPool(PDEVICE_OBJECT pDeviceObject,
  857. ULONG ulPoolSize)
  858. {
  859. PIRP_POOL pIrpPool = NULL;
  860. if ((TSAllocateMemory((PVOID *)&pIrpPool,
  861. sizeof(IRP_POOL) + (ulPoolSize * sizeof(PVOID)),
  862. strFunc9,
  863. "IrpPool")) == STATUS_SUCCESS)
  864. {
  865. PIRP pNewIrp;
  866. TSAllocateSpinLock(&pIrpPool->TdiSpinLock);
  867. pIrpPool->ulPoolSize = ulPoolSize;
  868. pIrpPool->fMustFree = FALSE;
  869. for (ULONG ulCount = 0; ulCount < ulPoolSize; ulCount++)
  870. {
  871. pNewIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
  872. if (pNewIrp)
  873. {
  874. pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();
  875. //
  876. // store this irp in the list of allocated irps
  877. //
  878. pIrpPool->pAllocatedIrp[ulCount] = pNewIrp;
  879. //
  880. // and add it to the beginning of the list of available irps
  881. //
  882. pNewIrp->AssociatedIrp.MasterIrp = pIrpPool->pAvailIrpList;
  883. pIrpPool->pAvailIrpList = pNewIrp;
  884. }
  885. }
  886. }
  887. return pIrpPool;
  888. }
  889. // ----------------------------------------------------
  890. //
  891. // Function: TSFreeIrpPool
  892. //
  893. // Arguments: ptr to irp pool to free
  894. //
  895. // Returns: none
  896. //
  897. // Descript: Frees the IRP pool allocated above
  898. //
  899. // ----------------------------------------------------
  900. VOID
  901. TSFreeIrpPool(PIRP_POOL pIrpPool)
  902. {
  903. if (pIrpPool)
  904. {
  905. //
  906. // free each irp in the Avail list
  907. // clearing it from the allocated list
  908. //
  909. PIRP pThisIrp;
  910. PIRP pIrpList;
  911. for(;;)
  912. {
  913. //
  914. // protect irppool structure while get AvailList or UsedList
  915. //
  916. TSAcquireSpinLock(&pIrpPool->TdiSpinLock);
  917. pIrpList = pIrpPool->pAvailIrpList;
  918. if (pIrpList)
  919. {
  920. pIrpPool->pAvailIrpList = NULL;
  921. }
  922. else
  923. {
  924. //
  925. // nothing on avail list, try used list
  926. //
  927. pIrpList = pIrpPool->pUsedIrpList;
  928. if (pIrpList)
  929. {
  930. pIrpPool->pUsedIrpList = NULL;
  931. }
  932. else
  933. {
  934. //
  935. // nothing on either list
  936. // go thru the pAllocatedIrp list just to be sure all are freed
  937. //
  938. for (ULONG ulCount = 0; ulCount < pIrpPool->ulPoolSize; ulCount++)
  939. {
  940. if (pIrpPool->pAllocatedIrp[ulCount])
  941. {
  942. pIrpPool->fMustFree = TRUE;
  943. TSReleaseSpinLock(&pIrpPool->TdiSpinLock);
  944. DebugPrint1("Irp at %p not freed!\n",
  945. pIrpPool->pAllocatedIrp[ulCount]);
  946. //
  947. // return here if a late irp needs to finish up cleanup
  948. //
  949. return;
  950. }
  951. }
  952. TSReleaseSpinLock(&pIrpPool->TdiSpinLock);
  953. //
  954. // finished cleanup here -- all irps accounted for
  955. //
  956. TSFreeSpinLock(&pIrpPool->TdiSpinLock);
  957. TSFreeMemory(pIrpPool);
  958. return;
  959. }
  960. }
  961. TSReleaseSpinLock(&pIrpPool->TdiSpinLock);
  962. while (pIrpList)
  963. {
  964. pThisIrp = pIrpList;
  965. pIrpList = pIrpList->AssociatedIrp.MasterIrp;
  966. pThisIrp->AssociatedIrp.MasterIrp = NULL;
  967. for (ULONG ulCount = 0; ulCount < pIrpPool->ulPoolSize; ulCount++)
  968. {
  969. if (pIrpPool->pAllocatedIrp[ulCount] == pThisIrp)
  970. {
  971. pIrpPool->pAllocatedIrp[ulCount] = NULL;
  972. break;
  973. }
  974. }
  975. IoFreeIrp(pThisIrp);
  976. } // end of while(pIrpList)
  977. } // end of for(;;)
  978. }
  979. }
  980. //////////////////////////////////////////////////////////////////////
  981. // end of file utils.cpp
  982. //////////////////////////////////////////////////////////////////////