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
23 /* See debug.h for debug/trace constants */
25 DWORD DebugTraceLevel
= MID_TRACE
;
26 //DWORD DebugTraceLevel = (MAX_TRACE + DEBUG_DATALINK);
28 DWORD DebugTraceLevel
= MIN_TRACE
;
29 //DWORD DebugTraceLevel = MAX_TRACE;
30 //DWORD DebugTraceLevel = DEBUG_ULTRA;
35 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
36 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
37 PDEVICE_OBJECT IPDeviceObject
= NULL
;
38 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
39 NDIS_HANDLE GlobalPacketPool
= NULL
;
40 NDIS_HANDLE GlobalBufferPool
= NULL
;
41 TDIEntityID
*EntityList
= NULL
;
42 ULONG EntityCount
= 0;
43 UDP_STATISTICS UDPStats
;
47 PDRIVER_OBJECT DriverContext
,
49 ULONG UniqueErrorValue
,
55 * FUNCTION: Writes an error log entry
57 * DriverContext = Pointer to the driver or device object
58 * ErrorCode = An error code to put in the log entry
59 * UniqueErrorValue = UniqueErrorValue in the error log packet
60 * FinalStatus = FinalStatus in the error log packet
61 * String = If not NULL, a pointer to a string to put in log entry
62 * DumpDataCount = Number of ULONGs of dump data
63 * DumpData = Pointer to dump data for the log entry
67 PIO_ERROR_LOG_PACKET LogEntry
;
71 static WCHAR DriverName
[] = L
"TCP/IP";
73 EntrySize
= sizeof(IO_ERROR_LOG_PACKET
) +
74 (DumpDataCount
* sizeof(ULONG
)) + sizeof(DriverName
);
77 StringSize
= (wcslen(String
) * sizeof(WCHAR
)) + sizeof(UNICODE_NULL
);
78 EntrySize
+= (UCHAR
)StringSize
;
81 LogEntry
= (PIO_ERROR_LOG_PACKET
)IoAllocateErrorLogEntry(
82 DriverContext
, EntrySize
);
85 LogEntry
->MajorFunctionCode
= -1;
86 LogEntry
->RetryCount
= -1;
87 LogEntry
->DumpDataSize
= (USHORT
)(DumpDataCount
* sizeof(ULONG
));
88 LogEntry
->NumberOfStrings
= (String
== NULL
) ? 1 : 2;
89 LogEntry
->StringOffset
= sizeof(IO_ERROR_LOG_PACKET
) + (DumpDataCount
-1) * sizeof(ULONG
);
90 LogEntry
->EventCategory
= 0;
91 LogEntry
->ErrorCode
= ErrorCode
;
92 LogEntry
->UniqueErrorValue
= UniqueErrorValue
;
93 LogEntry
->FinalStatus
= FinalStatus
;
94 LogEntry
->SequenceNumber
= -1;
95 LogEntry
->IoControlCode
= 0;
98 RtlCopyMemory(LogEntry
->DumpData
, DumpData
, DumpDataCount
* sizeof(ULONG
));
100 pString
= ((PUCHAR
)LogEntry
) + LogEntry
->StringOffset
;
101 RtlCopyMemory(pString
, DriverName
, sizeof(DriverName
));
102 pString
+= sizeof(DriverName
);
105 RtlCopyMemory(pString
, String
, StringSize
);
107 IoWriteErrorLogEntry(LogEntry
);
113 NTSTATUS
TiGetProtocolNumber(
114 PUNICODE_STRING FileName
,
117 * FUNCTION: Returns the protocol number from a file name
119 * FileName = Pointer to string with file name
120 * Protocol = Pointer to buffer to put protocol number in
122 * Status of operation
130 TI_DbgPrint(MAX_TRACE
, ("Called. FileName (%wZ).\n", FileName
));
132 Name
= FileName
->Buffer
;
134 if (*Name
++ != (WCHAR
)L
'\\')
135 return STATUS_UNSUCCESSFUL
;
137 if (*Name
== (WCHAR
)NULL
)
138 return STATUS_UNSUCCESSFUL
;
140 RtlInitUnicodeString(&us
, Name
);
142 Status
= RtlUnicodeStringToInteger(&us
, 10, &Value
);
143 if (!NT_SUCCESS(Status
) || ((Value
> 255)))
144 return STATUS_UNSUCCESSFUL
;
148 return STATUS_SUCCESS
;
153 * FUNCTION: Creates a file object
155 * DeviceObject = Pointer to a device object for this driver
156 * Irp = Pointer to a I/O request packet
158 * Status of the operation
160 NTSTATUS
TiCreateFileObject(
161 PDEVICE_OBJECT DeviceObject
,
164 PFILE_FULL_EA_INFORMATION EaInfo
;
165 PTRANSPORT_CONTEXT Context
;
166 PIO_STACK_LOCATION IrpSp
;
167 PTA_ADDRESS_IP Address
;
173 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
175 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
177 /* Parameter check */
179 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
180 return STATUS_INVALID_PARAMETER
;
183 /* Allocate resources here. We release them again if something failed */
184 Context
= ExAllocatePool(NonPagedPool
, sizeof(TRANSPORT_CONTEXT
));
186 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
187 return STATUS_INSUFFICIENT_RESOURCES
;
190 Context
->RefCount
= 1;
191 Context
->CancelIrps
= FALSE
;
192 KeInitializeEvent(&Context
->CleanupEvent
, NotificationEvent
, FALSE
);
194 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
195 IrpSp
->FileObject
->FsContext
= Context
;
196 Request
.RequestContext
= Irp
;
198 /* Branch to the right handler */
199 if ((EaInfo
->EaNameLength
== TDI_TRANSPORT_ADDRESS_LENGTH
) &&
200 (RtlCompareMemory(&EaInfo
->EaName
, TdiTransportAddress
,
201 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
202 /* This is a request to open an address */
204 /* Parameter checks */
205 Address
= (PTA_ADDRESS_IP
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
);
206 if ((EaInfo
->EaValueLength
< sizeof(TA_ADDRESS_IP
)) ||
207 (Address
->TAAddressCount
!= 1) ||
208 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
209 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
210 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
212 return STATUS_INVALID_PARAMETER
;
215 /* Open address file object */
217 /* Protocol depends on device object so find the protocol */
218 if (DeviceObject
== TCPDeviceObject
)
219 Protocol
= IPPROTO_TCP
;
220 else if (DeviceObject
== UDPDeviceObject
)
221 Protocol
= IPPROTO_UDP
;
222 else if (DeviceObject
== IPDeviceObject
)
223 Protocol
= IPPROTO_RAW
;
224 else if (DeviceObject
== RawIPDeviceObject
) {
225 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
226 if (!NT_SUCCESS(Status
)) {
227 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
229 return STATUS_INVALID_PARAMETER
;
232 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
234 return STATUS_INVALID_PARAMETER
;
237 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
238 if (NT_SUCCESS(Status
)) {
239 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
240 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
243 } else if ((EaInfo
->EaNameLength
== TDI_CONNECTION_CONTEXT_LENGTH
) &&
244 (RtlCompareMemory(&EaInfo
->EaName
, TdiConnectionContext
,
245 TDI_CONNECTION_CONTEXT_LENGTH
) == TDI_CONNECTION_CONTEXT_LENGTH
)) {
246 /* This is a request to open a connection endpoint */
248 /* Parameter checks */
250 if (EaInfo
->EaValueLength
< sizeof(PVOID
)) {
251 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
253 return STATUS_INVALID_PARAMETER
;
256 /* Can only do connection oriented communication using TCP */
258 if (DeviceObject
!= TCPDeviceObject
) {
259 TI_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
261 return STATUS_INVALID_PARAMETER
;
264 ClientContext
= *((PVOID
*)(EaInfo
->EaName
+ EaInfo
->EaNameLength
));
266 /* Open connection endpoint file object */
268 Status
= FileOpenConnection(&Request
, ClientContext
);
269 if (NT_SUCCESS(Status
)) {
270 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONNECTION_FILE
;
271 Context
->Handle
.ConnectionContext
= Request
.Handle
.ConnectionContext
;
274 /* This is a request to open a control connection */
276 TI_DbgPrint(MIN_TRACE
, ("Control connections are not implemented yet\n"));
278 Status
= STATUS_NOT_IMPLEMENTED
;
281 if (!NT_SUCCESS(Status
))
284 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
290 VOID
TiCleanupFileObjectComplete(
294 * FUNCTION: Completes an object cleanup IRP I/O request
296 * Context = Pointer to the IRP for this request
297 * Status = Final status of the operation
301 PIO_STACK_LOCATION IrpSp
;
302 PTRANSPORT_CONTEXT TranContext
;
306 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
307 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
309 Irp
->IoStatus
.Status
= Status
;
311 IoAcquireCancelSpinLock(&OldIrql
);
313 /* Remove the initial reference provided at object creation time */
314 TranContext
->RefCount
--;
317 if (TranContext
->RefCount
!= 0)
318 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
321 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
323 IoReleaseCancelSpinLock(OldIrql
);
328 * FUNCTION: Releases resources used by a file object
330 * DeviceObject = Pointer to a device object for this driver
331 * Irp = Pointer to a I/O request packet
333 * Status of the operation
335 * This function does not pend
337 NTSTATUS
TiCleanupFileObject(
338 PDEVICE_OBJECT DeviceObject
,
341 PIO_STACK_LOCATION IrpSp
;
342 PTRANSPORT_CONTEXT Context
;
347 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
348 Context
= IrpSp
->FileObject
->FsContext
;
350 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
351 return STATUS_INVALID_PARAMETER
;
354 IoAcquireCancelSpinLock(&OldIrql
);
356 Context
->CancelIrps
= TRUE
;
357 KeResetEvent(&Context
->CleanupEvent
);
359 IoReleaseCancelSpinLock(OldIrql
);
361 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
362 Request
.RequestContext
= Irp
;
364 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
365 case TDI_TRANSPORT_ADDRESS_FILE
:
366 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
367 Status
= FileCloseAddress(&Request
);
370 case TDI_CONNECTION_FILE
:
371 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
372 Status
= FileCloseConnection(&Request
);
375 case TDI_CONTROL_CHANNEL_FILE
:
376 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
377 Status
= FileCloseControlChannel(&Request
);
381 /* This should never happen */
383 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
385 IoAcquireCancelSpinLock(&OldIrql
);
386 Context
->CancelIrps
= FALSE
;
387 IoReleaseCancelSpinLock(OldIrql
);
389 return STATUS_INVALID_PARAMETER
;
392 if (Status
!= STATUS_PENDING
)
393 TiCleanupFileObjectComplete(Irp
, Status
);
395 KeWaitForSingleObject(&Context
->CleanupEvent
,
396 UserRequest
, KernelMode
, FALSE
, NULL
);
398 return Irp
->IoStatus
.Status
;
407 PDEVICE_OBJECT DeviceObject
,
410 * FUNCTION: Main dispath routine
412 * DeviceObject = Pointer to a device object for this driver
413 * Irp = Pointer to a I/O request packet
415 * Status of the operation
418 PIO_STACK_LOCATION IrpSp
;
420 PTRANSPORT_CONTEXT Context
;
422 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
424 IoMarkIrpPending(Irp
);
425 Irp
->IoStatus
.Status
= STATUS_PENDING
;
426 Irp
->IoStatus
.Information
= 0;
428 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
430 switch (IrpSp
->MajorFunction
) {
431 /* Open an address file, connection endpoint, or control connection */
433 Status
= TiCreateFileObject(DeviceObject
, Irp
);
436 /* Close an address file, connection endpoint, or control connection */
438 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
441 Status
= STATUS_SUCCESS
;
444 /* Release resources bound to an address file, connection endpoint,
445 or control connection */
447 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
451 Status
= STATUS_INVALID_DEVICE_REQUEST
;
454 if (Status
!= STATUS_PENDING
) {
455 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
456 Irp
->IoStatus
.Status
= Status
;
458 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
460 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
463 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
474 PDEVICE_OBJECT DeviceObject
,
477 * FUNCTION: Internal IOCTL dispatch routine
479 * DeviceObject = Pointer to a device object for this driver
480 * Irp = Pointer to a I/O request packet
482 * Status of the operation
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
);
509 case TDI_SEND_DATAGRAM
:
510 Status
= DispTdiSendDatagram(Irp
);
514 Status
= DispTdiAccept(Irp
);
518 Status
= DispTdiListen(Irp
);
522 Status
= DispTdiConnect(Irp
);
526 Status
= DispTdiDisconnect(Irp
);
529 case TDI_ASSOCIATE_ADDRESS
:
530 Status
= DispTdiAssociateAddress(Irp
);
533 case TDI_DISASSOCIATE_ADDRESS
:
534 Status
= DispTdiDisassociateAddress(Irp
);
537 case TDI_QUERY_INFORMATION
:
538 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
541 case TDI_SET_INFORMATION
:
542 Status
= DispTdiSetInformation(Irp
);
545 case TDI_SET_EVENT_HANDLER
:
546 Status
= DispTdiSetEventHandler(Irp
);
550 Status
= STATUS_SUCCESS
;
553 /* An unsupported IOCTL code was submitted */
555 Status
= STATUS_INVALID_DEVICE_REQUEST
;
558 if (Status
!= STATUS_PENDING
) {
559 Irp
->IoStatus
.Status
= Status
;
561 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
563 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
566 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
577 PDEVICE_OBJECT DeviceObject
,
580 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
582 * DeviceObject = Pointer to a device object for this driver
583 * Irp = Pointer to a I/O request packet
585 * Status of the operation
589 PIO_STACK_LOCATION IrpSp
;
591 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
593 Irp
->IoStatus
.Information
= 0;
595 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
597 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
598 if (NT_SUCCESS(Status
)) {
599 TiDispatchInternal(DeviceObject
, Irp
);
600 Status
= STATUS_PENDING
;
605 /* See if this request is TCP/IP specific */
606 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
607 case IOCTL_TCP_QUERY_INFORMATION_EX
:
608 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
611 case IOCTL_TCP_SET_INFORMATION_EX
:
612 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
616 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
617 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
618 Status
= STATUS_NOT_IMPLEMENTED
;
623 if (Status
!= STATUS_PENDING
) {
624 Irp
->IoStatus
.Status
= Status
;
626 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
628 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
631 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
638 PDRIVER_OBJECT DriverObject
)
640 * FUNCTION: Unloads the driver
642 * DriverObject = Pointer to driver object created by the system
648 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
649 if (!IsListEmpty(&AddressFileListHead
)) {
650 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
652 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
655 /* Unregister loopback adapter */
656 LoopUnregisterAdapter(NULL
);
658 /* Unregister protocol with NDIS */
659 LANUnregisterProtocol();
661 /* Shutdown transport level protocol subsystems */
667 /* Shutdown network level protocol subsystem */
670 /* Free NDIS buffer descriptors */
671 if (GlobalBufferPool
)
672 NdisFreeBufferPool(GlobalBufferPool
);
674 /* Free NDIS packet descriptors */
675 if (GlobalPacketPool
)
676 NdisFreePacketPool(GlobalPacketPool
);
678 /* Release all device objects */
681 IoDeleteDevice(TCPDeviceObject
);
684 IoDeleteDevice(UDPDeviceObject
);
686 if (RawIPDeviceObject
)
687 IoDeleteDevice(RawIPDeviceObject
);
690 IoDeleteDevice(IPDeviceObject
);
693 ExFreePool(EntityList
);
695 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
704 PDRIVER_OBJECT DriverObject
,
705 PUNICODE_STRING RegistryPath
)
707 * FUNCTION: Main driver entry point
709 * DriverObject = Pointer to a driver object for this driver
710 * RegistryPath = Registry node for configuration parameters
712 * Status of driver initialization
716 UNICODE_STRING strDeviceName
;
717 STRING strNdisDeviceName
;
718 NDIS_STATUS NdisStatus
;
719 PLAN_ADAPTER Adapter
;
720 NDIS_STRING DeviceName
;
722 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
724 /* FIXME: Create symbolic links in Win32 namespace */
726 /* Create IP device object */
727 RtlInitUnicodeStringFromLiteral(&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 RtlInitUnicodeStringFromLiteral(&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 RtlInitUnicodeStringFromLiteral(&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 RtlInitUnicodeStringFromLiteral(&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 /* Allocate NDIS packet descriptors */
766 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
767 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
768 TiUnload(DriverObject
);
769 return STATUS_INSUFFICIENT_RESOURCES
;
772 /* Allocate NDIS buffer descriptors */
773 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
774 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
775 TiUnload(DriverObject
);
776 return STATUS_INSUFFICIENT_RESOURCES
;
779 /* Initialize address file list and protecting spin lock */
780 InitializeListHead(&AddressFileListHead
);
781 KeInitializeSpinLock(&AddressFileListLock
);
783 /* Initialize connection endpoint list and protecting spin lock */
784 InitializeListHead(&ConnectionEndpointListHead
);
785 KeInitializeSpinLock(&ConnectionEndpointListLock
);
787 /* Initialize interface list and protecting spin lock */
788 InitializeListHead(&InterfaceListHead
);
789 KeInitializeSpinLock(&InterfaceListLock
);
791 /* Initialize network level protocol subsystem */
792 IPStartup(DriverObject
, RegistryPath
);
794 /* Initialize transport level protocol subsystems */
800 /* Register protocol with NDIS */
801 RtlInitString(&strNdisDeviceName
, IP_DEVICE_NAME
);
802 Status
= LANRegisterProtocol(&strNdisDeviceName
);
803 if (!NT_SUCCESS(Status
)) {
806 EVENT_TRANSPORT_REGISTER_FAILED
,
807 TI_ERROR_DRIVERENTRY
,
812 TiUnload(DriverObject
);
816 /* Open loopback adapter */
817 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
818 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
819 TiUnload(DriverObject
);
820 return STATUS_INSUFFICIENT_RESOURCES
;
823 /* Open underlying adapter(s) we are bound to */
825 /* FIXME: Get binding information from registry */
827 /* Put your own NDIS adapter device name here */
830 NdisInitUnicodeString(&DeviceName
, L
"\\Device\\ne2000");
833 //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
836 //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
838 NdisStatus
= LANRegisterAdapter(&DeviceName
, &Adapter
);
840 /* Skip network adapter if it does not exist */
841 if (!NT_SUCCESS(NdisStatus
)) {
842 TI_DbgPrint(MIN_TRACE
, ("Failed to intialize adapter. Status (0x%X).\n", Status
));
845 EVENT_TRANSPORT_ADAPTER_NOT_FOUND
,
846 TI_ERROR_DRIVERENTRY
,
851 TiUnload(DriverObject
);
852 return STATUS_DEVICE_DOES_NOT_EXIST
;
855 /* Setup network layer and transport layer entities */
856 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * 2);
857 if (!NT_SUCCESS(Status
)) {
858 TiUnload(DriverObject
);
859 return STATUS_INSUFFICIENT_RESOURCES
;
862 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
863 EntityList
[0].tei_instance
= 0;
864 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
865 EntityList
[1].tei_instance
= 0;
869 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
870 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
871 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
872 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
874 /* Initialize the driver object with this driver's entry points */
875 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = TiDispatchOpenClose
;
876 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = TiDispatchOpenClose
;
877 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = TiDispatchOpenClose
;
878 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = TiDispatchInternal
;
879 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = TiDispatch
;
881 DriverObject
->DriverUnload
= (PDRIVER_UNLOAD
)TiUnload
;
883 return STATUS_SUCCESS
;