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
12 #include <pseh/pseh.h>
16 #include "tdi_proto.h"
20 static VOID
DisplayBuffer(
27 if ((DebugTraceLevel
& MAX_TRACE
) == 0)
31 AFD_DbgPrint(MIN_TRACE
, ("Cannot display null buffer.\n"));
35 AFD_DbgPrint(MIN_TRACE
, ("Displaying buffer at (0x%X) Size (%d).\n", Buffer
, Size
));
38 for (i
= 0; i
< Size
; i
++) {
41 DbgPrint("%02X ", (p
[i
]) & 0xFF);
48 static NTSTATUS
TdiCall(
50 PDEVICE_OBJECT DeviceObject
,
52 PIO_STATUS_BLOCK Iosb
)
54 * FUNCTION: Calls a transport driver device
56 * Irp = Pointer to I/O Request Packet
57 * DeviceObject = Pointer to device object to call
58 * Event = An optional pointer to an event handle that will be
60 * Iosb = Pointer to an IO status block
67 AFD_DbgPrint(MID_TRACE
, ("Called\n"));
69 AFD_DbgPrint(MID_TRACE
, ("Irp->UserEvent = %x\n", Irp
->UserEvent
));
71 Status
= IoCallDriver(DeviceObject
, Irp
);
72 AFD_DbgPrint(MID_TRACE
, ("IoCallDriver: %08x\n", Status
));
74 if ((Status
== STATUS_PENDING
) && (Event
!= NULL
)) {
75 AFD_DbgPrint(MAX_TRACE
, ("Waiting on transport.\n"));
76 KeWaitForSingleObject(
82 Status
= Iosb
->Status
;
85 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
91 static NTSTATUS
TdiOpenDevice(
92 PUNICODE_STRING DeviceName
,
94 PFILE_FULL_EA_INFORMATION EaInfo
,
98 * FUNCTION: Opens a device
100 * DeviceName = Pointer to counted string with name of device
101 * EaLength = Length of EA information
102 * EaInfo = Pointer to buffer with EA information
103 * Handle = Address of buffer to place device handle
104 * Object = Address of buffer to place device object
106 * Status of operation
109 OBJECT_ATTRIBUTES Attr
;
110 IO_STATUS_BLOCK Iosb
;
113 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ)\n", DeviceName
));
115 InitializeObjectAttributes(&Attr
, /* Attribute buffer */
116 DeviceName
, /* Device name */
117 OBJ_CASE_INSENSITIVE
, /* Attributes */
118 NULL
, /* Root directory */
119 NULL
); /* Security descriptor */
121 Status
= ZwCreateFile(Handle
, /* Return file handle */
122 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, /* Desired access */
123 &Attr
, /* Object attributes */
124 &Iosb
, /* IO status */
125 0, /* Initial allocation size */
126 FILE_ATTRIBUTE_NORMAL
, /* File attributes */
127 FILE_SHARE_READ
| FILE_SHARE_WRITE
, /* Share access */
128 FILE_OPEN_IF
, /* Create disposition */
129 0, /* Create options */
130 EaInfo
, /* EA buffer */
131 EaLength
); /* EA length */
132 if (NT_SUCCESS(Status
)) {
133 Status
= ObReferenceObjectByHandle(*Handle
, /* Handle to open file */
134 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, /* Access mode */
135 NULL
, /* Object type */
136 KernelMode
, /* Access mode */
137 (PVOID
*)Object
, /* Pointer to object */
138 NULL
); /* Handle information */
139 if (!NT_SUCCESS(Status
)) {
140 AFD_DbgPrint(MIN_TRACE
, ("ObReferenceObjectByHandle() failed with status (0x%X).\n", Status
));
143 AFD_DbgPrint(MAX_TRACE
, ("Got handle (0x%X) Object (0x%X)\n",
147 AFD_DbgPrint(MIN_TRACE
, ("ZwCreateFile() failed with status (0x%X)\n", Status
));
154 NTSTATUS
TdiCloseDevice(
156 PFILE_OBJECT FileObject
)
158 AFD_DbgPrint(MAX_TRACE
, ("Called. Handle (0x%X) FileObject (0x%X)\n",
159 Handle
, FileObject
));
165 ObDereferenceObject(FileObject
);
167 return STATUS_SUCCESS
;
171 NTSTATUS
TdiOpenAddressFile(
172 PUNICODE_STRING DeviceName
,
173 PTRANSPORT_ADDRESS Name
,
174 PHANDLE AddressHandle
,
175 PFILE_OBJECT
*AddressObject
)
177 * FUNCTION: Opens an IPv4 address file object
179 * DeviceName = Pointer to counted string with name of device
180 * Name = Pointer to socket name (IPv4 address family)
181 * AddressHandle = Address of buffer to place address file handle
182 * AddressObject = Address of buffer to place address file object
184 * Status of operation
187 PFILE_FULL_EA_INFORMATION EaInfo
;
190 PTRANSPORT_ADDRESS Address
;
192 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ) Name (0x%X)\n",
195 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
196 EaLength
= sizeof(FILE_FULL_EA_INFORMATION
) +
197 TDI_TRANSPORT_ADDRESS_LENGTH
+
198 TaLengthOfTransportAddress( Name
) + 1;
199 EaInfo
= (PFILE_FULL_EA_INFORMATION
)ExAllocatePool(NonPagedPool
, EaLength
);
201 return STATUS_INSUFFICIENT_RESOURCES
;
203 RtlZeroMemory(EaInfo
, EaLength
);
204 EaInfo
->EaNameLength
= TDI_TRANSPORT_ADDRESS_LENGTH
;
205 /* Don't copy the terminating 0; we have already zeroed it */
206 RtlCopyMemory(EaInfo
->EaName
,
208 TDI_TRANSPORT_ADDRESS_LENGTH
);
209 EaInfo
->EaValueLength
= sizeof(TA_IP_ADDRESS
);
211 (PTRANSPORT_ADDRESS
)(EaInfo
->EaName
+ TDI_TRANSPORT_ADDRESS_LENGTH
+ 1); /* 0-terminated */
212 TaCopyTransportAddressInPlace( Address
, Name
);
214 Status
= TdiOpenDevice(DeviceName
,
224 NTSTATUS
TdiOpenConnectionEndpointFile(
225 PUNICODE_STRING DeviceName
,
226 PHANDLE ConnectionHandle
,
227 PFILE_OBJECT
*ConnectionObject
)
229 * FUNCTION: Opens a connection endpoint file object
231 * DeviceName = Pointer to counted string with name of device
232 * ConnectionHandle = Address of buffer to place connection endpoint file handle
233 * ConnectionObject = Address of buffer to place connection endpoint file object
235 * Status of operation
238 PFILE_FULL_EA_INFORMATION EaInfo
;
243 AFD_DbgPrint(MAX_TRACE
, ("Called. DeviceName (%wZ)\n", DeviceName
));
245 /* EaName must be 0-terminated, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
246 EaLength
= sizeof(FILE_FULL_EA_INFORMATION
) +
247 TDI_CONNECTION_CONTEXT_LENGTH
+
250 EaInfo
= (PFILE_FULL_EA_INFORMATION
)ExAllocatePool(NonPagedPool
, EaLength
);
252 return STATUS_INSUFFICIENT_RESOURCES
;
254 RtlZeroMemory(EaInfo
, EaLength
);
255 EaInfo
->EaNameLength
= TDI_CONNECTION_CONTEXT_LENGTH
;
256 /* Don't copy the terminating 0; we have already zeroed it */
257 RtlCopyMemory(EaInfo
->EaName
,
258 TdiConnectionContext
,
259 TDI_CONNECTION_CONTEXT_LENGTH
);
260 EaInfo
->EaValueLength
= sizeof(PVOID
);
261 ContextArea
= (PVOID
*)(EaInfo
->EaName
+ TDI_CONNECTION_CONTEXT_LENGTH
+ 1); /* 0-terminated */
262 /* FIXME: Allocate context area */
264 Status
= TdiOpenDevice(DeviceName
,
276 PFILE_OBJECT ConnectionObject
,
277 PTDI_CONNECTION_INFORMATION RemoteAddress
,
278 PIO_STATUS_BLOCK Iosb
,
279 PIO_COMPLETION_ROUTINE CompletionRoutine
,
280 PVOID CompletionContext
)
282 * FUNCTION: Connect a connection endpoint to a remote peer
284 * ConnectionObject = Pointer to connection endpoint file object
285 * RemoteAddress = Pointer to remote address
287 * Status of operation
290 PDEVICE_OBJECT DeviceObject
;
293 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
295 assert(ConnectionObject
);
297 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
299 *Irp
= TdiBuildInternalDeviceControlIrp(TDI_CONNECT
, /* Sub function */
300 DeviceObject
, /* Device object */
301 ConnectionObject
, /* File object */
305 return STATUS_INSUFFICIENT_RESOURCES
;
308 TdiBuildConnect(*Irp
, /* IRP */
309 DeviceObject
, /* Device object */
310 ConnectionObject
, /* File object */
311 CompletionRoutine
, /* Completion routine */
312 CompletionContext
, /* Completion routine context */
314 RemoteAddress
, /* Request connection information */
315 RemoteAddress
); /* Return connection information */
317 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
323 NTSTATUS
TdiAssociateAddressFile(
324 HANDLE AddressHandle
,
325 PFILE_OBJECT ConnectionObject
)
327 * FUNCTION: Associates a connection endpoint to an address file object
329 * AddressHandle = Handle to address file object
330 * ConnectionObject = Connection endpoint file object
332 * Status of operation
335 PDEVICE_OBJECT DeviceObject
;
336 IO_STATUS_BLOCK Iosb
;
341 AFD_DbgPrint(MAX_TRACE
, ("Called. AddressHandle (0x%X) ConnectionObject (0x%X)\n",
342 AddressHandle
, ConnectionObject
));
344 assert(ConnectionObject
);
346 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
348 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
350 Irp
= TdiBuildInternalDeviceControlIrp(TDI_ASSOCIATE_ADDRESS
, /* Sub function */
351 DeviceObject
, /* Device object */
352 ConnectionObject
, /* File object */
356 return STATUS_INSUFFICIENT_RESOURCES
;
358 TdiBuildAssociateAddress(Irp
,
365 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
373 PFILE_OBJECT ConnectionObject
,
374 PTDI_CONNECTION_INFORMATION
*RequestConnectionInfo
,
375 PTDI_CONNECTION_INFORMATION
*ReturnConnectionInfo
,
376 PIO_STATUS_BLOCK Iosb
,
377 PIO_COMPLETION_ROUTINE CompletionRoutine
,
378 PVOID CompletionContext
)
380 * FUNCTION: Listen on a connection endpoint for a connection request from a remote peer
382 * CompletionRoutine = Routine to be called when IRP is completed
383 * CompletionContext = Context for CompletionRoutine
385 * Status of operation
386 * May return STATUS_PENDING
389 PDEVICE_OBJECT DeviceObject
;
392 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
394 DeviceObject
= IoGetRelatedDeviceObject(ConnectionObject
);
396 Status
= TdiBuildNullConnectionInfo(RequestConnectionInfo
,
397 TDI_ADDRESS_TYPE_IP
);
398 if (!NT_SUCCESS(Status
))
401 *Irp
= TdiBuildInternalDeviceControlIrp(TDI_LISTEN
, /* Sub function */
402 DeviceObject
, /* Device object */
403 ConnectionObject
, /* File object */
408 ExFreePool(*RequestConnectionInfo
);
409 return STATUS_INSUFFICIENT_RESOURCES
;
412 TdiBuildListen(*Irp
, /* IRP */
413 DeviceObject
, /* Device object */
414 ConnectionObject
, /* File object */
415 CompletionRoutine
, /* Completion routine */
416 CompletionContext
, /* Completion routine context */
418 *RequestConnectionInfo
, /* Request connection information */
419 *ReturnConnectionInfo
); /* Return connection information */
421 Status
= TdiCall(*Irp
, DeviceObject
, NULL
/* Don't wait for completion */, Iosb
);
427 NTSTATUS
TdiSetEventHandler(
428 PFILE_OBJECT FileObject
,
433 * FUNCTION: Sets or resets an event handler
435 * FileObject = Pointer to file object
436 * EventType = Event code
437 * Handler = Event handler to be called when the event occurs
438 * Context = Context input to handler when the event occurs
440 * Status of operation
442 * Specify NULL for Handler to stop calling event handler
445 PDEVICE_OBJECT DeviceObject
;
446 IO_STATUS_BLOCK Iosb
;
451 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
455 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
457 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
459 Irp
= TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER
, /* Sub function */
460 DeviceObject
, /* Device object */
461 FileObject
, /* File object */
465 return STATUS_INSUFFICIENT_RESOURCES
;
469 TdiBuildSetEventHandler(Irp
,
478 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
484 NTSTATUS
TdiQueryDeviceControl(
485 PFILE_OBJECT FileObject
,
488 ULONG InputBufferLength
,
490 ULONG OutputBufferLength
,
493 * FUNCTION: Queries a device for information
495 * FileObject = Pointer to file object
496 * IoControlCode = I/O control code
497 * InputBuffer = Pointer to buffer with input data
498 * InputBufferLength = Length of InputBuffer
499 * OutputBuffer = Address of buffer to place output data
500 * OutputBufferLength = Length of OutputBuffer
502 * Status of operation
505 PDEVICE_OBJECT DeviceObject
;
506 IO_STATUS_BLOCK Iosb
;
511 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
513 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
515 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
525 return STATUS_INSUFFICIENT_RESOURCES
;
527 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
530 *Return
= Iosb
.Information
;
536 NTSTATUS
TdiQueryInformation(
537 PFILE_OBJECT FileObject
,
541 * FUNCTION: Query for information
543 * FileObject = Pointer to file object
544 * QueryType = Query type
545 * MdlBuffer = Pointer to MDL buffer specific for query type
547 * Status of operation
550 PDEVICE_OBJECT DeviceObject
;
551 IO_STATUS_BLOCK Iosb
;
556 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
558 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
560 Irp
= TdiBuildInternalDeviceControlIrp(IOCTL_TCP_QUERY_INFORMATION
, /* Sub function */
561 DeviceObject
, /* Device object */
562 ConnectionObject
, /* File object */
566 return STATUS_INSUFFICIENT_RESOURCES
;
569 TdiBuildQueryInformation(
578 Status
= TdiCall(Irp
, DeviceObject
, &Event
, &Iosb
);
584 NTSTATUS
TdiQueryInformationEx(
585 PFILE_OBJECT FileObject
,
594 * FUNCTION: Extended query for information
596 * FileObject = Pointer to file object
598 * Instance = Instance
599 * Class = Entity class
602 * OutputBuffer = Address of buffer to place data
603 * OutputLength = Address of buffer with length of OutputBuffer (updated)
605 * Status of operation
608 TCP_REQUEST_QUERY_INFORMATION_EX QueryInfo
;
610 RtlZeroMemory(&QueryInfo
, sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
));
611 QueryInfo
.ID
.toi_entity
.tei_entity
= Entity
;
612 QueryInfo
.ID
.toi_entity
.tei_instance
= Instance
;
613 QueryInfo
.ID
.toi_class
= Class
;
614 QueryInfo
.ID
.toi_type
= Type
;
615 QueryInfo
.ID
.toi_id
= Id
;
617 return TdiQueryDeviceControl(FileObject
, /* Transport/connection object */
618 IOCTL_TCP_QUERY_INFORMATION_EX
, /* Control code */
619 &QueryInfo
, /* Input buffer */
620 sizeof(TCP_REQUEST_QUERY_INFORMATION_EX
), /* Input buffer length */
621 OutputBuffer
, /* Output buffer */
622 *OutputLength
, /* Output buffer length */
623 OutputLength
); /* Return information */
626 NTSTATUS
TdiQueryAddress(
627 PFILE_OBJECT FileObject
,
630 * FUNCTION: Queries for a local IP address
632 * FileObject = Pointer to file object
633 * Address = Address of buffer to place local address
635 * Status of operation
639 TDIEntityID
*Entities
;
642 IPSNMP_INFO SnmpInfo
;
643 PIPADDR_ENTRY IpAddress
;
645 NTSTATUS Status
= STATUS_SUCCESS
;
647 AFD_DbgPrint(MAX_TRACE
, ("Called\n"));
649 BufferSize
= sizeof(TDIEntityID
) * 20;
650 Entities
= (TDIEntityID
*)ExAllocatePool(NonPagedPool
, BufferSize
);
652 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
653 return STATUS_INSUFFICIENT_RESOURCES
;
656 /* Query device for supported entities */
658 Status
= TdiQueryInformationEx(FileObject
, /* File object */
659 GENERIC_ENTITY
, /* Entity */
660 TL_INSTANCE
, /* Instance */
661 INFO_CLASS_GENERIC
, /* Entity class */
662 INFO_TYPE_PROVIDER
, /* Entity type */
663 ENTITY_LIST_ID
, /* Entity id */
664 Entities
, /* Output buffer */
665 &BufferSize
); /* Output buffer size */
666 if (!NT_SUCCESS(Status
)) {
667 AFD_DbgPrint(MIN_TRACE
, ("Unable to get list of supported entities (Status = 0x%X).\n", Status
));
668 ExFreePool(Entities
);
672 /* Locate an IP entity */
673 EntityCount
= BufferSize
/ sizeof(TDIEntityID
);
675 AFD_DbgPrint(MAX_TRACE
, ("EntityCount = %d\n", EntityCount
));
677 for (i
= 0; i
< EntityCount
; i
++) {
678 if (Entities
[i
].tei_entity
== CL_NL_ENTITY
) {
679 /* Query device for entity type */
681 BufferSize
= sizeof(EntityType
);
682 Status
= TdiQueryInformationEx(FileObject
, /* File object */
683 CL_NL_ENTITY
, /* Entity */
684 Entities
[i
].tei_instance
, /* Instance */
685 INFO_CLASS_GENERIC
, /* Entity class */
686 INFO_TYPE_PROVIDER
, /* Entity type */
687 ENTITY_TYPE_ID
, /* Entity id */
688 &EntityType
, /* Output buffer */
689 &BufferSize
); /* Output buffer size */
690 if (!NT_SUCCESS(Status
) || (EntityType
!= CL_NL_IP
)) {
691 AFD_DbgPrint(MIN_TRACE
, ("Unable to get entity of type IP (Status = 0x%X).\n", Status
));
695 /* Query device for SNMP information */
697 BufferSize
= sizeof(SnmpInfo
);
698 Status
= TdiQueryInformationEx(FileObject
, /* File object */
699 CL_NL_ENTITY
, /* Entity */
700 Entities
[i
].tei_instance
, /* Instance */
701 INFO_CLASS_PROTOCOL
, /* Entity class */
702 INFO_TYPE_PROVIDER
, /* Entity type */
703 IP_MIB_STATS_ID
, /* Entity id */
704 &SnmpInfo
, /* Output buffer */
705 &BufferSize
); /* Output buffer size */
706 if (!NT_SUCCESS(Status
) || (SnmpInfo
.NumAddr
== 0)) {
707 AFD_DbgPrint(MIN_TRACE
, ("Unable to get SNMP information or no IP addresses available (Status = 0x%X).\n", Status
));
711 /* Query device for all IP addresses */
713 if (SnmpInfo
.NumAddr
!= 0) {
714 BufferSize
= SnmpInfo
.NumAddr
* sizeof(IPADDR_ENTRY
);
715 IpAddress
= (PIPADDR_ENTRY
)ExAllocatePool(NonPagedPool
, BufferSize
);
717 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
721 Status
= TdiQueryInformationEx(FileObject
, /* File object */
722 CL_NL_ENTITY
, /* Entity */
723 Entities
[i
].tei_instance
, /* Instance */
724 INFO_CLASS_PROTOCOL
, /* Entity class */
725 INFO_TYPE_PROVIDER
, /* Entity type */
726 IP_MIB_ADDRTABLE_ENTRY_ID
, /* Entity id */
727 IpAddress
, /* Output buffer */
728 &BufferSize
); /* Output buffer size */
729 if (!NT_SUCCESS(Status
)) {
730 AFD_DbgPrint(MIN_TRACE
, ("Unable to get IP address (Status = 0x%X).\n", Status
));
731 ExFreePool(IpAddress
);
735 if (SnmpInfo
.NumAddr
!= 1) {
736 /* Skip loopback address */
737 PIPADDR_ENTRY IpAddressEntry
= (PIPADDR_ENTRY
)
738 ((PCHAR
)IpAddress
) + sizeof(IPADDR_ENTRY
);
739 *Address
= DN2H(IpAddressEntry
->Addr
);
741 /* Select the first address returned */
742 *Address
= DN2H(IpAddress
->Addr
);
745 ExFreePool(IpAddress
);
747 Status
= STATUS_UNSUCCESSFUL
;
753 ExFreePool(Entities
);
755 AFD_DbgPrint(MAX_TRACE
, ("Leaving\n"));
763 PFILE_OBJECT TransportObject
,
767 PIO_STATUS_BLOCK Iosb
,
768 PIO_COMPLETION_ROUTINE CompletionRoutine
,
769 PVOID CompletionContext
)
771 PDEVICE_OBJECT DeviceObject
;
772 NTSTATUS Status
= STATUS_SUCCESS
;
775 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
777 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
778 return STATUS_INVALID_PARAMETER
;
781 *Irp
= TdiBuildInternalDeviceControlIrp
782 ( TDI_SEND
, /* Sub function */
783 DeviceObject
, /* Device object */
784 TransportObject
, /* File object */
789 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
790 return STATUS_INSUFFICIENT_RESOURCES
;
793 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
795 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
796 BufferLength
, /* Length of buffer */
797 FALSE
, /* Not secondary */
798 FALSE
, /* Don't charge quota */
801 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
803 return STATUS_INSUFFICIENT_RESOURCES
;
807 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
809 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
811 Status
= STATUS_INSUFFICIENT_RESOURCES
;
814 if( !NT_SUCCESS(Status
) ) {
819 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
821 TdiBuildSend(*Irp
, /* I/O Request Packet */
822 DeviceObject
, /* Device object */
823 TransportObject
, /* File object */
824 CompletionRoutine
, /* Completion routine */
825 CompletionContext
, /* Completion context */
826 Mdl
, /* Data buffer */
828 BufferLength
); /* Length of data */
830 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
831 /* Does not block... The MDL is deleted in the receive completion
839 PFILE_OBJECT TransportObject
,
843 PIO_STATUS_BLOCK Iosb
,
844 PIO_COMPLETION_ROUTINE CompletionRoutine
,
845 PVOID CompletionContext
)
847 NTSTATUS Status
= STATUS_SUCCESS
;
848 PDEVICE_OBJECT DeviceObject
;
851 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
853 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
854 return STATUS_INVALID_PARAMETER
;
857 *Irp
= TdiBuildInternalDeviceControlIrp
858 ( TDI_RECEIVE
, /* Sub function */
859 DeviceObject
, /* Device object */
860 TransportObject
, /* File object */
865 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
866 return STATUS_INSUFFICIENT_RESOURCES
;
869 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
871 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
872 BufferLength
, /* Length of buffer */
873 FALSE
, /* Not secondary */
874 FALSE
, /* Don't charge quota */
875 *Irp
); /* Don't use IRP */
877 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
879 return STATUS_INSUFFICIENT_RESOURCES
;
883 AFD_DbgPrint(MIN_TRACE
, ("probe and lock\n"));
884 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
885 AFD_DbgPrint(MIN_TRACE
, ("probe and lock done\n"));
887 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
889 Status
= STATUS_INSUFFICIENT_RESOURCES
;
892 if( !NT_SUCCESS(Status
) ) {
897 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
899 TdiBuildReceive(*Irp
, /* I/O Request Packet */
900 DeviceObject
, /* Device object */
901 TransportObject
, /* File object */
902 CompletionRoutine
, /* Completion routine */
903 CompletionContext
, /* Completion context */
904 Mdl
, /* Data buffer */
906 BufferLength
); /* Length of data */
909 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
910 /* Does not block... The MDL is deleted in the receive completion
913 AFD_DbgPrint(MID_TRACE
,("Status %x Information %d\n",
914 Status
, Iosb
->Information
));
920 NTSTATUS
TdiReceiveDatagram(
922 PFILE_OBJECT TransportObject
,
926 PTDI_CONNECTION_INFORMATION Addr
,
927 PIO_STATUS_BLOCK Iosb
,
928 PIO_COMPLETION_ROUTINE CompletionRoutine
,
929 PVOID CompletionContext
)
931 * FUNCTION: Receives a datagram
933 * TransportObject = Pointer to transport object
934 * From = Receive filter (NULL if none)
935 * Address = Address of buffer to place remote address
936 * Buffer = Address of buffer to place received data
937 * BufferSize = Address of buffer with length of Buffer (updated)
939 * Status of operation
942 PDEVICE_OBJECT DeviceObject
;
946 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
948 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
949 return STATUS_INVALID_PARAMETER
;
952 *Irp
= TdiBuildInternalDeviceControlIrp
953 ( TDI_RECEIVE_DATAGRAM
, /* Sub function */
954 DeviceObject
, /* Device object */
955 TransportObject
, /* File object */
960 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
961 return STATUS_INSUFFICIENT_RESOURCES
;
964 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
966 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
967 BufferLength
, /* Length of buffer */
968 FALSE
, /* Not secondary */
969 FALSE
, /* Don't charge quota */
970 *Irp
); /* Don't use IRP */
972 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
974 return STATUS_INSUFFICIENT_RESOURCES
;
978 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
980 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
982 return STATUS_INSUFFICIENT_RESOURCES
;
985 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
987 TdiBuildReceiveDatagram
988 (*Irp
, /* I/O Request Packet */
989 DeviceObject
, /* Device object */
990 TransportObject
, /* File object */
991 CompletionRoutine
, /* Completion routine */
992 CompletionContext
, /* Completion context */
993 Mdl
, /* Data buffer */
997 Flags
); /* Length of data */
999 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
1000 /* Does not block... The MDL is deleted in the receive completion
1007 NTSTATUS
TdiSendDatagram(
1009 PFILE_OBJECT TransportObject
,
1012 PTDI_CONNECTION_INFORMATION Addr
,
1013 PIO_STATUS_BLOCK Iosb
,
1014 PIO_COMPLETION_ROUTINE CompletionRoutine
,
1015 PVOID CompletionContext
)
1017 * FUNCTION: Sends a datagram
1019 * TransportObject = Pointer to transport object
1020 * From = Send filter (NULL if none)
1021 * Address = Address of buffer to place remote address
1022 * Buffer = Address of buffer to place send data
1023 * BufferSize = Address of buffer with length of Buffer (updated)
1025 * Status of operation
1028 PDEVICE_OBJECT DeviceObject
;
1032 AFD_DbgPrint(MID_TRACE
,("Called(TransportObject %x)\n", TransportObject
));
1034 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1035 if (!DeviceObject
) {
1036 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
1037 return STATUS_INVALID_PARAMETER
;
1040 *Irp
= TdiBuildInternalDeviceControlIrp
1041 ( TDI_SEND_DATAGRAM
, /* Sub function */
1042 DeviceObject
, /* Device object */
1043 TransportObject
, /* File object */
1045 Iosb
); /* Status */
1048 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1049 return STATUS_INSUFFICIENT_RESOURCES
;
1052 AFD_DbgPrint(MID_TRACE
, ("Allocating irp for %x:%d\n", Buffer
,BufferLength
));
1054 Mdl
= IoAllocateMdl(Buffer
, /* Virtual address */
1055 BufferLength
, /* Length of buffer */
1056 FALSE
, /* Not secondary */
1057 FALSE
, /* Don't charge quota */
1058 *Irp
); /* Don't use IRP */
1061 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1063 return STATUS_INSUFFICIENT_RESOURCES
;
1067 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
1069 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
1071 return STATUS_INSUFFICIENT_RESOURCES
;
1074 AFD_DbgPrint(MID_TRACE
,("AFD>>> Got an MDL: %x\n", Mdl
));
1076 TdiBuildSendDatagram
1077 (*Irp
, /* I/O Request Packet */
1078 DeviceObject
, /* Device object */
1079 TransportObject
, /* File object */
1080 CompletionRoutine
, /* Completion routine */
1081 CompletionContext
, /* Completion context */
1082 Mdl
, /* Data buffer */
1083 BufferLength
, /* Bytes to send */
1084 Addr
); /* Address */
1086 Status
= TdiCall(*Irp
, DeviceObject
, NULL
, Iosb
);
1087 /* Does not block... The MDL is deleted in the send completion
1093 NTSTATUS
TdiDisconnect(
1094 PFILE_OBJECT TransportObject
,
1095 PLARGE_INTEGER Time
,
1097 PIO_STATUS_BLOCK Iosb
,
1098 PIO_COMPLETION_ROUTINE CompletionRoutine
,
1099 PVOID CompletionContext
,
1100 PTDI_CONNECTION_INFORMATION RequestConnectionInfo
,
1101 PTDI_CONNECTION_INFORMATION ReturnConnectionInfo
) {
1102 PDEVICE_OBJECT DeviceObject
;
1107 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1109 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1111 AFD_DbgPrint(MID_TRACE
,("Called(TransportObject %x)\n", TransportObject
));
1113 DeviceObject
= IoGetRelatedDeviceObject(TransportObject
);
1114 if (!DeviceObject
) {
1115 AFD_DbgPrint(MIN_TRACE
, ("Bad device object.\n"));
1116 return STATUS_INVALID_PARAMETER
;
1119 Irp
= TdiBuildInternalDeviceControlIrp
1120 ( TDI_SEND_DATAGRAM
, /* Sub function */
1121 DeviceObject
, /* Device object */
1122 TransportObject
, /* File object */
1124 Iosb
); /* Status */
1127 AFD_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1128 return STATUS_INSUFFICIENT_RESOURCES
;
1132 (Irp
, /* I/O Request Packet */
1133 DeviceObject
, /* Device object */
1134 TransportObject
, /* File object */
1135 CompletionRoutine
, /* Completion routine */
1136 CompletionContext
, /* Completion context */
1138 Flags
, /* Disconnect flags */
1139 RequestConnectionInfo
, /* Indication of who to disconnect */
1140 ReturnConnectionInfo
); /* Indication of who disconnected */
1142 Status
= TdiCall(Irp
, DeviceObject
, &Event
, Iosb
);