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
14 PIO_STACK_LOCATION IrpSp
)
16 * FUNCTION: Binds to an address
18 * Irp = Pointer to I/O request packet
19 * IrpSp = Pointer to current stack location of Irp
25 UINT InputBufferLength
;
26 UINT OutputBufferLength
;
27 PFILE_REQUEST_BIND Request
;
28 PFILE_REPLY_BIND Reply
;
31 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
32 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
34 /* Validate parameters */
35 if ((InputBufferLength
>= sizeof(FILE_REQUEST_BIND
)) &&
36 (OutputBufferLength
>= sizeof(FILE_REPLY_BIND
))) {
37 FCB
= IrpSp
->FileObject
->FsContext
;
39 Request
= (PFILE_REQUEST_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
40 Reply
= (PFILE_REPLY_BIND
)Irp
->AssociatedIrp
.SystemBuffer
;
42 switch (Request
->Name
.sa_family
) {
44 Status
= TdiOpenAddressFileIPv4(&FCB
->TdiDeviceName
,
46 &FCB
->TdiAddressObjectHandle
,
47 &FCB
->TdiAddressObject
);
50 AFD_DbgPrint(MIN_TRACE
, ("Bad address family (%d).\n", Request
->Name
.sa_family
));
51 Status
= STATUS_INVALID_PARAMETER
;
54 if (NT_SUCCESS(Status
)) {
55 AfdRegisterEventHandlers(FCB
);
56 FCB
->State
= SOCKET_STATE_BOUND
;
59 Status
= STATUS_INVALID_PARAMETER
;
61 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
67 NTSTATUS
AfdDispListen(
69 PIO_STACK_LOCATION IrpSp
)
71 * FUNCTION: Starts listening for connections
73 * Irp = Pointer to I/O request packet
74 * IrpSp = Pointer to current stack location of Irp
80 UINT InputBufferLength
;
81 UINT OutputBufferLength
;
82 PFILE_REQUEST_LISTEN Request
;
83 PFILE_REPLY_LISTEN Reply
;
86 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
87 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
89 /* Validate parameters */
90 if ((InputBufferLength
>= sizeof(FILE_REQUEST_LISTEN
)) &&
91 (OutputBufferLength
>= sizeof(FILE_REPLY_LISTEN
))) {
92 FCB
= IrpSp
->FileObject
->FsContext
;
94 Request
= (PFILE_REQUEST_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
95 Reply
= (PFILE_REPLY_LISTEN
)Irp
->AssociatedIrp
.SystemBuffer
;
97 Status
= STATUS_INVALID_PARAMETER
;
99 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
105 NTSTATUS
AfdDispSendTo(
107 PIO_STACK_LOCATION IrpSp
)
109 * FUNCTION: Sends data to an address
111 * Irp = Pointer to I/O request packet
112 * IrpSp = Pointer to current stack location of Irp
114 * Status of operation
118 UINT InputBufferLength
;
119 UINT OutputBufferLength
;
120 PFILE_REQUEST_SENDTO Request
;
121 PFILE_REPLY_SENDTO Reply
;
123 PVOID SystemVirtualAddress
;
124 PVOID DataBufferAddress
;
129 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
130 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
132 /* Validate parameters */
133 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SENDTO
)) &&
134 (OutputBufferLength
>= sizeof(FILE_REPLY_SENDTO
))) {
136 AFD_DbgPrint(MAX_TRACE
, ("FileObject at (0x%X).\n", IrpSp
->FileObject
));
137 AFD_DbgPrint(MAX_TRACE
, ("FCB at (0x%X).\n", IrpSp
->FileObject
->FsContext
));
138 AFD_DbgPrint(MAX_TRACE
, ("CCB at (0x%X).\n", IrpSp
->FileObject
->FsContext2
));
140 FCB
= IrpSp
->FileObject
->FsContext
;
141 Request
= (PFILE_REQUEST_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
142 Reply
= (PFILE_REPLY_SENDTO
)Irp
->AssociatedIrp
.SystemBuffer
;
143 BufferSize
= WSABufferSize(Request
->Buffers
, Request
->BufferCount
);
146 /* FIXME: Should we handle special cases here? */
147 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
148 BufferSize
+= sizeof(IPv4_HEADER
);
152 if (BufferSize
!= 0) {
153 AFD_DbgPrint(MAX_TRACE
, ("Allocating %d bytes for send buffer.\n", BufferSize
));
154 SystemVirtualAddress
= ExAllocatePool(NonPagedPool
, BufferSize
);
155 if (!SystemVirtualAddress
) {
156 return STATUS_INSUFFICIENT_RESOURCES
;
159 /* FIXME: Should we handle special cases here? */
160 if ((FCB
->SocketType
== SOCK_RAW
) && (FCB
->AddressFamily
== AF_INET
)) {
161 DataBufferAddress
= SystemVirtualAddress
+ sizeof(IPv4_HEADER
);
163 /* FIXME: Should TCP/IP driver assign source address for raw sockets? */
164 ((PSOCKADDR_IN
)&FCB
->SocketName
)->sin_addr
.S_un
.S_addr
= 0x0100007F;
167 (PIPv4_HEADER
)SystemVirtualAddress
,
173 DataBufferAddress
= SystemVirtualAddress
;
176 Status
= MergeWSABuffers(
178 Request
->BufferCount
,
182 if (!NT_SUCCESS(Status
)) {
183 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
187 SystemVirtualAddress
= NULL
;
192 SystemVirtualAddress
, /* Virtual address of buffer */
193 BufferSize
, /* Length of buffer */
194 FALSE
, /* Not secondary */
195 FALSE
, /* Don't charge quota */
196 NULL
); /* Don't use IRP */
198 ExFreePool(SystemVirtualAddress
);
199 return STATUS_INSUFFICIENT_RESOURCES
;
202 MmBuildMdlForNonPagedPool(Mdl
);
204 AFD_DbgPrint(MAX_TRACE
, ("System virtual address is (0x%X).\n", SystemVirtualAddress
));
205 AFD_DbgPrint(MAX_TRACE
, ("MDL for data buffer is at (0x%X).\n", Mdl
));
207 AFD_DbgPrint(MAX_TRACE
, ("AFD.SYS: NDIS data buffer is at (0x%X).\n", Mdl
));
208 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MdlFlags is (0x%X).\n", Mdl
->MdlFlags
));
209 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Next is at (0x%X).\n", Mdl
->Next
));
210 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer Size is (0x%X).\n", Mdl
->Size
));
211 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer MappedSystemVa is (0x%X).\n", Mdl
->MappedSystemVa
));
212 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer StartVa is (0x%X).\n", Mdl
->StartVa
));
213 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteCount is (0x%X).\n", Mdl
->ByteCount
));
214 AFD_DbgPrint(MAX_TRACE
, ("NDIS data buffer ByteOffset is (0x%X).\n", Mdl
->ByteOffset
));
220 MmProbeAndLockPages(Mdl
, KernelMode
, IoModifyAccess
);
222 } except(EXCEPTION_EXECUTE_HANDLER
) {
223 AFD_DbgPrint(MIN_TRACE
, ("MmProbeAndLockPages() failed.\n"));
225 if (BufferSize
!= 0) {
226 ExFreePool(SystemVirtualAddress
);
228 return STATUS_UNSUCCESSFUL
;
233 Status
= TdiSendDatagram(FCB
->TdiAddressObject
,
238 /* FIXME: Assumes synchronous operation */
245 if (BufferSize
!= 0) {
246 ExFreePool(SystemVirtualAddress
);
249 Reply
->NumberOfBytesSent
= BufferSize
;
250 Reply
->Status
= NO_ERROR
;
252 Status
= STATUS_INVALID_PARAMETER
;
254 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
260 NTSTATUS
AfdDispRecvFrom(
262 PIO_STACK_LOCATION IrpSp
)
264 * FUNCTION: Receives data from an address
266 * Irp = Pointer to I/O request packet
267 * IrpSp = Pointer to current stack location of Irp
269 * Status of operation
273 UINT InputBufferLength
;
274 UINT OutputBufferLength
;
275 PFILE_REQUEST_RECVFROM Request
;
276 PFILE_REPLY_RECVFROM Reply
;
277 PAFD_READ_REQUEST ReadRequest
;
281 AFD_DbgPrint(MAX_TRACE
, ("Called.\n"));
283 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
284 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
286 /* Validate parameters */
287 if ((InputBufferLength
>= sizeof(FILE_REQUEST_RECVFROM
)) &&
288 (OutputBufferLength
>= sizeof(FILE_REPLY_RECVFROM
))) {
289 FCB
= IrpSp
->FileObject
->FsContext
;
291 Request
= (PFILE_REQUEST_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
292 Reply
= (PFILE_REPLY_RECVFROM
)Irp
->AssociatedIrp
.SystemBuffer
;
294 KeAcquireSpinLock(&FCB
->ReadRequestQueueLock
, &OldIrql
);
296 if (IsListEmpty(&FCB
->ReadRequestQueue
)) {
297 /* Queue request and return STATUS_PENDING */
298 ReadRequest
->Irp
= Irp
;
299 ReadRequest
->RecvFromRequest
= Request
;
300 ReadRequest
->RecvFromReply
= Reply
;
301 InsertTailList(&FCB
->ReadRequestQueue
, &ReadRequest
->ListEntry
);
302 KeReleaseSpinLock(&FCB
->ReadRequestQueueLock
, OldIrql
);
303 Status
= STATUS_PENDING
;
305 /* Satisfy the request at once */
306 Status
= FillWSABuffers(
309 Request
->BufferCount
,
310 &Reply
->NumberOfBytesRecvd
);
311 KeReleaseSpinLock(&FCB
->ReadRequestQueueLock
, OldIrql
);
312 Reply
->Status
= NO_ERROR
;
315 Status
= STATUS_INVALID_PARAMETER
;
317 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));
323 NTSTATUS
AfdDispSelect(
325 PIO_STACK_LOCATION IrpSp
)
327 * FUNCTION: Checks if sockets have data in the receive buffers
329 * Irp = Pointer to I/O request packet
330 * IrpSp = Pointer to current stack location of Irp
332 * Status of operation
336 UINT InputBufferLength
;
337 UINT OutputBufferLength
;
338 PFILE_REQUEST_SELECT Request
;
339 PFILE_REPLY_SELECT Reply
;
342 InputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.InputBufferLength
;
343 OutputBufferLength
= IrpSp
->Parameters
.DeviceIoControl
.OutputBufferLength
;
345 /* Validate parameters */
346 if ((InputBufferLength
>= sizeof(FILE_REQUEST_SELECT
)) &&
347 (OutputBufferLength
>= sizeof(FILE_REPLY_SELECT
))) {
348 FCB
= IrpSp
->FileObject
->FsContext
;
350 Request
= (PFILE_REQUEST_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
351 Reply
= (PFILE_REPLY_SELECT
)Irp
->AssociatedIrp
.SystemBuffer
;
353 Status
= STATUS_INVALID_PARAMETER
;
355 AFD_DbgPrint(MAX_TRACE
, ("Status (0x%X).\n", Status
));