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
17 DWORD DebugTraceLevel
= 0x7fffffff;
19 DWORD DebugTraceLevel
= 0;
22 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
23 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
24 PDEVICE_OBJECT IPDeviceObject
= NULL
;
25 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
26 NDIS_HANDLE GlobalPacketPool
= NULL
;
27 NDIS_HANDLE GlobalBufferPool
= NULL
;
28 KSPIN_LOCK EntityListLock
;
29 TDIEntityInfo
*EntityList
= NULL
;
30 ULONG EntityCount
= 0;
32 UDP_STATISTICS UDPStats
;
36 PDRIVER_OBJECT DriverContext
,
38 ULONG UniqueErrorValue
,
44 * FUNCTION: Writes an error log entry
46 * DriverContext = Pointer to the driver or device object
47 * ErrorCode = An error code to put in the log entry
48 * UniqueErrorValue = UniqueErrorValue in the error log packet
49 * FinalStatus = FinalStatus in the error log packet
50 * String = If not NULL, a pointer to a string to put in log entry
51 * DumpDataCount = Number of ULONGs of dump data
52 * DumpData = Pointer to dump data for the log entry
56 PIO_ERROR_LOG_PACKET LogEntry
;
60 static WCHAR DriverName
[] = L
"TCP/IP";
62 EntrySize
= sizeof(IO_ERROR_LOG_PACKET
) +
63 (DumpDataCount
* sizeof(ULONG
)) + sizeof(DriverName
);
66 StringSize
= (wcslen(String
) * sizeof(WCHAR
)) + sizeof(UNICODE_NULL
);
67 EntrySize
+= (UCHAR
)StringSize
;
70 LogEntry
= (PIO_ERROR_LOG_PACKET
)IoAllocateErrorLogEntry(
71 DriverContext
, EntrySize
);
74 LogEntry
->MajorFunctionCode
= -1;
75 LogEntry
->RetryCount
= -1;
76 LogEntry
->DumpDataSize
= (USHORT
)(DumpDataCount
* sizeof(ULONG
));
77 LogEntry
->NumberOfStrings
= (String
== NULL
) ? 1 : 2;
78 LogEntry
->StringOffset
= sizeof(IO_ERROR_LOG_PACKET
) + (DumpDataCount
-1) * sizeof(ULONG
);
79 LogEntry
->EventCategory
= 0;
80 LogEntry
->ErrorCode
= ErrorCode
;
81 LogEntry
->UniqueErrorValue
= UniqueErrorValue
;
82 LogEntry
->FinalStatus
= FinalStatus
;
83 LogEntry
->SequenceNumber
= -1;
84 LogEntry
->IoControlCode
= 0;
87 RtlCopyMemory(LogEntry
->DumpData
, DumpData
, DumpDataCount
* sizeof(ULONG
));
89 pString
= ((PUCHAR
)LogEntry
) + LogEntry
->StringOffset
;
90 RtlCopyMemory(pString
, DriverName
, sizeof(DriverName
));
91 pString
+= sizeof(DriverName
);
94 RtlCopyMemory(pString
, String
, StringSize
);
96 IoWriteErrorLogEntry(LogEntry
);
102 NTSTATUS
TiGetProtocolNumber(
103 PUNICODE_STRING FileName
,
106 * FUNCTION: Returns the protocol number from a file name
108 * FileName = Pointer to string with file name
109 * Protocol = Pointer to buffer to put protocol number in
111 * Status of operation
119 TI_DbgPrint(MAX_TRACE
, ("Called. FileName (%wZ).\n", FileName
));
121 Name
= FileName
->Buffer
;
123 if (*Name
++ != (WCHAR
)L
'\\')
124 return STATUS_UNSUCCESSFUL
;
126 if (*Name
== (WCHAR
)NULL
)
127 return STATUS_UNSUCCESSFUL
;
129 RtlInitUnicodeString(&us
, Name
);
131 Status
= RtlUnicodeStringToInteger(&us
, 10, &Value
);
132 if (!NT_SUCCESS(Status
) || ((Value
> 255)))
133 return STATUS_UNSUCCESSFUL
;
137 return STATUS_SUCCESS
;
142 * FUNCTION: Creates a file object
144 * DeviceObject = Pointer to a device object for this driver
145 * Irp = Pointer to a I/O request packet
147 * Status of the operation
149 NTSTATUS
TiCreateFileObject(
150 PDEVICE_OBJECT DeviceObject
,
153 PFILE_FULL_EA_INFORMATION EaInfo
;
154 PTRANSPORT_CONTEXT Context
;
155 PIO_STACK_LOCATION IrpSp
;
156 PTA_IP_ADDRESS Address
;
162 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
164 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
166 /* Parameter check */
167 /* No EA information means that we're opening for SET/QUERY_INFORMATION
171 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
172 return STATUS_INVALID_PARAMETER
;
176 /* Allocate resources here. We release them again if something failed */
177 Context
= ExAllocatePool(NonPagedPool
, sizeof(TRANSPORT_CONTEXT
));
179 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
180 return STATUS_INSUFFICIENT_RESOURCES
;
183 Context
->RefCount
= 1;
184 Context
->CancelIrps
= FALSE
;
185 KeInitializeEvent(&Context
->CleanupEvent
, NotificationEvent
, FALSE
);
187 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
188 IrpSp
->FileObject
->FsContext
= Context
;
189 Request
.RequestContext
= Irp
;
191 /* Branch to the right handler */
193 (EaInfo
->EaNameLength
== TDI_TRANSPORT_ADDRESS_LENGTH
) &&
195 (&EaInfo
->EaName
, TdiTransportAddress
,
196 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
197 /* This is a request to open an address */
200 /* XXX This should probably be done in IoCreateFile() */
201 /* Parameter checks */
203 Address
= (PTA_IP_ADDRESS
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
+ 1); //0-term
205 if ((EaInfo
->EaValueLength
< sizeof(TA_IP_ADDRESS
)) ||
206 (Address
->TAAddressCount
!= 1) ||
207 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
208 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
209 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid:\n"));
210 TI_DbgPrint(MIN_TRACE
, ("AddressCount: %d\n", Address
->TAAddressCount
));
211 if( Address
->TAAddressCount
== 1 ) {
212 TI_DbgPrint(MIN_TRACE
, ("AddressLength: %\n",
213 Address
->Address
[0].AddressLength
));
214 TI_DbgPrint(MIN_TRACE
, ("AddressType: %\n",
215 Address
->Address
[0].AddressType
));
218 return STATUS_INVALID_PARAMETER
;
221 /* Open address file object */
224 /* Protocol depends on device object so find the protocol */
225 if (DeviceObject
== TCPDeviceObject
)
226 Protocol
= IPPROTO_TCP
;
227 else if (DeviceObject
== UDPDeviceObject
)
228 Protocol
= IPPROTO_UDP
;
229 else if (DeviceObject
== IPDeviceObject
)
230 Protocol
= IPPROTO_RAW
;
231 else if (DeviceObject
== RawIPDeviceObject
) {
232 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
233 if (!NT_SUCCESS(Status
)) {
234 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
236 return STATUS_INVALID_PARAMETER
;
239 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
241 return STATUS_INVALID_PARAMETER
;
244 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
245 if (NT_SUCCESS(Status
)) {
246 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
247 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
251 (EaInfo
->EaNameLength
== TDI_CONNECTION_CONTEXT_LENGTH
) &&
253 (&EaInfo
->EaName
, TdiConnectionContext
,
254 TDI_CONNECTION_CONTEXT_LENGTH
) ==
255 TDI_CONNECTION_CONTEXT_LENGTH
)) {
256 /* This is a request to open a connection endpoint */
258 /* Parameter checks */
260 if (EaInfo
->EaValueLength
< sizeof(PVOID
)) {
261 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
263 return STATUS_INVALID_PARAMETER
;
266 /* Can only do connection oriented communication using TCP */
268 if (DeviceObject
!= TCPDeviceObject
) {
269 TI_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
271 return STATUS_INVALID_PARAMETER
;
274 ClientContext
= *((PVOID
*)(EaInfo
->EaName
+ EaInfo
->EaNameLength
));
276 /* Open connection endpoint file object */
278 Status
= FileOpenConnection(&Request
, ClientContext
);
279 if (NT_SUCCESS(Status
)) {
280 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONNECTION_FILE
;
281 Context
->Handle
.ConnectionContext
= Request
.Handle
.ConnectionContext
;
284 /* This is a request to open a control connection */
285 Status
= FileOpenControlChannel(&Request
);
286 if (NT_SUCCESS(Status
)) {
287 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONTROL_CHANNEL_FILE
;
288 Context
->Handle
.ControlChannel
= Request
.Handle
.ControlChannel
;
292 if (!NT_SUCCESS(Status
))
295 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
301 VOID
TiCleanupFileObjectComplete(
305 * FUNCTION: Completes an object cleanup IRP I/O request
307 * Context = Pointer to the IRP for this request
308 * Status = Final status of the operation
312 PIO_STACK_LOCATION IrpSp
;
313 PTRANSPORT_CONTEXT TranContext
;
317 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
318 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
320 Irp
->IoStatus
.Status
= Status
;
322 IoAcquireCancelSpinLock(&OldIrql
);
324 /* Remove the initial reference provided at object creation time */
325 TranContext
->RefCount
--;
328 if (TranContext
->RefCount
!= 0)
329 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
332 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
334 IoReleaseCancelSpinLock(OldIrql
);
339 * FUNCTION: Releases resources used by a file object
341 * DeviceObject = Pointer to a device object for this driver
342 * Irp = Pointer to a I/O request packet
344 * Status of the operation
346 * This function does not pend
348 NTSTATUS
TiCleanupFileObject(
349 PDEVICE_OBJECT DeviceObject
,
352 PIO_STACK_LOCATION IrpSp
;
353 PTRANSPORT_CONTEXT Context
;
358 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
359 Context
= IrpSp
->FileObject
->FsContext
;
361 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
362 return STATUS_INVALID_PARAMETER
;
365 IoAcquireCancelSpinLock(&OldIrql
);
367 Context
->CancelIrps
= TRUE
;
368 KeResetEvent(&Context
->CleanupEvent
);
370 IoReleaseCancelSpinLock(OldIrql
);
372 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
373 Request
.RequestContext
= Irp
;
375 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
376 case TDI_TRANSPORT_ADDRESS_FILE
:
377 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
378 Status
= FileCloseAddress(&Request
);
381 case TDI_CONNECTION_FILE
:
382 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
383 Status
= FileCloseConnection(&Request
);
386 case TDI_CONTROL_CHANNEL_FILE
:
387 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
388 Status
= FileCloseControlChannel(&Request
);
392 /* This should never happen */
394 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
396 IoAcquireCancelSpinLock(&OldIrql
);
397 Context
->CancelIrps
= FALSE
;
398 IoReleaseCancelSpinLock(OldIrql
);
400 return STATUS_INVALID_PARAMETER
;
403 if (Status
!= STATUS_PENDING
)
404 TiCleanupFileObjectComplete(Irp
, Status
);
406 KeWaitForSingleObject(&Context
->CleanupEvent
,
407 UserRequest
, KernelMode
, FALSE
, NULL
);
409 return Irp
->IoStatus
.Status
;
415 IN PDEVICE_OBJECT DeviceObject
,
418 * FUNCTION: Main dispath routine
420 * DeviceObject = Pointer to a device object for this driver
421 * Irp = Pointer to a I/O request packet
423 * Status of the operation
426 PIO_STACK_LOCATION IrpSp
;
428 PTRANSPORT_CONTEXT Context
;
430 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
432 IoMarkIrpPending(Irp
);
433 Irp
->IoStatus
.Status
= STATUS_PENDING
;
434 Irp
->IoStatus
.Information
= 0;
436 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
438 switch (IrpSp
->MajorFunction
) {
439 /* Open an address file, connection endpoint, or control connection */
441 Status
= TiCreateFileObject(DeviceObject
, Irp
);
444 /* Close an address file, connection endpoint, or control connection */
446 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
449 Status
= STATUS_SUCCESS
;
452 /* Release resources bound to an address file, connection endpoint,
453 or control connection */
455 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
459 Status
= STATUS_INVALID_DEVICE_REQUEST
;
462 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
464 return IRPFinish( Irp
, Status
);
473 PDEVICE_OBJECT DeviceObject
,
476 * FUNCTION: Internal IOCTL dispatch routine
478 * DeviceObject = Pointer to a device object for this driver
479 * Irp = Pointer to a I/O request packet
481 * Status of the operation
485 BOOL Complete
= TRUE
;
486 PIO_STACK_LOCATION IrpSp
;
488 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
490 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
491 DeviceObject
, Irp
, IrpSp
->MinorFunction
));
493 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
494 Irp
->IoStatus
.Information
= 0;
496 switch (IrpSp
->MinorFunction
) {
498 Status
= DispTdiReceive(Irp
);
501 case TDI_RECEIVE_DATAGRAM
:
502 Status
= DispTdiReceiveDatagram(Irp
);
506 Status
= DispTdiSend(Irp
);
507 Complete
= FALSE
; /* Completed in DispTdiSend */
510 case TDI_SEND_DATAGRAM
:
511 Status
= DispTdiSendDatagram(Irp
);
515 Status
= DispTdiAccept(Irp
);
519 Status
= DispTdiListen(Irp
);
523 Status
= DispTdiConnect(Irp
);
527 Status
= DispTdiDisconnect(Irp
);
530 case TDI_ASSOCIATE_ADDRESS
:
531 Status
= DispTdiAssociateAddress(Irp
);
534 case TDI_DISASSOCIATE_ADDRESS
:
535 Status
= DispTdiDisassociateAddress(Irp
);
538 case TDI_QUERY_INFORMATION
:
539 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
542 case TDI_SET_INFORMATION
:
543 Status
= DispTdiSetInformation(Irp
);
546 case TDI_SET_EVENT_HANDLER
:
547 Status
= DispTdiSetEventHandler(Irp
);
551 Status
= STATUS_SUCCESS
;
554 /* An unsupported IOCTL code was submitted */
556 Status
= STATUS_INVALID_DEVICE_REQUEST
;
559 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
562 IRPFinish( Irp
, Status
);
573 PDEVICE_OBJECT DeviceObject
,
576 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
578 * DeviceObject = Pointer to a device object for this driver
579 * Irp = Pointer to a I/O request packet
581 * Status of the operation
585 PIO_STACK_LOCATION IrpSp
;
587 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
589 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
591 Irp
->IoStatus
.Information
= 0;
594 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
595 if (NT_SUCCESS(Status
)) {
596 TiDispatchInternal(DeviceObject
, Irp
);
597 Status
= STATUS_PENDING
;
602 /* See if this request is TCP/IP specific */
603 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
604 case IOCTL_TCP_QUERY_INFORMATION_EX
:
605 TI_DbgPrint(MIN_TRACE
, ("TCP_QUERY_INFORMATION_EX\n"));
606 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
609 case IOCTL_TCP_SET_INFORMATION_EX
:
610 TI_DbgPrint(MIN_TRACE
, ("TCP_SET_INFORMATION_EX\n"));
611 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
615 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
616 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
617 Status
= STATUS_NOT_IMPLEMENTED
;
622 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
624 return IRPFinish( Irp
, Status
);
628 VOID STDCALL
TiUnload(
629 PDRIVER_OBJECT DriverObject
)
631 * FUNCTION: Unloads the driver
633 * DriverObject = Pointer to driver object created by the system
639 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
640 if (!IsListEmpty(&AddressFileListHead
)) {
641 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
643 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
646 /* Unregister loopback adapter */
647 LoopUnregisterAdapter(NULL
);
649 /* Unregister protocol with NDIS */
650 LANUnregisterProtocol();
652 /* Shutdown transport level protocol subsystems */
658 /* Shutdown network level protocol subsystem */
661 /* Free NDIS buffer descriptors */
662 if (GlobalBufferPool
)
663 NdisFreeBufferPool(GlobalBufferPool
);
665 /* Free NDIS packet descriptors */
666 if (GlobalPacketPool
)
667 NdisFreePacketPool(GlobalPacketPool
);
669 /* Release all device objects */
672 IoDeleteDevice(TCPDeviceObject
);
675 IoDeleteDevice(UDPDeviceObject
);
677 if (RawIPDeviceObject
)
678 IoDeleteDevice(RawIPDeviceObject
);
681 IoDeleteDevice(IPDeviceObject
);
684 ExFreePool(EntityList
);
686 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
695 PDRIVER_OBJECT DriverObject
,
696 PUNICODE_STRING RegistryPath
)
698 * FUNCTION: Main driver entry point
700 * DriverObject = Pointer to a driver object for this driver
701 * RegistryPath = Registry node for configuration parameters
703 * Status of driver initialization
707 UNICODE_STRING strDeviceName
;
708 UNICODE_STRING strNdisDeviceName
;
709 NDIS_STATUS NdisStatus
;
710 NDIS_STRING DeviceName
;
712 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
715 TrackTag(NDIS_BUFFER_TAG
);
716 TrackTag(NDIS_PACKET_TAG
);
717 TrackTag(FBSD_MALLOC
);
718 TrackTag(EXALLOC_TAG
);
722 /* TdiInitialize() ? */
724 /* FIXME: Create symbolic links in Win32 namespace */
726 /* Create IP device object */
727 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_IP_DEVICE_NAME
);
728 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
729 FILE_DEVICE_NETWORK
, 0, FALSE
, &IPDeviceObject
);
730 if (!NT_SUCCESS(Status
)) {
731 TI_DbgPrint(MIN_TRACE
, ("Failed to create IP device object. Status (0x%X).\n", Status
));
735 /* Create RawIP device object */
736 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_RAWIP_DEVICE_NAME
);
737 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
738 FILE_DEVICE_NETWORK
, 0, FALSE
, &RawIPDeviceObject
);
739 if (!NT_SUCCESS(Status
)) {
740 TI_DbgPrint(MIN_TRACE
, ("Failed to create RawIP device object. Status (0x%X).\n", Status
));
741 TiUnload(DriverObject
);
745 /* Create UDP device object */
746 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_UDP_DEVICE_NAME
);
747 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
748 FILE_DEVICE_NETWORK
, 0, FALSE
, &UDPDeviceObject
);
749 if (!NT_SUCCESS(Status
)) {
750 TI_DbgPrint(MIN_TRACE
, ("Failed to create UDP device object. Status (0x%X).\n", Status
));
751 TiUnload(DriverObject
);
755 /* Create TCP device object */
756 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_TCP_DEVICE_NAME
);
757 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
758 FILE_DEVICE_NETWORK
, 0, FALSE
, &TCPDeviceObject
);
759 if (!NT_SUCCESS(Status
)) {
760 TI_DbgPrint(MIN_TRACE
, ("Failed to create TCP device object. Status (0x%X).\n", Status
));
761 TiUnload(DriverObject
);
765 /* Setup network layer and transport layer entities */
766 KeInitializeSpinLock(&EntityListLock
);
767 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * MAX_TDI_ENTITIES
);
768 if (!NT_SUCCESS(Status
)) {
769 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
770 TiUnload(DriverObject
);
771 return STATUS_INSUFFICIENT_RESOURCES
;
774 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
775 EntityList
[0].tei_instance
= 0;
776 EntityList
[0].context
= 0;
777 EntityList
[0].info_req
= InfoNetworkLayerTdiQueryEx
;
778 EntityList
[0].info_set
= InfoNetworkLayerTdiSetEx
;
779 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
780 EntityList
[1].tei_instance
= 0;
781 EntityList
[1].context
= 0;
782 EntityList
[1].info_req
= InfoTransportLayerTdiQueryEx
;
783 EntityList
[1].info_set
= InfoTransportLayerTdiSetEx
;
785 EntityMax
= MAX_TDI_ENTITIES
;
787 /* Allocate NDIS packet descriptors */
788 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
789 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
790 TiUnload(DriverObject
);
791 return STATUS_INSUFFICIENT_RESOURCES
;
794 /* Allocate NDIS buffer descriptors */
795 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
796 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
797 TiUnload(DriverObject
);
798 return STATUS_INSUFFICIENT_RESOURCES
;
801 /* Initialize address file list and protecting spin lock */
802 InitializeListHead(&AddressFileListHead
);
803 KeInitializeSpinLock(&AddressFileListLock
);
805 /* Initialize connection endpoint list and protecting spin lock */
806 InitializeListHead(&ConnectionEndpointListHead
);
807 KeInitializeSpinLock(&ConnectionEndpointListLock
);
809 /* Initialize interface list and protecting spin lock */
810 InitializeListHead(&InterfaceListHead
);
811 KeInitializeSpinLock(&InterfaceListLock
);
813 /* Initialize network level protocol subsystem */
814 IPStartup(DriverObject
, RegistryPath
);
816 /* Initialize transport level protocol subsystems */
822 /* Register protocol with NDIS */
823 /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
824 RtlInitUnicodeString(&strNdisDeviceName
, TCPIP_PROTOCOL_NAME
);
825 Status
= LANRegisterProtocol(&strNdisDeviceName
);
826 if (!NT_SUCCESS(Status
)) {
827 TI_DbgPrint(MIN_TRACE
,("Failed to register protocol with NDIS; status 0x%x\n", Status
));
830 EVENT_TRANSPORT_REGISTER_FAILED
,
831 TI_ERROR_DRIVERENTRY
,
836 TiUnload(DriverObject
);
840 /* Open loopback adapter */
841 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
842 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
843 TiUnload(DriverObject
);
844 return STATUS_INSUFFICIENT_RESOURCES
;
848 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
849 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
850 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
851 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
853 /* Initialize the driver object with this driver's entry points */
854 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = TiDispatchOpenClose
;
855 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = TiDispatchOpenClose
;
856 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = TiDispatchOpenClose
;
857 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = TiDispatchInternal
;
858 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = TiDispatch
;
860 DriverObject
->DriverUnload
= TiUnload
;
864 return STATUS_SUCCESS
;