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
21 /* See debug.h for debug/trace constants */
22 DWORD DebugTraceLevel
= MIN_TRACE
;
23 //DWORD DebugTraceLevel = MAX_TRACE;
24 //DWORD DebugTraceLevel = DEBUG_ULTRA;
28 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
29 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
30 PDEVICE_OBJECT IPDeviceObject
= NULL
;
31 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
32 NDIS_HANDLE GlobalPacketPool
= NULL
;
33 NDIS_HANDLE GlobalBufferPool
= NULL
;
34 TDIEntityID
*EntityList
= NULL
;
35 ULONG EntityCount
= 0;
36 UDP_STATISTICS UDPStats
;
40 PDRIVER_OBJECT DriverContext
,
42 ULONG UniqueErrorValue
,
48 * FUNCTION: Writes an error log entry
50 * DriverContext = Pointer to the driver or device object
51 * ErrorCode = An error code to put in the log entry
52 * UniqueErrorValue = UniqueErrorValue in the error log packet
53 * FinalStatus = FinalStatus in the error log packet
54 * String = If not NULL, a pointer to a string to put in log entry
55 * DumpDataCount = Number of ULONGs of dump data
56 * DumpData = Pointer to dump data for the log entry
60 PIO_ERROR_LOG_PACKET LogEntry
;
64 static WCHAR DriverName
[] = L
"TCP/IP";
66 EntrySize
= sizeof(IO_ERROR_LOG_PACKET
) +
67 (DumpDataCount
* sizeof(ULONG
)) + sizeof(DriverName
);
70 StringSize
= (wcslen(String
) * sizeof(WCHAR
)) + sizeof(UNICODE_NULL
);
71 EntrySize
+= (UCHAR
)StringSize
;
74 LogEntry
= (PIO_ERROR_LOG_PACKET
)IoAllocateErrorLogEntry(
75 DriverContext
, EntrySize
);
78 LogEntry
->MajorFunctionCode
= -1;
79 LogEntry
->RetryCount
= -1;
80 LogEntry
->DumpDataSize
= (USHORT
)(DumpDataCount
* sizeof(ULONG
));
81 LogEntry
->NumberOfStrings
= (String
== NULL
) ? 1 : 2;
82 LogEntry
->StringOffset
= sizeof(IO_ERROR_LOG_PACKET
) + (DumpDataCount
-1) * sizeof(ULONG
);
83 LogEntry
->EventCategory
= 0;
84 LogEntry
->ErrorCode
= ErrorCode
;
85 LogEntry
->UniqueErrorValue
= UniqueErrorValue
;
86 LogEntry
->FinalStatus
= FinalStatus
;
87 LogEntry
->SequenceNumber
= -1;
88 LogEntry
->IoControlCode
= 0;
91 RtlCopyMemory(LogEntry
->DumpData
, DumpData
, DumpDataCount
* sizeof(ULONG
));
93 pString
= ((PUCHAR
)LogEntry
) + LogEntry
->StringOffset
;
94 RtlCopyMemory(pString
, DriverName
, sizeof(DriverName
));
95 pString
+= sizeof(DriverName
);
98 RtlCopyMemory(pString
, String
, StringSize
);
100 IoWriteErrorLogEntry(LogEntry
);
106 NTSTATUS
TiGetProtocolNumber(
107 PUNICODE_STRING FileName
,
110 * FUNCTION: Returns the protocol number from a file name
112 * FileName = Pointer to string with file name
113 * Protocol = Pointer to buffer to put protocol number in
115 * Status of operation
123 TI_DbgPrint(MAX_TRACE
, ("Called. FileName (%wZ).\n", FileName
));
125 Name
= FileName
->Buffer
;
127 if (*Name
++ != (WCHAR
)L
'\\')
128 return STATUS_UNSUCCESSFUL
;
130 if (*Name
== (WCHAR
)NULL
)
131 return STATUS_UNSUCCESSFUL
;
133 RtlInitUnicodeString(&us
, Name
);
135 Status
= RtlUnicodeStringToInteger(&us
, 10, &Value
);
136 if (!NT_SUCCESS(Status
) || ((Value
> 255)))
137 return STATUS_UNSUCCESSFUL
;
141 return STATUS_SUCCESS
;
146 * FUNCTION: Creates a file object
148 * DeviceObject = Pointer to a device object for this driver
149 * Irp = Pointer to a I/O request packet
151 * Status of the operation
153 NTSTATUS
TiCreateFileObject(
154 PDEVICE_OBJECT DeviceObject
,
157 PFILE_FULL_EA_INFORMATION EaInfo
;
158 PTRANSPORT_CONTEXT Context
;
159 PIO_STACK_LOCATION IrpSp
;
160 PTA_ADDRESS_IP Address
;
166 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
168 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
170 /* Parameter check */
172 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
173 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 */
192 if ((EaInfo
->EaNameLength
== TDI_TRANSPORT_ADDRESS_LENGTH
) &&
193 (RtlCompareMemory(&EaInfo
->EaName
, TdiTransportAddress
,
194 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
195 /* This is a request to open an address */
197 /* Parameter checks */
198 Address
= (PTA_ADDRESS_IP
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
);
199 if ((EaInfo
->EaValueLength
< sizeof(TA_ADDRESS_IP
)) ||
200 (Address
->TAAddressCount
!= 1) ||
201 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
202 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
203 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
205 return STATUS_INVALID_PARAMETER
;
208 /* Open address file object */
210 /* Protocol depends on device object so find the protocol */
211 if (DeviceObject
== TCPDeviceObject
)
212 Protocol
= IPPROTO_TCP
;
213 else if (DeviceObject
== UDPDeviceObject
)
214 Protocol
= IPPROTO_UDP
;
215 else if (DeviceObject
== IPDeviceObject
)
216 Protocol
= IPPROTO_RAW
;
217 else if (DeviceObject
== RawIPDeviceObject
) {
218 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
219 if (!NT_SUCCESS(Status
)) {
220 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
222 return STATUS_INVALID_PARAMETER
;
225 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
227 return STATUS_INVALID_PARAMETER
;
230 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
231 if (NT_SUCCESS(Status
)) {
232 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
233 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
236 } else if ((EaInfo
->EaNameLength
== TDI_CONNECTION_CONTEXT_LENGTH
) &&
237 (RtlCompareMemory(&EaInfo
->EaName
, TdiConnectionContext
,
238 TDI_CONNECTION_CONTEXT_LENGTH
) == TDI_CONNECTION_CONTEXT_LENGTH
)) {
239 /* This is a request to open a connection endpoint */
241 /* Parameter checks */
243 if (EaInfo
->EaValueLength
< sizeof(PVOID
)) {
244 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
246 return STATUS_INVALID_PARAMETER
;
249 /* Can only do connection oriented communication using TCP */
251 if (DeviceObject
!= TCPDeviceObject
) {
252 TI_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
254 return STATUS_INVALID_PARAMETER
;
257 ClientContext
= *((PVOID
*)(EaInfo
->EaName
+ EaInfo
->EaNameLength
));
259 /* Open connection endpoint file object */
261 Status
= FileOpenConnection(&Request
, ClientContext
);
262 if (NT_SUCCESS(Status
)) {
263 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_CONNECTION_FILE
;
264 Context
->Handle
.ConnectionContext
= Request
.Handle
.ConnectionContext
;
267 /* This is a request to open a control connection */
269 TI_DbgPrint(MIN_TRACE
, ("Control connections are not implemented yet\n"));
271 Status
= STATUS_NOT_IMPLEMENTED
;
274 if (!NT_SUCCESS(Status
))
277 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
283 VOID
TiCleanupFileObjectComplete(
287 * FUNCTION: Completes an object cleanup IRP I/O request
289 * Context = Pointer to the IRP for this request
290 * Status = Final status of the operation
294 PIO_STACK_LOCATION IrpSp
;
295 PTRANSPORT_CONTEXT TranContext
;
299 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
300 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
302 Irp
->IoStatus
.Status
= Status
;
304 IoAcquireCancelSpinLock(&OldIrql
);
306 /* Remove the initial reference provided at object creation time */
307 TranContext
->RefCount
--;
310 if (TranContext
->RefCount
!= 0)
311 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
314 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
316 IoReleaseCancelSpinLock(OldIrql
);
321 * FUNCTION: Releases resources used by a file object
323 * DeviceObject = Pointer to a device object for this driver
324 * Irp = Pointer to a I/O request packet
326 * Status of the operation
328 * This function does not pend
330 NTSTATUS
TiCleanupFileObject(
331 PDEVICE_OBJECT DeviceObject
,
334 PIO_STACK_LOCATION IrpSp
;
335 PTRANSPORT_CONTEXT Context
;
340 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
341 Context
= IrpSp
->FileObject
->FsContext
;
343 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
344 return STATUS_INVALID_PARAMETER
;
347 IoAcquireCancelSpinLock(&OldIrql
);
349 Context
->CancelIrps
= TRUE
;
350 KeResetEvent(&Context
->CleanupEvent
);
352 IoReleaseCancelSpinLock(OldIrql
);
354 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
355 Request
.RequestContext
= Irp
;
357 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
358 case TDI_TRANSPORT_ADDRESS_FILE
:
359 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
360 Status
= FileCloseAddress(&Request
);
363 case TDI_CONNECTION_FILE
:
364 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
365 Status
= FileCloseConnection(&Request
);
368 case TDI_CONTROL_CHANNEL_FILE
:
369 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
370 Status
= FileCloseControlChannel(&Request
);
374 /* This should never happen */
376 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
378 IoAcquireCancelSpinLock(&OldIrql
);
379 Context
->CancelIrps
= FALSE
;
380 IoReleaseCancelSpinLock(OldIrql
);
382 return STATUS_INVALID_PARAMETER
;
385 if (Status
!= STATUS_PENDING
)
386 TiCleanupFileObjectComplete(Irp
, Status
);
388 KeWaitForSingleObject(&Context
->CleanupEvent
,
389 UserRequest
, KernelMode
, FALSE
, NULL
);
391 return Irp
->IoStatus
.Status
;
400 PDEVICE_OBJECT DeviceObject
,
403 * FUNCTION: Main dispath routine
405 * DeviceObject = Pointer to a device object for this driver
406 * Irp = Pointer to a I/O request packet
408 * Status of the operation
411 PIO_STACK_LOCATION IrpSp
;
413 PTRANSPORT_CONTEXT Context
;
415 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
417 IoMarkIrpPending(Irp
);
418 Irp
->IoStatus
.Status
= STATUS_PENDING
;
419 Irp
->IoStatus
.Information
= 0;
421 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
423 switch (IrpSp
->MajorFunction
) {
424 /* Open an address file, connection endpoint, or control connection */
426 Status
= TiCreateFileObject(DeviceObject
, Irp
);
429 /* Close an address file, connection endpoint, or control connection */
431 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
434 Status
= STATUS_SUCCESS
;
437 /* Release resources bound to an address file, connection endpoint,
438 or control connection */
440 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
444 Status
= STATUS_INVALID_DEVICE_REQUEST
;
447 if (Status
!= STATUS_PENDING
) {
448 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
449 Irp
->IoStatus
.Status
= Status
;
451 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
453 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
456 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
467 PDEVICE_OBJECT DeviceObject
,
470 * FUNCTION: Internal IOCTL dispatch routine
472 * DeviceObject = Pointer to a device object for this driver
473 * Irp = Pointer to a I/O request packet
475 * Status of the operation
479 PIO_STACK_LOCATION IrpSp
;
481 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
483 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
484 DeviceObject
, Irp
, IrpSp
->MinorFunction
));
486 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
487 Irp
->IoStatus
.Information
= 0;
489 switch (IrpSp
->MinorFunction
) {
491 Status
= DispTdiReceive(Irp
);
494 case TDI_RECEIVE_DATAGRAM
:
495 Status
= DispTdiReceiveDatagram(Irp
);
499 Status
= DispTdiSend(Irp
);
502 case TDI_SEND_DATAGRAM
:
503 Status
= DispTdiSendDatagram(Irp
);
507 Status
= DispTdiAccept(Irp
);
511 Status
= DispTdiListen(Irp
);
515 Status
= DispTdiConnect(Irp
);
519 Status
= DispTdiDisconnect(Irp
);
522 case TDI_ASSOCIATE_ADDRESS
:
523 Status
= DispTdiAssociateAddress(Irp
);
526 case TDI_DISASSOCIATE_ADDRESS
:
527 Status
= DispTdiDisassociateAddress(Irp
);
530 case TDI_QUERY_INFORMATION
:
531 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
534 case TDI_SET_INFORMATION
:
535 Status
= DispTdiSetInformation(Irp
);
538 case TDI_SET_EVENT_HANDLER
:
539 Status
= DispTdiSetEventHandler(Irp
);
543 Status
= STATUS_SUCCESS
;
546 /* An unsupported IOCTL code was submitted */
548 Status
= STATUS_INVALID_DEVICE_REQUEST
;
551 if (Status
!= STATUS_PENDING
) {
552 Irp
->IoStatus
.Status
= Status
;
554 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
556 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
559 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
570 PDEVICE_OBJECT DeviceObject
,
573 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
575 * DeviceObject = Pointer to a device object for this driver
576 * Irp = Pointer to a I/O request packet
578 * Status of the operation
582 PIO_STACK_LOCATION IrpSp
;
584 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
586 Irp
->IoStatus
.Information
= 0;
588 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
590 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
591 if (NT_SUCCESS(Status
)) {
592 TiDispatchInternal(DeviceObject
, Irp
);
593 Status
= STATUS_PENDING
;
598 /* See if this request is TCP/IP specific */
599 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
600 case IOCTL_TCP_QUERY_INFORMATION_EX
:
601 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
604 case IOCTL_TCP_SET_INFORMATION_EX
:
605 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
609 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
610 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
611 Status
= STATUS_NOT_IMPLEMENTED
;
616 if (Status
!= STATUS_PENDING
) {
617 Irp
->IoStatus
.Status
= Status
;
619 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
621 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
624 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
631 PDRIVER_OBJECT DriverObject
)
633 * FUNCTION: Unloads the driver
635 * DriverObject = Pointer to driver object created by the system
641 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
642 if (!IsListEmpty(&AddressFileListHead
)) {
643 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
645 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
648 /* Unregister loopback adapter */
649 LoopUnregisterAdapter(NULL
);
651 /* Unregister protocol with NDIS */
652 LANUnregisterProtocol();
654 /* Shutdown transport level protocol subsystems */
660 /* Shutdown network level protocol subsystem */
663 /* Free NDIS buffer descriptors */
664 if (GlobalBufferPool
)
665 NdisFreeBufferPool(GlobalBufferPool
);
667 /* Free NDIS packet descriptors */
668 if (GlobalPacketPool
)
669 NdisFreePacketPool(GlobalPacketPool
);
671 /* Release all device objects */
674 IoDeleteDevice(TCPDeviceObject
);
677 IoDeleteDevice(UDPDeviceObject
);
679 if (RawIPDeviceObject
)
680 IoDeleteDevice(RawIPDeviceObject
);
683 IoDeleteDevice(IPDeviceObject
);
686 ExFreePool(EntityList
);
688 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
697 PDRIVER_OBJECT DriverObject
,
698 PUNICODE_STRING RegistryPath
)
700 * FUNCTION: Main driver entry point
702 * DriverObject = Pointer to a driver object for this driver
703 * RegistryPath = Registry node for configuration parameters
705 * Status of driver initialization
709 UNICODE_STRING strDeviceName
;
710 STRING strNdisDeviceName
;
711 NDIS_STATUS NdisStatus
;
712 PLAN_ADAPTER Adapter
;
713 NDIS_STRING DeviceName
;
715 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
717 /* FIXME: Create symbolic links in Win32 namespace */
719 /* Create IP device object */
720 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_IP_DEVICE_NAME
);
721 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
722 FILE_DEVICE_NETWORK
, 0, FALSE
, &IPDeviceObject
);
723 if (!NT_SUCCESS(Status
)) {
724 TI_DbgPrint(MIN_TRACE
, ("Failed to create IP device object. Status (0x%X).\n", Status
));
728 /* Create RawIP device object */
729 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_RAWIP_DEVICE_NAME
);
730 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
731 FILE_DEVICE_NETWORK
, 0, FALSE
, &RawIPDeviceObject
);
732 if (!NT_SUCCESS(Status
)) {
733 TI_DbgPrint(MIN_TRACE
, ("Failed to create RawIP device object. Status (0x%X).\n", Status
));
734 TiUnload(DriverObject
);
738 /* Create UDP device object */
739 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_UDP_DEVICE_NAME
);
740 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
741 FILE_DEVICE_NETWORK
, 0, FALSE
, &UDPDeviceObject
);
742 if (!NT_SUCCESS(Status
)) {
743 TI_DbgPrint(MIN_TRACE
, ("Failed to create UDP device object. Status (0x%X).\n", Status
));
744 TiUnload(DriverObject
);
748 /* Create TCP device object */
749 RtlInitUnicodeStringFromLiteral(&strDeviceName
, DD_TCP_DEVICE_NAME
);
750 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
751 FILE_DEVICE_NETWORK
, 0, FALSE
, &TCPDeviceObject
);
752 if (!NT_SUCCESS(Status
)) {
753 TI_DbgPrint(MIN_TRACE
, ("Failed to create TCP device object. Status (0x%X).\n", Status
));
754 TiUnload(DriverObject
);
758 /* Allocate NDIS packet descriptors */
759 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
760 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
761 TiUnload(DriverObject
);
762 return STATUS_INSUFFICIENT_RESOURCES
;
765 /* Allocate NDIS buffer descriptors */
766 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
767 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
768 TiUnload(DriverObject
);
769 return STATUS_INSUFFICIENT_RESOURCES
;
772 /* Initialize address file list and protecting spin lock */
773 InitializeListHead(&AddressFileListHead
);
774 KeInitializeSpinLock(&AddressFileListLock
);
776 /* Initialize connection endpoint list and protecting spin lock */
777 InitializeListHead(&ConnectionEndpointListHead
);
778 KeInitializeSpinLock(&ConnectionEndpointListLock
);
780 /* Initialize interface list and protecting spin lock */
781 InitializeListHead(&InterfaceListHead
);
782 KeInitializeSpinLock(&InterfaceListLock
);
784 /* Initialize network level protocol subsystem */
785 IPStartup(DriverObject
, RegistryPath
);
787 /* Initialize transport level protocol subsystems */
793 /* Register protocol with NDIS */
794 RtlInitString(&strNdisDeviceName
, IP_DEVICE_NAME
);
795 Status
= LANRegisterProtocol(&strNdisDeviceName
);
796 if (!NT_SUCCESS(Status
)) {
799 EVENT_TRANSPORT_REGISTER_FAILED
,
800 TI_ERROR_DRIVERENTRY
,
805 TiUnload(DriverObject
);
809 /* Open loopback adapter */
810 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
811 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
812 TiUnload(DriverObject
);
813 return STATUS_INSUFFICIENT_RESOURCES
;
816 /* Open underlying adapter(s) we are bound to */
818 /* FIXME: Get binding information from registry */
820 /* Put your own NDIS adapter device name here */
823 NdisInitUnicodeString(&DeviceName
, L
"\\Device\\ne2000");
826 //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
829 //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
831 NdisStatus
= LANRegisterAdapter(&DeviceName
, &Adapter
);
833 /* Skip network adapter if it does not exist */
834 if (!NT_SUCCESS(NdisStatus
)) {
835 TI_DbgPrint(MIN_TRACE
, ("Failed to intialize adapter. Status (0x%X).\n", Status
));
838 EVENT_TRANSPORT_ADAPTER_NOT_FOUND
,
839 TI_ERROR_DRIVERENTRY
,
844 TiUnload(DriverObject
);
845 return STATUS_DEVICE_DOES_NOT_EXIST
;
848 /* Setup network layer and transport layer entities */
849 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * 2);
850 if (!NT_SUCCESS(Status
)) {
851 TiUnload(DriverObject
);
852 return STATUS_INSUFFICIENT_RESOURCES
;
855 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
856 EntityList
[0].tei_instance
= 0;
857 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
858 EntityList
[1].tei_instance
= 0;
862 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
863 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
864 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
865 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
867 /* Initialize the driver object with this driver's entry points */
868 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = TiDispatchOpenClose
;
869 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = TiDispatchOpenClose
;
870 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = TiDispatchOpenClose
;
871 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = TiDispatchInternal
;
872 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = TiDispatch
;
874 DriverObject
->DriverUnload
= (PDRIVER_UNLOAD
)TiUnload
;
876 return STATUS_SUCCESS
;