2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
5 * PURPOSE: Driver entry point
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
20 DWORD DebugTraceLevel
= MID_TRACE
;
23 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
24 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
25 PDEVICE_OBJECT IPDeviceObject
= NULL
;
26 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
27 NDIS_HANDLE GlobalPacketPool
= NULL
;
28 NDIS_HANDLE GlobalBufferPool
= NULL
;
29 TDIEntityID
*EntityList
= NULL
;
30 ULONG EntityCount
= 0;
31 UDP_STATISTICS UDPStats
;
35 PDRIVER_OBJECT DriverContext
,
37 ULONG UniqueErrorValue
,
43 * FUNCTION: Writes an error log entry
45 * DriverContext = Pointer to the driver or device object
46 * ErrorCode = An error code to put in the log entry
47 * UniqueErrorValue = UniqueErrorValue in the error log packet
48 * FinalStatus = FinalStatus in the error log packet
49 * String = If not NULL, a pointer to a string to put in log entry
50 * DumpDataCount = Number of ULONGs of dump data
51 * DumpData = Pointer to dump data for the log entry
55 PIO_ERROR_LOG_PACKET LogEntry
;
59 static WCHAR DriverName
[] = L
"TCP/IP";
61 EntrySize
= sizeof(IO_ERROR_LOG_PACKET
) +
62 (DumpDataCount
* sizeof(ULONG
)) + sizeof(DriverName
);
65 StringSize
= (wcslen(String
) * sizeof(WCHAR
)) + sizeof(UNICODE_NULL
);
66 EntrySize
+= (UCHAR
)StringSize
;
69 LogEntry
= (PIO_ERROR_LOG_PACKET
)IoAllocateErrorLogEntry(
70 DriverContext
, EntrySize
);
73 LogEntry
->MajorFunctionCode
= -1;
74 LogEntry
->RetryCount
= -1;
75 LogEntry
->DumpDataSize
= (USHORT
)(DumpDataCount
* sizeof(ULONG
));
76 LogEntry
->NumberOfStrings
= (String
== NULL
) ? 1 : 2;
77 LogEntry
->StringOffset
= sizeof(IO_ERROR_LOG_PACKET
) + (DumpDataCount
-1) * sizeof(ULONG
);
78 LogEntry
->EventCategory
= 0;
79 LogEntry
->ErrorCode
= ErrorCode
;
80 LogEntry
->UniqueErrorValue
= UniqueErrorValue
;
81 LogEntry
->FinalStatus
= FinalStatus
;
82 LogEntry
->SequenceNumber
= -1;
83 LogEntry
->IoControlCode
= 0;
86 RtlCopyMemory(LogEntry
->DumpData
, DumpData
, DumpDataCount
* sizeof(ULONG
));
88 pString
= ((PUCHAR
)LogEntry
) + LogEntry
->StringOffset
;
89 RtlCopyMemory(pString
, DriverName
, sizeof(DriverName
));
90 pString
+= sizeof(DriverName
);
93 RtlCopyMemory(pString
, String
, StringSize
);
95 IoWriteErrorLogEntry(LogEntry
);
101 NTSTATUS
TiGetProtocolNumber(
102 PUNICODE_STRING FileName
,
105 * FUNCTION: Returns the protocol number from a file name
107 * FileName = Pointer to string with file name
108 * Protocol = Pointer to buffer to put protocol number in
110 * Status of operation
118 TI_DbgPrint(MAX_TRACE
, ("Called. FileName (%wZ).\n", FileName
));
120 Name
= FileName
->Buffer
;
122 if (*Name
++ != (WCHAR
)L
'\\')
123 return STATUS_UNSUCCESSFUL
;
125 if (*Name
== (WCHAR
)NULL
)
126 return STATUS_UNSUCCESSFUL
;
128 RtlInitUnicodeString(&us
, Name
);
130 Status
= RtlUnicodeStringToInteger(&us
, 10, &Value
);
131 if (!NT_SUCCESS(Status
) || ((Value
> 255)))
132 return STATUS_UNSUCCESSFUL
;
136 return STATUS_SUCCESS
;
141 * FUNCTION: Creates a file object
143 * DeviceObject = Pointer to a device object for this driver
144 * Irp = Pointer to a I/O request packet
146 * Status of the operation
148 NTSTATUS
TiCreateFileObject(
149 PDEVICE_OBJECT DeviceObject
,
152 PFILE_FULL_EA_INFORMATION EaInfo
;
153 PTRANSPORT_CONTEXT Context
;
154 PIO_STACK_LOCATION IrpSp
;
155 PTA_ADDRESS_IP Address
;
161 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
163 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
165 /* Parameter check */
167 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
168 return STATUS_INVALID_PARAMETER
;
171 /* Allocate resources here. We release them again if something failed */
172 Context
= ExAllocatePool(NonPagedPool
, sizeof(TRANSPORT_CONTEXT
));
174 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
175 return STATUS_INSUFFICIENT_RESOURCES
;
178 Context
->RefCount
= 1;
179 Context
->CancelIrps
= FALSE
;
180 KeInitializeEvent(&Context
->CleanupEvent
, NotificationEvent
, FALSE
);
182 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
183 IrpSp
->FileObject
->FsContext
= Context
;
184 Request
.RequestContext
= Irp
;
186 /* Branch to the right handler */
187 if ((EaInfo
->EaNameLength
== TDI_TRANSPORT_ADDRESS_LENGTH
) &&
188 (RtlCompareMemory(&EaInfo
->EaName
, TdiTransportAddress
,
189 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
190 /* This is a request to open an address */
192 /* Parameter checks */
193 Address
= (PTA_ADDRESS_IP
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
);
194 if ((EaInfo
->EaValueLength
< sizeof(TA_ADDRESS_IP
)) ||
195 (Address
->TAAddressCount
!= 1) ||
196 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
197 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
198 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
200 return STATUS_INVALID_PARAMETER
;
203 /* Open address file object */
205 /* Protocol depends on device object so find the protocol */
206 if (DeviceObject
== TCPDeviceObject
)
207 Protocol
= IPPROTO_TCP
;
208 else if (DeviceObject
== UDPDeviceObject
)
209 Protocol
= IPPROTO_UDP
;
210 else if (DeviceObject
== IPDeviceObject
)
211 Protocol
= IPPROTO_RAW
;
212 else if (DeviceObject
== RawIPDeviceObject
) {
213 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
214 if (!NT_SUCCESS(Status
)) {
215 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
217 return STATUS_INVALID_PARAMETER
;
220 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
222 return STATUS_INVALID_PARAMETER
;
225 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
226 if (NT_SUCCESS(Status
)) {
227 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
228 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
231 } else if ((EaInfo
->EaNameLength
== TDI_CONNECTION_CONTEXT_LENGTH
) &&
232 (RtlCompareMemory(&EaInfo
->EaName
, TdiConnectionContext
,
233 TDI_CONNECTION_CONTEXT_LENGTH
) == TDI_CONNECTION_CONTEXT_LENGTH
)) {
234 /* This is a request to open a connection endpoint */
236 /* Parameter checks */
238 if (EaInfo
->EaValueLength
< sizeof(PVOID
)) {
239 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
241 return STATUS_INVALID_PARAMETER
;
244 /* Can only do connection oriented communication using TCP */
246 if (DeviceObject
!= TCPDeviceObject
) {
247 TI_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
249 return STATUS_INVALID_PARAMETER
;
252 ClientContext
= *((PVOID
*)(EaInfo
->EaName
+ EaInfo
->EaNameLength
));
254 /* Open connection endpoint file object */
256 Status
= FileOpenConnection(&Request
, ClientContext
);
257 if (NT_SUCCESS(Status
)) {
258 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONNECTION_FILE
;
259 Context
->Handle
.ConnectionContext
= Request
.Handle
.ConnectionContext
;
262 /* This is a request to open a control connection */
264 TI_DbgPrint(MIN_TRACE
, ("Control connections are not implemented yet\n"));
266 Status
= STATUS_NOT_IMPLEMENTED
;
269 if (!NT_SUCCESS(Status
))
272 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
278 VOID
TiCleanupFileObjectComplete(
282 * FUNCTION: Completes an object cleanup IRP I/O request
284 * Context = Pointer to the IRP for this request
285 * Status = Final status of the operation
289 PIO_STACK_LOCATION IrpSp
;
290 PTRANSPORT_CONTEXT TranContext
;
294 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
295 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
297 Irp
->IoStatus
.Status
= Status
;
299 IoAcquireCancelSpinLock(&OldIrql
);
301 /* Remove the initial reference provided at object creation time */
302 TranContext
->RefCount
--;
305 if (TranContext
->RefCount
!= 0)
306 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
309 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
311 IoReleaseCancelSpinLock(OldIrql
);
316 * FUNCTION: Releases resources used by a file object
318 * DeviceObject = Pointer to a device object for this driver
319 * Irp = Pointer to a I/O request packet
321 * Status of the operation
323 * This function does not pend
325 NTSTATUS
TiCleanupFileObject(
326 PDEVICE_OBJECT DeviceObject
,
329 PIO_STACK_LOCATION IrpSp
;
330 PTRANSPORT_CONTEXT Context
;
335 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
336 Context
= IrpSp
->FileObject
->FsContext
;
338 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
339 return STATUS_INVALID_PARAMETER
;
342 IoAcquireCancelSpinLock(&OldIrql
);
344 Context
->CancelIrps
= TRUE
;
345 KeResetEvent(&Context
->CleanupEvent
);
347 IoReleaseCancelSpinLock(OldIrql
);
349 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
350 Request
.RequestContext
= Irp
;
352 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
353 case TDI_TRANSPORT_ADDRESS_FILE
:
354 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
355 Status
= FileCloseAddress(&Request
);
358 case TDI_CONNECTION_FILE
:
359 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
360 Status
= FileCloseConnection(&Request
);
363 case TDI_CONTROL_CHANNEL_FILE
:
364 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
365 Status
= FileCloseControlChannel(&Request
);
369 /* This should never happen */
371 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
373 IoAcquireCancelSpinLock(&OldIrql
);
374 Context
->CancelIrps
= FALSE
;
375 IoReleaseCancelSpinLock(OldIrql
);
377 return STATUS_INVALID_PARAMETER
;
380 if (Status
!= STATUS_PENDING
)
381 TiCleanupFileObjectComplete(Irp
, Status
);
383 KeWaitForSingleObject(&Context
->CleanupEvent
,
384 UserRequest
, KernelMode
, FALSE
, NULL
);
386 return Irp
->IoStatus
.Status
;
395 IN PDEVICE_OBJECT DeviceObject
,
398 * FUNCTION: Main dispath routine
400 * DeviceObject = Pointer to a device object for this driver
401 * Irp = Pointer to a I/O request packet
403 * Status of the operation
406 PIO_STACK_LOCATION IrpSp
;
408 PTRANSPORT_CONTEXT Context
;
410 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
412 IoMarkIrpPending(Irp
);
413 Irp
->IoStatus
.Status
= STATUS_PENDING
;
414 Irp
->IoStatus
.Information
= 0;
416 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
418 switch (IrpSp
->MajorFunction
) {
419 /* Open an address file, connection endpoint, or control connection */
421 Status
= TiCreateFileObject(DeviceObject
, Irp
);
424 /* Close an address file, connection endpoint, or control connection */
426 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
429 Status
= STATUS_SUCCESS
;
432 /* Release resources bound to an address file, connection endpoint,
433 or control connection */
435 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
439 Status
= STATUS_INVALID_DEVICE_REQUEST
;
442 if (Status
!= STATUS_PENDING
) {
443 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
444 Irp
->IoStatus
.Status
= Status
;
446 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
448 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
451 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
462 PDEVICE_OBJECT DeviceObject
,
465 * FUNCTION: Internal IOCTL dispatch routine
467 * DeviceObject = Pointer to a device object for this driver
468 * Irp = Pointer to a I/O request packet
470 * Status of the operation
474 PIO_STACK_LOCATION IrpSp
;
476 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
478 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
479 DeviceObject
, Irp
, IrpSp
->MinorFunction
));
481 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
482 Irp
->IoStatus
.Information
= 0;
484 switch (IrpSp
->MinorFunction
) {
486 Status
= DispTdiReceive(Irp
);
489 case TDI_RECEIVE_DATAGRAM
:
490 Status
= DispTdiReceiveDatagram(Irp
);
494 Status
= DispTdiSend(Irp
);
497 case TDI_SEND_DATAGRAM
:
498 Status
= DispTdiSendDatagram(Irp
);
502 Status
= DispTdiAccept(Irp
);
506 Status
= DispTdiListen(Irp
);
510 Status
= DispTdiConnect(Irp
);
514 Status
= DispTdiDisconnect(Irp
);
517 case TDI_ASSOCIATE_ADDRESS
:
518 Status
= DispTdiAssociateAddress(Irp
);
521 case TDI_DISASSOCIATE_ADDRESS
:
522 Status
= DispTdiDisassociateAddress(Irp
);
525 case TDI_QUERY_INFORMATION
:
526 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
529 case TDI_SET_INFORMATION
:
530 Status
= DispTdiSetInformation(Irp
);
533 case TDI_SET_EVENT_HANDLER
:
534 Status
= DispTdiSetEventHandler(Irp
);
538 Status
= STATUS_SUCCESS
;
541 /* An unsupported IOCTL code was submitted */
543 Status
= STATUS_INVALID_DEVICE_REQUEST
;
546 if (Status
!= STATUS_PENDING
) {
547 Irp
->IoStatus
.Status
= Status
;
549 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
551 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
554 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
565 PDEVICE_OBJECT DeviceObject
,
568 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
570 * DeviceObject = Pointer to a device object for this driver
571 * Irp = Pointer to a I/O request packet
573 * Status of the operation
577 PIO_STACK_LOCATION IrpSp
;
579 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
581 Irp
->IoStatus
.Information
= 0;
583 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
585 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
586 if (NT_SUCCESS(Status
)) {
587 TiDispatchInternal(DeviceObject
, Irp
);
588 Status
= STATUS_PENDING
;
593 /* See if this request is TCP/IP specific */
594 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
595 case IOCTL_TCP_QUERY_INFORMATION_EX
:
596 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
599 case IOCTL_TCP_SET_INFORMATION_EX
:
600 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
604 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
605 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
606 Status
= STATUS_NOT_IMPLEMENTED
;
611 if (Status
!= STATUS_PENDING
) {
612 Irp
->IoStatus
.Status
= Status
;
614 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
616 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
619 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
626 PDRIVER_OBJECT DriverObject
)
628 * FUNCTION: Unloads the driver
630 * DriverObject = Pointer to driver object created by the system
636 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
637 if (!IsListEmpty(&AddressFileListHead
)) {
638 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
640 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
643 /* Unregister loopback adapter */
644 LoopUnregisterAdapter(NULL
);
646 /* Unregister protocol with NDIS */
647 LANUnregisterProtocol();
649 /* Shutdown transport level protocol subsystems */
655 /* Shutdown network level protocol subsystem */
658 /* Free NDIS buffer descriptors */
659 if (GlobalBufferPool
)
660 NdisFreeBufferPool(GlobalBufferPool
);
662 /* Free NDIS packet descriptors */
663 if (GlobalPacketPool
)
664 NdisFreePacketPool(GlobalPacketPool
);
666 /* Release all device objects */
669 IoDeleteDevice(TCPDeviceObject
);
672 IoDeleteDevice(UDPDeviceObject
);
674 if (RawIPDeviceObject
)
675 IoDeleteDevice(RawIPDeviceObject
);
678 IoDeleteDevice(IPDeviceObject
);
681 ExFreePool(EntityList
);
683 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
692 PDRIVER_OBJECT DriverObject
,
693 PUNICODE_STRING RegistryPath
)
695 * FUNCTION: Main driver entry point
697 * DriverObject = Pointer to a driver object for this driver
698 * RegistryPath = Registry node for configuration parameters
700 * Status of driver initialization
704 UNICODE_STRING strDeviceName
;
705 UNICODE_STRING strNdisDeviceName
;
706 NDIS_STATUS NdisStatus
;
707 NDIS_STRING DeviceName
;
709 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
711 /* TdiInitialize() ? */
713 /* FIXME: Create symbolic links in Win32 namespace */
715 /* Create IP device object */
716 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_IP_DEVICE_NAME
);
717 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
718 FILE_DEVICE_NETWORK
, 0, FALSE
, &IPDeviceObject
);
719 if (!NT_SUCCESS(Status
)) {
720 TI_DbgPrint(MIN_TRACE
, ("Failed to create IP device object. Status (0x%X).\n", Status
));
724 /* Create RawIP device object */
725 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_RAWIP_DEVICE_NAME
);
726 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
727 FILE_DEVICE_NETWORK
, 0, FALSE
, &RawIPDeviceObject
);
728 if (!NT_SUCCESS(Status
)) {
729 TI_DbgPrint(MIN_TRACE
, ("Failed to create RawIP device object. Status (0x%X).\n", Status
));
730 TiUnload(DriverObject
);
734 /* Create UDP device object */
735 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_UDP_DEVICE_NAME
);
736 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
737 FILE_DEVICE_NETWORK
, 0, FALSE
, &UDPDeviceObject
);
738 if (!NT_SUCCESS(Status
)) {
739 TI_DbgPrint(MIN_TRACE
, ("Failed to create UDP device object. Status (0x%X).\n", Status
));
740 TiUnload(DriverObject
);
744 /* Create TCP device object */
745 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_TCP_DEVICE_NAME
);
746 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
747 FILE_DEVICE_NETWORK
, 0, FALSE
, &TCPDeviceObject
);
748 if (!NT_SUCCESS(Status
)) {
749 TI_DbgPrint(MIN_TRACE
, ("Failed to create TCP device object. Status (0x%X).\n", Status
));
750 TiUnload(DriverObject
);
754 /* Allocate NDIS packet descriptors */
755 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
756 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
757 TiUnload(DriverObject
);
758 return STATUS_INSUFFICIENT_RESOURCES
;
761 /* Allocate NDIS buffer descriptors */
762 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
763 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
764 TiUnload(DriverObject
);
765 return STATUS_INSUFFICIENT_RESOURCES
;
768 /* Initialize address file list and protecting spin lock */
769 InitializeListHead(&AddressFileListHead
);
770 KeInitializeSpinLock(&AddressFileListLock
);
772 /* Initialize connection endpoint list and protecting spin lock */
773 InitializeListHead(&ConnectionEndpointListHead
);
774 KeInitializeSpinLock(&ConnectionEndpointListLock
);
776 /* Initialize interface list and protecting spin lock */
777 InitializeListHead(&InterfaceListHead
);
778 KeInitializeSpinLock(&InterfaceListLock
);
780 /* Initialize network level protocol subsystem */
781 IPStartup(DriverObject
, RegistryPath
);
783 /* Initialize transport level protocol subsystems */
789 /* Register protocol with NDIS */
790 /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
791 RtlInitUnicodeString(&strNdisDeviceName
, TCPIP_PROTOCOL_NAME
);
792 Status
= LANRegisterProtocol(&strNdisDeviceName
);
793 if (!NT_SUCCESS(Status
)) {
794 TI_DbgPrint(MIN_TRACE
,("Failed to register protocol with NDIS; status 0x%x\n", Status
));
797 EVENT_TRANSPORT_REGISTER_FAILED
,
798 TI_ERROR_DRIVERENTRY
,
803 TiUnload(DriverObject
);
807 /* Open loopback adapter */
808 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
809 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
810 TiUnload(DriverObject
);
811 return STATUS_INSUFFICIENT_RESOURCES
;
814 /* Setup network layer and transport layer entities */
815 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * 2);
816 if (!NT_SUCCESS(Status
)) {
817 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
818 TiUnload(DriverObject
);
819 return STATUS_INSUFFICIENT_RESOURCES
;
822 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
823 EntityList
[0].tei_instance
= 0;
824 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
825 EntityList
[1].tei_instance
= 0;
829 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
830 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
831 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
832 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
834 /* Initialize the driver object with this driver's entry points */
835 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
836 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
837 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
838 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)TiDispatchInternal
;
839 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)TiDispatch
;
841 DriverObject
->DriverUnload
= (PDRIVER_UNLOAD
)TiUnload
;
843 return STATUS_SUCCESS
;