Implement support for MSG_PEEK.
[reactos.git] / reactos / drivers / network / afd / afd / info.c
1 /* $Id$
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: drivers/net/afd/afd/info.c
5 * PURPOSE: Ancillary functions driver
6 * PROGRAMMER: Art Yerkes (ayerkes@speakeasy.net)
7 * UPDATE HISTORY:
8 * 20040708 Created
9 */
10 #include "afd.h"
11 #include "tdi_proto.h"
12 #include "tdiconn.h"
13 #include "debug.h"
14 #include "pseh/pseh.h"
15
16 NTSTATUS STDCALL
17 AfdGetInfo( PDEVICE_OBJECT DeviceObject, PIRP Irp,
18 PIO_STACK_LOCATION IrpSp ) {
19 NTSTATUS Status = STATUS_SUCCESS;
20 PAFD_INFO InfoReq = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
21 PFILE_OBJECT FileObject = IrpSp->FileObject;
22 PAFD_FCB FCB = FileObject->FsContext;
23
24 AFD_DbgPrint(MID_TRACE,("Called %x %x\n", InfoReq,
25 InfoReq ? InfoReq->InformationClass : 0));
26
27 _SEH_TRY {
28 if( !SocketAcquireStateLock( FCB ) ) {
29 Status = LostSocket( Irp, TRUE );
30 _SEH_YIELD(return Status);
31 }
32
33 switch( InfoReq->InformationClass ) {
34 case AFD_INFO_RECEIVE_WINDOW_SIZE:
35 InfoReq->Information.Ulong = FCB->Recv.Size;
36 break;
37
38 case AFD_INFO_SEND_WINDOW_SIZE:
39 InfoReq->Information.Ulong = FCB->Send.Size;
40 AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
41 break;
42
43 case AFD_INFO_GROUP_ID_TYPE:
44 InfoReq->Information.Ulong = 0; /* What is group id */
45 break;
46
47 case AFD_INFO_BLOCKING_MODE:
48 InfoReq->Information.Ulong = 0;
49 break;
50
51 default:
52 AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
53 InfoReq->InformationClass));
54 Status = STATUS_INVALID_PARAMETER;
55 break;
56 }
57 } _SEH_HANDLE {
58 AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
59 Status = STATUS_INVALID_PARAMETER;
60 } _SEH_END;
61
62 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
63
64 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
65 }
66
67 NTSTATUS STDCALL
68 AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
69 PIO_STACK_LOCATION IrpSp, BOOLEAN Local ) {
70 NTSTATUS Status = STATUS_SUCCESS;
71 PFILE_OBJECT FileObject = IrpSp->FileObject;
72 PAFD_FCB FCB = FileObject->FsContext;
73 PMDL Mdl = NULL, SysMdl = NULL;
74 PTDI_CONNECTION_INFORMATION ConnInfo = NULL;
75 PTRANSPORT_ADDRESS TransAddr = NULL;
76
77 AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
78
79 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp, FALSE );
80
81 if( FCB->AddressFile.Object == NULL) {
82 return UnlockAndMaybeComplete( FCB, STATUS_UNSUCCESSFUL, Irp, 0,
83 NULL, FALSE );
84 }
85
86 Mdl = IoAllocateMdl
87 ( Irp->UserBuffer,
88 IrpSp->Parameters.DeviceIoControl.OutputBufferLength,
89 FALSE,
90 FALSE,
91 NULL );
92
93 if( Mdl != NULL ) {
94 _SEH_TRY {
95 MmProbeAndLockPages( Mdl, Irp->RequestorMode, IoModifyAccess );
96 } _SEH_HANDLE {
97 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
98 Status = _SEH_GetExceptionCode();
99 } _SEH_END;
100
101 if( NT_SUCCESS(Status) ) {
102 if( Local ) {
103 Status = TdiQueryInformation
104 ( FCB->AddressFile.Object,
105 TDI_QUERY_ADDRESS_INFO,
106 Mdl );
107 } else {
108 if( !NT_SUCCESS
109 ( Status = TdiBuildNullConnectionInfo
110 ( &ConnInfo,
111 FCB->LocalAddress->Address[0].AddressType ) ) ) {
112 SysMdl = IoAllocateMdl
113 ( ConnInfo,
114 sizeof( TDI_CONNECTION_INFORMATION ) +
115 TaLengthOfTransportAddress
116 ( ConnInfo->RemoteAddress ),
117 FALSE,
118 FALSE,
119 NULL );
120 }
121
122 if( SysMdl ) {
123 MmBuildMdlForNonPagedPool( SysMdl );
124 Status = TdiQueryInformation
125 ( FCB->AddressFile.Object,
126 TDI_QUERY_CONNECTION_INFO,
127 SysMdl );
128 } else Status = STATUS_NO_MEMORY;
129
130 if( NT_SUCCESS(Status) ) {
131 TransAddr =
132 (PTRANSPORT_ADDRESS)MmMapLockedPages
133 ( Mdl, IoModifyAccess );
134 }
135
136 if( TransAddr )
137 RtlCopyMemory( TransAddr, ConnInfo->RemoteAddress,
138 TaLengthOfTransportAddress
139 ( ConnInfo->RemoteAddress ) );
140
141 if( ConnInfo ) ExFreePool( ConnInfo );
142 if( SysMdl ) IoFreeMdl( SysMdl );
143 }
144 }
145
146 /* MmUnlockPages( Mdl ); */
147 /* IoFreeMdl( Mdl ); */
148 } else {
149 Status = STATUS_INSUFFICIENT_RESOURCES;
150 }
151
152 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
153
154 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL, FALSE );
155 }