2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: File object dispatch functions
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
12 NTSTATUS
AfdpDispRecv(
15 PFILE_REQUEST_RECVFROM Request
,
16 PFILE_REPLY_RECVFROM Reply
)
18 * FUNCTION: Receives data
20 * Irp = Pointer to I/O request packet
21 * FCB = Pointer to file control block
22 * Request = Address of request buffer
23 * Reply = Address of reply buffer (same as request buffer)
28 PAFD_READ_REQUEST ReadRequest
;
33 KeAcquireSpinLock(&FCB
->ReceiveQueueLock
, &OldIrql
);
34 if (IsListEmpty(&FCB
->ReceiveQueue
)) {
35 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
37 /* Queue a read request and return STATUS_PENDING */
39 AFD_DbgPrint(MAX_TRACE
, ("Queueing read request.\n"));
41 /*ReadRequest = (PAFD_READ_REQUEST)ExAllocateFromNPagedLookasideList(
42 &ReadRequestLookasideList);*/
43 ReadRequest
= (PAFD_READ_REQUEST
)ExAllocatePool(
45 sizeof(AFD_READ_REQUEST
));
47 ReadRequest
->Irp
= Irp
;
48 ReadRequest
->RecvFromRequest
= Request
;
49 ReadRequest
->RecvFromReply
= Reply
;
51 ExInterlockedInsertTailList(
52 &FCB
->ReadRequestQueue
,
53 &ReadRequest
->ListEntry
,
54 &FCB
->ReadRequestQueueLock
);
55 Status
= STATUS_PENDING
;
57 Status
= STATUS_INSUFFICIENT_RESOURCES
;
60 AFD_DbgPrint(MAX_TRACE
, ("Satisfying read request.\n"));
62 /* Satisfy the request at once */
63 Status
= FillWSABuffers(
68 KeReleaseSpinLock(&FCB
->ReceiveQueueLock
, OldIrql
);
70 Reply
->NumberOfBytesRecvd
= Count
;
71 Reply
->Status
= NO_ERROR
;
73 AFD_DbgPrint(MAX_TRACE
, ("Bytes received (0x%X).\n", Count
));
82 PIO_STACK_LOCATION IrpSp
)
84 * FUNCTION: Binds to an address
86 * Irp = Pointer to I/O request packet
87 * IrpSp = Pointer to current stack location of Irp
93 UINT InputBufferLength
;
94 UINT OutputBufferLength
;
95 PFILE_REQUEST_BIND Request
;
96 PFILE_REPLY_BIND Reply
;
99 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
100 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
102 /* Validate parameters */
103 if ((InputBufferLength
>= sizeof(FILE_REQUEST_BIND
)) &&
104 (OutputBufferLength
>= sizeof(FILE_REPLY_BIND
))) {
105 FCB
= IrpSp
->FileObject
->FsContext
;
107 Request
= (PFILE_REQUEST_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
108 Reply
= (PFILE_REPLY_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
110 Status
= TdiOpenAddressFile(
113 &FCB
->TdiAddressObjectHandle
,
114 &FCB
->TdiAddressObject
);
116 if (NT_SUCCESS(Status
)) {
117 AfdRegisterEventHandlers(FCB
);
118 FCB
->State
= SOCKET_STATE_BOUND
;
119 Reply
->Status
= NO_ERROR
;
121 //FIXME: WSAEADDRNOTAVAIL
122 Reply
->Status
= WSAEINVAL
;
125 Status
= STATUS_INVALID_PARAMETER
;
127 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
135 AfdDispCompleteListen(
136 PDEVICE_OBJECT DeviceObject
,
140 PAFD_LISTEN_REQUEST ListenRequest
= (PAFD_LISTEN_REQUEST
) Context
;
142 AFD_DbgPrint(MAX_TRACE
, ("Called. ListenRequest (0x%X).\n", ListenRequest
));
144 AFD_DbgPrint(MAX_TRACE
, ("Fcb (0x%X).\n", ListenRequest
->Fcb
));
146 return STATUS_SUCCESS
;
150 NTSTATUS
AfdDispListen(
152 PIO_STACK_LOCATION IrpSp
)
154 * FUNCTION: Starts listening for connections
156 * Irp = Pointer to I/O request packet
157 * IrpSp = Pointer to current stack location of Irp
159 * Status of operation
163 UINT InputBufferLength
;
164 UINT OutputBufferLength
;
165 PFILE_REQUEST_LISTEN Request
;
166 PFILE_REPLY_LISTEN Reply
;
168 PAFD_LISTEN_REQUEST ListenRequest
;
170 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
171 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
173 /* Validate parameters */
174 Status
= STATUS_INVALID_PARAMETER
;
175 if ((InputBufferLength
>= sizeof(FILE_REQUEST_LISTEN
)) &&
176 (OutputBufferLength
>= sizeof(FILE_REPLY_LISTEN
))) {
177 FCB
= IrpSp
->FileObject
->FsContext
;
179 Request
= (PFILE_REQUEST_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
180 Reply
= (PFILE_REPLY_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
182 if (FCB
->State
== SOCKET_STATE_BOUND
)
184 /* We have a bound socket so go ahead and create a connection endpoint
185 and associate it with the address file object */
187 Status
= TdiOpenConnectionEndpointFile(
189 &FCB
->TdiConnectionObjectHandle
,
190 &FCB
->TdiConnectionObject
);
192 if (NT_SUCCESS(Status
))
194 Status
= TdiAssociateAddressFile(
195 FCB
->TdiAddressObjectHandle
,
196 FCB
->TdiConnectionObject
);
198 if (NT_SUCCESS(Status
))
200 ListenRequest
= ExAllocateFromNPagedLookasideList(&ListenRequestLookasideList
);
201 if (ListenRequest
!= NULL
)
203 ListenRequest
->Fcb
= FCB
;
204 /* FIXME: Protect ListenRequestQueue */
205 InsertTailList(&FCB
->ListenRequestQueue
, &ListenRequest
->ListEntry
);
207 Status
= TdiListen(FCB
->TdiConnectionObject
, AfdDispCompleteListen
, ListenRequest
);
208 if ((Status
== STATUS_PENDING
) || NT_SUCCESS(Status
))
210 if (Status
!= STATUS_PENDING
)
212 AFD_DbgPrint(MIN_TRACE
, ("FIXME: Status (0x%X).\n", Status
));
214 Status
= STATUS_SUCCESS
;
218 /* FIXME: Cleanup ListenRequest */
219 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
224 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
225 Status
= STATUS_NO_MEMORY
;
230 /* FIXME: Cleanup from TdiOpenConnectionEndpointFile */
234 if (NT_SUCCESS(Status
)) {
235 Reply
->Status
= NO_ERROR
;
237 Reply
->Status
= WSAEINVAL
;
240 else if (FCB
->State
== SOCKET_STATE_CONNECTED
)
242 Reply
->Status
= WSAEISCONN
;
246 Reply
->Status
= WSAEINVAL
;
250 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
256 NTSTATUS
AfdDispSendTo(
258 PIO_STACK_LOCATION IrpSp
)
260 * FUNCTION: Sends data to an address
262 * Irp = Pointer to I/O request packet
263 * IrpSp = Pointer to current stack location of Irp
265 * Status of operation
269 UINT InputBufferLength
;
270 UINT OutputBufferLength
;
271 PFILE_REQUEST_SENDTO Request
;
272 PFILE_REPLY_SENDTO Reply
;
274 PVOID SystemVirtualAddress
;
275 PVOID DataBufferAddress
;
280 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
281 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
283 /* Validate parameters */
284 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SENDTO
)) &&
285 (OutputBufferLength
>= sizeof(FILE_REPLY_SENDTO
))) {
287 AFD_DbgPrint(MAX_TRACE
, ("FileObject at (0x%X).\n", IrpSp
->FileObject
));
288 AFD_DbgPrint(MAX_TRACE
, ("FCB at (0x%X).\n", IrpSp
->FileObject
->FsContext
));
289 AFD_DbgPrint(MAX_TRACE
, ("CCB at (0x%X).\n", IrpSp
->FileObject
->FsContext2
));
291 FCB
= IrpSp
->FileObject
->FsContext
;
292 Request
= (PFILE_REQUEST_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
293 Reply
= (PFILE_REPLY_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
295 /* Since we're using bufferred I/O */
296 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
297 BufferSize
= WSABufferSize(Request
->Buffers
, Request
->BufferCount
);
300 /* FIXME: Should we handle special cases here? */
301 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
302 BufferSize
+= sizeof(IPv4_HEADER
);
306 if (BufferSize
!= 0) {
307 AFD_DbgPrint(MAX_TRACE
, ("Allocating %d bytes for send buffer.\n", BufferSize
));
308 SystemVirtualAddress
= ExAllocatePool(NonPagedPool
, BufferSize
);
309 if (!SystemVirtualAddress
) {
310 return STATUS_INSUFFICIENT_RESOURCES
;
313 /* FIXME: Should we handle special cases here? */
314 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
315 DataBufferAddress
= ((PCHAR
)SystemVirtualAddress
) + sizeof(IPv4_HEADER
);
317 /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
318 ((PSOCKADDR_IN
)&FCB
->SocketName
)->sin_addr
.S_un
.S_addr
= 0x0100007F;
321 (PIPv4_HEADER
)SystemVirtualAddress
,
327 DataBufferAddress
= SystemVirtualAddress
;
330 Status
= MergeWSABuffers(
332 Request
->BufferCount
,
336 if (!NT_SUCCESS(Status
)) {
337 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
341 SystemVirtualAddress
= NULL
;
346 SystemVirtualAddress
, /* Virtual address of buffer */
347 BufferSize
, /* Length of buffer */
348 FALSE
, /* Not secondary */
349 FALSE
, /* Don't charge quota */
350 NULL
); /* Don't use IRP */
352 ExFreePool(SystemVirtualAddress
);
353 return STATUS_INSUFFICIENT_RESOURCES
;
356 MmBuildMdlForNonPagedPool(Mdl
);
358 AFD_DbgPrint(MAX_TRACE
, ("System virtual address is (0x%X).\n", SystemVirtualAddress
));
359 AFD_DbgPrint(MAX_TRACE
, ("MDL for data buffer is at (0x%X).\n", Mdl
));
361 AFD_DbgPrint(MAX_TRACE
, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl
));
362 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl
->MdlFlags
));
363 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Next is at (0x%X).\n", Mdl
->Next
));
364 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Size is (0x%X).\n", Mdl
->Size
));
365 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl
->MappedSystemVa
));
366 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer StartVa is (0x%X).\n", Mdl
->StartVa
));
367 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl
->ByteCount
));
368 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl
->ByteOffset
));
374 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
376 } except(EXCEPTION_EXECUTE_HANDLER
) {
377 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
379 if (BufferSize
!= 0) {
380 ExFreePool(SystemVirtualAddress
);
382 return STATUS_UNSUCCESSFUL
;
387 if (!FCB
->TdiAddressObject
) {
388 struct sockaddr_in BindName
;
390 RtlZeroMemory(&BindName
,sizeof(BindName
));
391 BindName
.sin_family
= AF_INET
;
393 Status
= TdiOpenAddressFile
394 (&FCB
->TdiDeviceName
,
395 (SOCKADDR
*)&BindName
,
396 &FCB
->TdiAddressObjectHandle
,
397 &FCB
->TdiAddressObject
);
399 if (NT_SUCCESS(Status
)) {
400 AfdRegisterEventHandlers(FCB
);
401 FCB
->State
= SOCKET_STATE_BOUND
;
402 Reply
->Status
= NO_ERROR
;
404 //FIXME: WSAEADDRNOTAVAIL
405 Reply
->Status
= WSAEINVAL
;
412 Status
= TdiSendDatagram(FCB
->TdiAddressObject
,
417 /* FIXME: Assumes synchronous operation */
424 if (BufferSize
!= 0) {
425 ExFreePool(SystemVirtualAddress
);
428 Reply
->NumberOfBytesSent
= BufferSize
;
429 Reply
->Status
= NO_ERROR
;
431 Status
= STATUS_INVALID_PARAMETER
;
433 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
439 NTSTATUS
AfdDispRecvFrom(
441 PIO_STACK_LOCATION IrpSp
)
443 * FUNCTION: Receives data from an address
445 * Irp = Pointer to I/O request packet
446 * IrpSp = Pointer to current stack location of Irp
448 * Status of operation
452 UINT InputBufferLength
;
453 UINT OutputBufferLength
;
454 PFILE_REQUEST_RECVFROM Request
;
455 PFILE_REPLY_RECVFROM Reply
;
458 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
460 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
461 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
463 /* Validate parameters */
464 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECVFROM
)) &&
465 (OutputBufferLength
>= sizeof(FILE_REPLY_RECVFROM
))) {
466 FCB
= IrpSp
->FileObject
->FsContext
;
468 Request
= (PFILE_REQUEST_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
469 Reply
= (PFILE_REPLY_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
470 /* Since we're using bufferred I/O */
471 Request
->Buffers
= (LPWSABUF
)(Request
+ 1);
473 Status
= AfdpDispRecv(
479 Status
= STATUS_INVALID_PARAMETER
;
482 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
495 DWORD
AfdpDispSelectEx(
497 SelectOperation Operation
)
499 PFILE_OBJECT FileObject
;
506 AFD_DbgPrint(MAX_TRACE
, ("FDSet (0x%X) Operation (0x%X).\n",
509 AFD_DbgPrint(MAX_TRACE
, ("FDSet->fd_count (0x%X).\n", FDSet
->fd_count
));
512 for (i
= 0; i
< FDSet
->fd_count
; i
++) {
514 AFD_DbgPrint(MAX_TRACE
, ("Handle (0x%X).\n", FDSet
->fd_array
[i
]));
516 Status
= ObReferenceObjectByHandle(
517 (HANDLE
)FDSet
->fd_array
[i
],
523 if (NT_SUCCESS(Status
)) {
524 AFD_DbgPrint(MAX_TRACE
, ("File object is at (0x%X).\n", FileObject
));
526 Current
= FileObject
->FsContext
;
530 KeAcquireSpinLock(&Current
->ReceiveQueueLock
, &OldIrql
);
531 if (!IsListEmpty(&Current
->ReceiveQueue
)) {
532 AFD_DbgPrint(MAX_TRACE
, ("Socket is readable.\n"));
535 KeReleaseSpinLock(&Current
->ReceiveQueueLock
, OldIrql
);
538 /* FIXME: How can we check for writability? */
542 /* FIXME: What is this? */
547 ObDereferenceObject(FileObject
);
554 NTSTATUS
AfdDispSelect(
556 PIO_STACK_LOCATION IrpSp
)
558 * FUNCTION: Checks if sockets have data in the receive buffers
559 * and/or if client can send data
561 * Irp = Pointer to I/O request packet
562 * IrpSp = Pointer to current stack location of Irp
564 * Status of operation
568 UINT InputBufferLength
;
569 UINT OutputBufferLength
;
570 PFILE_REQUEST_SELECT Request
;
571 PFILE_REPLY_SELECT Reply
;
575 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
576 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
578 /* Validate parameters */
579 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SELECT
)) &&
580 (OutputBufferLength
>= sizeof(FILE_REPLY_SELECT
))) {
581 FCB
= IrpSp
->FileObject
->FsContext
;
583 Request
= (PFILE_REQUEST_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
584 Reply
= (PFILE_REPLY_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
586 AFD_DbgPrint(MAX_TRACE
, ("R (0x%X) W (0x%X).\n",
587 Request
->ReadFDSet
, Request
->WriteFDSet
));
591 if (Request
->WriteFDSet
) {
592 AFD_DbgPrint(MAX_TRACE
, ("Write.\n"));
593 SocketCount
+= AfdpDispSelectEx(Request
->WriteFDSet
, soWrite
);
595 if (Request
->ReadFDSet
) {
596 AFD_DbgPrint(MAX_TRACE
, ("Read.\n"));
597 SocketCount
+= AfdpDispSelectEx(Request
->ReadFDSet
, soRead
);
599 if (Request
->ExceptFDSet
) {
600 SocketCount
+= AfdpDispSelectEx(Request
->ExceptFDSet
, soExcept
);
603 AFD_DbgPrint(MAX_TRACE
, ("Sockets selected (0x%X).\n", SocketCount
));
605 Reply
->Status
= NO_ERROR
;
606 Reply
->SocketCount
= SocketCount
;
607 Status
= STATUS_SUCCESS
;
609 Status
= STATUS_INVALID_PARAMETER
;
611 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
616 NTSTATUS
AfdDispEventSelect(
618 PIO_STACK_LOCATION IrpSp
)
620 * FUNCTION: Associate an event object with one or more network events
622 * Irp = Pointer to I/O request packet
623 * IrpSp = Pointer to current stack location of Irp
625 * Status of operation
629 UINT InputBufferLength
;
630 UINT OutputBufferLength
;
631 PFILE_REQUEST_EVENTSELECT Request
;
632 PFILE_REPLY_EVENTSELECT Reply
;
636 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
637 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
639 /* Validate parameters */
640 if ((InputBufferLength
>= sizeof(FILE_REQUEST_EVENTSELECT
)) &&
641 (OutputBufferLength
>= sizeof(FILE_REPLY_EVENTSELECT
))) {
642 FCB
= IrpSp
->FileObject
->FsContext
;
644 Request
= (PFILE_REQUEST_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
645 Reply
= (PFILE_REPLY_EVENTSELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
647 FCB
->NetworkEvents
.lNetworkEvents
= Request
->lNetworkEvents
;
648 for (i
= 0; i
< FD_MAX_EVENTS
; i
++) {
649 if ((Request
->lNetworkEvents
& (1 << i
)) > 0) {
650 FCB
->EventObjects
[i
] = Request
->hEventObject
;
652 /* The effect of any previous call to this function is cancelled */
653 FCB
->EventObjects
[i
] = (WSAEVENT
)0;
657 Reply
->Status
= NO_ERROR
;
658 Status
= STATUS_SUCCESS
;
660 Status
= STATUS_INVALID_PARAMETER
;
662 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
667 NTSTATUS
AfdDispEnumNetworkEvents(
669 PIO_STACK_LOCATION IrpSp
)
671 * FUNCTION: Reports network events
673 * Irp = Pointer to I/O request packet
674 * IrpSp = Pointer to current stack location of Irp
676 * Status of operation
680 UINT InputBufferLength
;
681 UINT OutputBufferLength
;
682 PFILE_REQUEST_ENUMNETWORKEVENTS Request
;
683 PFILE_REPLY_ENUMNETWORKEVENTS Reply
;
687 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
688 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
690 /* Validate parameters */
691 if ((InputBufferLength
>= sizeof(FILE_REQUEST_ENUMNETWORKEVENTS
)) &&
692 (OutputBufferLength
>= sizeof(FILE_REPLY_ENUMNETWORKEVENTS
))) {
693 FCB
= IrpSp
->FileObject
->FsContext
;
695 Request
= (PFILE_REQUEST_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
696 Reply
= (PFILE_REPLY_ENUMNETWORKEVENTS
)Irp
->AssociatedIrp
.SystemBuffer
;
698 EventObject
= (HANDLE
)Request
->hEventObject
;
701 &Reply
->NetworkEvents
,
703 sizeof(WSANETWORKEVENTS
));
707 sizeof(WSANETWORKEVENTS
));
709 if (EventObject
!= NULL
) {
710 ZwClearEvent(EventObject
);
713 Reply
->Status
= NO_ERROR
;
714 Status
= STATUS_SUCCESS
;
716 Status
= STATUS_INVALID_PARAMETER
;
718 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
724 NTSTATUS
AfdDispRecv(
726 PIO_STACK_LOCATION IrpSp
)
728 * FUNCTION: Receives data from an address
730 * Irp = Pointer to I/O request packet
731 * IrpSp = Pointer to current stack location of Irp
733 * Status of operation
738 UINT InputBufferLength
;
739 UINT OutputBufferLength
;
740 PFILE_REQUEST_RECV Request
;
741 PFILE_REPLY_RECV Reply
;
742 DWORD NumberOfBytesRecvd
;
745 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
747 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
748 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
750 /* Validate parameters */
751 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECV
)) &&
752 (OutputBufferLength
>= sizeof(FILE_REPLY_RECV
))) {
753 FCB
= IrpSp
->FileObject
->FsContext
;
755 Request
= (PFILE_REQUEST_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
756 Reply
= (PFILE_REPLY_RECV
)Irp
->AssociatedIrp
.SystemBuffer
;
758 Status
= AfdpDispRecv(
762 Request
->BufferCount
,
763 &NumberOfBytesRecvd
);
764 Reply
->NumberOfBytesRecvd
= NumberOfBytesRecvd
;
765 Reply
->Status
= NO_ERROR
;
767 Status
= STATUS_INVALID_PARAMETER
;
770 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
774 return STATUS_SUCCESS
;
779 NTSTATUS
AfdDispSend(
781 PIO_STACK_LOCATION IrpSp
)
783 * FUNCTION: Sends data
785 * Irp = Pointer to I/O request packet
786 * IrpSp = Pointer to current stack location of Irp
788 * Status of operation
792 UINT InputBufferLength
;
793 UINT OutputBufferLength
;
794 PFILE_REQUEST_SEND Request
;
795 PFILE_REPLY_SEND Reply
;
798 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
799 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
801 /* Validate parameters */
802 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SEND
)) &&
803 (OutputBufferLength
>= sizeof(FILE_REPLY_SEND
))) {
804 FCB
= IrpSp
->FileObject
->FsContext
;
806 Request
= (PFILE_REQUEST_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
807 Reply
= (PFILE_REPLY_SEND
)Irp
->AssociatedIrp
.SystemBuffer
;
809 Reply
->NumberOfBytesSent
= 0;
810 Reply
->Status
= NO_ERROR
;
812 Status
= STATUS_INVALID_PARAMETER
;
814 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
820 NTSTATUS
AfdDispConnect(
822 PIO_STACK_LOCATION IrpSp
)
824 * FUNCTION: Connect to a remote peer
826 * Irp = Pointer to I/O request packet
827 * IrpSp = Pointer to current stack location of Irp
829 * Status of operation
833 UINT InputBufferLength
;
834 UINT OutputBufferLength
;
835 PFILE_REQUEST_CONNECT Request
;
836 PFILE_REPLY_CONNECT Reply
;
838 SOCKADDR_IN LocalAddress
;
840 AFD_DbgPrint(MIN_TRACE
, ("\n"));
842 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
843 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
845 /* Validate parameters */
846 Status
= STATUS_INVALID_PARAMETER
;
847 if ((InputBufferLength
>= sizeof(FILE_REQUEST_CONNECT
)) &&
848 (OutputBufferLength
>= sizeof(FILE_REPLY_CONNECT
))) {
849 FCB
= IrpSp
->FileObject
->FsContext
;
851 Request
= (PFILE_REQUEST_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
852 Reply
= (PFILE_REPLY_CONNECT
)Irp
->AssociatedIrp
.SystemBuffer
;
854 AFD_DbgPrint(MIN_TRACE
, ("\n"));
856 if (FCB
->State
== SOCKET_STATE_BOUND
) {
857 Reply
->Status
= WSAEADDRINUSE
;
858 } else if (FCB
->State
== SOCKET_STATE_CONNECTED
) {
859 Reply
->Status
= WSAEISCONN
;
861 /* We have an unbound socket so go ahead and create an address
862 file object and a connection endpoint and associate the two */
864 AFD_DbgPrint(MIN_TRACE
, ("\n"));
866 /* FIXME: Get from client */
867 LocalAddress
.sin_family
= AF_INET
;
868 LocalAddress
.sin_port
= 1700;
869 LocalAddress
.sin_addr
.S_un
.S_addr
= 0x0; /* Dynamically allocate */
871 Status
= TdiOpenAddressFile(
873 (LPSOCKADDR
)&LocalAddress
,
874 &FCB
->TdiAddressObjectHandle
,
875 &FCB
->TdiAddressObject
);
877 if (NT_SUCCESS(Status
)) {
878 AfdRegisterEventHandlers(FCB
);
879 FCB
->State
= SOCKET_STATE_BOUND
;
882 AFD_DbgPrint(MIN_TRACE
, ("\n"));
884 if (NT_SUCCESS(Status
)) {
885 Status
= TdiOpenConnectionEndpointFile(
887 &FCB
->TdiConnectionObjectHandle
,
888 &FCB
->TdiConnectionObject
);
891 AFD_DbgPrint(MIN_TRACE
, ("\n"));
893 if (NT_SUCCESS(Status
)) {
894 Status
= TdiAssociateAddressFile(
895 FCB
->TdiAddressObjectHandle
,
896 FCB
->TdiConnectionObject
);
899 AFD_DbgPrint(MIN_TRACE
, ("\n"));
901 if (NT_SUCCESS(Status
)) {
902 /* Now attempt to connect to the remote peer */
904 FCB
->TdiConnectionObject
,
908 AFD_DbgPrint(MIN_TRACE
, ("\n"));
910 if (NT_SUCCESS(Status
)) {
911 FCB
->State
= SOCKET_STATE_CONNECTED
;
912 Reply
->Status
= NO_ERROR
;
914 Reply
->Status
= WSAEINVAL
;
919 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));