summaryrefslogtreecommitdiffstats
path: root/private/ntos/tdi/tcpip/tcp/ntinit.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/tdi/tcpip/tcp/ntinit.c1038
1 files changed, 1038 insertions, 0 deletions
diff --git a/private/ntos/tdi/tcpip/tcp/ntinit.c b/private/ntos/tdi/tcpip/tcp/ntinit.c
new file mode 100644
index 000000000..e1fdbd7f7
--- /dev/null
+++ b/private/ntos/tdi/tcpip/tcp/ntinit.c
@@ -0,0 +1,1038 @@
+/*++
+
+Copyright (c) 1991 Microsoft Corporation
+
+Module Name:
+
+ ntinit.c
+
+Abstract:
+
+ NT specific routines for loading and configuring the TCP/UDP driver.
+
+Author:
+
+ Mike Massa (mikemas) Aug 13, 1993
+
+Revision History:
+
+ Who When What
+ -------- -------- ----------------------------------------------
+ mikemas 08-13-93 created
+
+Notes:
+
+--*/
+
+#include <oscfg.h>
+#include <ntddip.h>
+#include <ndis.h>
+#include <cxport.h>
+#include <tdi.h>
+#include <tdikrnl.h>
+#include <tdint.h>
+#include <tdistat.h>
+#include <tdiinfo.h>
+#include <ip.h>
+
+#include "queue.h"
+#include "addr.h"
+#include "tcp.h"
+#include "tcb.h"
+#include "udp.h"
+#include "raw.h"
+#include "tcpconn.h"
+#include "tcpcfg.h"
+#include <ntddtcp.h>
+#include "secfltr.h"
+
+//
+// Global variables.
+//
+PDRIVER_OBJECT TCPDriverObject = NULL;
+PDEVICE_OBJECT TCPDeviceObject = NULL;
+PDEVICE_OBJECT UDPDeviceObject = NULL;
+PDEVICE_OBJECT RawIPDeviceObject = NULL;
+extern PDEVICE_OBJECT IPDeviceObject;
+
+//
+//Place holder for Maximum duplicate acks we would like
+//to see before we do fast retransmit
+//
+#if FAST_RETRANSMIT
+uint MaxDupAcks;
+#endif
+
+
+#ifdef _PNP_POWER
+
+HANDLE TCPRegistrationHandle;
+HANDLE UDPRegistrationHandle;
+HANDLE IPRegistrationHandle;
+
+#endif
+
+#ifdef SYN_ATTACK
+BOOLEAN SynAttackProtect; //if TRUE, syn-att protection checks
+ // are made
+uint TCPPortsExhausted; //# of ports exhausted
+uint TCPMaxPortsExhausted; //Max # of ports that must be exhausted
+ // for syn-att protection to kick in
+uint TCPMaxPortsExhaustedLW; //Low-watermark of # of ports exhausted
+ //When reached, we revert to normal
+ // count for syn-ack retries
+uint TCPMaxHalfOpen; //Max # of half-open connections allowed
+ // before we dec. the syn-ack retries
+uint TCPMaxHalfOpenRetried; //Max # of half-open conn. that have
+ // been retried at least 1 time
+uint TCPMaxHalfOpenRetriedLW; //Low-watermark of the above. When
+ // go down to it, we revert to normal
+ // # of retries for syn-acks
+uint TCPHalfOpen; //# of half-open connections
+uint TCPHalfOpenRetried; //# of half-open conn. that have been
+ //retried at least once
+#endif
+//
+// External function prototypes
+//
+
+int
+tlinit(
+ void
+ );
+
+NTSTATUS
+TCPDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+TCPDispatchInternalDeviceControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+IPDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ );
+
+NTSTATUS
+IPDriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+NTSTATUS
+GetRegMultiSZValue(
+ HANDLE KeyHandle,
+ PWCHAR ValueName,
+ PUNICODE_STRING ValueData
+ );
+
+PWCHAR
+EnumRegMultiSz(
+ IN PWCHAR MszString,
+ IN ULONG MszStringLength,
+ IN ULONG StringIndex
+ );
+
+//
+// Local funcion prototypes
+//
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+void *
+TLRegisterProtocol(
+ uchar Protocol,
+ void *RcvHandler,
+ void *XmitHandler,
+ void *StatusHandler,
+ void *RcvCmpltHandler
+ );
+
+IP_STATUS
+TLGetIPInfo(
+ IPInfo *Buffer,
+ int Size
+ );
+
+uchar
+TCPGetConfigInfo(
+ void
+ );
+
+NTSTATUS
+TCPInitializeParameter(
+ HANDLE KeyHandle,
+ PWCHAR ValueName,
+ PULONG Value
+ );
+
+#ifdef SECFLTR
+
+uint
+EnumSecurityFilterValue(
+ PNDIS_STRING FilterList,
+ ulong Index,
+ ulong *FilterValue
+ );
+
+#endif // SECFLTR
+
+#ifdef RASAUTODIAL
+VOID
+TCPAcdBind();
+#endif // RASAUTODIAL
+
+
+#ifdef ALLOC_PRAGMA
+
+#pragma alloc_text(INIT, DriverEntry)
+#pragma alloc_text(INIT, TLRegisterProtocol)
+#pragma alloc_text(INIT, TLGetIPInfo)
+#pragma alloc_text(INIT, TCPGetConfigInfo)
+#pragma alloc_text(INIT, TCPInitializeParameter)
+
+#ifdef SECFLTR
+#pragma alloc_text(PAGE, EnumSecurityFilterValue)
+#endif // SECFLTR
+
+#ifdef RASAUTODIAL
+#pragma alloc_text(INIT, TCPAcdBind)
+#endif // RASAUTODIAL
+
+#endif // ALLOC_PRAGMA
+
+
+//
+// Function definitions
+//
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+
+/*++
+
+Routine Description:
+
+ Initialization routine for the TCP/UDP driver.
+
+Arguments:
+
+ DriverObject - Pointer to the TCP driver object created by the system.
+ DeviceDescription - The name of TCP's node in the registry.
+
+Return Value:
+
+ The final status from the initialization operation.
+
+--*/
+
+{
+ NTSTATUS status;
+ UNICODE_STRING deviceName;
+ USHORT i;
+ int initStatus;
+
+
+#ifdef _PNP_POWER
+ TdiInitialize();
+#endif
+
+#ifdef SECFLTR
+ //
+ // IP calls the security filter code, so initialize it first.
+ //
+ InitializeSecurityFilters();
+
+#endif // SECFLTR
+
+ //
+ // Initialize IP
+ //
+ status = IPDriverEntry(DriverObject, RegistryPath);
+
+ if (!NT_SUCCESS(status)) {
+ TCPTRACE(("Tcpip: IP initialization failed, status %lx\n", status));
+ return(status);
+ }
+
+ //
+ // Initialize TCP, UDP, and RawIP
+ //
+ TCPDriverObject = DriverObject;
+
+ //
+ // Create the device objects. IoCreateDevice zeroes the memory
+ // occupied by the object.
+ //
+
+ RtlInitUnicodeString(&deviceName, DD_TCP_DEVICE_NAME);
+
+ status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &deviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &TCPDeviceObject
+ );
+
+ if (!NT_SUCCESS(status)) {
+ CTELogEvent(
+ DriverObject,
+ EVENT_TCPIP_CREATE_DEVICE_FAILED,
+ 1,
+ 1,
+ &deviceName.Buffer,
+ 0,
+ NULL
+ );
+
+ TCPTRACE((
+ "TCP: Failed to create TCP device object, status %lx\n",
+ status
+ ));
+ goto init_failed;
+ }
+
+ RtlInitUnicodeString(&deviceName, DD_UDP_DEVICE_NAME);
+
+ status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &deviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &UDPDeviceObject
+ );
+
+ if (!NT_SUCCESS(status)) {
+ CTELogEvent(
+ DriverObject,
+ EVENT_TCPIP_CREATE_DEVICE_FAILED,
+ 1,
+ 1,
+ &deviceName.Buffer,
+ 0,
+ NULL
+ );
+
+ TCPTRACE((
+ "TCP: Failed to create UDP device object, status %lx\n",
+ status
+ ));
+ goto init_failed;
+ }
+
+ RtlInitUnicodeString(&deviceName, DD_RAW_IP_DEVICE_NAME);
+
+ status = IoCreateDevice(
+ DriverObject,
+ 0,
+ &deviceName,
+ FILE_DEVICE_NETWORK,
+ 0,
+ FALSE,
+ &RawIPDeviceObject
+ );
+
+ if (!NT_SUCCESS(status)) {
+ CTELogEvent(
+ DriverObject,
+ EVENT_TCPIP_CREATE_DEVICE_FAILED,
+ 1,
+ 1,
+ &deviceName.Buffer,
+ 0,
+ NULL
+ );
+
+ TCPTRACE((
+ "TCP: Failed to create Raw IP device object, status %lx\n",
+ status
+ ));
+ goto init_failed;
+ }
+
+ //
+ // Initialize the driver object
+ //
+ DriverObject->DriverUnload = NULL;
+ DriverObject->FastIoDispatch = NULL;
+ for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
+ DriverObject->MajorFunction[i] = TCPDispatch;
+ }
+
+ //
+ // We special case Internal Device Controls because they are the
+ // hot path for kernel-mode clients.
+ //
+ DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
+ TCPDispatchInternalDeviceControl;
+
+ //
+ // Intialize the device objects.
+ //
+ TCPDeviceObject->Flags |= DO_DIRECT_IO;
+ UDPDeviceObject->Flags |= DO_DIRECT_IO;
+ RawIPDeviceObject->Flags |= DO_DIRECT_IO;
+
+ //
+ // Finally, initialize the stack.
+ //
+ initStatus = tlinit();
+
+ if (initStatus == TRUE) {
+#ifdef RASAUTODIAL
+ //
+ // Get the automatic connection driver
+ // entry points.
+ //
+ TCPAcdBind();
+#endif // RASAUTODIAL
+
+
+#ifdef _PNP_POWER
+
+ RtlInitUnicodeString(&deviceName, DD_TCP_DEVICE_NAME);
+ (void)TdiRegisterDeviceObject(&deviceName,&TCPRegistrationHandle);
+
+ RtlInitUnicodeString(&deviceName, DD_UDP_DEVICE_NAME);
+ (void)TdiRegisterDeviceObject(&deviceName,&UDPRegistrationHandle);
+
+ RtlInitUnicodeString(&deviceName, DD_RAW_IP_DEVICE_NAME);
+ (void)TdiRegisterDeviceObject(&deviceName,&IPRegistrationHandle);
+
+#endif
+ return(STATUS_SUCCESS);
+ }
+
+ TCPTRACE((
+ "Tcpip: TCP/UDP initialization failed, but IP will be available.\n"
+ ));
+
+ CTELogEvent(
+ DriverObject,
+ EVENT_TCPIP_TCP_INIT_FAILED,
+ 1,
+ 0,
+ NULL,
+ 0,
+ NULL
+ );
+ status = STATUS_UNSUCCESSFUL;
+
+
+init_failed:
+
+ //
+ // IP has successfully started, but TCP & UDP failed. Set the
+ // Dispatch routine to point to IP only, since the TCP and UDP
+ // devices don't exist.
+ //
+
+ if (TCPDeviceObject != NULL) {
+ IoDeleteDevice(TCPDeviceObject);
+ }
+
+ if (UDPDeviceObject != NULL) {
+ IoDeleteDevice(UDPDeviceObject);
+ }
+
+ if (RawIPDeviceObject != NULL) {
+ IoDeleteDevice(RawIPDeviceObject);
+ }
+
+ for (i=0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
+ DriverObject->MajorFunction[i] = IPDispatch;
+ }
+
+ return(STATUS_SUCCESS);
+}
+
+
+IP_STATUS
+TLGetIPInfo(
+ IPInfo *Buffer,
+ int Size
+ )
+
+/*++
+
+Routine Description:
+
+ Returns information necessary for TCP to call into IP.
+
+Arguments:
+
+ Buffer - A pointer to the IP information structure.
+
+ Size - The size of Buffer.
+
+Return Value:
+
+ The IP status of the operation.
+
+--*/
+
+{
+ return(IPGetInfo(Buffer, Size));
+}
+
+
+void *
+TLRegisterProtocol(
+ uchar Protocol,
+ void *RcvHandler,
+ void *XmitHandler,
+ void *StatusHandler,
+ void *RcvCmpltHandler
+ )
+
+/*++
+
+Routine Description:
+
+ Calls the IP driver's protocol registration function.
+
+Arguments:
+
+ Protocol - The protocol number to register.
+
+ RcvHandler - Transport's packet receive handler.
+
+ XmitHandler - Transport's packet transmit complete handler.
+
+ StatusHandler - Transport's status update handler.
+
+ RcvCmpltHandler - Transport's receive complete handler
+
+Return Value:
+
+ A context value for the protocol to pass to IP when transmitting.
+
+--*/
+
+{
+ return(IPRegisterProtocol(
+ Protocol,
+ RcvHandler,
+ XmitHandler,
+ StatusHandler,
+ RcvCmpltHandler
+ )
+ );
+}
+
+
+//
+// Interval in milliseconds between keepalive transmissions until a
+// response is received.
+//
+#define DEFAULT_KEEPALIVE_INTERVAL 1000
+
+//
+// time to first keepalive transmission. 2 hours == 7,200,000 milliseconds
+//
+#define DEFAULT_KEEPALIVE_TIME 7200000
+
+#ifdef SYN_ATTACK
+#define MIN_THRESHOLD_MAX_HO 100
+#define MIN_THRESHOLD_MAX_HO_RETRIED 80
+#endif
+
+uchar
+TCPGetConfigInfo(
+ void
+ )
+
+/*++
+
+Routine Description:
+
+ Initializes TCP global configuration parameters.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ Zero on failure, nonzero on success.
+
+--*/
+
+{
+ HANDLE keyHandle;
+ NTSTATUS status;
+ OBJECT_ATTRIBUTES objectAttributes;
+ UNICODE_STRING UKeyName;
+ ULONG maxConnectRexmits = 0;
+ ULONG maxConnectResponseRexmits = 0;
+ ULONG maxDataRexmits = 0;
+ ULONG pptpmaxDataRexmits = 0;
+ ULONG useRFC1122UrgentPointer = 0;
+ BOOLEAN AsSystem;
+
+
+ //
+ // Initialize to the defaults in case an error occurs somewhere.
+ //
+ KAInterval = DEFAULT_KEEPALIVE_INTERVAL;
+ KeepAliveTime = DEFAULT_KEEPALIVE_TIME;
+ PMTUDiscovery = TRUE;
+ PMTUBHDetect = FALSE;
+ DeadGWDetect = TRUE;
+ DefaultRcvWin = 0; // Automagically pick a reasonable one.
+ MaxConnections = DEFAULT_MAX_CONNECTIONS;
+ maxConnectRexmits = MAX_CONNECT_REXMIT_CNT;
+ maxConnectResponseRexmits = MAX_CONNECT_RESPONSE_REXMIT_CNT;
+ pptpmaxDataRexmits = maxDataRexmits = MAX_REXMIT_CNT;
+ BSDUrgent = TRUE;
+ FinWait2TO = FIN_WAIT2_TO;
+ NTWMaxConnectCount = NTW_MAX_CONNECT_COUNT;
+ NTWMaxConnectTime = NTW_MAX_CONNECT_TIME;
+ MaxUserPort = MAX_USER_PORT;
+
+
+#if FAST_RETRANSMIT
+// Default number of duplicate acks
+ MaxDupAcks = 2;
+#endif
+
+
+#ifdef SYN_ATTACK
+ SynAttackProtect = FALSE; //by default it is always off
+ if (MmIsThisAnNtAsSystem()) {
+ TCPMaxPortsExhausted = 5;
+ TCPMaxHalfOpen = 100;
+ TCPMaxHalfOpenRetried = 80;
+ }
+ else {
+ TCPMaxPortsExhausted = 5;
+ TCPMaxHalfOpen = 500;
+ TCPMaxHalfOpenRetried = 400;
+ }
+#endif
+
+#ifdef SECFLTR
+ SecurityFilteringEnabled = FALSE;
+#endif // SECFLTR
+
+
+ //
+ // Read the TCP optional (hidden) registry parameters.
+ //
+ RtlInitUnicodeString(
+ &UKeyName,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
+ );
+
+ memset(&objectAttributes, 0, sizeof(OBJECT_ATTRIBUTES));
+
+ InitializeObjectAttributes(
+ &objectAttributes,
+ &UKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL
+ );
+
+ status = ZwOpenKey(
+ &keyHandle,
+ KEY_READ,
+ &objectAttributes
+ );
+
+ if (NT_SUCCESS(status)) {
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"KeepAliveInterval",
+ &KAInterval
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"KeepAliveTime",
+ &KeepAliveTime
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"EnablePMTUBHDetect",
+ &PMTUBHDetect
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpWindowSize",
+ &DefaultRcvWin
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpNumConnections",
+ &MaxConnections
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpMaxConnectRetransmissions",
+ &maxConnectRexmits
+ );
+
+ if (maxConnectRexmits > 255) {
+ maxConnectRexmits = 255;
+ }
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpMaxConnectResponseRetransmissions",
+ &maxConnectResponseRexmits
+ );
+
+ if (maxConnectResponseRexmits > 255) {
+ maxConnectResponseRexmits = 255;
+ }
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpMaxDataRetransmissions",
+ &maxDataRexmits
+ );
+
+ if (maxDataRexmits > 255) {
+ maxDataRexmits = 255;
+ }
+
+
+#if FAST_RETRANSMIT
+ // Limit the MaxDupAcks to 3
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpMaxDupAcks",
+ &MaxDupAcks
+ );
+
+ if (MaxDupAcks > 3) {
+ MaxDupAcks = 3;
+ }
+ if (MaxDupAcks < 0) {
+ MaxDupAcks = 1;
+ }
+#endif
+
+
+
+#ifdef SYN_ATTACK
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"SynAttackProtect",
+ (unsigned long *)&SynAttackProtect
+ );
+
+
+ if (SynAttackProtect) {
+
+ //
+ // We don't want syn-attack protection to kick in if the user
+ // has set the MaxConnectResponseRetransmissions to lower than
+ // a certain threshold.
+ //
+ if (maxConnectResponseRexmits >= MAX_CONNECT_RESPONSE_REXMIT_CNT){
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TCPMaxPortsExhausted",
+ &TCPMaxPortsExhausted
+ );
+
+ TCPMaxPortsExhaustedLW = MAX((TCPMaxPortsExhausted >> 1) + (TCPMaxPortsExhausted >> 2), 1);
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TCPMaxHalfOpen",
+ &TCPMaxHalfOpen
+ );
+
+ if (TCPMaxHalfOpen < MIN_THRESHOLD_MAX_HO) {
+ TCPMaxHalfOpen = MIN_THRESHOLD_MAX_HO;
+ }
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TCPMaxHalfOpenRetried",
+ &TCPMaxHalfOpenRetried
+ );
+
+ if (
+ (TCPMaxHalfOpenRetried > TCPMaxHalfOpen) ||
+ (TCPMaxHalfOpenRetried < MIN_THRESHOLD_MAX_HO_RETRIED)
+ )
+
+ {
+ TCPMaxHalfOpenRetried = MIN_THRESHOLD_MAX_HO_RETRIED;
+ }
+
+ TCPMaxHalfOpenRetriedLW = (TCPMaxHalfOpenRetried >> 1) +
+ (TCPMaxHalfOpenRetried >> 2);
+ }
+ else {
+ SynAttackProtect = FALSE;
+ }
+
+ }
+#endif
+
+ //
+ // If we fail, then set to same value as maxDataRexmit so that the
+ // max(pptpmaxDataRexmit,maxDataRexmit) is a decent value
+ // Need this since TCPInitializeParameter no longer "initializes"
+ // to a default value
+ //
+
+ if(TCPInitializeParameter(keyHandle,
+ L"PPTPTcpMaxDataRetransmissions",
+ &pptpmaxDataRexmits) != STATUS_SUCCESS)
+ {
+ pptpmaxDataRexmits = maxDataRexmits;
+ }
+
+ if (pptpmaxDataRexmits > 255) {
+ pptpmaxDataRexmits = 255;
+ }
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpUseRFC1122UrgentPointer",
+ &useRFC1122UrgentPointer
+ );
+
+ if (useRFC1122UrgentPointer) {
+ BSDUrgent = FALSE;
+ }
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"TcpTimedWaitDelay",
+ &FinWait2TO
+ );
+
+ if (FinWait2TO < 30) {
+ FinWait2TO = 30;
+ }
+ if (FinWait2TO > 300) {
+ FinWait2TO = 300;
+ }
+ FinWait2TO = MS_TO_TICKS(FinWait2TO*1000);
+
+ NTWMaxConnectTime = MS_TO_TICKS(NTWMaxConnectTime*1000);
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"MaxUserPort",
+ &MaxUserPort
+ );
+
+ if (MaxUserPort < 5000) {
+ MaxUserPort = 5000;
+ }
+ if (MaxUserPort > 65534) {
+ MaxUserPort = 65534;
+ }
+
+ //
+ // Read a few IP optional (hidden) registry parameters that TCP
+ // cares about.
+ //
+ TCPInitializeParameter(
+ keyHandle,
+ L"EnablePMTUDiscovery",
+ &PMTUDiscovery
+ );
+
+ TCPInitializeParameter(
+ keyHandle,
+ L"EnableDeadGWDetect",
+ &DeadGWDetect
+ );
+
+#ifdef SECFLTR
+ TCPInitializeParameter(
+ keyHandle,
+ L"EnableSecurityFilters",
+ &SecurityFilteringEnabled
+ );
+#endif // SECFLTR
+
+ ZwClose(keyHandle);
+ }
+
+ MaxConnectRexmitCount = maxConnectRexmits;
+ MaxConnectResponseRexmitCount = maxConnectResponseRexmits;
+#ifdef SYN_ATTACK
+ MaxConnectResponseRexmitCountTmp = MaxConnectResponseRexmitCount;
+#endif
+
+ //
+ // Use the greater of the two, hence both values should be valid
+ //
+
+ MaxDataRexmitCount = (maxDataRexmits > pptpmaxDataRexmits ? maxDataRexmits : pptpmaxDataRexmits) ;
+
+ return(1);
+}
+
+
+#define WORK_BUFFER_SIZE 256
+
+NTSTATUS
+TCPInitializeParameter(
+ HANDLE KeyHandle,
+ PWCHAR ValueName,
+ PULONG Value
+ )
+
+/*++
+
+Routine Description:
+
+ Initializes a ULONG parameter from the registry or to a default
+ parameter if accessing the registry value fails.
+
+Arguments:
+
+ KeyHandle - An open handle to the registry key for the parameter.
+ ValueName - The UNICODE name of the registry value to read.
+ Value - The ULONG into which to put the data.
+ DefaultValue - The default to assign if reading the registry fails.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ NTSTATUS status;
+ ULONG resultLength;
+ PKEY_VALUE_FULL_INFORMATION keyValueFullInformation;
+ UCHAR keybuf[WORK_BUFFER_SIZE];
+ UNICODE_STRING UValueName;
+
+
+ RtlInitUnicodeString(&UValueName, ValueName);
+
+ keyValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)keybuf;
+ RtlZeroMemory(keyValueFullInformation, sizeof(keyValueFullInformation));
+
+ status = ZwQueryValueKey(
+ KeyHandle,
+ &UValueName,
+ KeyValueFullInformation,
+ keyValueFullInformation,
+ WORK_BUFFER_SIZE,
+ &resultLength
+ );
+
+ if (status == STATUS_SUCCESS) {
+ if (keyValueFullInformation->Type == REG_DWORD) {
+ *Value = *((ULONG UNALIGNED *) ((PCHAR)keyValueFullInformation +
+ keyValueFullInformation->DataOffset));
+ }
+ }
+
+ return(status);
+}
+
+
+#ifdef SECFLTR
+
+TDI_STATUS
+GetSecurityFilterList(
+ NDIS_HANDLE ConfigHandle,
+ ulong Protocol,
+ PNDIS_STRING FilterList
+ )
+{
+ PWCHAR parameterName;
+ TDI_STATUS status;
+
+
+ if (Protocol == PROTOCOL_TCP) {
+ parameterName = L"TcpAllowedPorts";
+ }
+ else if (Protocol == PROTOCOL_UDP) {
+ parameterName = L"UdpAllowedPorts";
+ }
+ else {
+ parameterName = L"RawIpAllowedProtocols";
+ }
+
+ status = GetRegMultiSZValue(
+ ConfigHandle,
+ parameterName,
+ FilterList
+ );
+
+ if (!NT_SUCCESS(status)) {
+ FilterList->Length = 0;
+ }
+
+ return(status);
+}
+
+
+uint
+EnumSecurityFilterValue(
+ PNDIS_STRING FilterList,
+ ulong Index,
+ ulong *FilterValue
+ )
+{
+ PWCHAR valueString;
+ UNICODE_STRING unicodeString;
+ NTSTATUS status;
+
+
+ PAGED_CODE();
+
+
+ valueString = EnumRegMultiSz(
+ FilterList->Buffer,
+ FilterList->Length,
+ Index
+ );
+
+ if ((valueString == NULL) || (valueString[0] == UNICODE_NULL)) {
+ return(FALSE);
+ }
+
+ RtlInitUnicodeString(&unicodeString, valueString);
+
+ status = RtlUnicodeStringToInteger(&unicodeString, 0, FilterValue);
+
+ if (!(NT_SUCCESS(status))) {
+ TCPTRACE(("TCP: Invalid filter value %ws\n", valueString));
+ return(FALSE);
+ }
+
+ return(TRUE);
+}
+
+#endif // SECFLTR