Some work on winsock stack
[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 if (FileObject)
42 FileObject->FsContext = (PVOID)&NewFCB->NTRequiredFCB;
43
44 return NewFCB;
45 }
46
47
48 PAFDCCB AfdInitializeCCB(
49 PAFDFCB FCB,
50 PFILE_OBJECT FileObject)
51 /*
52 * FUNCTION: Allocates and initializes a Context Control Block structure
53 */
54 {
55 PAFDCCB NewCCB;
56
57 NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
58 if (!NewCCB)
59 return NULL;
60
61 RtlZeroMemory(NewCCB, sizeof(AFDCCB));
62
63 NewCCB->FileObject = FileObject;
64
65 FileObject->FsContext2 = (PVOID)NewCCB;
66
67 InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
68
69 return NewCCB;
70 }
71
72
73 NTSTATUS AfdCreate(
74 PDEVICE_OBJECT DeviceObject,
75 PIRP Irp)
76 {
77 PAFD_SOCKET_INFORMATION SocketInfo;
78 PFILE_FULL_EA_INFORMATION EaInfo;
79 PDEVICE_EXTENSION DeviceExt;
80 PTA_ADDRESS Address;
81 NTSTATUS Status;
82 ULONG EaLength;
83 PAFDFCB FCB;
84 PAFDCCB CCB;
85 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
86 PFILE_OBJECT FileObject = IrpSp->FileObject;
87
88 AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
89
90 DeviceExt = DeviceObject->DeviceExtension;
91
92 EaInfo = Irp->AssociatedIrp.SystemBuffer;
93
94 /* Parameter check */
95 if (!EaInfo) {
96 AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
97 return STATUS_INVALID_PARAMETER;
98 }
99
100 SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
101
102 EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
103 EaInfo->EaNameLength +
104 EaInfo->EaValueLength;
105
106 if (EaLength < sizeof(FILE_FULL_EA_INFORMATION) +
107 AFD_SOCKET_LENGTH + sizeof(AFD_SOCKET_INFORMATION)) {
108 AFD_DbgPrint(MIN_TRACE, ("EA information has invalid length.\n"));
109 return STATUS_INVALID_PARAMETER;
110 }
111
112 AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
113
114 /* FIXME: File/socket could already be open, do a search for it */
115
116 FCB = AfdInitializeFCB(DeviceExt, FileObject);
117 CCB = AfdInitializeCCB(FCB, FileObject);
118 if (CCB && FCB) {
119 FCB->AddressFamily = SocketInfo->AddressFamily;
120 FCB->SocketType = SocketInfo->SocketType;
121 FCB->Protocol = SocketInfo->Protocol;
122 FCB->HelperContext = SocketInfo->HelperContext;
123 FCB->NotificationEvents = SocketInfo->NotificationEvents;
124 RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
125 } else {
126 Status = STATUS_INSUFFICIENT_RESOURCES;
127 }
128
129 if (!NT_SUCCESS(Status)) {
130 /* FIXME: Cleanup */
131 }
132
133 Irp->IoStatus.Status = Status;
134 Irp->IoStatus.Information = 0;
135
136 IoCompleteRequest(Irp, IO_NO_INCREMENT);
137
138 AFD_DbgPrint(MIN_TRACE, ("Leaving. Status (0x%X).\n", Status));
139
140 return Status;
141 }
142
143
144 NTSTATUS AfdClose(
145 PDEVICE_OBJECT DeviceObject,
146 PIRP Irp)
147 {
148 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
149 PFILE_OBJECT FileObject = IrpSp->FileObject;
150 NTSTATUS Status;
151 PAFDFCB FCB;
152 PAFDCCB CCB;
153
154 FCB = FileObject->FsContext;
155 CCB = FileObject->FsContext2;
156
157 AFD_DbgPrint(MIN_TRACE, ("Called.\n"));
158
159 switch (IrpSp->MajorFunction) {
160 /* Close a file object */
161 case IRP_MJ_CLOSE:
162 FCB->ReferenceCount--;
163 if (FCB->ReferenceCount < 1) {
164 /* Close TDI connection file object */
165 if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
166 TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
167 FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
168 }
169
170 /* Close TDI address file object */
171 if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
172 AfdDeregisterEventHandlers(FCB);
173 TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
174 FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
175 }
176
177 ExFreePool(FCB);
178 }
179
180 Status = STATUS_SUCCESS;
181 break;
182
183 /* Release resources bound to a file object */
184 case IRP_MJ_CLEANUP:
185 FCB->OpenHandleCount--;
186 Status = STATUS_SUCCESS;
187 break;
188
189 default:
190 Status = STATUS_INVALID_DEVICE_REQUEST;
191 }
192
193 ExFreePool(CCB);
194
195 Irp->IoStatus.Status = Status;
196 Irp->IoStatus.Information = 0;
197
198 IoCompleteRequest(Irp, IO_NO_INCREMENT);
199 return Status;
200 }
201
202 /* EOF */