📄 ioctl.c
字号:
Return Value:
Status - doesn't pend
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulInputBufLen;
PATMSM_ADAPTER pAdapt;
TraceIn(AtmSmIoctlCloseRecvHandle);
ulInputBufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
if(ulInputBufLen < sizeof(HANDLE))
{
DbgErr(("Input length is invalid\n"));
TraceOut(AtmSmIoctlCloseRecvHandle);
return STATUS_INVALID_PARAMETER;
}
pAdapt = (PATMSM_ADAPTER)(*(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer));
DbgLoud(("Recv Context is 0x%x\n", pAdapt));
// Note - VerifyRecvOpenContext adds a reference to the adapter
// if successful, which we remove when we are done
if(STATUS_SUCCESS != (Status = VerifyRecvOpenContext(pAdapt)))
{
DbgInfo(("Couldn't put a reference on the adapter - pAdapt - 0x%x\n",
pAdapt));
TraceOut(AtmSmIoctlCloseRecvHandle);
return Status;
}
// we have a valid RecvContext
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
if(pAdapt->pRecvIrp)
{
PIRP pRecvIrp = pAdapt->pRecvIrp;
pAdapt->pRecvIrp = NULL;
// there is an Irp pending, complete it
pRecvIrp->IoStatus.Status = STATUS_CANCELLED;
pRecvIrp->Cancel = TRUE;
pRecvIrp->IoStatus.Information = 0;
IoCompleteRequest(pRecvIrp, IO_NETWORK_INCREMENT);
}
pAdapt->fAdapterOpenedForRecv = FALSE;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
// remove the reference added while verifying
AtmSmDereferenceAdapter(pAdapt);
pIrp->IoStatus.Information = 0;
TraceOut(AtmSmIoctlCloseRecvHandle);
return Status;
}
NTSTATUS AtmSmIoctlConnectToDsts(
PIRP pIrp,
PIO_STACK_LOCATION pIrpSp
)
/*++
Routine Description:
This routine is used to initiate a connection to 1 (P-P) or more (PMP)
destinations.
NOTE! This uses buffered I/O
Arguments:
Return Value:
Status - Pending or error
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
PCONNECT_INFO pConnectInfo = (PCONNECT_INFO)
pIrp->AssociatedIrp.SystemBuffer;
ULONG ul, ulInputBufLen, ulOutputBufLen, ulCompareLength;
PATMSM_ADAPTER pAdapt;
PATMSM_VC pVc;
#if DBG
ATM_ADDRESS AtmAddr;
#endif
TraceIn(AtmSmIoctlConnectToDsts);
ulInputBufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
ulOutputBufLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if(ulInputBufLen < sizeof(CONNECT_INFO))
{
DbgErr(("Input length < sizeof(CONNECT_INFO)\n"));
TraceOut(AtmSmIoctlConnectToDsts);
return STATUS_INVALID_PARAMETER;
}
if(pConnectInfo->ulNumDsts == 0)
{
DbgErr(("Number of destinations is zero\n"));
TraceOut(AtmSmIoctlConnectToDsts);
return STATUS_INVALID_PARAMETER;
}
if((ulInputBufLen - (sizeof(CONNECT_INFO))/(sizeof(UCHAR)*ATM_ADDRESS_LENGTH))
< pConnectInfo->ulNumDsts -1)
{
DbgErr(("Input length is invalid\n"));
TraceOut(AtmSmIoctlConnectToDsts);
return STATUS_INVALID_PARAMETER;
}
if(ulOutputBufLen < sizeof(HANDLE))
{
DbgErr(("Output length is not sufficient\n"));
TraceOut(AtmSmIoctlConnectToDsts);
return STATUS_BUFFER_TOO_SMALL;
}
#if DBG
AtmAddr.AddressType = ATM_NSAP;
AtmAddr.NumberOfDigits = ATM_ADDRESS_LENGTH;
RtlCopyMemory(AtmAddr.Address, pConnectInfo->ucLocalATMAddr,
(sizeof(UCHAR) * ATM_ADDRESS_LENGTH));
DumpATMAddress(ATMSMD_INFO, "Connect to Dsts - Local AtmAddress - ",
&AtmAddr);
DbgInfo(("No of destinations - %u\n", pConnectInfo->ulNumDsts));
for(ul = 0; ul < pConnectInfo->ulNumDsts; ul++)
{
RtlCopyMemory(AtmAddr.Address, pConnectInfo->ucDstATMAddrs[ul],
(sizeof(UCHAR) * ATM_ADDRESS_LENGTH));
DumpATMAddress(ATMSMD_INFO, " Destination AtmAddress - ", &AtmAddr);
}
#endif
do
{ // break off loop
//
// grab the global lock and find out which adapter is being refered to.
//
ACQUIRE_GLOBAL_LOCK();
// we don't compare the selector byte
ulCompareLength = sizeof(UCHAR) * (ATM_ADDRESS_LENGTH - 1);
for(pAdapt = AtmSmGlobal.pAdapterList; pAdapt;
pAdapt = pAdapt->pAdapterNext)
{
if(ulCompareLength == RtlCompareMemory(
pConnectInfo->ucLocalATMAddr,
pAdapt->ConfiguredAddress.Address,
ulCompareLength))
break;
}
RELEASE_GLOBAL_LOCK();
if(NULL == pAdapt)
{
DbgErr(("Specified adapter address not found.\n"));
Status = STATUS_OBJECT_NAME_INVALID;
break;
}
// no need to add reference here since the allocation of VC
// will add the VC
// create a VC structure and based on whether it is PMP or not
// we add the party members to the VC and ask it to connect
Status = AtmSmAllocVc(pAdapt,
&pVc,
(pConnectInfo->bPMP?
VC_TYPE_PMP_OUTGOING :
VC_TYPE_PP_OUTGOING),
NULL);
if(NDIS_STATUS_SUCCESS != Status)
{
DbgErr(("Failed to create ougoing VC. Status - 0x%X.\n", Status));
Status = STATUS_NO_MEMORY;
break;
}
ACQUIRE_ADAPTER_GEN_LOCK(pAdapt);
if(!pConnectInfo->bPMP)
{
// this is P-P
// copy the destination address
PATM_ADDRESS pAtmAddr = &pVc->HwAddr.Address;
pAtmAddr->AddressType = ATM_NSAP;
pAtmAddr->NumberOfDigits = ATM_ADDRESS_LENGTH;
RtlCopyMemory(pAtmAddr->Address, pConnectInfo->ucDstATMAddrs[0],
(sizeof(UCHAR) * ATM_ADDRESS_LENGTH));
// Note: we don't get the correct selector byte from user mode
// we assume the selector byte used by the destination is
// the same.
pAtmAddr->Address[ATM_ADDRESS_LENGTH-1] = pAdapt->SelByte;
}
else
{
for(ul = 0; ul < pConnectInfo->ulNumDsts; ul++)
{
PATMSM_PMP_MEMBER pMember;
PATM_ADDRESS pAtmAddr;
AtmSmAllocMem(&pMember, PATMSM_PMP_MEMBER,
sizeof(ATMSM_PMP_MEMBER));
if(NULL == pMember)
{
DbgErr(("Failed to allocate member. No resources\n"));
// cleanup the members and VC
while(NULL != (pMember = pVc->pPMPMembers))
{
AtmSmFreeMem(pMember);
pVc->ulRefCount--;
}
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
AtmSmDereferenceVc(pVc);
Status = STATUS_NO_MEMORY;
break;
}
NdisZeroMemory(pMember, sizeof(ATMSM_PMP_MEMBER));
pMember->ulSignature = atmsm_member_signature;
pMember->pVc = pVc;
ATMSM_SET_MEMBER_STATE(pMember, ATMSM_MEMBER_IDLE);
pAtmAddr = &pMember->HwAddr.Address;
pAtmAddr->AddressType = ATM_NSAP;
pAtmAddr->NumberOfDigits = ATM_ADDRESS_LENGTH;
RtlCopyMemory(pAtmAddr->Address,
pConnectInfo->ucDstATMAddrs[ul],
(sizeof(UCHAR) * ATM_ADDRESS_LENGTH));
// Note: we don't get the correct selector byte from user mode
// we assume the selector byte used by the destination is
// the same.
pAtmAddr->Address[ATM_ADDRESS_LENGTH-1] = pAdapt->SelByte;
pMember->pNext = pVc->pPMPMembers;
pVc->pPMPMembers = pMember;
pVc->ulNumTotalMembers++;
// Also add a reference for each members
pVc->ulRefCount++;
}
}
pVc->pConnectIrp = pIrp;
IoMarkIrpPending(pIrp);
// we will return pending
Status = STATUS_PENDING;
RELEASE_ADAPTER_GEN_LOCK(pAdapt);
DbgInfo(("Initiated a VC connection - Adapter 0x%x VC - 0x%x\n",
pAdapt, pVc));
if(!pConnectInfo->bPMP)
{
AtmSmConnectPPVC(pVc);
}
else
{
AtmSmConnectToPMPDestinations(pVc);
}
} while(FALSE);
TraceOut(AtmSmIoctlConnectToDsts);
return Status;
}
NTSTATUS AtmSmIoctlSendToDsts(
PIRP pIrp,
PIO_STACK_LOCATION pIrpSp
)
/*++
Routine Description:
This routine is used to send a packet to destination(s) for which we
already have a connection.
NOTE! This uses Direct I/O for buffer to send data
Arguments:
Return Value:
Status - Pending or error
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulInputBufLen, ulOutputBufLen;
PATMSM_VC pVc;
ULONG ulControlCode;
TraceIn(AtmSmIoctlSendToDsts);
ulControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
ASSERT(METHOD_IN_DIRECT == (ulControlCode & 0x3));
ulInputBufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
if(sizeof(HANDLE) != ulInputBufLen)
{
DbgErr(("Input buffer length is invalid!\n"));
ASSERT(FALSE);
TraceOut(AtmSmIoctlSendToDsts);
return STATUS_INVALID_PARAMETER;
}
ulOutputBufLen = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
if(0 == ulOutputBufLen)
{
DbgErr(("Output buffer length is 0!\n"));
ASSERT(FALSE);
TraceOut(AtmSmIoctlRecvData);
return STATUS_INVALID_PARAMETER;
}
DbgLoud(("Send - Output buffer length = %u\n", ulOutputBufLen));
pVc = (PATMSM_VC)(*(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer));
DbgLoud(("Connect Context is 0x%x\n", pVc));
// Note - VerifyConnectContext adds a reference to the VC
// if successful, which we remove when we are done
if(STATUS_SUCCESS != (Status = VerifyConnectContext(pVc)))
{
TraceOut(AtmSmIoctlSendToDsts);
return Status;
}
// we have a valid ConnectContext
do
{ // break off loop
PNDIS_PACKET pPacket;
PATMSM_ADAPTER pAdapt = pVc->pAdapt;
//
// Try to get a packet
//
NdisAllocatePacket(
&Status,
&pPacket,
pAdapt->PacketPoolHandle
);
if(NDIS_STATUS_SUCCESS != Status)
{
//
// No free packets
//
Status = STATUS_UNSUCCESSFUL;
break;
}
(GET_PROTO_RSVD(pPacket))->pSendIrp=pIrp;
#ifdef BUG_IN_NEW_DMA
{
PNDIS_BUFFER pBuffer;
PVOID pSrcVA =
MmGetSystemAddressForMdl(pIrp->MdlAddress);
UINT uiBufSize =
MmGetMdlByteCount(pIrp->MdlAddress);
// allocate the Buffer Descriptor
NdisAllocateBuffer(&Status,
&pBuffer,
pAdapt->BufferPoolHandle,
pSrcVA,
uiBufSize);
if(NDIS_STATUS_SUCCESS != Status)
{
NdisFreePacket(pPacket);
break;
}
// add the buffer to the packet
NdisChainBufferAtFront(pPacket,
pBuffer);
}
#else // BUG_IN_NEW_DMA
//
// Attach the send buffer to the packet
//
NdisChainBufferAtFront(pPacket, pIrp->MdlAddress);
#endif // BUG_IN_NEW_DMA
IoMarkIrpPending(pIrp);
Status = STATUS_PENDING;
// send the packet on the VC
AtmSmSendPacketOnVc(pVc, pPacket);
}while(FALSE);
// remove the reference added to the VC while verifying
AtmSmDereferenceVc(pVc);
TraceOut(AtmSmIoctlSendToDsts);
return Status;
}
NTSTATUS AtmSmIoctlCloseSendHandle(
PIRP pIrp,
PIO_STACK_LOCATION pIrpSp
)
/*++
Routine Description:
This routine is used to close a handle that was obtained when we established
a connection to destinations.
NOTE! This uses buffered I/O
Arguments:
Return Value:
Status - doesn't pend
--*/
{
NTSTATUS Status = STATUS_SUCCESS;
ULONG ulInputBufLen;
PATMSM_VC pVc;
TraceIn(AtmSmIoctlCloseSendHandle);
ulInputBufLen = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
if(ulInputBufLen < sizeof(HANDLE))
{
DbgErr(("Input length is invalid\n"));
TraceOut(AtmSmIoctlCloseSendHandle);
return STATUS_INVALID_PARAMETER;
}
pVc = (PATMSM_VC)(*(PHANDLE)(pIrp->AssociatedIrp.SystemBuffer));
DbgLoud(("Connect Context is 0x%x\n", pVc));
// Note - VerifyConnectContext adds a reference to the VC
// if successful, which we remove when we are done
if(STATUS_SUCCESS != (Status = VerifyConnectContext(pVc)))
{
TraceOut(AtmSmIoctlCloseSendHandle);
return Status;
}
// we have a valid Connect Context - disconnect it
AtmSmDisconnectVc(pVc);
// remove the reference added to the VC while verifying
AtmSmDereferenceVc(pVc);
TraceOut(AtmSmIoctlCloseSendHandle);
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -