|
|
/*++
Copyright (c) 2000-2000 Microsoft Corporation
Module Name:
Query.c
Abstract:
This module implements Query handling routines for the PGM Transport
Author:
Mohammad Shabbir Alam (MAlam) 3-30-2000
Revision History:
--*/
#include "precomp.h"
#ifdef FILE_LOGGING
#include "query.tmh"
#endif // FILE_LOGGING
//******************* Pageable Routine Declarations ****************
#ifdef ALLOC_PRAGMA
// #pragma alloc_text(PAGE, PgmQueryInformation) Should not be pageable!
#endif
//******************* Pageable Routine Declarations ****************
//----------------------------------------------------------------------------
NTSTATUS QueryAddressCompletion( IN PDEVICE_OBJECT pDeviceContext, IN PIRP pIrp, IN PVOID Context ) /*++
Routine Description:
This routine handles the completion event when the Query address Information completes.
Arguments:
IN pDeviceContext -- unused. IN pIrp -- Supplies Irp that the transport has finished processing. IN Context -- not used
Return Value:
NTSTATUS - Final status of the set event operation
--*/ { tTDI_QUERY_ADDRESS_INFO *pTdiQueryInfo; PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation(pIrp); tCOMMON_SESSION_CONTEXT *pSession = pIrpSp->FileObject->FsContext;
if ((NT_SUCCESS (pIrp->IoStatus.Status)) && (pTdiQueryInfo = (tTDI_QUERY_ADDRESS_INFO *) MmGetSystemAddressForMdlSafe (pIrp->MdlAddress, HighPagePriority))) { if (PGM_VERIFY_HANDLE3 (pSession, PGM_VERIFY_SESSION_UNASSOCIATED, PGM_VERIFY_SESSION_SEND, PGM_VERIFY_SESSION_RECEIVE)) { PgmTrace (LogAllFuncs, ("QueryAddressCompletion: " \ "Tdi IpAddress=<%x>, Port=<%x>\n", ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->in_addr, ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->sin_port));
//
// Save the transport's address information in our own structure!
//
pSession->TdiIpAddress =((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->in_addr; pSession->TdiPort = ((PTDI_ADDRESS_IP) &pTdiQueryInfo->IpAddress.Address[0].Address)->sin_port; } else { PgmTrace (LogError, ("QueryAddressCompletion: ERROR -- " \ "Invalid Session Context <%p>\n", pSession)); } } else { PgmTrace (LogError, ("QueryAddressCompletion: ERROR -- " \ "Transport returned <%x>, pTdiQueryInfo=<%p>\n", pIrp->IoStatus.Status, pTdiQueryInfo)); }
//
// Must return a non-error status otherwise the IO system will not copy
// back into the users buffer.
//
return (STATUS_SUCCESS); }
//----------------------------------------------------------------------------
NTSTATUS QueryProviderCompletion( IN PDEVICE_OBJECT pDeviceContext, IN PIRP pIrp, IN PVOID Context ) /*++
Routine Description:
This routine handles the completion event when the Query Provider Information completes. This routine must decrement the MaxDgramSize and max send size by the respective NBT header sizes.
Arguments:
IN pDeviceContext -- unused. IN pIrp -- Supplies Irp that the transport has finished processing. IN Context -- not used
Return Value:
The final status from the operation (success or an exception).
--*/ { PTDI_PROVIDER_INFO pProvider;
if ((NT_SUCCESS (pIrp->IoStatus.Status)) && (pProvider = (PTDI_PROVIDER_INFO) MmGetSystemAddressForMdlSafe (pIrp->MdlAddress, HighPagePriority))) {
//
// Set the correct service flags to indicate what Pgm supports.
//
pProvider->ServiceFlags = TDI_SERVICE_MESSAGE_MODE | TDI_SERVICE_CONNECTION_MODE | TDI_SERVICE_ERROR_FREE_DELIVERY | TDI_SERVICE_MULTICAST_SUPPORTED | TDI_SERVICE_NO_ZERO_LENGTH | TDI_SERVICE_FORCE_ACCESS_CHECK | TDI_SERVICE_ROUTE_DIRECTED;
/*
ISSUE: Do we need: TDI_SERVICE_INTERNAL_BUFFERING ? TDI_SERVICE_FORCE_ACCESS_CHECK ? TDI_SERVICE_CONNECTIONLESS_MODE ? TDI_SERVICE_DELAYED_ACCEPTANCE ? TDI_SERVICE_BROADCAST_SUPPORTED ? */ pProvider->MinimumLookaheadData = 1;
//
// The following data is for Streams
//
pProvider->MaxSendSize = SENDER_MAX_WINDOW_SIZE_PACKETS;
if (pProvider->MaxDatagramSize > PGM_MAX_FEC_DATA_HEADER_LENGTH) { pProvider->MaxDatagramSize -= PGM_MAX_FEC_DATA_HEADER_LENGTH; } else { pProvider->MaxDatagramSize = 0; }
PgmTrace (LogAllFuncs, ("QueryProviderCompletion: " \ "SvcFlags=<%x> MaxSendSize=<%d>, MaxDgramSize=<%d>\n", pProvider->ServiceFlags, pProvider->MaxSendSize, pProvider->MaxDatagramSize)); } else { PgmTrace (LogError, ("QueryProviderCompletion: ERROR -- " \ "Transport returned <%x>, pProvider=<%p>\n", pIrp->IoStatus.Status, pProvider)); }
//
// Must return a non-error status otherwise the IO system will not copy
// back into the users buffer.
//
return (STATUS_SUCCESS); }
//----------------------------------------------------------------------------
NTSTATUS PgmQueryInformation( IN tPGM_DEVICE *pPgmDevice, IN PIRP pIrp, IN PIO_STACK_LOCATION pIrpSp ) /*++
Routine Description:
This routine performs the TdiQueryInformation request for the transport provider.
Arguments:
IN pPgmDevice -- Pgm's Device object context IN pIrp -- Client's request Irp IN pIrpSp -- current request's stack pointer
Return Value:
NTSTATUS - Final status of the set event operation
--*/ { NTSTATUS status = STATUS_NOT_IMPLEMENTED; ULONG Size, BytesCopied = 0; PTDI_REQUEST_KERNEL_QUERY_INFORMATION Query; tTDI_QUERY_ADDRESS_INFO TdiQueryInfo; tADDRESS_CONTEXT *pAddress = pIrpSp->FileObject->FsContext; tCOMMON_SESSION_CONTEXT *pSession = pIrpSp->FileObject->FsContext;
Query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION) &pIrpSp->Parameters;
switch (Query->QueryType) { case TDI_QUERY_PROVIDER_INFO: { PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \ "[TDI_QUERY_PROVIDER_INFO]:\n"));
TdiBuildQueryInformation (pIrp, pPgmDevice->pControlDeviceObject, pPgmDevice->pControlFileObject, QueryProviderCompletion, NULL, TDI_QUERY_PROVIDER_INFO, pIrp->MdlAddress);
status = IoCallDriver (pPgmDevice->pControlDeviceObject, pIrp); //
// we must return the next drivers ret code back to the IO subsystem
//
status = STATUS_PENDING; break; }
case TDI_QUERY_ADDRESS_INFO: { if (pIrp->MdlAddress) { if (PGM_VERIFY_HANDLE2 (pAddress, PGM_VERIFY_ADDRESS, PGM_VERIFY_ADDRESS_DOWN)) { PgmZeroMemory (&TdiQueryInfo, sizeof (tTDI_QUERY_ADDRESS_INFO)); TdiQueryInfo.ActivityCount = 1; TdiQueryInfo.IpAddress.TAAddressCount = 1; TdiQueryInfo.IpAddress.Address[0].AddressType = TDI_ADDRESS_TYPE_IP; TdiQueryInfo.IpAddress.Address[0].AddressLength = sizeof(TDI_ADDRESS_IP); ((PTDI_ADDRESS_IP) &TdiQueryInfo.IpAddress.Address[0].Address)->in_addr = htonl (pAddress->ReceiverMCastAddr); ((PTDI_ADDRESS_IP) &TdiQueryInfo.IpAddress.Address[0].Address)->sin_port = htons (pAddress->ReceiverMCastPort);
//
// Due to the structure being Unaligned, we cannot reference the address
// and port fields directly!
//
Size = offsetof (tTDI_QUERY_ADDRESS_INFO, IpAddress.Address[0].Address) + sizeof(TDI_ADDRESS_IP);
status = TdiCopyBufferToMdl (&TdiQueryInfo, 0, Size, pIrp->MdlAddress, 0, &BytesCopied); pIrp->IoStatus.Information = BytesCopied;
PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \ "[ADDRESS_INFO]: pAddress=<%p>, Copied=<%d/%d>\n", pAddress, BytesCopied, Size));
break; } else if (PGM_VERIFY_HANDLE2 (pSession, PGM_VERIFY_SESSION_SEND, PGM_VERIFY_SESSION_RECEIVE)) { if ((pAddress = pSession->pAssociatedAddress) && (PGM_VERIFY_HANDLE (pAddress, PGM_VERIFY_ADDRESS))) { TdiBuildQueryInformation (pIrp, pAddress->pDeviceObject, pAddress->pFileObject, QueryAddressCompletion, NULL, TDI_QUERY_ADDRESS_INFO, pIrp->MdlAddress);
PgmTrace (LogAllFuncs, ("PgmQueryInformation: " \ "[ADDRESS_INFO]: pSession=<%p>, querying transport ...\n", pSession));
status = IoCallDriver (pPgmDevice->pControlDeviceObject, pIrp); //
// we must return the next drivers ret code back to the IO subsystem
//
status = STATUS_PENDING; } else { PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \ "[ADDRESS_INFO]: pSession=<%p>, Invalid pAddress=<%p>\n", pSession, pAddress));
status = STATUS_INVALID_HANDLE; }
break; } else // neither an address nor a connect context!
{ PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \ "[TDI_QUERY_ADDRESS_INFO]: Invalid Handle=<%p>\n", pIrpSp->FileObject->FsContext));
status = STATUS_INVALID_HANDLE; } } else { PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \ "[TDI_QUERY_ADDRESS_INFO]: No Mdl, pIrp=<%p>\n", pIrp));
status = STATUS_UNSUCCESSFUL; }
break; }
default: { PgmTrace (LogError, ("PgmQueryInformation: ERROR -- " \ "Query=<%d> not Implemented!\n", Query->QueryType));
break; } }
return (status); } //----------------------------------------------------------------------------
|