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

////////////////////////////////////////////////////////////////////
//
// 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
//////////////////////////////////////////////////////////////////////