static NDIS_STATUS ReceiverInitializeBuffers(PRECEIVER Receiver) { NDIS_STATUS Status; /* We must always be able to allocate a packet from DoRxPacket. */ NdisAllocatePacketPoolEx( &Status, &Receiver->RecvPacketPool, XENNET_MAX_RFDS, 0xffff - XENNET_MAX_RFDS, PROTOCOL_RESERVED_SIZE_IN_PACKET); if (Status != NDIS_STATUS_SUCCESS) return Status; return ReceiverCommonInitializeBuffers(&Receiver->Common); }
VOID natpBindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ) { NDIS_HANDLE ConfigHandle = NULL; PNDIS_CONFIGURATION_PARAMETER Param; NDIS_STRING DeviceStr = UPPER_BINDINGS; PFILTER_ADAPTER pAdapt = NULL; NDIS_STATUS Sts; UINT MediumIndex, i; ULONG TotalSize; WCHAR DevicePrefix[] = L"\\Device\\"; UNREFERENCED_PARAMETER(BindContext); UNREFERENCED_PARAMETER(SystemSpecific2); __try{ NdisOpenProtocolConfiguration( Status, &ConfigHandle, SystemSpecific1 ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisReadConfiguration( Status, &Param, ConfigHandle, &DeviceStr, NdisParameterString ); if (*Status != NDIS_STATUS_SUCCESS) __leave; TotalSize = sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength + DeviceName->MaximumLength; NdisAllocateMemoryWithTag(&pAdapt, TotalSize, NAT_TAG); if (NULL == pAdapt){ *Status = NDIS_STATUS_RESOURCES; __leave; } NdisZeroMemory(pAdapt, TotalSize); pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength; pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length; pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER)); NdisMoveMemory( pAdapt->DeviceName.Buffer, Param->ParameterData.StringData.Buffer, Param->ParameterData.StringData.MaximumLength ); if(sizeof(DevicePrefix) >= DeviceName->Length){ }else{ pAdapt->RootDeviceName.MaximumLength = DeviceName->MaximumLength; pAdapt->RootDeviceName.Length = DeviceName->Length - sizeof(DevicePrefix) + sizeof(WCHAR); pAdapt->RootDeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(FILTER_ADAPTER) + Param->ParameterData.StringData.MaximumLength); NdisMoveMemory( pAdapt->RootDeviceName.Buffer, DeviceName->Buffer + sizeof(DevicePrefix)/sizeof(WCHAR) - 1, DeviceName->MaximumLength - sizeof(DevicePrefix)/sizeof(WCHAR) + 1 ); } NdisInitializeEvent(&pAdapt->Event); NdisAllocateSpinLock(&pAdapt->Lock); natInitControlBlock(&pAdapt->ctrl); NdisAllocatePacketPoolEx( Status, &pAdapt->SndPP1, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->SndPP2, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocateBufferPool( Status, &pAdapt->SndBP, MIN_PACKET_POOL_SIZE ); if ( *Status != NDIS_STATUS_SUCCESS ) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->RcvPP1, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocatePacketPoolEx( Status, &pAdapt->RcvPP2, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET ); if (*Status != NDIS_STATUS_SUCCESS) __leave; NdisAllocateBufferPool( Status, &pAdapt->RcvBP, MIN_PACKET_POOL_SIZE ); if ( *Status != NDIS_STATUS_SUCCESS ) __leave; NdisOpenAdapter( Status, &Sts, &pAdapt->BindingHandle, &MediumIndex, MediumArray, sizeof(MediumArray)/sizeof(NDIS_MEDIUM), ProtHandle, pAdapt, DeviceName, 0,NULL ); if (*Status == NDIS_STATUS_PENDING){ NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } if (*Status != NDIS_STATUS_SUCCESS) __leave; pAdapt->Medium = MediumArray[MediumIndex]; pAdapt->MiniportInitPending = TRUE; NdisInitializeEvent(&pAdapt->MiniportInitEvent); *Status = NdisIMInitializeDeviceInstanceEx( DriverHandle, &pAdapt->DeviceName, pAdapt ); if (*Status != NDIS_STATUS_SUCCESS) __leave; StartQueryInfo( pAdapt ); } __finally{ } if (ConfigHandle != NULL) NdisCloseConfiguration(ConfigHandle); if(NDIS_STATUS_SUCCESS != *Status){ if (pAdapt != NULL){ if (pAdapt->BindingHandle != NULL){ NDIS_STATUS LocalStatus; NdisResetEvent(&pAdapt->Event); NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle); pAdapt->BindingHandle = NULL; if (LocalStatus == NDIS_STATUS_PENDING){ NdisWaitEvent(&pAdapt->Event, 0); LocalStatus = pAdapt->Status; } } natFreeAllItems(&pAdapt->ctrl); natFreeAllFwSessionsAndRules(&pAdapt->ctrl); for(i = 0;i<FLT_FW_SESSION_HASH_TBL_SZ;i++) NdisFreeSpinLock(pAdapt->ctrl.FwSessionLocks + i); NdisFreeSpinLock(&pAdapt->ctrl.IcmpRuleLock); NdisFreeSpinLock(&pAdapt->ctrl.UdpRuleLock); NdisFreeSpinLock(&pAdapt->ctrl.TcpRuleLock); natmFreeAllPacketPools(pAdapt); NdisFreeSpinLock(&pAdapt->Lock); NdisFreeMemory(pAdapt, 0, 0); pAdapt = NULL; } } }
/****************************************************************************** * * Name: AllocateRxQ() * * Description: Allocate Rx Buffer * * Arguments: PMRVDRV_ADAPTER Adapter * * Return Value: NDIS_STATUS_SUCCESS or NDIS_STATUS_FAILURE * * Notes: * *****************************************************************************/ NDIS_STATUS AllocateRxQ( IN PMRVDRV_ADAPTER Adapter ) { ULONG i; NDIS_STATUS tStatus; BOOLEAN bSuccess = TRUE; PACKET_QUEUE_NODE **pNode; PNDIS_PACKET_OOB_DATA pOOB; /// Initialize rx-related variables Adapter->RxBufferPoolHandle = Adapter->RxPacketPoolHandle = NULL; // InitializeQKeeper(&Adapter->RxPacketFreeQueue); // for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ ) { Adapter->pRxBufVM[i] = NULL; Adapter->pRxBuffer[i] = NULL; Adapter->pRxPacket[i] = NULL; } /// Allocate all needed memory space do { // packet pool NdisAllocatePacketPoolEx( &tStatus, &Adapter->RxPacketPoolHandle, MRVDRV_NUM_RX_PKT_IN_QUEUE, MRVDRV_NUM_RX_PKT_IN_QUEUE, PROTOCOL_RESERVED_SIZE_IN_PACKET); if ( tStatus != NDIS_STATUS_SUCCESS ) { DBGPRINT(DBG_LOAD | DBG_ERROR, (L"Unable to allocate packet pool!\n")); return tStatus; } // buffer pool NdisAllocateBufferPool( &tStatus, &Adapter->RxBufferPoolHandle, MRVDRV_NUM_RX_PKT_IN_QUEUE); if ( tStatus != NDIS_STATUS_SUCCESS ) { DBGPRINT(DBG_LOAD | DBG_ERROR, (L"Unable to allocate buffer pool!\n")); bSuccess = FALSE; break; } // assign space to used three array for ( i=0; i < MRVDRV_NUM_RX_PKT_IN_QUEUE; i++ ) { // data payload space array tStatus = NdisAllocateMemoryWithTag( &Adapter->pRxBufVM[i], MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, MRVDRV_MEMORY_TAG); //to hide unused packet header ahead of pointer. //(ULONG)Adapter->pRxBufVM[i] += (sizeof(RxPD)+sizeof(pkt.Len)+sizeof(pkt.Type)); (ULONG)Adapter->pRxBufVM[i] += MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE; if ( tStatus != NDIS_STATUS_SUCCESS ) { bSuccess = FALSE; break; } // buffer array NdisAllocateBuffer( &tStatus, &Adapter->pRxBuffer[i], Adapter->RxBufferPoolHandle, Adapter->pRxBufVM[i], (MRVDRV_ETH_RX_PACKET_BUFFER_SIZE-MRVDRV_ETH_RX_HIDDEN_HEADER_SIZE)); if ( tStatus != NDIS_STATUS_SUCCESS ) { bSuccess = FALSE; break; } // packet array NdisAllocatePacket( &tStatus, &Adapter->pRxPacket[i], Adapter->RxPacketPoolHandle); if ( tStatus != NDIS_STATUS_SUCCESS ) { bSuccess = FALSE; break; } // init OBB space pOOB = NDIS_OOB_DATA_FROM_PACKET(Adapter->pRxPacket[i]); NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA)); NDIS_SET_PACKET_HEADER_SIZE(Adapter->pRxPacket[i], MRVDRV_ETH_HEADER_SIZE); // chain the packet and buffer NdisChainBufferAtFront(Adapter->pRxPacket[i], Adapter->pRxBuffer[i]); // fill packet node Adapter->RxPacketQueueNode[i].pPacket = Adapter->pRxPacket[i]; pNode = (PACKET_QUEUE_NODE **)Adapter->pRxPacket[i]->MiniportReserved; *pNode = &Adapter->RxPacketQueueNode[i]; // insert to free queue InsertQNodeAtTail(&Adapter->RxPacketFreeQueue, &Adapter->RxPacketQueueNode[i]); } // end of for(;;) } while (0); if ( ! bSuccess ) { // clean up all FreeRxQ(Adapter); return NDIS_STATUS_FAILURE; } Adapter->sNumOutstandingRxPacket = 0; return NDIS_STATUS_SUCCESS; }
VOID PtBindAdapter( OUT PNDIS_STATUS Status, IN NDIS_HANDLE BindContext, IN PNDIS_STRING DeviceName, IN PVOID SystemSpecific1, IN PVOID SystemSpecific2 ) /*++ Routine Description: Called by NDIS to bind to a miniport below. Arguments: Status - Return status of bind here. BindContext - Can be passed to NdisCompleteBindAdapter if this call is pended. DeviceName - Device name to bind to. This is passed to NdisOpenAdapter. SystemSpecific1 - Can be passed to NdisOpenProtocolConfiguration to read per-binding information SystemSpecific2 - Unused Return Value: NDIS_STATUS_PENDING if this call is pended. In this case call NdisCompleteBindAdapter to complete. Anything else Completes this call synchronously --*/ { NDIS_HANDLE ConfigHandle = NULL; PNDIS_CONFIGURATION_PARAMETER Param; NDIS_STRING DeviceStr = NDIS_STRING_CONST("UpperBindings"); PADAPT pAdapt = NULL; NDIS_STATUS Sts; UINT MediumIndex; ULONG TotalSize; PNDIS_CONFIGURATION_PARAMETER BundleParam; NDIS_STRING BundleStr = NDIS_STRING_CONST("BundleId"); NDIS_STATUS BundleStatus; DBGPRINT(("==> Protocol BindAdapter\n")); do { // // Access the configuration section for our binding-specific // parameters. // NdisOpenProtocolConfiguration(Status, &ConfigHandle, SystemSpecific1); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Read the "UpperBindings" reserved key that contains a list // of device names representing our miniport instances corresponding // to this lower binding. Since this is a 1:1 IM driver, this key // contains exactly one name. // // If we want to implement a N:1 mux driver (N adapter instances // over a single lower binding), then UpperBindings will be a // MULTI_SZ containing a list of device names - we would loop through // this list, calling NdisIMInitializeDeviceInstanceEx once for // each name in it. // NdisReadConfiguration(Status, &Param, ConfigHandle, &DeviceStr, NdisParameterString); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Allocate memory for the Adapter structure. This represents both the // protocol context as well as the adapter structure when the miniport // is initialized. // // In addition to the base structure, allocate space for the device // instance string. // TotalSize = sizeof(ADAPT) + Param->ParameterData.StringData.MaximumLength; NdisAllocateMemoryWithTag(&pAdapt, TotalSize, TAG); if (pAdapt == NULL) { *Status = NDIS_STATUS_RESOURCES; break; } // // Initialize the adapter structure. We copy in the IM device // name as well, because we may need to use it in a call to // NdisIMCancelInitializeDeviceInstance. The string returned // by NdisReadConfiguration is active (i.e. available) only // for the duration of this call to our BindAdapter handler. // NdisZeroMemory(pAdapt, TotalSize); pAdapt->DeviceName.MaximumLength = Param->ParameterData.StringData.MaximumLength; pAdapt->DeviceName.Length = Param->ParameterData.StringData.Length; pAdapt->DeviceName.Buffer = (PWCHAR)((ULONG_PTR)pAdapt + sizeof(ADAPT)); NdisMoveMemory(pAdapt->DeviceName.Buffer, Param->ParameterData.StringData.Buffer, Param->ParameterData.StringData.MaximumLength); NdisInitializeEvent(&pAdapt->Event); // // Allocate a packet pool for sends. We need this to pass sends down. // We cannot use the same packet descriptor that came down to our send // handler (see also NDIS 5.1 packet stacking). // NdisAllocatePacketPoolEx(Status, &pAdapt->SendPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, sizeof(SEND_RSVD)); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Allocate a packet pool for receives. We need this to indicate receives. // Same consideration as sends (see also NDIS 5.1 packet stacking). // NdisAllocatePacketPoolEx(Status, &pAdapt->RecvPacketPoolHandle, MIN_PACKET_POOL_SIZE, MAX_PACKET_POOL_SIZE - MIN_PACKET_POOL_SIZE, PROTOCOL_RESERVED_SIZE_IN_PACKET); if (*Status != NDIS_STATUS_SUCCESS) { break; } // // Now open the adapter below and complete the initialization // NdisOpenAdapter(Status, &Sts, &pAdapt->BindingHandle, &MediumIndex, MediumArray, sizeof(MediumArray)/sizeof(NDIS_MEDIUM), ProtHandle, pAdapt, DeviceName, 0, NULL); if (*Status == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); *Status = pAdapt->Status; } if (*Status != NDIS_STATUS_SUCCESS) { break; } pAdapt->Medium = MediumArray[MediumIndex]; // // Now ask NDIS to initialize our miniport (upper) edge. // Set the flag below to synchronize with a possible call // to our protocol Unbind handler that may come in before // our miniport initialization happens. // pAdapt->MiniportInitPending = TRUE; NdisInitializeEvent(&pAdapt->MiniportInitEvent); *Status = NdisIMInitializeDeviceInstanceEx(DriverHandle, &pAdapt->DeviceName, pAdapt); if (*Status != NDIS_STATUS_SUCCESS) { DBGPRINT(("BindAdapter: Adapt %p, IMInitializeDeviceInstance error %x\n", pAdapt, *Status)); break; } } while(FALSE); // // Close the configuration handle now - see comments above with // the call to NdisIMInitializeDeviceInstanceEx. // if (ConfigHandle != NULL) { NdisCloseConfiguration(ConfigHandle); } if (*Status != NDIS_STATUS_SUCCESS) { if (pAdapt != NULL) { if (pAdapt->BindingHandle != NULL) { NDIS_STATUS LocalStatus; // // Close the binding we opened above. // NdisCloseAdapter(&LocalStatus, pAdapt->BindingHandle); pAdapt->BindingHandle = NULL; if (LocalStatus == NDIS_STATUS_PENDING) { NdisWaitEvent(&pAdapt->Event, 0); LocalStatus = pAdapt->Status; } } if (pAdapt->SendPacketPoolHandle != NULL) { NdisFreePacketPool(pAdapt->SendPacketPoolHandle); } if (pAdapt->RecvPacketPoolHandle != NULL) { NdisFreePacketPool(pAdapt->RecvPacketPoolHandle); } NdisFreeMemory(pAdapt, sizeof(ADAPT), 0); pAdapt = NULL; } } DBGPRINT(("<== Protocol BindAdapter: pAdapt %p, Status %x\n", pAdapt, *Status)); }
NTSTATUS NTAPI TiDispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp) /* * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests * ARGUMENTS: * DeviceObject = Pointer to a device object for this driver * Irp = Pointer to a I/O request packet * RETURNS: * Status of the operation */ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp)); DbgPrint("TiDispatch Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp); Irp->IoStatus.Information = 0; #if 0 Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp); if (NT_SUCCESS(Status)) { TiDispatchInternal(DeviceObject, Irp); Status = STATUS_PENDING; } else { #else if (TRUE) { #endif /* See if this request is TCP/IP specific */ switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_TCP_QUERY_INFORMATION_EX: TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n")); Status = DispTdiQueryInformationEx(Irp, IrpSp); break; case IOCTL_TCP_SET_INFORMATION_EX: TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n")); Status = DispTdiSetInformationEx(Irp, IrpSp); break; case IOCTL_SET_IP_ADDRESS: TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n")); Status = DispTdiSetIPAddress(Irp, IrpSp); break; case IOCTL_DELETE_IP_ADDRESS: TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n")); Status = DispTdiDeleteIPAddress(Irp, IrpSp); break; default: TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n", IrpSp->Parameters.DeviceIoControl.IoControlCode)); Status = STATUS_NOT_IMPLEMENTED; break; } } TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status)); return IRPFinish( Irp, Status ); } NTSTATUS DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { NTSTATUS Status; UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME); UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME); UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME); UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME); UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME); NDIS_STATUS NdisStatus; LARGE_INTEGER DueTime; TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] \n")); //_asm int 3; KdPrint(("driver entery..................\n")); /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ /* Initialize our periodic timer and its associated DPC object. When the timer expires, the IPTimeout deferred procedure call (DPC) is queued */ KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); KeInitializeTimer(&IPTimer); /* Create IP device object */ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } ChewInit( IPDeviceObject ); /* Create RawIP device object */ Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Create UDP device object */ Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Create TCP device object */ Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Setup network layer and transport layer entities */ KeInitializeSpinLock(&EntityListLock); EntityList = ExAllocatePoolWithTag(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES, TDI_ENTITY_TAG ); if (!EntityList) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } EntityCount = 0; EntityMax = MAX_TDI_ENTITIES; /* Allocate NDIS packet descriptors */ NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate NDIS buffer descriptors */ NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000); if (NdisStatus != NDIS_STATUS_SUCCESS) { TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } /* Initialize address file list and protecting spin lock */ InitializeListHead(&AddressFileListHead); KeInitializeSpinLock(&AddressFileListLock); /* Initialize connection endpoint list and protecting spin lock */ InitializeListHead(&ConnectionEndpointListHead); KeInitializeSpinLock(&ConnectionEndpointListLock); /* Initialize interface list and protecting spin lock */ InitializeListHead(&InterfaceListHead); KeInitializeSpinLock(&InterfaceListLock); /* Initialize network level protocol subsystem */ IPStartup(RegistryPath); /* Initialize transport level protocol subsystems */ Status = RawIPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = UDPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = ICMPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } /* Use direct I/O */ IPDeviceObject->Flags |= DO_DIRECT_IO; RawIPDeviceObject->Flags |= DO_DIRECT_IO; UDPDeviceObject->Flags |= DO_DIRECT_IO; TCPDeviceObject->Flags |= DO_DIRECT_IO; /* Initialize the driver object with this driver's entry points */ DriverObject->MajorFunction[IRP_MJ_CREATE] = TiDispatchOpenClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = TiDispatchOpenClose; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch; DriverObject->DriverUnload = TiUnload; /* Open loopback adapter */ Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Register protocol with NDIS */ /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */ Status = LANRegisterProtocol(&strNdisDeviceName); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status)); TiWriteErrorLog( DriverObject, EVENT_TRANSPORT_REGISTER_FAILED, TI_ERROR_DRIVERENTRY, Status, NULL, 0, NULL); TiUnload(DriverObject); return Status; } /* Start the periodic timer with an initial and periodic relative expiration time of IP_TIMEOUT milliseconds */ DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n")); return STATUS_SUCCESS; }
NTSTATUS NTAPI DriverEntry( PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) /* * FUNCTION: Main driver entry point * ARGUMENTS: * DriverObject = Pointer to a driver object for this driver * RegistryPath = Registry node for configuration parameters * RETURNS: * Status of driver initialization */ { NTSTATUS Status; UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME); UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME); UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME); UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME); UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME); NDIS_STATUS NdisStatus; LARGE_INTEGER DueTime; TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n")); /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ /* Initialize our periodic timer and its associated DPC object. When the timer expires, the IPTimeout deferred procedure call (DPC) is queued */ KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); KeInitializeTimer(&IPTimer); /* Create IP device object */ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } ChewInit( IPDeviceObject ); /* Create RawIP device object */ Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Create UDP device object */ Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Create TCP device object */ Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Setup network layer and transport layer entities */ KeInitializeSpinLock(&EntityListLock); EntityList = ExAllocatePoolWithTag(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES, TDI_ENTITY_TAG ); if (!EntityList) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } EntityCount = 0; EntityMax = MAX_TDI_ENTITIES; /* Allocate NDIS packet descriptors */ NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate NDIS buffer descriptors */ NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000); if (NdisStatus != NDIS_STATUS_SUCCESS) { TiUnload(DriverObject); return STATUS_INSUFFICIENT_RESOURCES; } /* Initialize address file list and protecting spin lock */ InitializeListHead(&AddressFileListHead); KeInitializeSpinLock(&AddressFileListLock); /* Initialize connection endpoint list and protecting spin lock */ InitializeListHead(&ConnectionEndpointListHead); KeInitializeSpinLock(&ConnectionEndpointListLock); /* Initialize interface list and protecting spin lock */ InitializeListHead(&InterfaceListHead); KeInitializeSpinLock(&InterfaceListLock); /* Initialize network level protocol subsystem */ IPStartup(RegistryPath); /* Initialize transport level protocol subsystems */ Status = RawIPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = UDPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } Status = ICMPStartup(); if( !NT_SUCCESS(Status) ) { TiUnload(DriverObject); return Status; } /* Use direct I/O */ IPDeviceObject->Flags |= DO_DIRECT_IO; RawIPDeviceObject->Flags |= DO_DIRECT_IO; UDPDeviceObject->Flags |= DO_DIRECT_IO; TCPDeviceObject->Flags |= DO_DIRECT_IO; /* Initialize the driver object with this driver's entry points */ DriverObject->MajorFunction[IRP_MJ_CREATE] = TiDispatchOpenClose; DriverObject->MajorFunction[IRP_MJ_CLOSE] = TiDispatchOpenClose; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch; DriverObject->DriverUnload = TiUnload; /* Open loopback adapter */ Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); TiUnload(DriverObject); return Status; } /* Register protocol with NDIS */ /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */ Status = LANRegisterProtocol(&strNdisDeviceName); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status)); TiWriteErrorLog( DriverObject, EVENT_TRANSPORT_REGISTER_FAILED, TI_ERROR_DRIVERENTRY, Status, NULL, 0, NULL); TiUnload(DriverObject); return Status; } /* Start the periodic timer with an initial and periodic relative expiration time of IP_TIMEOUT milliseconds */ DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n")); return STATUS_SUCCESS; }