2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Ancillary Function Driver
5 * PURPOSE: File object creation and destruction
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/09-2000 Created
12 PAFDFCB AfdInitializeFCB(
13 PDEVICE_EXTENSION DeviceExt,
14 PFILE_OBJECT FileObject OPTIONAL)
16 * FUNCTION: Allocates and initializes a File Control Block structure
21 NewFCB = ExAllocatePool(NonPagedPool, sizeof(AFDFCB));
25 RtlZeroMemory(NewFCB, sizeof(AFDFCB));
27 ExInitializeResourceLite(&NewFCB->NTRequiredFCB.MainResource);
28 ExInitializeResourceLite(&NewFCB->NTRequiredFCB.PagingIoResource);
30 NewFCB->DeviceExt = DeviceExt;
31 NewFCB->ReferenceCount = 1;
32 NewFCB->OpenHandleCount = 1;
34 NewFCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
35 NewFCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
37 InitializeListHead(&NewFCB->CCBListHead);
39 InsertTailList(&DeviceExt->FCBListHead, &NewFCB->ListEntry);
41 InitializeListHead(&NewFCB->ReceiveQueue);
42 KeInitializeSpinLock(&NewFCB->ReceiveQueueLock);
44 InitializeListHead(&NewFCB->ReadRequestQueue);
45 KeInitializeSpinLock(&NewFCB->ReadRequestQueueLock);
48 FileObject->FsContext = (PVOID)NewFCB;
50 AFD_DbgPrint(MAX_TRACE, ("FCB created for file object (0x%X) at (0x%X).\n", FileObject, NewFCB));
56 PAFDCCB AfdInitializeCCB(
58 PFILE_OBJECT FileObject)
60 * FUNCTION: Allocates and initializes a Context Control Block structure
65 NewCCB = ExAllocatePool(NonPagedPool, sizeof(AFDCCB));
69 RtlZeroMemory(NewCCB, sizeof(AFDCCB));
71 NewCCB->FileObject = FileObject;
73 FileObject->FsContext2 = (PVOID)NewCCB;
75 InsertTailList(&FCB->CCBListHead, &NewCCB->ListEntry);
77 AFD_DbgPrint(MAX_TRACE, ("CCB created for file object (0x%X) at (0x%X).\n", FileObject, NewCCB));
86 PDEVICE_OBJECT DeviceObject,
89 PAFD_SOCKET_INFORMATION SocketInfo;
90 PFILE_FULL_EA_INFORMATION EaInfo;
91 PDEVICE_EXTENSION DeviceExt;
97 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
98 PFILE_OBJECT FileObject = IrpSp->FileObject;
100 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
102 assert(DeviceObject);
104 DeviceExt = DeviceObject->DeviceExtension;
106 EaInfo = Irp->AssociatedIrp.SystemBuffer;
108 /* Parameter check */
110 AFD_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n"));
111 return STATUS_INVALID_PARAMETER;
114 SocketInfo = (PAFD_SOCKET_INFORMATION)(EaInfo->EaName + EaInfo->EaNameLength);
116 EaLength = sizeof(FILE_FULL_EA_INFORMATION) +
117 EaInfo->EaNameLength +
118 EaInfo->EaValueLength;
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;
126 AFD_DbgPrint(MAX_TRACE, ("EaInfo at (0x%X) length is (%d).\n", EaInfo, EaLength));
128 /* FIXME: File/socket could already be open, do a search for it */
130 FCB = AfdInitializeFCB(DeviceExt, FileObject);
132 CCB = AfdInitializeCCB(FCB, FileObject);
135 FCB->CommandChannel = SocketInfo->CommandChannel;
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;
145 if (RtlCreateUnicodeString(&FCB->TdiDeviceName, SocketInfo->TdiDeviceName.Buffer)) {
147 RtlCopyUnicodeString(&FCB->TdiDeviceName, &SocketInfo->TdiDeviceName);
149 AFD_DbgPrint(MAX_TRACE, ("TDI device name is (%wZ).\n", &FCB->TdiDeviceName));
151 /* Open address file now for raw sockets */
152 if (FCB->SocketType == SOCK_RAW) {
153 AFD_DbgPrint(MAX_TRACE, ("Opening raw socket.\n"));
155 Status = TdiOpenAddressFile(
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;
165 AFD_DbgPrint(MAX_TRACE, ("AfdRegisterEventHandlers() failed (0x%X).\n", Status));
168 AFD_DbgPrint(MAX_TRACE, ("TdiOpenAddressFile() failed (0x%X).\n", Status));
171 Status = STATUS_SUCCESS;
173 Status = STATUS_INSUFFICIENT_RESOURCES;
175 Status = STATUS_SUCCESS;
177 Status = STATUS_INSUFFICIENT_RESOURCES;
179 if (!NT_SUCCESS(Status)) {
181 AFD_DbgPrint(MAX_TRACE, ("FIXME: Cleanup.\n"));
184 Irp->IoStatus.Status = Status;
185 Irp->IoStatus.Information = 0;
187 IoCompleteRequest(Irp, IO_NO_INCREMENT);
189 AFD_DbgPrint(MAX_TRACE, ("Leaving. Status (0x%X).\n", Status));
198 PDEVICE_OBJECT DeviceObject,
201 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp);
202 PFILE_OBJECT FileObject = IrpSp->FileObject;
207 AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
209 assert(DeviceObject);
212 FCB = FileObject->FsContext;
213 CCB = FileObject->FsContext2;
215 switch (IrpSp->MajorFunction) {
216 /* Close a file object */
218 FCB->ReferenceCount--;
219 if (FCB->ReferenceCount < 1) {
220 if (!FCB->CommandChannel) {
221 /* Close TDI connection file object */
222 if (FCB->TdiConnectionObjectHandle != INVALID_HANDLE_VALUE) {
223 TdiCloseDevice(FCB->TdiConnectionObjectHandle, FCB->TdiConnectionObject);
224 FCB->TdiConnectionObjectHandle = INVALID_HANDLE_VALUE;
227 /* Close TDI address file object */
228 if (FCB->TdiAddressObjectHandle != INVALID_HANDLE_VALUE) {
229 AfdDeregisterEventHandlers(FCB);
230 TdiCloseDevice(FCB->TdiAddressObjectHandle, FCB->TdiAddressObject);
231 FCB->TdiAddressObjectHandle = INVALID_HANDLE_VALUE;
238 Status = STATUS_SUCCESS;
241 /* Release resources bound to a file object */
243 FCB->OpenHandleCount--;
244 Status = STATUS_SUCCESS;
248 Status = STATUS_INVALID_DEVICE_REQUEST;
253 Irp->IoStatus.Status = Status;
254 Irp->IoStatus.Information = 0;
256 AFD_DbgPrint(MAX_TRACE, ("Completing IRP at (0x%X).\n", Irp));
258 IoCompleteRequest(Irp, IO_NO_INCREMENT);