// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil -*- (for GNU Emacs) // // Copyright (c) 1985-2000 Microsoft Corporation // // This file is part of the Microsoft Research IPv6 Network Protocol Stack. // You should have received a copy of the Microsoft End-User License Agreement // for this software along with this release; see the file "license.txt". // If not, please see http://www.research.microsoft.com/msripv6/license.htm, // or write to Microsoft Research, One Microsoft Way, Redmond, WA 98052-6399. // // Abstract: // // NT specific routines for loading and configuring the IP driver. // #define _CTYPE_DISABLE_MACROS // REVIEW: does this do anything? #include #include #include #include "ip6def.h" #include #include #include #include #include #include "neighbor.h" #include "route.h" // // Global variables. // PDRIVER_OBJECT IPDriverObject; PDEVICE_OBJECT IPDeviceObject; HANDLE IPv6ProviderHandle; int IPv6IndicatedProviderReady; uint UseEtherSnap = FALSE; #ifdef DEBUG_OBJECTS extern LIST_ENTRY FileObjectList; extern KSPIN_LOCK FileObjectLock; #endif // // Local function prototypes // NTSTATUS IPDriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath); uint UseEtherSNAP(PNDIS_STRING Name); #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, IPDriverEntry) #pragma alloc_text(PAGE, UseEtherSNAP) #endif // ALLOC_PRAGMA // // Function definitions // //* IPDriverEntry // // This is the IPv6 protocol initialization entry point, called from // the common DriverEntry routine upon loading. // NTSTATUS // Status of initialization operation. IPDriverEntry( IN PDRIVER_OBJECT DriverObject, // Common TCP/IP driver object. IN PUNICODE_STRING RegistryPath) // Path to our info in the registry. { NTSTATUS Status; UNICODE_STRING DeviceName; UNICODE_STRING WinDeviceName; UNREFERENCED_PARAMETER(RegistryPath); IPDriverObject = DriverObject; #ifdef DEBUG_OBJECTS InitializeListHead(&FileObjectList); KeInitializeSpinLock(&FileObjectLock); #endif // // Create the device object. IoCreateDevice zeroes the memory // occupied by the object. // RtlInitUnicodeString(&DeviceName, DD_IPV6_DEVICE_NAME); Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_NETWORK, FILE_DEVICE_SECURE_OPEN, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR, "IP init failed: " "Unable to create device object %ws, Status %lx.", DD_IPV6_DEVICE_NAME, Status)); return(Status); } // // Create a Win32-accessible link for the device. // This will allow Windows programs to make IOCTLs. // RtlInitUnicodeString(&WinDeviceName, L"\\??\\" WIN_IPV6_BASE_DEVICE_NAME); Status = IoCreateSymbolicLink(&WinDeviceName, &DeviceName); if (!NT_SUCCESS(Status)) { KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR, "IPv6: IoCreateSymbolicLink failed\n")); IoDeleteDevice(IPDeviceObject); return STATUS_UNSUCCESSFUL; } // // Register as a TDI provider. // Status = TdiRegisterProvider(&DeviceName, &IPv6ProviderHandle); if (!NT_SUCCESS(Status)) { KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR, "IPv6: TdiRegisterProvider failed\n")); IoDeleteDevice(IPDeviceObject); return STATUS_UNSUCCESSFUL; } // // Initialize the device object. // IPDeviceObject->Flags |= DO_DIRECT_IO; // // Initialize the list of pending echo request IRPs. // InitializeListHead(&PendingEchoList); // // Read configuration parameters from the registry // and then initialize. // ConfigureGlobalParameters(); if (!IPInit()) { // // REVIEW: Write an error log entry here? // KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_INTERNAL_ERROR, "IP initialization failed.\n")); TdiDeregisterProvider(IPv6ProviderHandle); IoDeleteDevice(IPDeviceObject); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; } //* IPv6ProviderReady // // Indicate that we are ready to operate as a TDI provider. // void IPv6ProviderReady(void) { int DidIndicateProviderReady; NTSTATUS Status; ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); // // Ensure that we only indicate provider ready once. // DidIndicateProviderReady = InterlockedExchange( (PLONG)&IPv6IndicatedProviderReady, TRUE); if (! DidIndicateProviderReady) { // // Create persistent interfaces after any NDIS interfaces. // ConfigurePersistentInterfaces(); // // Now indicate to TDI that we are ready. // Status = TdiProviderReady(IPv6ProviderHandle); if (!NT_SUCCESS(Status)) KdPrintEx((DPFLTR_TCPIP6_ID, DPFLTR_NTOS_ERROR, "IPv6: TdiProviderReady failed: %x\n", Status)); } } //* UseEtherSNAP // // Determines whether the EtherSNAP protocol should be used on an interface. // uint // Returns: Nonzero if SNAP is to be used on the I/F. Zero otherwise. UseEtherSNAP( PNDIS_STRING Name) // Device name of the interface in question. { UNREFERENCED_PARAMETER(Name); // // We currently set this on a global basis. // return(UseEtherSnap); }