"save your files before committing them!" -> good
[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 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
28
29 _SEH_TRY {
30 switch( InfoReq->InformationClass ) {
31 case AFD_INFO_RECEIVE_WINDOW_SIZE:
32 InfoReq->Information.Ulong = FCB->Recv.Size;
33 break;
34
35 case AFD_INFO_SEND_WINDOW_SIZE:
36 InfoReq->Information.Ulong = FCB->Send.Size;
37 AFD_DbgPrint(MID_TRACE,("Send window size %d\n", FCB->Send.Size));
38 break;
39
40 case AFD_INFO_GROUP_ID_TYPE:
41 InfoReq->Information.Ulong = 0; /* What is group id */
42 break;
43
44 case AFD_INFO_BLOCKING_MODE:
45 InfoReq->Information.Ulong = 0;
46 break;
47
48 case AFD_INFO_RECEIVE_CONTENT_SIZE:
49 /* Only touch InfoReq if a socket has been set up.
50 Behaviour was verified under WinXP SP2. */
51 if(FCB->AddressFile.Object)
52 InfoReq->Information.Ulong = FCB->Recv.Content - FCB->Recv.BytesUsed;
53
54 break;
55
56 default:
57 AFD_DbgPrint(MID_TRACE,("Unknown info id %x\n",
58 InfoReq->InformationClass));
59 Status = STATUS_INVALID_PARAMETER;
60 break;
61 }
62 } _SEH_HANDLE {
63 AFD_DbgPrint(MID_TRACE,("Exception executing GetInfo\n"));
64 Status = STATUS_INVALID_PARAMETER;
65 } _SEH_END;
66
67 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
68
69 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL );
70 }
71
72 NTSTATUS STDCALL
73 AfdGetSockOrPeerName( PDEVICE_OBJECT DeviceObject, PIRP Irp,
74 PIO_STACK_LOCATION IrpSp, BOOLEAN Local ) {
75 NTSTATUS Status = STATUS_SUCCESS;
76 PFILE_OBJECT FileObject = IrpSp->FileObject;
77 PAFD_FCB FCB = FileObject->FsContext;
78 PMDL Mdl = NULL, SysMdl = NULL;
79 PTDI_CONNECTION_INFORMATION ConnInfo = NULL;
80 PTRANSPORT_ADDRESS TransAddr = NULL;
81
82 AFD_DbgPrint(MID_TRACE,("Called on %x\n", FCB));
83
84 if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
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 if( FCB->AddressFile.Object == NULL ) {
104 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0,
105 NULL );
106 }
107
108 Status = TdiQueryInformation
109 ( FCB->AddressFile.Object,
110 TDI_QUERY_ADDRESS_INFO,
111 Mdl );
112 } else {
113 if( FCB->Connection.Object == NULL ) {
114 return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER, Irp, 0,
115 NULL );
116 }
117
118 if( NT_SUCCESS
119 ( Status = TdiBuildNullConnectionInfo
120 ( &ConnInfo,
121 FCB->LocalAddress->Address[0].AddressType ) ) ) {
122 SysMdl = IoAllocateMdl
123 ( ConnInfo,
124 sizeof( TDI_CONNECTION_INFORMATION ) +
125 TaLengthOfTransportAddress
126 ( ConnInfo->RemoteAddress ),
127 FALSE,
128 FALSE,
129 NULL );
130 }
131
132 if( SysMdl ) {
133 _SEH_TRY {
134 MmProbeAndLockPages( SysMdl, Irp->RequestorMode, IoModifyAccess );
135 } _SEH_HANDLE {
136 AFD_DbgPrint(MIN_TRACE, ("MmProbeAndLockPages() failed.\n"));
137 Status = _SEH_GetExceptionCode();
138 } _SEH_END;
139 } else Status = STATUS_NO_MEMORY;
140
141 if( NT_SUCCESS(Status) ) {
142 Status = TdiQueryInformation
143 ( FCB->Connection.Object,
144 TDI_QUERY_CONNECTION_INFO,
145 SysMdl );
146 }
147
148 if( NT_SUCCESS(Status) ) {
149 TransAddr =
150 (PTRANSPORT_ADDRESS)MmGetSystemAddressForMdlSafe( Mdl, NormalPagePriority );
151
152 if( TransAddr )
153 RtlCopyMemory( TransAddr, ConnInfo->RemoteAddress,
154 TaLengthOfTransportAddress
155 ( ConnInfo->RemoteAddress ) );
156 else Status = STATUS_INSUFFICIENT_RESOURCES;
157 }
158
159 if( ConnInfo ) ExFreePool( ConnInfo );
160 if( SysMdl ) IoFreeMdl( SysMdl );
161 if( TransAddr ) MmUnmapLockedPages( TransAddr, Mdl );
162 MmUnlockPages( Mdl );
163 IoFreeMdl( Mdl );
164 }
165 }
166 } else {
167 Status = STATUS_INSUFFICIENT_RESOURCES;
168 }
169
170 AFD_DbgPrint(MID_TRACE,("Returning %x\n", Status));
171
172 return UnlockAndMaybeComplete( FCB, Status, Irp, 0, NULL );
173 }