windows-nt/Source/XPSP1/NT/base/fs/rdr2/rxce/daytona/tdimisc.c

174 lines
3.7 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
rxtdi.c
Abstract:
This module implements the NT TDI related routines used by RXCE. The wrappers are necessary to
ensure that all the OS dependencies can be localized to select modules like this for
customization.
Revision History:
Balan Sethu Raman [SethuR] 15-Feb-1995
--*/
#include "precomp.h"
#pragma hdrstop
ULONG
ComputeTransportAddressLength(
PTRANSPORT_ADDRESS pTransportAddress)
/*++
Routine Description:
computes the length in bytes of a TRANSPORT_ADDRESS structure
Arguments:
pTransportAddress - TRANSPORT_ADDRESS instance
Return Value:
the length of the instance in bytes
Notes:
Since this structure is packed the arithmetic has to be done using unaligned pointers.
--*/
{
ULONG Size = 0;
if (pTransportAddress != NULL) {
LONG Index;
TA_ADDRESS *pTaAddress;
Size = FIELD_OFFSET(TRANSPORT_ADDRESS,Address) +
FIELD_OFFSET(TA_ADDRESS,Address) * pTransportAddress->TAAddressCount;
pTaAddress = (TA_ADDRESS *)pTransportAddress->Address;
for (Index = 0;Index <pTransportAddress->TAAddressCount;Index++) {
Size += pTaAddress->AddressLength;
pTaAddress = (TA_ADDRESS *)((PCHAR)pTaAddress +
FIELD_OFFSET(TA_ADDRESS,Address) +
pTaAddress->AddressLength);
}
}
return Size;
}
PIRP
RxCeAllocateIrpWithMDL(
IN CCHAR StackSize,
IN BOOLEAN ChargeQuota,
IN PMDL Buffer)
/*++
Routine Description:
computes the length in bytes of a TRANSPORT_ADDRESS structure
Arguments:
pTransportAddress - TRANSPORT_ADDRESS instance
Return Value:
the length of the instance in bytes
Notes:
Currently the RxCeAllocateIrp and RxCeFreeIrp are implemented as wrappers around the
IO calls. One possible optimization to consider would be to maintain a pool of IRP's
which can be reused.
--*/
{
PIRP pIrp = NULL;
PRX_IRP_LIST_ITEM pListItem = NULL;
pIrp = IoAllocateIrp(StackSize,ChargeQuota);
if (pIrp != NULL) {
pListItem = RxAllocatePoolWithTag(
NonPagedPool,
sizeof(RX_IRP_LIST_ITEM),
RX_IRPC_POOLTAG);
if (pListItem == NULL) {
IoFreeIrp(pIrp);
pIrp = NULL;
} else {
KIRQL SavedIrql;
pListItem->pIrp = pIrp;
pListItem->CopyDataBuffer = Buffer;
pListItem->Completed = 0;
InitializeListHead(&pListItem->IrpsList);
KeAcquireSpinLock(&RxIrpsListSpinLock,&SavedIrql);
InsertTailList(&RxIrpsList,&pListItem->IrpsList);
KeReleaseSpinLock(&RxIrpsListSpinLock,SavedIrql);
}
}
return pIrp;
}
VOID
RxCeFreeIrp(PIRP pIrp)
/*++
Routine Description:
frees an IRP
Arguments:
pIrp - IRP to be freed
--*/
{
KIRQL SavedIrql;
PLIST_ENTRY pListEntry;
BOOLEAN IrpFound = FALSE;
PRX_IRP_LIST_ITEM pListItem = NULL;
KeAcquireSpinLock(&RxIrpsListSpinLock,&SavedIrql);
pListEntry = RxIrpsList.Flink;
while (pListEntry != &RxIrpsList) {
pListItem = CONTAINING_RECORD(
pListEntry,
RX_IRP_LIST_ITEM,
IrpsList);
if (pListItem->pIrp == pIrp) {
IrpFound = TRUE;
//ASSERT(pListItem->Completed);
RemoveEntryList(pListEntry);
RxFreePool(pListItem);
break;
} else {
pListEntry = pListEntry->Flink;
}
}
KeReleaseSpinLock(&RxIrpsListSpinLock,SavedIrql);
ASSERT(IrpFound);
IoFreeIrp(pIrp);
}