//////////////////////////////////////////////////////////////////// // // Copyright (c) 2001 Microsoft Corporation // // Module Name: // utils.cpp // // Abstract: // This module contains some utility functions for the tdi sample driver // ///////////////////////////////////////////////////////////////////// #include "sysvars.h" ///////////////////////////////////////////////////// // private constants ///////////////////////////////////////////////////// //const PCHAR strFunc1 = "TSAllocateMemory"; const PCHAR strFunc2 = "TSFreeMemory"; const PCHAR strFunc3 = "TSScanMemoryPool"; //const PCHAR strFunc4 = "TSInsertNode"; const PCHAR strFunc5 = "TSRemoveNode"; const PCHAR strFunc6 = "TSGetObjectFromHandle"; //const PCHAR strFunc6 = "TSAllocateIrp"; //const PCHAR strFunc7 = "TSFreeIrp"; //const PCHAR strFunc8 = "TSPrintTaAddress"; const PCHAR strFunc9 = "TSllocateIrpPool"; const PCHAR strFuncA = "TSFreeIrpPool"; //////////////////////////////////////////////////// // public functions //////////////////////////////////////////////////// // -------------------------------------------------------------------- // // Function: TSAllocateMemory // // Arguments: ppvVirtualAddress -- addr of pointer to set to allocated block // ulLength -- length of memory to allocate // strFunction -- ptr to function name string // strTitle -- ptr to title of this allocation // // Returns: lStatus // // Descript: This function acts as a wrapper for the ExAllocatePoolWithTag // function. It also stores info for each memory block that can // identify them in case of "memory leaks" // // --------------------------------------------------------------------- // // this structure store information about this memory block to allow // us to track memory blocks, and verify that they are freed properly, that // we don't write beyond the end of them, etc // struct PRIVATE_MEMORY { ULONG ulSignature; // ulMEMORY_BLOCK PCHAR strFunction; // name of function doing allocate PCHAR strTitle; // Title for specific allocate ULONG ulLength; // ulong index of trailer (=(length/4)-1 PRIVATE_MEMORY *pLastMemPtr; // ptr to last allocated block PRIVATE_MEMORY *pNextMemPtr; // ptr to next allocated block }; const ULONG ulTRAIL_PATTERN = 0x0f1e2d3c; const ULONG ulMEMORY_BLOCK = 0x4b5a6978; #define TDISAMPLE_TAG 'aSDT' NTSTATUS TSAllocateMemory(PVOID *ppvVirtualAddress, ULONG ulLength, CONST PCHAR strFunction, CONST PCHAR strTitle) { PVOID pvBaseMemory; // base -- where actual memory allocated // // allocate for length plus header plus trailer, rounded up to next dword // ulLength += (sizeof(PRIVATE_MEMORY) + sizeof(ULONG) + 3); ulLength &= 0xfffffffc; // // allocate it // pvBaseMemory = ExAllocatePoolWithTag(NonPagedPool, ulLength, TDISAMPLE_TAG); // // things to do if allocation was successful // if (pvBaseMemory) { // // zero the memory // RtlZeroMemory(pvBaseMemory, ulLength); // // set up our header and trailer info // PRIVATE_MEMORY *pPrivateMemory // our header information = (PRIVATE_MEMORY *)pvBaseMemory; PULONG pulBase = (PULONG)pvBaseMemory; // // adjust the ptr we return to allocated memory // *ppvVirtualAddress = (PUCHAR)pvBaseMemory + sizeof(PRIVATE_MEMORY); // // set up our header information // ulLength /= sizeof(ULONG); // set ulLength to ulong index of trailer --ulLength; pPrivateMemory->ulSignature = ulMEMORY_BLOCK; pPrivateMemory->strFunction = strFunction; pPrivateMemory->strTitle = strTitle; pPrivateMemory->ulLength = ulLength; // // set up the trailer information // pulBase[ulLength] = ulTRAIL_PATTERN; // // insert at head of linked list.. // (note that memory is already initialized to null) // TSAcquireSpinLock(&MemTdiSpinLock); if (pvMemoryList) { ((PRIVATE_MEMORY *)pvMemoryList)->pLastMemPtr = pPrivateMemory; pPrivateMemory->pNextMemPtr = (PRIVATE_MEMORY *)pvMemoryList; } pvMemoryList = pPrivateMemory; TSReleaseSpinLock(&MemTdiSpinLock); return STATUS_SUCCESS; } else { DebugPrint3("%s: unable to allocate %u bytes for %s\n", strFunction, ulLength, strTitle); *ppvVirtualAddress = NULL; return STATUS_INSUFFICIENT_RESOURCES; } } // ------------------------------------------------------------------- // // Function: TSFreeMemory // // Arguments: pvVirtualAddress -- address of memory block to free // // Returns: None // // Descript: This function is a wrapper around the ExFreePool // function. it helps track memory // to make sure that we cleanup up everything... // // -------------------------------------------------------------------- VOID TSFreeMemory(PVOID pvVirtualAddress) { if (pvVirtualAddress == NULL) { DebugPrint1("%s: memory block already freed!\n", strFunc2); DbgBreakPoint(); return; } // // back up to start of header information // pvVirtualAddress = (PVOID)((PUCHAR)pvVirtualAddress - sizeof(PRIVATE_MEMORY)); PRIVATE_MEMORY *pPrivateMemory // ptr to our header block = (PRIVATE_MEMORY *)pvVirtualAddress; PULONG pulTemp // temp ptr into allocated block = (PULONG)pvVirtualAddress; ULONG ulLength = pPrivateMemory->ulLength; // // is this a valid memory block? // if (pPrivateMemory->ulSignature != ulMEMORY_BLOCK) { DebugPrint2("%s: invalid memory block at %p!\n", strFunc2, pPrivateMemory); DbgBreakPoint(); return; } // // check that the trailer is still ok // if (pulTemp[ulLength] != ulTRAIL_PATTERN) { DebugPrint2("%s: trailer overwritten for block staring at %p\n", strFunc2, pPrivateMemory); DbgBreakPoint(); return; } // // remove it from the linked list.. // TSAcquireSpinLock(&MemTdiSpinLock); // // is it first block in list? // if (pPrivateMemory->pLastMemPtr == (PRIVATE_MEMORY *)NULL) { pvMemoryList = pPrivateMemory->pNextMemPtr; } else { PRIVATE_MEMORY *pLastPrivateMemory = pPrivateMemory->pLastMemPtr; pLastPrivateMemory->pNextMemPtr = pPrivateMemory->pNextMemPtr; } // // fix ptr of next memory block if necessary // if (pPrivateMemory->pNextMemPtr != (PVOID)NULL) { PRIVATE_MEMORY *pNextPrivateMemory = pPrivateMemory->pNextMemPtr; pNextPrivateMemory->pLastMemPtr = pPrivateMemory->pLastMemPtr; } TSReleaseSpinLock(&MemTdiSpinLock); // // zero memory and free--make sure we adjust ulLength to be the true length // RtlZeroMemory(pvVirtualAddress, sizeof(ULONG) * (ulLength + 1)); ExFreePool(pvVirtualAddress); } // ------------------------------------------------------------------- // // Function: TSScanMemoryPool // // Arguments: none // // Returns: none // // Descript: Scans to see if any tdi sample owned memory blocks have // not been freed // // ------------------------------------------------------------------- VOID TSScanMemoryPool(VOID) { TSAcquireSpinLock(&MemTdiSpinLock); if (pvMemoryList) { PRIVATE_MEMORY *pPrivateMemory // our header information = (PRIVATE_MEMORY *)pvMemoryList; PULONG pulTemp; DebugPrint0("The following memory blocks have not been freed!\n"); while (pPrivateMemory) { // // is this a valid memory block? // if (pPrivateMemory->ulSignature != ulMEMORY_BLOCK) { DebugPrint1("Memory block at %p has an invalid signature!\n", pPrivateMemory); DbgBreakPoint(); } DebugPrint2("Memory block at %p: total length = %d bytes\n", pPrivateMemory, sizeof(ULONG) * (pPrivateMemory->ulLength + 1)); DebugPrint2("Block '%s' was allocated by function %s\n", pPrivateMemory->strTitle, pPrivateMemory->strFunction); pulTemp = (PULONG)pPrivateMemory; // // check that the trailer is still ok // if (pulTemp[pPrivateMemory->ulLength] != ulTRAIL_PATTERN) { DebugPrint0("The trailer for this memory block has been overwritten\n"); DbgBreakPoint(); } DebugPrint0("\n"); pPrivateMemory = pPrivateMemory->pNextMemPtr; } DebugPrint0("\n\n\n"); } else { DebugPrint0("All Tdi Sample memory blocks freed properly!\n"); } TSReleaseSpinLock(&MemTdiSpinLock); } // -------------------------------------------- // // Function: TSInsertNode // // Arguments: pNewNode -- node to insert into list // // Returns: Handle where we put things // // Descript: insert the object at the first empty slot in the // table. Return Handle for it (NULL if error) // // -------------------------------------------- ULONG TSInsertNode(PGENERIC_HEADER pNewNode) { ULONG ulTdiHandle = 0; for (ULONG ulCount = 0; ulCount < ulMAX_OBJ_HANDLES; ulCount++) { if (pObjectList->GenHead[ulCount] == NULL) { pObjectList->GenHead[ulCount] = pNewNode; ulTdiHandle = (ulCount + pNewNode->ulSignature); break; } } return ulTdiHandle; } // --------------------------------------------- // // Function: TSRemoveNode // // Arguments: pOldNode -- node to remove from it's linked list.. // // Returns: none // // Descript: remove from appropriate linked list // // --------------------------------------------- VOID TSRemoveNode(ULONG ulTdiHandle) { ULONG ulType; ULONG ulSlot; PGENERIC_HEADER pGenericHeader; ulType = ulTdiHandle & usOBJ_TYPE_MASK; if ((ulType == ulControlChannelObject) || (ulType == ulAddressObject) || (ulType == ulEndpointObject)) { ulSlot = ulTdiHandle & usOBJ_HANDLE_MASK; pGenericHeader = pObjectList->GenHead[ulSlot]; if (pGenericHeader) { if (pGenericHeader->ulSignature == ulType) { pObjectList->GenHead[ulSlot] = NULL; return; } // // from here down, error cases // else { DebugPrint1("%s: wrong type for node!\n", strFunc5); } } else { DebugPrint1("%s: node is null!\n", strFunc5); } } else { DebugPrint1("%s: Bad handle type value\n", strFunc5); } } // --------------------------------------------- // // Function: TSGetObjectFromHandle // // Arguments: TdiHandle -- the handle passed in to us // ulType -- the type the handle needs to have // // Returns: pGenericHeader of object (NULL if error) // // Descript: fetch object from list via handle // // --------------------------------------------- PGENERIC_HEADER TSGetObjectFromHandle(ULONG ulTdiHandle, ULONG ulType) { ULONG ulHandleType = ulTdiHandle & usOBJ_TYPE_MASK; if ((ulHandleType & ulType) == ulHandleType) { ULONG ulHandleSlot = ulTdiHandle & usOBJ_HANDLE_MASK; PGENERIC_HEADER pGenericHeader = pObjectList->GenHead[ulHandleSlot]; if (pGenericHeader) { if (pGenericHeader->ulSignature == ulHandleType) { return pGenericHeader; } // // from here down, error conditions // else { DebugPrint1("%s: wrong type for node!\n", strFunc6); } } else { DebugPrint1("%s: node is null!\n", strFunc6); } } else { DebugPrint1("%s: Bad handle type value\n", strFunc6); } // DbgBreakPoint(); return NULL; } // ---------------------------------------------------- // // Function: TSAllocateIrp // // Arguments: pDeviceObject -- device object to call with this irp // pIrpPool -- irp pool to allocate from (may be NULL) // // Returns: IRP that was allocated (NULL if error) // // Descript: allocates a single IRP for use in calling the // lower level driver (TdiProvider) // // NOTE: much of this code taken from ntos\io\iosubs.c\IoBuildDeviceIoRequest // see TSAllocateIrpPool for how we cheat // // ---------------------------------------------------- PIRP TSAllocateIrp(PDEVICE_OBJECT pDeviceObject, PIRP_POOL pIrpPool) { PIRP pNewIrp = NULL; if (pIrpPool) { pNewIrp = pIrpPool->pAvailIrpList; if (!pNewIrp) { TSAcquireSpinLock(&pIrpPool->TdiSpinLock); pIrpPool->pAvailIrpList = pIrpPool->pUsedIrpList; pIrpPool->pUsedIrpList = NULL; TSReleaseSpinLock(&pIrpPool->TdiSpinLock); pNewIrp = pIrpPool->pAvailIrpList; } if (pNewIrp) { pIrpPool->pAvailIrpList = pNewIrp->AssociatedIrp.MasterIrp; pNewIrp->AssociatedIrp.MasterIrp = NULL; } } else { pNewIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE); pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread();; } if (pNewIrp) { PIO_STACK_LOCATION pIrpSp = IoGetNextIrpStackLocation(pNewIrp); pIrpSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; pIrpSp->Parameters.DeviceIoControl.OutputBufferLength = 0; pIrpSp->Parameters.DeviceIoControl.InputBufferLength = 0; pIrpSp->Parameters.DeviceIoControl.IoControlCode = 0x00000003; pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer = NULL; pNewIrp->UserBuffer = NULL; pNewIrp->UserIosb = NULL; pNewIrp->UserEvent = NULL; pNewIrp->RequestorMode = KernelMode; } return pNewIrp; } // ---------------------------------------------------- // // Function: TSFreeIrp // // Arguments: IRP to free // pIrpPool -- pool to free to (may be NULL) // // Returns: none // // Descript: Frees the IRP passed in // See TSAllocateIrpPool for how we cheat.. // // ---------------------------------------------------- VOID TSFreeIrp(PIRP pIrp, PIRP_POOL pIrpPool) { if (pIrpPool) { TSAcquireSpinLock(&pIrpPool->TdiSpinLock); pIrp->AssociatedIrp.MasterIrp = pIrpPool->pUsedIrpList; pIrpPool->pUsedIrpList = pIrp; TSReleaseSpinLock(&pIrpPool->TdiSpinLock); if (pIrpPool->fMustFree) { TSFreeIrpPool(pIrpPool); } } else { IoFreeIrp(pIrp); } } // --------------------------------- // // Function: TSPrintTaAddress // // Arguments: pTaAddress -- address to print out info for // // Returns: none // // Descript: prints out information in pTaAddress structure // // --------------------------------- VOID TSPrintTaAddress(PTA_ADDRESS pTaAddress) { BOOLEAN fShowAddress = TRUE; DebugPrint0("AddressType = TDI_ADDRESS_TYPE_"); switch (pTaAddress->AddressType) { case TDI_ADDRESS_TYPE_UNSPEC: DebugPrint0("UNSPEC\n"); break; case TDI_ADDRESS_TYPE_UNIX: DebugPrint0("UNIX\n"); break; case TDI_ADDRESS_TYPE_IP: DebugPrint0("IP\n"); fShowAddress = FALSE; { PTDI_ADDRESS_IP pTdiAddressIp = (PTDI_ADDRESS_IP)pTaAddress->Address; PUCHAR pucTemp = (PUCHAR)&pTdiAddressIp->in_addr; DebugPrint5("sin_port = 0x%04x\n" "in_addr = %u.%u.%u.%u\n", pTdiAddressIp->sin_port, pucTemp[0], pucTemp[1], pucTemp[2], pucTemp[3]); } break; case TDI_ADDRESS_TYPE_IMPLINK: DebugPrint0("IMPLINK\n"); break; case TDI_ADDRESS_TYPE_PUP: DebugPrint0("PUP\n"); break; case TDI_ADDRESS_TYPE_CHAOS: DebugPrint0("CHAOS\n"); break; case TDI_ADDRESS_TYPE_IPX: DebugPrint0("IPX\n"); fShowAddress = FALSE; { PTDI_ADDRESS_IPX pTdiAddressIpx = (PTDI_ADDRESS_IPX)pTaAddress->Address; DebugPrint8("NetworkAddress = 0x%08x\n" "NodeAddress = %u.%u.%u.%u.%u.%u\n" "Socket = 0x%04x\n", pTdiAddressIpx->NetworkAddress, pTdiAddressIpx->NodeAddress[0], pTdiAddressIpx->NodeAddress[1], pTdiAddressIpx->NodeAddress[2], pTdiAddressIpx->NodeAddress[3], pTdiAddressIpx->NodeAddress[4], pTdiAddressIpx->NodeAddress[5], pTdiAddressIpx->Socket); } break; case TDI_ADDRESS_TYPE_NBS: DebugPrint0("NBS\n"); break; case TDI_ADDRESS_TYPE_ECMA: DebugPrint0("ECMA\n"); break; case TDI_ADDRESS_TYPE_DATAKIT: DebugPrint0("DATAKIT\n"); break; case TDI_ADDRESS_TYPE_CCITT: DebugPrint0("CCITT\n"); break; case TDI_ADDRESS_TYPE_SNA: DebugPrint0("SNA\n"); break; case TDI_ADDRESS_TYPE_DECnet: DebugPrint0("DECnet\n"); break; case TDI_ADDRESS_TYPE_DLI: DebugPrint0("DLI\n"); break; case TDI_ADDRESS_TYPE_LAT: DebugPrint0("LAT\n"); break; case TDI_ADDRESS_TYPE_HYLINK: DebugPrint0("HYLINK\n"); break; case TDI_ADDRESS_TYPE_APPLETALK: DebugPrint0("APPLETALK\n"); fShowAddress = FALSE; { PTDI_ADDRESS_APPLETALK pTdiAddressAppleTalk = (PTDI_ADDRESS_APPLETALK)pTaAddress->Address; DebugPrint3("Network = 0x%04x\n" "Node = 0x%02x\n" "Socket = 0x%02x\n", pTdiAddressAppleTalk->Network, pTdiAddressAppleTalk->Node, pTdiAddressAppleTalk->Socket); } break; case TDI_ADDRESS_TYPE_NETBIOS: DebugPrint0("NETBIOS\n"); fShowAddress = FALSE; { PTDI_ADDRESS_NETBIOS pTdiAddressNetbios = (PTDI_ADDRESS_NETBIOS)pTaAddress->Address; UCHAR pucName[17]; // // make sure we have a zero-terminated name to print... // RtlCopyMemory(pucName, pTdiAddressNetbios->NetbiosName, 16); pucName[16] = 0; DebugPrint0("NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_"); switch (pTdiAddressNetbios->NetbiosNameType) { case TDI_ADDRESS_NETBIOS_TYPE_UNIQUE: DebugPrint0("UNIQUE\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_GROUP: DebugPrint0("GROUP\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE: DebugPrint0("QUICK_UNIQUE\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_QUICK_GROUP: DebugPrint0("QUICK_GROUP\n"); break; default: DebugPrint1("INVALID [0x%04x]\n", pTdiAddressNetbios->NetbiosNameType); break; } DebugPrint1("NetbiosName = %s\n", pucName); } break; case TDI_ADDRESS_TYPE_8022: DebugPrint0("8022\n"); fShowAddress = FALSE; { PTDI_ADDRESS_8022 pTdiAddress8022 = (PTDI_ADDRESS_8022)pTaAddress->Address; DebugPrint6("Address = %02x-%02x-%02x-%02x-%02x-%02x\n", pTdiAddress8022->MACAddress[0], pTdiAddress8022->MACAddress[1], pTdiAddress8022->MACAddress[2], pTdiAddress8022->MACAddress[3], pTdiAddress8022->MACAddress[4], pTdiAddress8022->MACAddress[5]); } break; case TDI_ADDRESS_TYPE_OSI_TSAP: DebugPrint0("OSI_TSAP\n"); fShowAddress = FALSE; { PTDI_ADDRESS_OSI_TSAP pTdiAddressOsiTsap = (PTDI_ADDRESS_OSI_TSAP)pTaAddress->Address; ULONG ulSelectorLength; ULONG ulAddressLength; PUCHAR pucTemp = pTdiAddressOsiTsap->tp_addr; DebugPrint0("TpAddrType = ISO_"); switch (pTdiAddressOsiTsap->tp_addr_type) { case ISO_HIERARCHICAL: DebugPrint0("HIERARCHICAL\n"); ulSelectorLength = pTdiAddressOsiTsap->tp_tsel_len; ulAddressLength = pTdiAddressOsiTsap->tp_taddr_len; break; case ISO_NON_HIERARCHICAL: DebugPrint0("NON_HIERARCHICAL\n"); ulSelectorLength = 0; ulAddressLength = pTdiAddressOsiTsap->tp_taddr_len; break; default: DebugPrint1("INVALID [0x%04x]\n", pTdiAddressOsiTsap->tp_addr_type); ulSelectorLength = 0; ulAddressLength = 0; break; } if (ulSelectorLength) { ULONG ulCount; DebugPrint0("TransportSelector: "); for (ulCount = 0; ulCount < ulSelectorLength; ulCount++) { DebugPrint1("%02x ", *pucTemp); ++pucTemp; } DebugPrint0("\n"); } if (ulAddressLength) { ULONG ulCount; DebugPrint0("TransportAddress: "); for (ulCount = 0; ulCount < ulAddressLength; ulCount++) { DebugPrint1("%02x ", *pucTemp); ++pucTemp; } DebugPrint0("\n"); } } break; case TDI_ADDRESS_TYPE_NETONE: DebugPrint0("NETONE\n"); fShowAddress = FALSE; { PTDI_ADDRESS_NETONE pTdiAddressNetone = (PTDI_ADDRESS_NETONE)pTaAddress->Address; UCHAR pucName[21]; // // make sure have 0-terminated name // RtlCopyMemory(pucName, pTdiAddressNetone->NetoneName, 20); pucName[20] = 0; DebugPrint0("NetoneNameType = TDI_ADDRESS_NETONE_TYPE_"); switch (pTdiAddressNetone->NetoneNameType) { case TDI_ADDRESS_NETONE_TYPE_UNIQUE: DebugPrint0("UNIQUE\n"); break; case TDI_ADDRESS_NETONE_TYPE_ROTORED: DebugPrint0("ROTORED\n"); break; default: DebugPrint1("INVALID [0x%04x]\n", pTdiAddressNetone->NetoneNameType); break; } DebugPrint1("NetoneName = %s\n", pucName); } break; case TDI_ADDRESS_TYPE_VNS: DebugPrint0("VNS\n"); fShowAddress = FALSE; { PTDI_ADDRESS_VNS pTdiAddressVns = (PTDI_ADDRESS_VNS)pTaAddress->Address; DebugPrint4("NetAddress: %02x-%02x-%02x-%02x\n", pTdiAddressVns->net_address[0], pTdiAddressVns->net_address[1], pTdiAddressVns->net_address[2], pTdiAddressVns->net_address[3]); DebugPrint5("SubnetAddr: %02x-%02x\n" "Port: %02x-%02x\n" "Hops: %u\n", pTdiAddressVns->subnet_addr[0], pTdiAddressVns->subnet_addr[1], pTdiAddressVns->port[0], pTdiAddressVns->port[1], pTdiAddressVns->hops); } break; case TDI_ADDRESS_TYPE_NETBIOS_EX: DebugPrint0("NETBIOS_EX\n"); fShowAddress = FALSE; { PTDI_ADDRESS_NETBIOS_EX pTdiAddressNetbiosEx = (PTDI_ADDRESS_NETBIOS_EX)pTaAddress->Address; UCHAR pucEndpointName[17]; UCHAR pucNetbiosName[17]; // // make sure we have zero-terminated names to print... // RtlCopyMemory(pucEndpointName, pTdiAddressNetbiosEx->EndpointName, 16); pucEndpointName[16] = 0; RtlCopyMemory(pucNetbiosName, pTdiAddressNetbiosEx->NetbiosAddress.NetbiosName, 16); pucNetbiosName[16] = 0; DebugPrint1("EndpointName = %s\n" "NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_", pucEndpointName); switch (pTdiAddressNetbiosEx->NetbiosAddress.NetbiosNameType) { case TDI_ADDRESS_NETBIOS_TYPE_UNIQUE: DebugPrint0("UNIQUE\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_GROUP: DebugPrint0("GROUP\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_QUICK_UNIQUE: DebugPrint0("QUICK_UNIQUE\n"); break; case TDI_ADDRESS_NETBIOS_TYPE_QUICK_GROUP: DebugPrint0("QUICK_GROUP\n"); break; default: DebugPrint1("INVALID [0x%04x]\n", pTdiAddressNetbiosEx->NetbiosAddress.NetbiosNameType); break; } DebugPrint1("NetbiosName = %s\n", pucNetbiosName); } break; case TDI_ADDRESS_TYPE_IP6: DebugPrint0("IPv6\n"); fShowAddress = FALSE; { PTDI_ADDRESS_IP6 pTdiAddressIp6 = (PTDI_ADDRESS_IP6)pTaAddress->Address; PUCHAR pucTemp = (PUCHAR)&pTdiAddressIp6->sin6_addr; DebugPrint3("SinPort6 = 0x%04x\n" "FlowInfo = 0x%08x\n" "ScopeId = 0x%08x\n", pTdiAddressIp6->sin6_port, pTdiAddressIp6->sin6_flowinfo, pTdiAddressIp6->sin6_scope_id); DebugPrint8("In6_addr = %x%02x:%x%02x:%x%02x:%x%02x:", pucTemp[0], pucTemp[1], pucTemp[2], pucTemp[3], pucTemp[4], pucTemp[5], pucTemp[6], pucTemp[7]); DebugPrint8("%x%02x:%x%02x:%x%02x:%x%02x\n", pucTemp[8], pucTemp[9], pucTemp[10], pucTemp[11], pucTemp[12], pucTemp[13], pucTemp[14], pucTemp[15]); } break; default: DebugPrint1("UNKNOWN [0x%08x]\n", pTaAddress->AddressType); break; } if (fShowAddress) { PUCHAR pucTemp = pTaAddress->Address; DebugPrint1("AddressLength = %d\n" "Address = ", pTaAddress->AddressLength); for (ULONG ulCount = 0; ulCount < pTaAddress->AddressLength; ulCount++) { DebugPrint1("%02x ", *pucTemp); pucTemp++; } DebugPrint0("\n"); } } // ---------------------------------------------------- // // Function: TSAllocateIrpPool // // Arguments: device object // // Returns: ptr to irp pool // // Descript: allocates an IRP pool when the driver starts, so // we don't have to worry about being in an inappropriate // IRQL when we need one... // // NOTE: we cheat a little in maintaining our list of available Irps // We use the AssociatedIrp.MasterIrp field to point to the // next IRP in our list. Because of this, we need to explicitly // set this field to NULL whenever we remove one of the IRPs from our // list.. // // ---------------------------------------------------- PIRP_POOL TSAllocateIrpPool(PDEVICE_OBJECT pDeviceObject, ULONG ulPoolSize) { PIRP_POOL pIrpPool = NULL; if ((TSAllocateMemory((PVOID *)&pIrpPool, sizeof(IRP_POOL) + (ulPoolSize * sizeof(PVOID)), strFunc9, "IrpPool")) == STATUS_SUCCESS) { PIRP pNewIrp; TSAllocateSpinLock(&pIrpPool->TdiSpinLock); pIrpPool->ulPoolSize = ulPoolSize; pIrpPool->fMustFree = FALSE; for (ULONG ulCount = 0; ulCount < ulPoolSize; ulCount++) { pNewIrp = IoAllocateIrp(pDeviceObject->StackSize, FALSE); if (pNewIrp) { pNewIrp->Tail.Overlay.Thread = PsGetCurrentThread(); // // store this irp in the list of allocated irps // pIrpPool->pAllocatedIrp[ulCount] = pNewIrp; // // and add it to the beginning of the list of available irps // pNewIrp->AssociatedIrp.MasterIrp = pIrpPool->pAvailIrpList; pIrpPool->pAvailIrpList = pNewIrp; } } } return pIrpPool; } // ---------------------------------------------------- // // Function: TSFreeIrpPool // // Arguments: ptr to irp pool to free // // Returns: none // // Descript: Frees the IRP pool allocated above // // ---------------------------------------------------- VOID TSFreeIrpPool(PIRP_POOL pIrpPool) { if (pIrpPool) { // // free each irp in the Avail list // clearing it from the allocated list // PIRP pThisIrp; PIRP pIrpList; for(;;) { // // protect irppool structure while get AvailList or UsedList // TSAcquireSpinLock(&pIrpPool->TdiSpinLock); pIrpList = pIrpPool->pAvailIrpList; if (pIrpList) { pIrpPool->pAvailIrpList = NULL; } else { // // nothing on avail list, try used list // pIrpList = pIrpPool->pUsedIrpList; if (pIrpList) { pIrpPool->pUsedIrpList = NULL; } else { // // nothing on either list // go thru the pAllocatedIrp list just to be sure all are freed // for (ULONG ulCount = 0; ulCount < pIrpPool->ulPoolSize; ulCount++) { if (pIrpPool->pAllocatedIrp[ulCount]) { pIrpPool->fMustFree = TRUE; TSReleaseSpinLock(&pIrpPool->TdiSpinLock); DebugPrint1("Irp at %p not freed!\n", pIrpPool->pAllocatedIrp[ulCount]); // // return here if a late irp needs to finish up cleanup // return; } } TSReleaseSpinLock(&pIrpPool->TdiSpinLock); // // finished cleanup here -- all irps accounted for // TSFreeSpinLock(&pIrpPool->TdiSpinLock); TSFreeMemory(pIrpPool); return; } } TSReleaseSpinLock(&pIrpPool->TdiSpinLock); while (pIrpList) { pThisIrp = pIrpList; pIrpList = pIrpList->AssociatedIrp.MasterIrp; pThisIrp->AssociatedIrp.MasterIrp = NULL; for (ULONG ulCount = 0; ulCount < pIrpPool->ulPoolSize; ulCount++) { if (pIrpPool->pAllocatedIrp[ulCount] == pThisIrp) { pIrpPool->pAllocatedIrp[ulCount] = NULL; break; } } IoFreeIrp(pThisIrp); } // end of while(pIrpList) } // end of for(;;) } } ////////////////////////////////////////////////////////////////////// // end of file utils.cpp //////////////////////////////////////////////////////////////////////