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;
27 PDEVICE_OBJECT TCPDeviceObject
= NULL
;
28 PDEVICE_OBJECT UDPDeviceObject
= NULL
;
29 PDEVICE_OBJECT IPDeviceObject
= NULL
;
30 PDEVICE_OBJECT RawIPDeviceObject
= NULL
;
31 NDIS_HANDLE GlobalPacketPool
= NULL
;
32 NDIS_HANDLE GlobalBufferPool
= NULL
;
33 TDIEntityID
*EntityList
= NULL
;
34 ULONG EntityCount
= 0;
35 UDP_STATISTICS UDPStats
;
39 PDRIVER_OBJECT DriverContext
,
41 ULONG UniqueErrorValue
,
47 * FUNCTION: Writes an error log entry
49 * DriverContext = Pointer to the driver or device object
50 * ErrorCode = An error code to put in the log entry
51 * UniqueErrorValue = UniqueErrorValue in the error log packet
52 * FinalStatus = FinalStatus in the error log packet
53 * String = If not NULL, a pointer to a string to put in log entry
54 * DumpDataCount = Number of ULONGs of dump data
55 * DumpData = Pointer to dump data for the log entry
59 PIO_ERROR_LOG_PACKET LogEntry
;
63 static WCHAR DriverName
[] = L
"TCP/IP";
65 EntrySize
= sizeof(IO_ERROR_LOG_PACKET
) +
66 (DumpDataCount
* sizeof(ULONG
)) + sizeof(DriverName
);
69 StringSize
= (wcslen(String
) * sizeof(WCHAR
)) + sizeof(UNICODE_NULL
);
70 EntrySize
+= (UCHAR
)StringSize
;
73 LogEntry
= (PIO_ERROR_LOG_PACKET
)IoAllocateErrorLogEntry(
74 DriverContext
, EntrySize
);
77 LogEntry
->MajorFunctionCode
= -1;
78 LogEntry
->RetryCount
= -1;
79 LogEntry
->DumpDataSize
= (USHORT
)(DumpDataCount
* sizeof(ULONG
));
80 LogEntry
->NumberOfStrings
= (String
== NULL
) ? 1 : 2;
81 LogEntry
->StringOffset
= sizeof(IO_ERROR_LOG_PACKET
) + (DumpDataCount
-1) * sizeof(ULONG
);
82 LogEntry
->EventCategory
= 0;
83 LogEntry
->ErrorCode
= ErrorCode
;
84 LogEntry
->UniqueErrorValue
= UniqueErrorValue
;
85 LogEntry
->FinalStatus
= FinalStatus
;
86 LogEntry
->SequenceNumber
= -1;
87 LogEntry
->IoControlCode
= 0;
90 RtlCopyMemory(LogEntry
->DumpData
, DumpData
, DumpDataCount
* sizeof(ULONG
));
92 pString
= ((PUCHAR
)LogEntry
) + LogEntry
->StringOffset
;
93 RtlCopyMemory(pString
, DriverName
, sizeof(DriverName
));
94 pString
+= sizeof(DriverName
);
97 RtlCopyMemory(pString
, String
, StringSize
);
99 IoWriteErrorLogEntry(LogEntry
);
105 NTSTATUS
TiGetProtocolNumber(
106 PUNICODE_STRING FileName
,
109 * FUNCTION: Returns the protocol number from a file name
111 * FileName = Pointer to string with file name
112 * Protocol = Pointer to buffer to put protocol number in
114 * Status of operation
122 TI_DbgPrint(MAX_TRACE
, ("Called. FileName (%wZ).\n", FileName
));
124 Name
= FileName
->Buffer
;
126 if (*Name
++ != (WCHAR
)L
'\\')
127 return STATUS_UNSUCCESSFUL
;
129 if (*Name
== (WCHAR
)NULL
)
130 return STATUS_UNSUCCESSFUL
;
132 RtlInitUnicodeString(&us
, Name
);
134 Status
= RtlUnicodeStringToInteger(&us
, 10, &Value
);
135 if (!NT_SUCCESS(Status
) || ((Value
> 255)))
136 return STATUS_UNSUCCESSFUL
;
140 return STATUS_SUCCESS
;
145 * FUNCTION: Creates a file object
147 * DeviceObject = Pointer to a device object for this driver
148 * Irp = Pointer to a I/O request packet
150 * Status of the operation
152 NTSTATUS
TiCreateFileObject(
153 PDEVICE_OBJECT DeviceObject
,
156 PIO_STACK_LOCATION IrpSp
;
157 PFILE_FULL_EA_INFORMATION EaInfo
;
158 PTA_ADDRESS_IP Address
;
159 PTRANSPORT_CONTEXT Context
;
164 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
166 EaInfo
= Irp
->AssociatedIrp
.SystemBuffer
;
168 /* Parameter check */
170 TI_DbgPrint(MIN_TRACE
, ("No EA information in IRP.\n"));
171 return STATUS_INVALID_PARAMETER
;
174 /* Allocate resources here. We release them again if something failed */
175 Context
= ExAllocatePool(NonPagedPool
, sizeof(TRANSPORT_CONTEXT
));
177 TI_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
178 return STATUS_INSUFFICIENT_RESOURCES
;
181 Context
->RefCount
= 1;
182 Context
->CancelIrps
= FALSE
;
183 KeInitializeEvent(&Context
->CleanupEvent
, NotificationEvent
, FALSE
);
185 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
186 IrpSp
->FileObject
->FsContext
= Context
;
187 Request
.RequestContext
= Irp
;
189 /* Branch to the right handler */
190 if ((EaInfo
->EaNameLength
==TDI_TRANSPORT_ADDRESS_LENGTH
) &&
191 (RtlCompareMemory(&EaInfo
->EaName
, TdiTransportAddress
,
192 TDI_TRANSPORT_ADDRESS_LENGTH
) == TDI_TRANSPORT_ADDRESS_LENGTH
)) {
193 /* This is a request to open an address */
195 /* Parameter checks */
196 Address
= (PTA_ADDRESS_IP
)(EaInfo
->EaName
+ EaInfo
->EaNameLength
);
197 if ((EaInfo
->EaValueLength
< sizeof(TA_ADDRESS_IP
)) ||
198 (Address
->TAAddressCount
!= 1) ||
199 (Address
->Address
[0].AddressLength
< TDI_ADDRESS_LENGTH_IP
) ||
200 (Address
->Address
[0].AddressType
!= TDI_ADDRESS_TYPE_IP
)) {
201 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
203 return STATUS_INVALID_PARAMETER
;
206 /* Open address file object */
208 /* Protocol depends on device object so find the protocol */
209 if (DeviceObject
== TCPDeviceObject
)
210 Protocol
= IPPROTO_TCP
;
211 else if (DeviceObject
== UDPDeviceObject
)
212 Protocol
= IPPROTO_UDP
;
213 else if (DeviceObject
== IPDeviceObject
)
214 Protocol
= IPPROTO_RAW
;
215 else if (DeviceObject
== RawIPDeviceObject
) {
216 Status
= TiGetProtocolNumber(&IrpSp
->FileObject
->FileName
, &Protocol
);
217 if (!NT_SUCCESS(Status
)) {
218 TI_DbgPrint(MIN_TRACE
, ("Raw IP protocol number is invalid.\n"));
220 return STATUS_INVALID_PARAMETER
;
223 TI_DbgPrint(MIN_TRACE
, ("Invalid device object at (0x%X).\n", DeviceObject
));
225 return STATUS_INVALID_PARAMETER
;
228 Status
= FileOpenAddress(&Request
, Address
, Protocol
, NULL
);
229 if (NT_SUCCESS(Status
)) {
230 IrpSp
->FileObject
->FsContext2
= (PVOID
)TDI_TRANSPORT_ADDRESS_FILE
;
231 Context
->Handle
.AddressHandle
= Request
.Handle
.AddressHandle
;
234 TI_DbgPrint(MIN_TRACE
, ("Connection endpoint, and control connections are not supported.\n"));
235 /* FIXME: Open a connection endpoint, or control connection */
236 Status
= STATUS_NOT_IMPLEMENTED
;
239 if (!NT_SUCCESS(Status
))
242 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
248 VOID
TiCleanupFileObjectComplete(
252 * FUNCTION: Completes an object cleanup IRP I/O request
254 * Context = Pointer to the IRP for this request
255 * Status = Final status of the operation
259 PIO_STACK_LOCATION IrpSp
;
260 PTRANSPORT_CONTEXT TranContext
;
264 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
265 TranContext
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
267 Irp
->IoStatus
.Status
= Status
;
269 IoAcquireCancelSpinLock(&OldIrql
);
271 /* Remove the initial reference provided at object creation time */
272 TranContext
->RefCount
--;
275 if (TranContext
->RefCount
!= 0)
276 TI_DbgPrint(DEBUG_REFCOUNT
, ("TranContext->RefCount is %i, should be 0.\n", TranContext
->RefCount
));
279 KeSetEvent(&TranContext
->CleanupEvent
, 0, FALSE
);
281 IoReleaseCancelSpinLock(OldIrql
);
286 * FUNCTION: Releases resources used by a file object
288 * DeviceObject = Pointer to a device object for this driver
289 * Irp = Pointer to a I/O request packet
291 * Status of the operation
293 * This function does not pend
295 NTSTATUS
TiCleanupFileObject(
296 PDEVICE_OBJECT DeviceObject
,
299 PIO_STACK_LOCATION IrpSp
;
300 PTRANSPORT_CONTEXT Context
;
305 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
306 Context
= IrpSp
->FileObject
->FsContext
;
308 TI_DbgPrint(MIN_TRACE
, ("Parameters are invalid.\n"));
309 return STATUS_INVALID_PARAMETER
;
312 IoAcquireCancelSpinLock(&OldIrql
);
314 Context
->CancelIrps
= TRUE
;
315 KeResetEvent(&Context
->CleanupEvent
);
317 IoReleaseCancelSpinLock(OldIrql
);
319 Request
.RequestNotifyObject
= TiCleanupFileObjectComplete
;
320 Request
.RequestContext
= Irp
;
322 switch ((ULONG_PTR
)IrpSp
->FileObject
->FsContext2
) {
323 case TDI_TRANSPORT_ADDRESS_FILE
:
324 Request
.Handle
.AddressHandle
= Context
->Handle
.AddressHandle
;
325 Status
= FileCloseAddress(&Request
);
328 case TDI_CONNECTION_FILE
:
329 Request
.Handle
.ConnectionContext
= Context
->Handle
.ConnectionContext
;
330 Status
= FileCloseConnection(&Request
);
333 case TDI_CONTROL_CHANNEL_FILE
:
334 Request
.Handle
.ControlChannel
= Context
->Handle
.ControlChannel
;
335 Status
= FileCloseControlChannel(&Request
);
339 /* This should never happen */
341 TI_DbgPrint(MIN_TRACE
, ("Unknown transport context.\n"));
343 IoAcquireCancelSpinLock(&OldIrql
);
344 Context
->CancelIrps
= FALSE
;
345 IoReleaseCancelSpinLock(OldIrql
);
347 return STATUS_INVALID_PARAMETER
;
350 if (Status
!= STATUS_PENDING
)
351 TiCleanupFileObjectComplete(Irp
, Status
);
353 KeWaitForSingleObject(&Context
->CleanupEvent
,
354 UserRequest
, KernelMode
, FALSE
, NULL
);
356 return Irp
->IoStatus
.Status
;
365 PDEVICE_OBJECT DeviceObject
,
368 * FUNCTION: Main dispath routine
370 * DeviceObject = Pointer to a device object for this driver
371 * Irp = Pointer to a I/O request packet
373 * Status of the operation
376 PIO_STACK_LOCATION IrpSp
;
378 PTRANSPORT_CONTEXT Context
;
380 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject
, Irp
));
382 IoMarkIrpPending(Irp
);
383 Irp
->IoStatus
.Status
= STATUS_PENDING
;
384 Irp
->IoStatus
.Information
= 0;
386 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
388 switch (IrpSp
->MajorFunction
) {
389 /* Open an address file, connection endpoint, or control connection */
391 Status
= TiCreateFileObject(DeviceObject
, Irp
);
394 /* Close an address file, connection endpoint, or control connection */
396 Context
= (PTRANSPORT_CONTEXT
)IrpSp
->FileObject
->FsContext
;
399 Status
= STATUS_SUCCESS
;
402 /* Release resources bound to an address file, connection endpoint,
403 or control connection */
405 Status
= TiCleanupFileObject(DeviceObject
, Irp
);
409 Status
= STATUS_INVALID_DEVICE_REQUEST
;
412 if (Status
!= STATUS_PENDING
) {
413 IrpSp
->Control
&= ~SL_PENDING_RETURNED
;
414 Irp
->IoStatus
.Status
= Status
;
416 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
418 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
421 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status is (0x%X)\n", Status
));
432 PDEVICE_OBJECT DeviceObject
,
435 * FUNCTION: Internal IOCTL dispatch routine
437 * DeviceObject = Pointer to a device object for this driver
438 * Irp = Pointer to a I/O request packet
440 * Status of the operation
444 PIO_STACK_LOCATION IrpSp
;
446 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
448 TI_DbgPrint(DEBUG_IRP
, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
449 DeviceObject
, Irp
, IrpSp
->MinorFunction
));
451 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
452 Irp
->IoStatus
.Information
= 0;
454 switch (IrpSp
->MinorFunction
) {
456 Status
= DispTdiReceive(Irp
);
459 case TDI_RECEIVE_DATAGRAM
:
460 Status
= DispTdiReceiveDatagram(Irp
);
464 Status
= DispTdiSend(Irp
);
467 case TDI_SEND_DATAGRAM
:
468 Status
= DispTdiSendDatagram(Irp
);
472 Status
= DispTdiAccept(Irp
);
476 Status
= DispTdiListen(Irp
);
480 Status
= DispTdiConnect(Irp
);
484 Status
= DispTdiDisconnect(Irp
);
487 case TDI_ASSOCIATE_ADDRESS
:
488 Status
= DispTdiAssociateAddress(Irp
);
491 case TDI_DISASSOCIATE_ADDRESS
:
492 Status
= DispTdiDisassociateAddress(Irp
);
495 case TDI_QUERY_INFORMATION
:
496 Status
= DispTdiQueryInformation(DeviceObject
, Irp
);
499 case TDI_SET_INFORMATION
:
500 Status
= DispTdiSetInformation(Irp
);
503 case TDI_SET_EVENT_HANDLER
:
504 Status
= DispTdiSetEventHandler(Irp
);
508 Status
= STATUS_SUCCESS
;
511 /* An unsupported IOCTL code was submitted */
513 Status
= STATUS_INVALID_DEVICE_REQUEST
;
516 if (Status
!= STATUS_PENDING
) {
517 Irp
->IoStatus
.Status
= Status
;
519 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
521 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
524 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
535 PDEVICE_OBJECT DeviceObject
,
538 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
540 * DeviceObject = Pointer to a device object for this driver
541 * Irp = Pointer to a I/O request packet
543 * Status of the operation
547 PIO_STACK_LOCATION IrpSp
;
549 TI_DbgPrint(DEBUG_IRP
, ("Called. IRP is at (0x%X).\n", Irp
));
551 Irp
->IoStatus
.Information
= 0;
553 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
555 Status
= TdiMapUserRequest(DeviceObject
, Irp
, IrpSp
);
556 if (NT_SUCCESS(Status
)) {
557 TiDispatchInternal(DeviceObject
, Irp
);
558 Status
= STATUS_PENDING
;
563 /* See if this request is TCP/IP specific */
564 switch (IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
) {
565 case IOCTL_TCP_QUERY_INFORMATION_EX
:
566 Status
= DispTdiQueryInformationEx(Irp
, IrpSp
);
569 case IOCTL_TCP_SET_INFORMATION_EX
:
570 Status
= DispTdiSetInformationEx(Irp
, IrpSp
);
574 TI_DbgPrint(MIN_TRACE
, ("Unknown IOCTL 0x%X\n",
575 IrpSp
->Parameters
.DeviceIoControl
.IoControlCode
));
576 Status
= STATUS_NOT_IMPLEMENTED
;
581 if (Status
!= STATUS_PENDING
) {
582 Irp
->IoStatus
.Status
= Status
;
584 TI_DbgPrint(DEBUG_IRP
, ("Completing IRP at (0x%X).\n", Irp
));
586 IoCompleteRequest(Irp
, IO_NETWORK_INCREMENT
);
589 TI_DbgPrint(DEBUG_IRP
, ("Leaving. Status = (0x%X).\n", Status
));
596 PDRIVER_OBJECT DriverObject
)
598 * FUNCTION: Unloads the driver
600 * DriverObject = Pointer to driver object created by the system
606 KeAcquireSpinLock(&AddressFileListLock
, &OldIrql
);
607 if (!IsListEmpty(&AddressFileListHead
)) {
608 TI_DbgPrint(MIN_TRACE
, ("Open address file objects exists.\n"));
610 KeReleaseSpinLock(&AddressFileListLock
, OldIrql
);
613 /* Unregister loopback adapter */
614 LoopUnregisterAdapter(NULL
);
616 /* Unregister protocol with NDIS */
617 LANUnregisterProtocol();
619 /* Shutdown transport level protocol subsystems */
625 /* Shutdown network level protocol subsystem */
628 /* Free NDIS buffer descriptors */
629 if (GlobalBufferPool
)
630 NdisFreeBufferPool(GlobalBufferPool
);
632 /* Free NDIS packet descriptors */
633 if (GlobalPacketPool
)
634 NdisFreePacketPool(GlobalPacketPool
);
636 /* Release all device objects */
639 IoDeleteDevice(TCPDeviceObject
);
642 IoDeleteDevice(UDPDeviceObject
);
644 if (RawIPDeviceObject
)
645 IoDeleteDevice(RawIPDeviceObject
);
648 IoDeleteDevice(IPDeviceObject
);
651 ExFreePool(EntityList
);
653 TI_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
662 PDRIVER_OBJECT DriverObject
,
663 PUNICODE_STRING RegistryPath
)
665 * FUNCTION: Main driver entry point
667 * DriverObject = Pointer to a driver object for this driver
668 * RegistryPath = Registry node for configuration parameters
670 * Status of driver initialization
674 UNICODE_STRING strDeviceName
;
675 STRING strNdisDeviceName
;
676 NDIS_STATUS NdisStatus
;
677 PLAN_ADAPTER Adapter
;
678 NDIS_STRING DeviceName
;
680 TI_DbgPrint(MAX_TRACE
, ("Called.\n"));
682 /* FIXME: Create symbolic links in Win32 namespace */
684 /* Create IP device object */
685 RtlInitUnicodeString(&strDeviceName
, DD_IP_DEVICE_NAME
);
686 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
687 FILE_DEVICE_NETWORK
, 0, FALSE
, &IPDeviceObject
);
688 if (!NT_SUCCESS(Status
)) {
689 TI_DbgPrint(MIN_TRACE
, ("Failed to create IP device object. Status (0x%X).\n", Status
));
693 /* Create RawIP device object */
694 RtlInitUnicodeString(&strDeviceName
, DD_RAWIP_DEVICE_NAME
);
695 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
696 FILE_DEVICE_NETWORK
, 0, FALSE
, &RawIPDeviceObject
);
697 if (!NT_SUCCESS(Status
)) {
698 TI_DbgPrint(MIN_TRACE
, ("Failed to create RawIP device object. Status (0x%X).\n", Status
));
699 TiUnload(DriverObject
);
703 /* Create UDP device object */
704 RtlInitUnicodeString(&strDeviceName
, DD_UDP_DEVICE_NAME
);
705 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
706 FILE_DEVICE_NETWORK
, 0, FALSE
, &UDPDeviceObject
);
707 if (!NT_SUCCESS(Status
)) {
708 TI_DbgPrint(MIN_TRACE
, ("Failed to create UDP device object. Status (0x%X).\n", Status
));
709 TiUnload(DriverObject
);
713 /* Create TCP device object */
714 RtlInitUnicodeString(&strDeviceName
, DD_TCP_DEVICE_NAME
);
715 Status
= IoCreateDevice(DriverObject
, 0, &strDeviceName
,
716 FILE_DEVICE_NETWORK
, 0, FALSE
, &TCPDeviceObject
);
717 if (!NT_SUCCESS(Status
)) {
718 TI_DbgPrint(MIN_TRACE
, ("Failed to create TCP device object. Status (0x%X).\n", Status
));
719 TiUnload(DriverObject
);
723 /* Allocate NDIS packet descriptors */
724 NdisAllocatePacketPool(&NdisStatus
, &GlobalPacketPool
, 100, sizeof(PACKET_CONTEXT
));
725 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
726 TiUnload(DriverObject
);
727 return STATUS_INSUFFICIENT_RESOURCES
;
730 /* Allocate NDIS buffer descriptors */
731 NdisAllocateBufferPool(&NdisStatus
, &GlobalBufferPool
, 100);
732 if (NdisStatus
!= NDIS_STATUS_SUCCESS
) {
733 TiUnload(DriverObject
);
734 return STATUS_INSUFFICIENT_RESOURCES
;
737 /* Initialize address file list and protecting spin lock */
738 InitializeListHead(&AddressFileListHead
);
739 KeInitializeSpinLock(&AddressFileListLock
);
741 /* Initialize interface list and protecting spin lock */
742 InitializeListHead(&InterfaceListHead
);
743 KeInitializeSpinLock(&InterfaceListLock
);
745 /* Initialize network level protocol subsystem */
746 IPStartup(DriverObject
, RegistryPath
);
748 /* Initialize transport level protocol subsystems */
754 /* Register protocol with NDIS */
755 RtlInitString(&strNdisDeviceName
, IP_DEVICE_NAME
);
756 Status
= LANRegisterProtocol(&strNdisDeviceName
);
757 if (!NT_SUCCESS(Status
)) {
760 EVENT_TRANSPORT_REGISTER_FAILED
,
761 TI_ERROR_DRIVERENTRY
,
766 TiUnload(DriverObject
);
770 /* Open loopback adapter */
771 if (!NT_SUCCESS(LoopRegisterAdapter(NULL
, NULL
))) {
772 TI_DbgPrint(MIN_TRACE
, ("Failed to create loopback adapter. Status (0x%X).\n", Status
));
773 TiUnload(DriverObject
);
774 return STATUS_INSUFFICIENT_RESOURCES
;
777 /* Open underlying adapter(s) we are bound to */
779 /* FIXME: Get binding information from registry */
781 /* Put your own NDIS adapter device name here */
784 NdisInitUnicodeString(&DeviceName
, L
"\\Device\\ne2000");
787 //NdisInitUnicodeString(&DeviceName, L"\\Device\\El90x1");
790 //NdisInitUnicodeString(&DeviceName, L"\\Device\\{56388B49-67BB-4419-A3F4-28DF190B9149}");
792 NdisStatus
= LANRegisterAdapter(&DeviceName
, &Adapter
);
794 /* Skip network adapter if it does not exist */
795 if (!NT_SUCCESS(NdisStatus
)) {
796 TI_DbgPrint(MIN_TRACE
, ("Failed to intialize adapter. Status (0x%X).\n", Status
));
799 EVENT_TRANSPORT_ADAPTER_NOT_FOUND
,
800 TI_ERROR_DRIVERENTRY
,
805 TiUnload(DriverObject
);
806 return STATUS_DEVICE_DOES_NOT_EXIST
;
809 /* Setup network layer and transport layer entities */
810 EntityList
= ExAllocatePool(NonPagedPool
, sizeof(TDIEntityID
) * 2);
811 if (!NT_SUCCESS(Status
)) {
812 TiUnload(DriverObject
);
813 return STATUS_INSUFFICIENT_RESOURCES
;
816 EntityList
[0].tei_entity
= CL_NL_ENTITY
;
817 EntityList
[0].tei_instance
= 0;
818 EntityList
[1].tei_entity
= CL_TL_ENTITY
;
819 EntityList
[1].tei_instance
= 0;
823 IPDeviceObject
->Flags
|= DO_DIRECT_IO
;
824 RawIPDeviceObject
->Flags
|= DO_DIRECT_IO
;
825 UDPDeviceObject
->Flags
|= DO_DIRECT_IO
;
826 TCPDeviceObject
->Flags
|= DO_DIRECT_IO
;
828 /* Initialize the driver object with this driver's entry points */
829 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = TiDispatchOpenClose
;
830 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = TiDispatchOpenClose
;
831 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = TiDispatchOpenClose
;
832 DriverObject
->MajorFunction
[IRP_MJ_INTERNAL_DEVICE_CONTROL
] = TiDispatchInternal
;
833 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = TiDispatch
;
835 DriverObject
->DriverUnload
= (PDRIVER_UNLOAD
)TiUnload
;
837 return STATUS_SUCCESS
;