summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/isn/spx/spxquery.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/tdi/isn/spx/spxquery.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/private/ntos/tdi/isn/spx/spxquery.c b/private/ntos/tdi/isn/spx/spxquery.c
new file mode 100644
index 000000000..047ecabe8
--- /dev/null
+++ b/private/ntos/tdi/isn/spx/spxquery.c
@@ -0,0 +1,259 @@
+/*++
+
+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
+