summaryrefslogblamecommitdiffstats
path: root/private/ntos/tdi/isnp/spx/spxquery.c
blob: 047ecabe81f263e204e3c2915ac9591b6a1400d2 (plain) (tree)


































































































































































































































































                                                                                                                 
/*++

Copyright (c) 1989-1993 Microsoft Corporation

Module Name:

    spxquery.c

Abstract:

    This module contains code which performs the following TDI services:

        o   TdiQueryInformation

Author:

	Adam   Barr		 (adamba)  Initial Version
    Nikhil Kamkolkar (nikhilk) 11-November-1993

Environment:

    Kernel mode

Revision History:

--*/

#include "precomp.h"
#pragma hdrstop

//  Discardable code after Init time
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, SpxQueryInitProviderInfo)
#endif

//	Define module number for event logging entries
#define	FILENUM		SPXQUERY

// Useful macro to obtain the total length of an MDL chain.
#define SpxGetMdlChainLength(Mdl, Length) { \
    PMDL _Mdl = (Mdl); \
    *(Length) = 0; \
    while (_Mdl) { \
        *(Length) += MmGetMdlByteCount(_Mdl); \
        _Mdl = _Mdl->Next; \
    } \
}



VOID
SpxQueryInitProviderInfo(
    PTDI_PROVIDER_INFO  ProviderInfo
    )
{
    //  Initialize to defaults first
    RtlZeroMemory((PVOID)ProviderInfo, sizeof(TDI_PROVIDER_INFO));

    ProviderInfo->Version 		= SPX_TDI_PROVIDERINFO_VERSION;
    KeQuerySystemTime (&ProviderInfo->StartTime);
    ProviderInfo->MinimumLookaheadData	= SPX_PINFOMINMAXLOOKAHEAD;
    ProviderInfo->MaximumLookaheadData	= IpxLineInfo.MaximumPacketSize;
    ProviderInfo->MaxSendSize 	= SPX_PINFOSENDSIZE;
    ProviderInfo->ServiceFlags 	= SPX_PINFOSERVICEFLAGS;
    return;
}




NTSTATUS
SpxTdiQueryInformation(
    IN PDEVICE Device,
    IN PREQUEST Request
    )

/*++

Routine Description:

    This routine performs the TdiQueryInformation request for the transport
    provider.

Arguments:

    Request - the request for the operation.

Return Value:

    NTSTATUS - status of operation.

--*/

{
    NTSTATUS 							status;
    PSPX_ADDR_FILE 						AddressFile;
    PSPX_CONN_FILE 						ConnectionFile;
    PTDI_REQUEST_KERNEL_QUERY_INFORMATION 	query;
	struct {
        ULONG 			ActivityCount;
        TA_IPX_ADDRESS 	SpxAddress;
    } AddressInfo;



    // what type of status do we want?
    query = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)REQUEST_PARAMETERS(Request);

    switch (query->QueryType)
	{
	case TDI_QUERY_CONNECTION_INFO:

		status = STATUS_NOT_IMPLEMENTED;
		break;

    case TDI_QUERY_ADDRESS_INFO:

        // The caller wants the exact address value.

        ConnectionFile = (PSPX_CONN_FILE)REQUEST_OPEN_CONTEXT(Request);
        status = SpxConnFileVerify(ConnectionFile);

        if (status == STATUS_SUCCESS) {
            AddressFile = ConnectionFile->scf_AddrFile;
            SpxConnFileDereference(ConnectionFile, CFREF_VERIFY);
        } else {
            AddressFile = (PSPX_ADDR_FILE)REQUEST_OPEN_CONTEXT(Request);
        }

        status = SpxAddrFileVerify(AddressFile);

        if (status == STATUS_SUCCESS)
		{
			DBGPRINT(RECEIVE, INFO,
					("SpxTdiQuery: Net.Socket %lx.%lx\n",
						*(PULONG)Device->dev_Network,
						AddressFile->saf_Addr->sa_Socket));

            AddressInfo.ActivityCount = 0;
            (VOID)SpxBuildTdiAddress(
                &AddressInfo.SpxAddress,
                sizeof(TA_IPX_ADDRESS),
                Device->dev_Network,
                Device->dev_Node,
                AddressFile->saf_Addr->sa_Socket);

            status = TdiCopyBufferToMdl(
                &AddressInfo,
                0,
                sizeof(AddressInfo),
                REQUEST_NDIS_BUFFER(Request),
                0,
                &REQUEST_INFORMATION(Request));

            SpxAddrFileDereference(AddressFile, AFREF_VERIFY);

        }

        break;

    case TDI_QUERY_PROVIDER_INFO: {
        BYTE    socketType;
        TDI_PROVIDER_INFO  providerInfo = Device->dev_ProviderInfo;

        //
        // The device name extension comes down in the Irp
        //
    	if (!NT_SUCCESS(status = SpxUtilGetSocketType(
    								REQUEST_OPEN_NAME(Request),
    								&socketType))) {
            DBGPRINT(RECEIVE, ERR, ("TDI_QUERY_PROVIDER_INFO: SpxUtilGetSocketType failed: %lx\n", status));
    		return(status);
    	}

        //
        // The Catapult folks had a problem where AFD was discarding buffered sends on the NT box when it got a
        // local disconnect on SPX1. This was because the Orderly release flag was always set in the provider
        // info. AFD queries this once per device type. We detect the device above and OR in the orderly release
        // flag if this query came down on an SPX2 endpoint.
        // This is to make sure that AFD follows the correct disconnect semantics for SPX1 and SPX2 (SPX1 does
        // only abortive; SPX2 does both abortive and orderly).
        //
        // BUGBUG: this will still not solve the problem completely since a connection that starts off as an SPX2
        // one can still be negotiated to SPX1 if the remote supports only SPX1.
        //
        if ((socketType == SOCKET2_TYPE_SEQPKT) ||
            (socketType == SOCKET2_TYPE_STREAM)) {

            DBGPRINT(RECEIVE, INFO, ("TDI_QUERY_PROVIDER_INFO: SPX2 socket\n"));
            providerInfo.ServiceFlags |= TDI_SERVICE_ORDERLY_RELEASE;
        } else {
            DBGPRINT(RECEIVE, INFO, ("TDI_QUERY_PROVIDER_INFO: SPX1 socket\n"));
        }

        status = TdiCopyBufferToMdl (
                    &providerInfo,
                    0,
                    sizeof (TDI_PROVIDER_INFO),
                    REQUEST_TDI_BUFFER(Request),
                    0,
                    &REQUEST_INFORMATION(Request));
        break;
    }

    case TDI_QUERY_PROVIDER_STATISTICS:

        status = TdiCopyBufferToMdl (
                    &Device->dev_Stat,
                    0,
                    FIELD_OFFSET (TDI_PROVIDER_STATISTICS, ResourceStats[0]),
                    REQUEST_TDI_BUFFER(Request),
                    0,
                    &REQUEST_INFORMATION(Request));
        break;

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    return status;

} // SpxTdiQueryInformation



NTSTATUS
SpxTdiSetInformation(
    IN PDEVICE Device,
    IN PREQUEST Request
    )

/*++

Routine Description:

    This routine performs the TdiSetInformation request for the transport
    provider.

Arguments:

    Device - the device.

    Request - the request for the operation.

Return Value:

    NTSTATUS - status of operation.

--*/

{
    UNREFERENCED_PARAMETER (Device);
    UNREFERENCED_PARAMETER (Request);

    return STATUS_NOT_IMPLEMENTED;

} // SpxTdiSetInformation