Raw IP and ICMP fixes
[reactos.git] / reactos / drivers / net / afd / afd / opnclose.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
4 * FILE: afd/opnclose.c
5 * PURPOSE: File object creation and destruction
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/09-2000 Created
9 */
10 #include <afd.h>
11
12 PAFDFCB AfdInitializeFCB(
13 PDEVICE_EXTENSION DeviceExt,
14 PFILE_OBJECT FileObject OPTIONAL)
15 /*
16 * FUNCTION: Allocates and initializes a File Control Block structure
17 */
18 {
19 PAFDFCB NewFCB;
20
21 NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
22 if (!NewFCB)
23 return NULL;
24
25 RtlZeroMemory(NewFCB, sizeof(AFDFCB));
26
27 ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
28 ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
29
30 NewFCB->DeviceExt = DeviceExt;
31 NewFCB->ReferenceCount = 1;
32 NewFCB->OpenHandleCount = 1;
33
34 NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
35 NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
36
37 InitializeListHead(&NewFCB->CCBListHead);
38
39 InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
40
41 InitializeListHead(&NewFCB->ReceiveQueue);
42 KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
43
44 InitializeListHead(&NewFCB->ReadRequestQueue);
45 KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
46
47 if (FileObject)
48 FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
49
50 AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
51
52 return NewFCB;
53 }
54
55
56 PAFDCCB AfdInitializeCCB(
57 PAFDFCB FCB,
58 PFILE_OBJECT FileObject)
59 /*
60 * FUNCTION: Allocates and initializes a Context Control Block structure
61 */
62 {
63 PAFDCCB NewCCB;
64
65 NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
66 if (!NewCCB)
67 return NULL;
68
69 RtlZeroMemory(NewCCB, sizeof(AFDCCB));
70
71 NewCCB->FileObject = FileObject;
72
73 FileObject->FsContext2 = (PVOID)NewCCB;
74
75 InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
76
77 AFD_DbgPrint(MAX_TRACE, ("CCB created for file object (0x%X) at (0x%X).\n", FileObject, NewCCB));
78
79 return NewCCB;
80 }
81
82
83 NTSTATUS
84 STDCALL
85 AfdCreate(
86 PDEVICE_OBJECT DeviceObject,
87 PIRP Irp)
88 {
89 PAFD_SOCKET_INFORMATION SocketInfo;
90 PFILE_FULL_EA_INFORMATION EaInfo;
91 PDEVICE_EXTENSION DeviceExt;
92 PTA_ADDRESS Address;
93 NTSTATUS Status;
94 ULONG EaLength;
95 PAFDFCB FCB;
96 PAFDCCB CCB;
97 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
98 PFILE_OBJECT FileObject = IrpSp->FileObject;
99
100 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
101
102 assert(DeviceObject);
103
104 DeviceExt = DeviceObject->DeviceExtension;
105
106 EaInfo = Irp->AssociatedIrp.SystemBuffer;
107
108 /* Parameter check */
109 if (!EaInfo) {
110 AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
111 return STATUS_INVALID_PARAMETER;
112 }
113
114 SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
115
116 EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
117 EaInfo->EaNameLength +
118 EaInfo->EaValueLength;
119
120 if (EaLength < sizeof(FILE_FULL_EA_INFORMATION) +
121 AFD_SOCKET_LENGTH + sizeof(AFD_SOCKET_INFORMATION)) {
122 AFD_DbgPrint(MIN_TRACE, ("EA information has invalid length.\n"));
123 return STATUS_INVALID_PARAMETER;
124 }
125
126 AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
127
128 /* FIXME: File/socket could already be open, do a search for it */
129
130 FCB = AfdInitializeFCB(DeviceExt, FileObject);
131
132 CCB = AfdInitializeCCB(FCB, FileObject);
133
134 if (CCB && FCB) {
135 FCB->CommandChannel = SocketInfo->CommandChannel;
136
137 if (!FCB->CommandChannel) {
138 FCB->AddressFamily = SocketInfo->AddressFamily;
139 FCB->SocketType = SocketInfo->SocketType;
140 FCB->Protocol = SocketInfo->Protocol;
141 FCB->SocketName = SocketInfo->Name;
142 FCB->HelperContext = SocketInfo->HelperContext;
143 FCB->NotificationEvents = SocketInfo->NotificationEvents;
144
145 if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) {
146
147 RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
148
149 AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
150
151 /* Open address file now for raw sockets */
152 if (FCB->SocketType == SOCK_RAW) {
153 AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
154
155 Status = TdiOpenAddressFile(
156 &FCB->TdiDeviceName,
157 &SocketInfo->Name,
158 &FCB->TdiAddressObjectHandle,
159 &FCB->TdiAddressObject);
160 if (NT_SUCCESS(Status)) {
161 Status = AfdRegisterEventHandlers(FCB);
162 if (NT_SUCCESS(Status)) {
163 FCB->State = SOCKET_STATE_BOUND;
164 } else {
165 AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status));
166 }
167 } else {
168 AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status));
169 }
170 } else
171 Status = STATUS_SUCCESS;
172 } else
173 Status = STATUS_INSUFFICIENT_RESOURCES;
174 } else
175 Status = STATUS_SUCCESS;
176 } else
177 Status = STATUS_INSUFFICIENT_RESOURCES;
178
179 if (!NT_SUCCESS(Status)) {
180 /* FIXME: Cleanup */
181 }
182
183 Irp->IoStatus.Status = Status;
184 Irp->IoStatus.Information = 0;
185
186 IoCompleteRequest(Irp, IO_NO_INCREMENT);
187
188 AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
189
190 return Status;
191 }
192
193
194 NTSTATUS
195 STDCALL
196 AfdClose(
197 PDEVICE_OBJECT DeviceObject,
198 PIRP Irp)
199 {
200 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
201 PFILE_OBJECT FileObject = IrpSp->FileObject;
202 NTSTATUS Status;
203 PAFDFCB FCB;
204 PAFDCCB CCB;
205
206 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
207
208 assert(DeviceObject);
209 assert(FileObject);
210
211 FCB = FileObject->FsContext;
212 CCB = FileObject->FsContext2;
213
214 switch (IrpSp->MajorFunction) {
215 /* Close a file object */
216 case IRP_MJ_CLOSE:
217 FCB->ReferenceCount--;
218 if (FCB->ReferenceCount < 1) {
219 if (!FCB->CommandChannel) {
220 /* Close TDI connection file object */
221 if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
222 TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
223 FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
224 }
225
226 /* Close TDI address file object */
227 if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
228 AfdDeregisterEventHandlers(FCB);
229 TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
230 FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
231 }
232 }
233
234 ExFreePool(FCB);
235 }
236
237 Status = STATUS_SUCCESS;
238 break;
239
240 /* Release resources bound to a file object */
241 case IRP_MJ_CLEANUP:
242 FCB->OpenHandleCount--;
243 Status = STATUS_SUCCESS;
244 break;
245
246 default:
247 Status = STATUS_INVALID_DEVICE_REQUEST;
248 }
249
250 ExFreePool(CCB);
251
252 Irp->IoStatus.Status = Status;
253 Irp->IoStatus.Information = 0;
254
255 IoCompleteRequest(Irp, IO_NO_INCREMENT);
256 return Status;
257 }
258
259 /* EOF */