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; }