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
18 #include <rosrtl/string.h>
21 DWORD DebugTraceLevel
= MIN_TRACE
;
24 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
25 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
26 PDEVICE_OBJECT IPDeviceObject
= NULL
;
27 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
28 NDIS_HANDLE GlobalPacketPool
= NULL
;
29 NDIS_HANDLE GlobalBufferPool
= NULL
;
30 TDIEntityID
*EntityList
= NULL
;
31 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 */
168 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
169 return STATUS_INVALID_PARAMETER
;
172 /* Allocate resources here. We release them again if something failed */
173 Context
= ExAllocatePool(NonPagedPool
, sizeof(TRANSPORT_CONTEXT
));
175 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
176 return STATUS_INSUFFICIENT_RESOURCES
;
179 Context
->RefCount
= 1;
180 Context
->CancelIrps
= FALSE
;
181 KeInitializeEvent(&Context
->CleanupEvent
, NotificationEvent
, FALSE
);
183 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
184 IrpSp
->FileObject
->FsContext
= Context
;
185 Request
.RequestContext
= Irp
;
187 /* Branch to the right handler */
188 if ((EaInfo
->EaNameLength
== TDI_TRANSPORT_ADDRESS_LENGTH
) &&
189 (RtlCompareMemory(&EaInfo
->EaName
, TdiTransportAddress
,
190 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
191 /* This is a request to open an address */
193 /* Parameter checks */
194 Address
= (PTA_IP_ADDRESS
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
);
195 if ((EaInfo
->EaValueLength
< sizeof(TA_IP_ADDRESS
)) ||
196 (Address
->TAAddressCount
!= 1) ||
197 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
198 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
199 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
201 return STATUS_INVALID_PARAMETER
;
204 /* Open address file object */
206 /* Protocol depends on device object so find the protocol */
207 if (DeviceObject
== TCPDeviceObject
)
208 Protocol
= IPPROTO_TCP
;
209 else if (DeviceObject
== UDPDeviceObject
)
210 Protocol
= IPPROTO_UDP
;
211 else if (DeviceObject
== IPDeviceObject
)
212 Protocol
= IPPROTO_RAW
;
213 else if (DeviceObject
== RawIPDeviceObject
) {
214 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
215 if (!NT_SUCCESS(Status
)) {
216 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
218 return STATUS_INVALID_PARAMETER
;
221 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
223 return STATUS_INVALID_PARAMETER
;
226 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
227 if (NT_SUCCESS(Status
)) {
228 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
229 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
232 } else if ((EaInfo
->EaNameLength
== TDI_CONNECTION_CONTEXT_LENGTH
) &&
233 (RtlCompareMemory(&EaInfo
->EaName
, TdiConnectionContext
,
234 TDI_CONNECTION_CONTEXT_LENGTH
) == TDI_CONNECTION_CONTEXT_LENGTH
)) {
235 /* This is a request to open a connection endpoint */
237 /* Parameter checks */
239 if (EaInfo
->EaValueLength
< sizeof(PVOID
)) {
240 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
242 return STATUS_INVALID_PARAMETER
;
245 /* Can only do connection oriented communication using TCP */
247 if (DeviceObject
!= TCPDeviceObject
) {
248 TI_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
250 return STATUS_INVALID_PARAMETER
;
253 ClientContext
= *((PVOID
*)(EaInfo
->EaName
+ EaInfo
->EaNameLength
));
255 /* Open connection endpoint file object */
257 Status
= FileOpenConnection(&Request
, ClientContext
);
258 if (NT_SUCCESS(Status
)) {
259 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONNECTION_FILE
;
260 Context
->Handle
.ConnectionContext
= Request
.Handle
.ConnectionContext
;
263 /* This is a request to open a control connection */
265 TI_DbgPrint(MIN_TRACE
, ("Control connections are not implemented yet\n"));
267 Status
= STATUS_NOT_IMPLEMENTED
;
270 if (!NT_SUCCESS(Status
))
273 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
279 VOID
TiCleanupFileObjectComplete(
283 * FUNCTION: Completes an object cleanup IRP I/O request
285 * Context = Pointer to the IRP for this request
286 * Status = Final status of the operation
290 PIO_STACK_LOCATION IrpSp
;
291 PTRANSPORT_CONTEXT TranContext
;
295 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
296 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
298 Irp
->IoStatus
.Status
= Status
;
300 IoAcquireCancelSpinLock(&OldIrql
);
302 /* Remove the initial reference provided at object creation time */
303 TranContext
->RefCount
--;
306 if (TranContext
->RefCount
!= 0)
307 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
310 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
312 IoReleaseCancelSpinLock(OldIrql
);
317 * FUNCTION: Releases resources used by a file object
319 * DeviceObject = Pointer to a device object for this driver
320 * Irp = Pointer to a I/O request packet
322 * Status of the operation
324 * This function does not pend
326 NTSTATUS
TiCleanupFileObject(
327 PDEVICE_OBJECT DeviceObject
,
330 PIO_STACK_LOCATION IrpSp
;
331 PTRANSPORT_CONTEXT Context
;
336 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
337 Context
= IrpSp
->FileObject
->FsContext
;
339 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
340 return STATUS_INVALID_PARAMETER
;
343 IoAcquireCancelSpinLock(&OldIrql
);
345 Context
->CancelIrps
= TRUE
;
346 KeResetEvent(&Context
->CleanupEvent
);
348 IoReleaseCancelSpinLock(OldIrql
);
350 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
351 Request
.RequestContext
= Irp
;
353 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
354 case TDI_TRANSPORT_ADDRESS_FILE
:
355 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
356 Status
= FileCloseAddress(&Request
);
359 case TDI_CONNECTION_FILE
:
360 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
361 Status
= FileCloseConnection(&Request
);
364 case TDI_CONTROL_CHANNEL_FILE
:
365 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
366 Status
= FileCloseControlChannel(&Request
);
370 /* This should never happen */
372 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
374 IoAcquireCancelSpinLock(&OldIrql
);
375 Context
->CancelIrps
= FALSE
;
376 IoReleaseCancelSpinLock(OldIrql
);
378 return STATUS_INVALID_PARAMETER
;
381 if (Status
!= STATUS_PENDING
)
382 TiCleanupFileObjectComplete(Irp
, Status
);
384 KeWaitForSingleObject(&Context
->CleanupEvent
,
385 UserRequest
, KernelMode
, FALSE
, NULL
);
387 return Irp
->IoStatus
.Status
;
396 IN PDEVICE_OBJECT DeviceObject
,
399 * FUNCTION: Main dispath routine
401 * DeviceObject = Pointer to a device object for this driver
402 * Irp = Pointer to a I/O request packet
404 * Status of the operation
407 PIO_STACK_LOCATION IrpSp
;
409 PTRANSPORT_CONTEXT Context
;
411 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
413 IoMarkIrpPending(Irp
);
414 Irp
->IoStatus
.Status
= STATUS_PENDING
;
415 Irp
->IoStatus
.Information
= 0;
417 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
419 switch (IrpSp
->MajorFunction
) {
420 /* Open an address file, connection endpoint, or control connection */
422 Status
= TiCreateFileObject(DeviceObject
, Irp
);
425 /* Close an address file, connection endpoint, or control connection */
427 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
430 Status
= STATUS_SUCCESS
;
433 /* Release resources bound to an address file, connection endpoint,
434 or control connection */
436 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
440 Status
= STATUS_INVALID_DEVICE_REQUEST
;
443 if (Status
!= STATUS_PENDING
) {
444 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
445 Irp
->IoStatus
.Status
= Status
;
447 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
449 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
452 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
463 PDEVICE_OBJECT DeviceObject
,
466 * FUNCTION: Internal IOCTL dispatch routine
468 * DeviceObject = Pointer to a device object for this driver
469 * Irp = Pointer to a I/O request packet
471 * Status of the operation
475 PIO_STACK_LOCATION IrpSp
;
477 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
479 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
480 DeviceObject
, Irp
, IrpSp
->MinorFunction
));
482 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
483 Irp
->IoStatus
.Information
= 0;
485 switch (IrpSp
->MinorFunction
) {
487 Status
= DispTdiReceive(Irp
);
490 case TDI_RECEIVE_DATAGRAM
:
491 Status
= DispTdiReceiveDatagram(Irp
);
495 Status
= DispTdiSend(Irp
);
498 case TDI_SEND_DATAGRAM
:
499 Status
= DispTdiSendDatagram(Irp
);
503 Status
= DispTdiAccept(Irp
);
507 Status
= DispTdiListen(Irp
);
511 Status
= DispTdiConnect(Irp
);
515 Status
= DispTdiDisconnect(Irp
);
518 case TDI_ASSOCIATE_ADDRESS
:
519 Status
= DispTdiAssociateAddress(Irp
);
522 case TDI_DISASSOCIATE_ADDRESS
:
523 Status
= DispTdiDisassociateAddress(Irp
);
526 case TDI_QUERY_INFORMATION
:
527 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
530 case TDI_SET_INFORMATION
:
531 Status
= DispTdiSetInformation(Irp
);
534 case TDI_SET_EVENT_HANDLER
:
535 Status
= DispTdiSetEventHandler(Irp
);
539 Status
= STATUS_SUCCESS
;
542 /* An unsupported IOCTL code was submitted */
544 Status
= STATUS_INVALID_DEVICE_REQUEST
;
547 if (Status
!= STATUS_PENDING
) {
548 Irp
->IoStatus
.Status
= Status
;
550 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
552 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
555 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
566 PDEVICE_OBJECT DeviceObject
,
569 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
571 * DeviceObject = Pointer to a device object for this driver
572 * Irp = Pointer to a I/O request packet
574 * Status of the operation
578 PIO_STACK_LOCATION IrpSp
;
580 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
582 Irp
->IoStatus
.Information
= 0;
584 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
586 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
587 if (NT_SUCCESS(Status
)) {
588 TiDispatchInternal(DeviceObject
, Irp
);
589 Status
= STATUS_PENDING
;
594 /* See if this request is TCP/IP specific */
595 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
596 case IOCTL_TCP_QUERY_INFORMATION_EX
:
597 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
600 case IOCTL_TCP_SET_INFORMATION_EX
:
601 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
605 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
606 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
607 Status
= STATUS_NOT_IMPLEMENTED
;
612 if (Status
!= STATUS_PENDING
) {
613 Irp
->IoStatus
.Status
= Status
;
615 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
617 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
620 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
627 PDRIVER_OBJECT DriverObject
)
629 * FUNCTION: Unloads the driver
631 * DriverObject = Pointer to driver object created by the system
637 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
638 if (!IsListEmpty(&AddressFileListHead
)) {
639 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
641 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
644 /* Unregister loopback adapter */
645 LoopUnregisterAdapter(NULL
);
647 /* Unregister protocol with NDIS */
648 LANUnregisterProtocol();
650 /* Shutdown transport level protocol subsystems */
656 /* Shutdown network level protocol subsystem */
659 /* Free NDIS buffer descriptors */
660 if (GlobalBufferPool
)
661 NdisFreeBufferPool(GlobalBufferPool
);
663 /* Free NDIS packet descriptors */
664 if (GlobalPacketPool
)
665 NdisFreePacketPool(GlobalPacketPool
);
667 /* Release all device objects */
670 IoDeleteDevice(TCPDeviceObject
);
673 IoDeleteDevice(UDPDeviceObject
);
675 if (RawIPDeviceObject
)
676 IoDeleteDevice(RawIPDeviceObject
);
679 IoDeleteDevice(IPDeviceObject
);
682 ExFreePool(EntityList
);
684 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
693 PDRIVER_OBJECT DriverObject
,
694 PUNICODE_STRING RegistryPath
)
696 * FUNCTION: Main driver entry point
698 * DriverObject = Pointer to a driver object for this driver
699 * RegistryPath = Registry node for configuration parameters
701 * Status of driver initialization
705 UNICODE_STRING strDeviceName
;
706 UNICODE_STRING strNdisDeviceName
;
707 NDIS_STATUS NdisStatus
;
708 NDIS_STRING DeviceName
;
710 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
712 /* TdiInitialize() ? */
714 /* FIXME: Create symbolic links in Win32 namespace */
716 /* Create IP device object */
717 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_IP_DEVICE_NAME
);
718 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
719 FILE_DEVICE_NETWORK
, 0, FALSE
, &IPDeviceObject
);
720 if (!NT_SUCCESS(Status
)) {
721 TI_DbgPrint(MIN_TRACE
, ("Failed to create IP device object. Status (0x%X).\n", Status
));
725 /* Create RawIP device object */
726 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_RAWIP_DEVICE_NAME
);
727 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
728 FILE_DEVICE_NETWORK
, 0, FALSE
, &RawIPDeviceObject
);
729 if (!NT_SUCCESS(Status
)) {
730 TI_DbgPrint(MIN_TRACE
, ("Failed to create RawIP device object. Status (0x%X).\n", Status
));
731 TiUnload(DriverObject
);
735 /* Create UDP device object */
736 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_UDP_DEVICE_NAME
);
737 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
738 FILE_DEVICE_NETWORK
, 0, FALSE
, &UDPDeviceObject
);
739 if (!NT_SUCCESS(Status
)) {
740 TI_DbgPrint(MIN_TRACE
, ("Failed to create UDP device object. Status (0x%X).\n", Status
));
741 TiUnload(DriverObject
);
745 /* Create TCP device object */
746 RtlRosInitUnicodeStringFromLiteral(&strDeviceName
, DD_TCP_DEVICE_NAME
);
747 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
748 FILE_DEVICE_NETWORK
, 0, FALSE
, &TCPDeviceObject
);
749 if (!NT_SUCCESS(Status
)) {
750 TI_DbgPrint(MIN_TRACE
, ("Failed to create TCP device object. Status (0x%X).\n", Status
));
751 TiUnload(DriverObject
);
755 /* Allocate NDIS packet descriptors */
756 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
757 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
758 TiUnload(DriverObject
);
759 return STATUS_INSUFFICIENT_RESOURCES
;
762 /* Allocate NDIS buffer descriptors */
763 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
764 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
765 TiUnload(DriverObject
);
766 return STATUS_INSUFFICIENT_RESOURCES
;
769 /* Initialize address file list and protecting spin lock */
770 InitializeListHead(&AddressFileListHead
);
771 KeInitializeSpinLock(&AddressFileListLock
);
773 /* Initialize connection endpoint list and protecting spin lock */
774 InitializeListHead(&ConnectionEndpointListHead
);
775 KeInitializeSpinLock(&ConnectionEndpointListLock
);
777 /* Initialize interface list and protecting spin lock */
778 InitializeListHead(&InterfaceListHead
);
779 KeInitializeSpinLock(&InterfaceListLock
);
781 /* Initialize network level protocol subsystem */
782 IPStartup(DriverObject
, RegistryPath
);
784 /* Initialize transport level protocol subsystems */
790 /* Register protocol with NDIS */
791 /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
792 RtlInitUnicodeString(&strNdisDeviceName
, TCPIP_PROTOCOL_NAME
);
793 Status
= LANRegisterProtocol(&strNdisDeviceName
);
794 if (!NT_SUCCESS(Status
)) {
795 TI_DbgPrint(MIN_TRACE
,("Failed to register protocol with NDIS; status 0x%x\n", Status
));
798 EVENT_TRANSPORT_REGISTER_FAILED
,
799 TI_ERROR_DRIVERENTRY
,
804 TiUnload(DriverObject
);
808 /* Open loopback adapter */
809 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
810 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
811 TiUnload(DriverObject
);
812 return STATUS_INSUFFICIENT_RESOURCES
;
815 /* Setup network layer and transport layer entities */
816 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * 2);
817 if (!NT_SUCCESS(Status
)) {
818 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
819 TiUnload(DriverObject
);
820 return STATUS_INSUFFICIENT_RESOURCES
;
823 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
824 EntityList
[0].tei_instance
= 0;
825 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
826 EntityList
[1].tei_instance
= 0;
830 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
831 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
832 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
833 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
835 /* Initialize the driver object with this driver's entry points */
836 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
837 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
838 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = (PDRIVER_DISPATCH
)TiDispatchOpenClose
;
839 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)TiDispatchInternal
;
840 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = (PDRIVER_DISPATCH
)TiDispatch
;
842 DriverObject
->DriverUnload
= (PDRIVER_UNLOAD
)TiUnload
;
844 return STATUS_SUCCESS
;