2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: Transport Driver Interface functions
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
25 if ((DebugTraceLevel
& MAX_TRACE
) == 0)
29 AFD_DbgPrint(MIN_TRACE
, ("Cannot display null buffer.\n"));
33 AFD_DbgPrint(MIN_TRACE
, ("Displaying buffer at (0x%X) Size (%d).\n", Buffer
, Size
));
36 for (i
= 0; i
< Size
; i
++) {
39 DbgPrint("%02X ", (p
[i
]) & 0xFF);
47 PDEVICE_OBJECT DeviceObject
,
49 PIO_STATUS_BLOCK Iosb
)
51 * FUNCTION: Calls a transport driver device
53 * Irp = Pointer to I/O Request Packet
54 * DeviceObject = Pointer to device object to call
55 * Event = An optional pointer to an event handle that will be
57 * Iosb = Pointer to an IO status block
64 AFD_DbgPrint(MID_TRACE
, ("Called\n"));
66 AFD_DbgPrint(MID_TRACE
, ("Irp->UserEvent = %x\n", Irp
->UserEvent
));
68 Status
= IoCallDriver(DeviceObject
, Irp
);
69 AFD_DbgPrint(MID_TRACE
, ("IoCallDriver: %08x\n", Status
));
71 if ((Status
== STATUS_PENDING
) && (Event
!= NULL
)) {
72 AFD_DbgPrint(MAX_TRACE
, ("Waiting on transport.\n"));
73 KeWaitForSingleObject(
79 Status
= Iosb
->Status
;
82 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
88 NTSTATUS
TdiOpenDevice(
89 PUNICODE_STRING DeviceName
,
91 PFILE_FULL_EA_INFORMATION EaInfo
,
95 * FUNCTION: Opens a device
97 * DeviceName = Pointer to counted string with name of device
98 * EaLength = Length of EA information
99 * EaInfo = Pointer to buffer with EA information
100 * Handle = Address of buffer to place device handle
101 * Object = Address of buffer to place device object
103 * Status of operation
106 OBJECT_ATTRIBUTES Attr
;
107 IO_STATUS_BLOCK Iosb
;
110 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ)\n", DeviceName
));
112 InitializeObjectAttributes(&Attr
, /* Attribute buffer */
113 DeviceName
, /* Device name */
114 OBJ_CASE_INSENSITIVE
, /* Attributes */
115 NULL
, /* Root directory */
116 NULL
); /* Security descriptor */
118 Status
= ZwCreateFile(Handle
, /* Return file handle */
119 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, /* Desired access */
120 &Attr
, /* Object attributes */
121 &Iosb
, /* IO status */
122 0, /* Initial allocation size */
123 FILE_ATTRIBUTE_NORMAL
, /* File attributes */
124 FILE_SHARE_READ
| FILE_SHARE_WRITE
, /* Share access */
125 FILE_OPEN_IF
, /* Create disposition */
126 0, /* Create options */
127 EaInfo
, /* EA buffer */
128 EaLength
); /* EA length */
129 if (NT_SUCCESS(Status
)) {
130 Status
= ObReferenceObjectByHandle(*Handle
, /* Handle to open file */
131 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, /* Access mode */
132 NULL
, /* Object type */
133 KernelMode
, /* Access mode */
134 (PVOID
*)Object
, /* Pointer to object */
135 NULL
); /* Handle information */
136 if (!NT_SUCCESS(Status
)) {
137 AFD_DbgPrint(MIN_TRACE
, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status
));
140 AFD_DbgPrint(MAX_TRACE
, ("Got handle (0x%X) Object (0x%X)\n",
144 AFD_DbgPrint(MIN_TRACE
, ("ZwCreateFile() failed with status (0x%X)\n", Status
));
151 NTSTATUS
TdiCloseDevice(
153 PFILE_OBJECT FileObject
)
155 AFD_DbgPrint(MAX_TRACE
, ("Called. Handle (0x%X) FileObject (0x%X)\n",
156 Handle
, FileObject
));
162 ObDereferenceObject(FileObject
);
164 return STATUS_SUCCESS
;
168 NTSTATUS
TdiOpenAddressFile(
169 PUNICODE_STRING DeviceName
,
170 PTRANSPORT_ADDRESS Name
,
171 PHANDLE AddressHandle
,
172 PFILE_OBJECT
*AddressObject
)
174 * FUNCTION: Opens an IPv4 address file object
176 * DeviceName = Pointer to counted string with name of device
177 * Name = Pointer to socket name (IPv4 address family)
178 * AddressHandle = Address of buffer to place address file handle
179 * AddressObject = Address of buffer to place address file object
181 * Status of operation
184 PFILE_FULL_EA_INFORMATION EaInfo
;
187 PTRANSPORT_ADDRESS Address
;
189 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ) Name (0x%X)\n",
192 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
193 EaLength
= sizeof(FILE_FULL_EA_INFORMATION
) +
194 TDI_TRANSPORT_ADDRESS_LENGTH
+
195 TaLengthOfTransportAddress( Name
) + 1;
196 EaInfo
= (PFILE_FULL_EA_INFORMATION
)ExAllocatePool(NonPagedPool
, EaLength
);
198 return STATUS_INSUFFICIENT_RESOURCES
;
200 RtlZeroMemory(EaInfo
, EaLength
);
201 EaInfo
->EaNameLength
= TDI_TRANSPORT_ADDRESS_LENGTH
;
202 /* Don't copy the terminating 0; we have already zeroed it */
203 RtlCopyMemory(EaInfo
->EaName
,
205 TDI_TRANSPORT_ADDRESS_LENGTH
);
206 EaInfo
->EaValueLength
= sizeof(TA_IP_ADDRESS
);
208 (PTRANSPORT_ADDRESS
)(EaInfo
->EaName
+ TDI_TRANSPORT_ADDRESS_LENGTH
+ 1); /* 0-terminated */
209 TaCopyTransportAddressInPlace( Address
, Name
);
211 Status
= TdiOpenDevice(DeviceName
,
221 NTSTATUS
TdiOpenConnectionEndpointFile(
222 PUNICODE_STRING DeviceName
,
223 PHANDLE ConnectionHandle
,
224 PFILE_OBJECT
*ConnectionObject
)
226 * FUNCTION: Opens a connection endpoint file object
228 * DeviceName = Pointer to counted string with name of device
229 * ConnectionHandle = Address of buffer to place connection endpoint file handle
230 * ConnectionObject = Address of buffer to place connection endpoint file object
232 * Status of operation
235 PFILE_FULL_EA_INFORMATION EaInfo
;
240 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ)\n", DeviceName
));
242 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
243 EaLength
= sizeof(FILE_FULL_EA_INFORMATION
) +
244 TDI_CONNECTION_CONTEXT_LENGTH
+
247 EaInfo
= (PFILE_FULL_EA_INFORMATION
)ExAllocatePool(NonPagedPool
, EaLength
);
249 return STATUS_INSUFFICIENT_RESOURCES
;
251 RtlZeroMemory(EaInfo
, EaLength
);
252 EaInfo
->EaNameLength
= TDI_CONNECTION_CONTEXT_LENGTH
;
253 /* Don't copy the terminating 0; we have already zeroed it */
254 RtlCopyMemory(EaInfo
->EaName
,
255 TdiConnectionContext
,
256 TDI_CONNECTION_CONTEXT_LENGTH
);
257 EaInfo
->EaValueLength
= sizeof(PVOID
);
258 ContextArea
= (PVOID
*)(EaInfo
->EaName
+ TDI_CONNECTION_CONTEXT_LENGTH
+ 1); /* 0-terminated */
259 /* FIXME: Allocate context area */
261 Status
= TdiOpenDevice(DeviceName
,
273 PFILE_OBJECT ConnectionObject
,
274 PTDI_CONNECTION_INFORMATION RemoteAddress
,
275 PIO_STATUS_BLOCK Iosb
,
276 PIO_COMPLETION_ROUTINE CompletionRoutine
,
277 PVOID CompletionContext
)
279 * FUNCTION: Connect a connection endpoint to a remote peer
281 * ConnectionObject = Pointer to connection endpoint file object
282 * RemoteAddress = Pointer to remote address
284 * Status of operation
287 PDEVICE_OBJECT DeviceObject
;
290 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
292 assert(ConnectionObject
);
294 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
296 *Irp
= TdiBuildInternalDeviceControlIrp(TDI_CONNECT
, /* Sub function */
297 DeviceObject
, /* Device object */
298 ConnectionObject
, /* File object */
302 return STATUS_INSUFFICIENT_RESOURCES
;
305 TdiBuildConnect(*Irp
, /* IRP */
306 DeviceObject
, /* Device object */
307 ConnectionObject
, /* File object */
308 CompletionRoutine
, /* Completion routine */
309 CompletionContext
, /* Completion routine context */
311 RemoteAddress
, /* Request connection information */
312 RemoteAddress
); /* Return connection information */
314 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
320 NTSTATUS
TdiAssociateAddressFile(
321 HANDLE AddressHandle
,
322 PFILE_OBJECT ConnectionObject
)
324 * FUNCTION: Associates a connection endpoint to an address file object
326 * AddressHandle = Handle to address file object
327 * ConnectionObject = Connection endpoint file object
329 * Status of operation
332 PDEVICE_OBJECT DeviceObject
;
333 IO_STATUS_BLOCK Iosb
;
338 AFD_DbgPrint(MAX_TRACE
, ("Called. AddressHandle (0x%X) ConnectionObject (0x%X)\n",
339 AddressHandle
, ConnectionObject
));
341 assert(ConnectionObject
);
343 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
345 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
347 Irp
= TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS
, /* Sub function */
348 DeviceObject
, /* Device object */
349 ConnectionObject
, /* File object */
353 return STATUS_INSUFFICIENT_RESOURCES
;
355 TdiBuildAssociateAddress(Irp
,
362 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
370 PFILE_OBJECT ConnectionObject
,
371 PTDI_CONNECTION_INFORMATION
*RequestConnectionInfo
,
372 PTDI_CONNECTION_INFORMATION
*ReturnConnectionInfo
,
373 PIO_STATUS_BLOCK Iosb
,
374 PIO_COMPLETION_ROUTINE CompletionRoutine
,
375 PVOID CompletionContext
)
377 * FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
379 * CompletionRoutine = Routine to be called when IRP is completed
380 * CompletionContext = Context for CompletionRoutine
382 * Status of operation
383 * May return STATUS_PENDING
386 PDEVICE_OBJECT DeviceObject
;
389 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
391 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
393 Status
= TdiBuildNullConnectionInfo(RequestConnectionInfo
,
394 TDI_ADDRESS_TYPE_IP
);
395 if (!NT_SUCCESS(Status
))
398 *Irp
= TdiBuildInternalDeviceControlIrp(TDI_LISTEN
, /* Sub function */
399 DeviceObject
, /* Device object */
400 ConnectionObject
, /* File object */
405 ExFreePool(*RequestConnectionInfo
);
406 return STATUS_INSUFFICIENT_RESOURCES
;
409 TdiBuildListen(*Irp
, /* IRP */
410 DeviceObject
, /* Device object */
411 ConnectionObject
, /* File object */
412 CompletionRoutine
, /* Completion routine */
413 CompletionContext
, /* Completion routine context */
415 *RequestConnectionInfo
, /* Request connection information */
416 *ReturnConnectionInfo
); /* Return connection information */
418 Status
= TdiCall(*Irp
, DeviceObject
, NULL
/* Don't wait for completion */, Iosb
);
424 NTSTATUS
TdiSetEventHandler(
425 PFILE_OBJECT FileObject
,
430 * FUNCTION: Sets or resets an event handler
432 * FileObject = Pointer to file object
433 * EventType = Event code
434 * Handler = Event handler to be called when the event occurs
435 * Context = Context input to handler when the event occurs
437 * Status of operation
439 * Specify NULL for Handler to stop calling event handler
442 PDEVICE_OBJECT DeviceObject
;
443 IO_STATUS_BLOCK Iosb
;
448 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
452 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
454 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
456 Irp
= TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER
, /* Sub function */
457 DeviceObject
, /* Device object */
458 FileObject
, /* File object */
462 return STATUS_INSUFFICIENT_RESOURCES
;
466 TdiBuildSetEventHandler(Irp
,
475 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
481 NTSTATUS
TdiQueryDeviceControl(
482 PFILE_OBJECT FileObject
,
485 ULONG InputBufferLength
,
487 ULONG OutputBufferLength
,
490 * FUNCTION: Queries a device for information
492 * FileObject = Pointer to file object
493 * IoControlCode = I/O control code
494 * InputBuffer = Pointer to buffer with input data
495 * InputBufferLength = Length of InputBuffer
496 * OutputBuffer = Address of buffer to place output data
497 * OutputBufferLength = Length of OutputBuffer
499 * Status of operation
502 PDEVICE_OBJECT DeviceObject
;
503 IO_STATUS_BLOCK Iosb
;
508 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
510 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
512 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
522 return STATUS_INSUFFICIENT_RESOURCES
;
524 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
527 *Return
= Iosb
.Information
;
533 NTSTATUS
TdiQueryInformation(
534 PFILE_OBJECT FileObject
,
538 * FUNCTION: Query for information
540 * FileObject = Pointer to file object
541 * QueryType = Query type
542 * MdlBuffer = Pointer to MDL buffer specific for query type
544 * Status of operation
547 PDEVICE_OBJECT DeviceObject
;
548 IO_STATUS_BLOCK Iosb
;
553 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
555 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
557 Irp
= TdiBuildInternalDeviceControlIrp(IOCTL_TCP_QUERY_INFORMATION
, /* Sub function */
558 DeviceObject
, /* Device object */
559 ConnectionObject
, /* File object */
563 return STATUS_INSUFFICIENT_RESOURCES
;
566 TdiBuildQueryInformation(
575 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
581 NTSTATUS
TdiQueryInformationEx(
582 PFILE_OBJECT FileObject
,
591 * FUNCTION: Extended query for information
593 * FileObject = Pointer to file object
595 * Instance = Instance
596 * Class = Entity class
599 * OutputBuffer = Address of buffer to place data
600 * OutputLength = Address of buffer with length of OutputBuffer (updated)
602 * Status of operation
605 TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo
;
607 RtlZeroMemory(&QueryInfo
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
608 QueryInfo
.ID
.toi_entity
.tei_entity
= Entity
;
609 QueryInfo
.ID
.toi_entity
.tei_instance
= Instance
;
610 QueryInfo
.ID
.toi_class
= Class
;
611 QueryInfo
.ID
.toi_type
= Type
;
612 QueryInfo
.ID
.toi_id
= Id
;
614 return TdiQueryDeviceControl(FileObject
, /* Transport/connection object */
615 IOCTL_TCP_QUERY_INFORMATION_EX
, /* Control code */
616 &QueryInfo
, /* Input buffer */
617 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
), /* Input buffer length */
618 OutputBuffer
, /* Output buffer */
619 *OutputLength
, /* Output buffer length */
620 OutputLength
); /* Return information */
623 NTSTATUS
TdiQueryAddress(
624 PFILE_OBJECT FileObject
,
627 * FUNCTION: Queries for a local IP address
629 * FileObject = Pointer to file object
630 * Address = Address of buffer to place local address
632 * Status of operation
636 TDIEntityID
*Entities
;
639 IPSNMP_INFO SnmpInfo
;
640 PIPADDR_ENTRY IpAddress
;
642 NTSTATUS Status
= STATUS_SUCCESS
;
644 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
646 BufferSize
= sizeof(TDIEntityID
) * 20;
647 Entities
= (TDIEntityID
*)ExAllocatePool(NonPagedPool
, BufferSize
);
649 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
650 return STATUS_INSUFFICIENT_RESOURCES
;
653 /* Query device for supported entities */
655 Status
= TdiQueryInformationEx(FileObject
, /* File object */
656 GENERIC_ENTITY
, /* Entity */
657 TL_INSTANCE
, /* Instance */
658 INFO_CLASS_GENERIC
, /* Entity class */
659 INFO_TYPE_PROVIDER
, /* Entity type */
660 ENTITY_LIST_ID
, /* Entity id */
661 Entities
, /* Output buffer */
662 &BufferSize
); /* Output buffer size */
663 if (!NT_SUCCESS(Status
)) {
664 AFD_DbgPrint(MIN_TRACE
, ("Unable to get list of supported entities (Status = 0x%X).\n", Status
));
665 ExFreePool(Entities
);
669 /* Locate an IP entity */
670 EntityCount
= BufferSize
/ sizeof(TDIEntityID
);
672 AFD_DbgPrint(MAX_TRACE
, ("EntityCount = %d\n", EntityCount
));
674 for (i
= 0; i
< EntityCount
; i
++) {
675 if (Entities
[i
].tei_entity
== CL_NL_ENTITY
) {
676 /* Query device for entity type */
678 BufferSize
= sizeof(EntityType
);
679 Status
= TdiQueryInformationEx(FileObject
, /* File object */
680 CL_NL_ENTITY
, /* Entity */
681 Entities
[i
].tei_instance
, /* Instance */
682 INFO_CLASS_GENERIC
, /* Entity class */
683 INFO_TYPE_PROVIDER
, /* Entity type */
684 ENTITY_TYPE_ID
, /* Entity id */
685 &EntityType
, /* Output buffer */
686 &BufferSize
); /* Output buffer size */
687 if (!NT_SUCCESS(Status
) || (EntityType
!= CL_NL_IP
)) {
688 AFD_DbgPrint(MIN_TRACE
, ("Unable to get entity of type IP (Status = 0x%X).\n", Status
));
692 /* Query device for SNMP information */
694 BufferSize
= sizeof(SnmpInfo
);
695 Status
= TdiQueryInformationEx(FileObject
, /* File object */
696 CL_NL_ENTITY
, /* Entity */
697 Entities
[i
].tei_instance
, /* Instance */
698 INFO_CLASS_PROTOCOL
, /* Entity class */
699 INFO_TYPE_PROVIDER
, /* Entity type */
700 IP_MIB_STATS_ID
, /* Entity id */
701 &SnmpInfo
, /* Output buffer */
702 &BufferSize
); /* Output buffer size */
703 if (!NT_SUCCESS(Status
) || (SnmpInfo
.NumAddr
== 0)) {
704 AFD_DbgPrint(MIN_TRACE
, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status
));
708 /* Query device for all IP addresses */
710 if (SnmpInfo
.NumAddr
!= 0) {
711 BufferSize
= SnmpInfo
.NumAddr
* sizeof(IPADDR_ENTRY
);
712 IpAddress
= (PIPADDR_ENTRY
)ExAllocatePool(NonPagedPool
, BufferSize
);
714 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
718 Status
= TdiQueryInformationEx(FileObject
, /* File object */
719 CL_NL_ENTITY
, /* Entity */
720 Entities
[i
].tei_instance
, /* Instance */
721 INFO_CLASS_PROTOCOL
, /* Entity class */
722 INFO_TYPE_PROVIDER
, /* Entity type */
723 IP_MIB_ADDRTABLE_ENTRY_ID
, /* Entity id */
724 IpAddress
, /* Output buffer */
725 &BufferSize
); /* Output buffer size */
726 if (!NT_SUCCESS(Status
)) {
727 AFD_DbgPrint(MIN_TRACE
, ("Unable to get IP address (Status = 0x%X).\n", Status
));
728 ExFreePool(IpAddress
);
732 if (SnmpInfo
.NumAddr
!= 1) {
733 /* Skip loopback address */
734 PIPADDR_ENTRY IpAddressEntry
= (PIPADDR_ENTRY
)
735 ((PCHAR
)IpAddress
) + sizeof(IPADDR_ENTRY
);
736 *Address
= DN2H(IpAddressEntry
->Addr
);
738 /* Select the first address returned */
739 *Address
= DN2H(IpAddress
->Addr
);
742 ExFreePool(IpAddress
);
744 Status
= STATUS_UNSUCCESSFUL
;
750 ExFreePool(Entities
);
752 AFD_DbgPrint(MAX_TRACE
, ("Leaving\n"));
760 PFILE_OBJECT TransportObject
,
764 PIO_STATUS_BLOCK Iosb
,
765 PIO_COMPLETION_ROUTINE CompletionRoutine
,
766 PVOID CompletionContext
)
768 PDEVICE_OBJECT DeviceObject
;
769 NTSTATUS Status
= STATUS_SUCCESS
;
772 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
774 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
775 return STATUS_INVALID_PARAMETER
;
778 *Irp
= TdiBuildInternalDeviceControlIrp
779 ( TDI_SEND
, /* Sub function */
780 DeviceObject
, /* Device object */
781 TransportObject
, /* File object */
786 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
787 return STATUS_INSUFFICIENT_RESOURCES
;
790 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
792 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
793 BufferLength
, /* Length of buffer */
794 FALSE
, /* Not secondary */
795 FALSE
, /* Don't charge quota */
798 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
800 return STATUS_INSUFFICIENT_RESOURCES
;
804 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
806 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
808 Status
= STATUS_INSUFFICIENT_RESOURCES
;
811 if( !NT_SUCCESS(Status
) ) {
816 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
818 TdiBuildSend(*Irp
, /* I/O Request Packet */
819 DeviceObject
, /* Device object */
820 TransportObject
, /* File object */
821 CompletionRoutine
, /* Completion routine */
822 CompletionContext
, /* Completion context */
823 Mdl
, /* Data buffer */
825 BufferLength
); /* Length of data */
827 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
828 /* Does not block... The MDL is deleted in the receive completion
836 PFILE_OBJECT TransportObject
,
840 PIO_STATUS_BLOCK Iosb
,
841 PIO_COMPLETION_ROUTINE CompletionRoutine
,
842 PVOID CompletionContext
)
844 NTSTATUS Status
= STATUS_SUCCESS
;
845 PDEVICE_OBJECT DeviceObject
;
848 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
850 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
851 return STATUS_INVALID_PARAMETER
;
854 *Irp
= TdiBuildInternalDeviceControlIrp
855 ( TDI_RECEIVE
, /* Sub function */
856 DeviceObject
, /* Device object */
857 TransportObject
, /* File object */
862 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
863 return STATUS_INSUFFICIENT_RESOURCES
;
866 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
868 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
869 BufferLength
, /* Length of buffer */
870 FALSE
, /* Not secondary */
871 FALSE
, /* Don't charge quota */
872 *Irp
); /* Don't use IRP */
874 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
876 return STATUS_INSUFFICIENT_RESOURCES
;
880 AFD_DbgPrint(MIN_TRACE
, ("probe and lock\n"));
881 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
882 AFD_DbgPrint(MIN_TRACE
, ("probe and lock done\n"));
884 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
886 Status
= STATUS_INSUFFICIENT_RESOURCES
;
889 if( !NT_SUCCESS(Status
) ) {
894 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
896 TdiBuildReceive(*Irp
, /* I/O Request Packet */
897 DeviceObject
, /* Device object */
898 TransportObject
, /* File object */
899 CompletionRoutine
, /* Completion routine */
900 CompletionContext
, /* Completion context */
901 Mdl
, /* Data buffer */
903 BufferLength
); /* Length of data */
906 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
907 /* Does not block... The MDL is deleted in the receive completion
910 AFD_DbgPrint(MID_TRACE
,("Status %x Information %d\n",
911 Status
, Iosb
->Information
));
917 NTSTATUS
TdiReceiveDatagram(
919 PFILE_OBJECT TransportObject
,
923 PTDI_CONNECTION_INFORMATION Addr
,
924 PIO_STATUS_BLOCK Iosb
,
925 PIO_COMPLETION_ROUTINE CompletionRoutine
,
926 PVOID CompletionContext
)
928 * FUNCTION: Receives a datagram
930 * TransportObject = Pointer to transport object
931 * From = Receive filter (NULL if none)
932 * Address = Address of buffer to place remote address
933 * Buffer = Address of buffer to place received data
934 * BufferSize = Address of buffer with length of Buffer (updated)
936 * Status of operation
939 PDEVICE_OBJECT DeviceObject
;
943 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
945 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
946 return STATUS_INVALID_PARAMETER
;
949 *Irp
= TdiBuildInternalDeviceControlIrp
950 ( TDI_RECEIVE_DATAGRAM
, /* Sub function */
951 DeviceObject
, /* Device object */
952 TransportObject
, /* File object */
957 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
958 return STATUS_INSUFFICIENT_RESOURCES
;
961 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
963 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
964 BufferLength
, /* Length of buffer */
965 FALSE
, /* Not secondary */
966 FALSE
, /* Don't charge quota */
967 *Irp
); /* Don't use IRP */
969 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
971 return STATUS_INSUFFICIENT_RESOURCES
;
975 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
977 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
979 return STATUS_INSUFFICIENT_RESOURCES
;
982 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
984 TdiBuildReceiveDatagram
985 (*Irp
, /* I/O Request Packet */
986 DeviceObject
, /* Device object */
987 TransportObject
, /* File object */
988 CompletionRoutine
, /* Completion routine */
989 CompletionContext
, /* Completion context */
990 Mdl
, /* Data buffer */
994 Flags
); /* Length of data */
996 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
997 /* Does not block... The MDL is deleted in the receive completion
1004 NTSTATUS
TdiSendDatagram(
1006 PFILE_OBJECT TransportObject
,
1009 PTDI_CONNECTION_INFORMATION Addr
,
1010 PIO_STATUS_BLOCK Iosb
,
1011 PIO_COMPLETION_ROUTINE CompletionRoutine
,
1012 PVOID CompletionContext
)
1014 * FUNCTION: Sends a datagram
1016 * TransportObject = Pointer to transport object
1017 * From = Send filter (NULL if none)
1018 * Address = Address of buffer to place remote address
1019 * Buffer = Address of buffer to place send data
1020 * BufferSize = Address of buffer with length of Buffer (updated)
1022 * Status of operation
1025 PDEVICE_OBJECT DeviceObject
;
1029 AFD_DbgPrint(MID_TRACE
,("Called(TransportObject %x)\n", TransportObject
));
1031 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1032 if (!DeviceObject
) {
1033 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
1034 return STATUS_INVALID_PARAMETER
;
1037 *Irp
= TdiBuildInternalDeviceControlIrp
1038 ( TDI_SEND_DATAGRAM
, /* Sub function */
1039 DeviceObject
, /* Device object */
1040 TransportObject
, /* File object */
1042 Iosb
); /* Status */
1045 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1046 return STATUS_INSUFFICIENT_RESOURCES
;
1049 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
1051 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
1052 BufferLength
, /* Length of buffer */
1053 FALSE
, /* Not secondary */
1054 FALSE
, /* Don't charge quota */
1055 *Irp
); /* Don't use IRP */
1058 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1060 return STATUS_INSUFFICIENT_RESOURCES
;
1064 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
1066 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
1068 return STATUS_INSUFFICIENT_RESOURCES
;
1071 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
1073 TdiBuildSendDatagram
1074 (*Irp
, /* I/O Request Packet */
1075 DeviceObject
, /* Device object */
1076 TransportObject
, /* File object */
1077 CompletionRoutine
, /* Completion routine */
1078 CompletionContext
, /* Completion context */
1079 Mdl
, /* Data buffer */
1080 BufferLength
, /* Bytes to send */
1081 Addr
); /* Address */
1083 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
1084 /* Does not block... The MDL is deleted in the send completion
1090 NTSTATUS
TdiDisconnect(
1091 PFILE_OBJECT TransportObject
,
1092 PLARGE_INTEGER Time
,
1094 PIO_STATUS_BLOCK Iosb
,
1095 PIO_COMPLETION_ROUTINE CompletionRoutine
,
1096 PVOID CompletionContext
,
1097 PTDI_CONNECTION_INFORMATION RequestConnectionInfo
,
1098 PTDI_CONNECTION_INFORMATION ReturnConnectionInfo
) {
1099 PDEVICE_OBJECT DeviceObject
;
1104 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1106 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1108 AFD_DbgPrint(MID_TRACE
,("Called(TransportObject %x)\n", TransportObject
));
1110 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1111 if (!DeviceObject
) {
1112 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
1113 return STATUS_INVALID_PARAMETER
;
1116 Irp
= TdiBuildInternalDeviceControlIrp
1117 ( TDI_SEND_DATAGRAM
, /* Sub function */
1118 DeviceObject
, /* Device object */
1119 TransportObject
, /* File object */
1121 Iosb
); /* Status */
1124 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1125 return STATUS_INSUFFICIENT_RESOURCES
;
1129 (Irp
, /* I/O Request Packet */
1130 DeviceObject
, /* Device object */
1131 TransportObject
, /* File object */
1132 CompletionRoutine
, /* Completion routine */
1133 CompletionContext
, /* Completion context */
1135 Flags
, /* Disconnect flags */
1136 RequestConnectionInfo
, /* Indication of who to disconnect */
1137 ReturnConnectionInfo
); /* Indication of who disconnected */
1139 Status
= TdiCall(Irp
, DeviceObject
, &Event
, Iosb
);