1 /* $Id: fs.c,v 1.11 2000/03/06 01:02:30 ea Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/fs.c
6 * PURPOSE: Filesystem functions
7 * PROGRAMMER: David Welch (welch@mcmail.com)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
18 #include <internal/debug.h>
20 /* TYPES *******************************************************************/
24 PDEVICE_OBJECT DeviceObject
;
28 /* GLOBALS ******************************************************************/
30 static KSPIN_LOCK FileSystemListLock
;
31 static LIST_ENTRY FileSystemListHead
;
33 /* FUNCTIONS *****************************************************************/
38 IN HANDLE DeviceHandle
,
39 IN HANDLE EventHandle OPTIONAL
,
40 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
41 IN PVOID ApcContext OPTIONAL
,
42 OUT PIO_STATUS_BLOCK IoStatusBlock
,
43 IN ULONG IoControlCode
,
45 IN ULONG InputBufferSize
,
46 OUT PVOID OutputBuffer
,
47 IN ULONG OutputBufferSize
51 PFILE_OBJECT FileObject
;
53 PIO_STACK_LOCATION StackPtr
;
56 if (InputBufferSize
> 0)
58 Status
= ObReferenceObjectByHandle(DeviceHandle
,
59 FILE_WRITE_DATA
|FILE_READ_DATA
,
62 (PVOID
*) &FileObject
,
64 if (Status
!= STATUS_SUCCESS
)
69 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
70 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
71 FileObject
->DeviceObject
,
79 ObDereferenceObject(FileObject
);
80 return(STATUS_UNSUCCESSFUL
);
82 StackPtr
= IoGetNextIrpStackLocation(Irp
);
85 ObDereferenceObject(FileObject
);
86 return(STATUS_UNSUCCESSFUL
);
88 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
89 StackPtr
->FileObject
= FileObject
;
90 StackPtr
->Parameters
.Write
.Length
= InputBufferSize
;
91 DPRINT("FileObject->DeviceObject %x\n",FileObject
->DeviceObject
);
92 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
93 if (Status
==STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
95 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
97 ObDereferenceObject(FileObject
);
98 return(Irp
->IoStatus
.Status
);
101 if (OutputBufferSize
> 0)
104 Status
= ObReferenceObjectByHandle(DeviceHandle
,
105 FILE_WRITE_DATA
|FILE_READ_DATA
,
108 (PVOID
*) &FileObject
,
110 if (Status
!= STATUS_SUCCESS
)
115 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
117 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
118 FileObject
->DeviceObject
,
126 ObDereferenceObject(FileObject
);
127 return(STATUS_UNSUCCESSFUL
);
129 StackPtr
= IoGetNextIrpStackLocation(Irp
);
130 if (StackPtr
== NULL
)
132 return(STATUS_UNSUCCESSFUL
);
134 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
135 StackPtr
->FileObject
= FileObject
;
136 StackPtr
->Parameters
.Read
.Length
= OutputBufferSize
;
137 DPRINT("FileObject->DeviceObject %x\n",FileObject
->DeviceObject
);
138 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
139 if (Status
==STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
141 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
143 return(Irp
->IoStatus
.Status
);
148 VOID
IoInitFileSystemImplementation(VOID
)
150 InitializeListHead(&FileSystemListHead
);
151 KeInitializeSpinLock(&FileSystemListLock
);
154 NTSTATUS
IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject
,
155 PDEVICE_OBJECT DeviceToMount
)
159 IO_STATUS_BLOCK IoStatusBlock
;
162 DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
163 DeviceObject
,DeviceToMount
);
165 assert_irql(PASSIVE_LEVEL
);
167 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
168 Irp
= IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME
,
173 Status
= IoCallDriver(DeviceObject
,Irp
);
174 if (Status
==STATUS_PENDING
)
176 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
177 Status
= IoStatusBlock
.Status
;
182 NTSTATUS
IoAskFileSystemToLoad(PDEVICE_OBJECT DeviceObject
)
187 NTSTATUS
IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject
)
189 * FUNCTION: Trys to mount a storage device
191 * DeviceObject = Device to try and mount
196 PLIST_ENTRY current_entry
;
197 FILE_SYSTEM_OBJECT
* current
;
200 assert_irql(PASSIVE_LEVEL
);
202 DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject
);
204 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
205 current_entry
= FileSystemListHead
.Flink
;
206 while (current_entry
!=(&FileSystemListHead
))
208 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
209 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
210 Status
= IoAskFileSystemToMountDevice(current
->DeviceObject
,
212 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
215 case STATUS_FS_DRIVER_REQUIRED
:
216 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
217 (void)IoAskFileSystemToLoad(DeviceObject
);
218 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
219 current_entry
= FileSystemListHead
.Flink
;
223 DeviceObject
->Vpb
->Flags
= DeviceObject
->Vpb
->Flags
|
225 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
226 return(STATUS_SUCCESS
);
228 case STATUS_UNRECOGNIZED_VOLUME
:
230 current_entry
= current_entry
->Flink
;
233 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
234 return(STATUS_UNRECOGNIZED_VOLUME
);
237 VOID
IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject
)
239 FILE_SYSTEM_OBJECT
* fs
;
241 DPRINT("IoRegisterFileSystem(DeviceObject %x)\n",DeviceObject
);
243 fs
=ExAllocatePool(NonPagedPool
,sizeof(FILE_SYSTEM_OBJECT
));
246 fs
->DeviceObject
= DeviceObject
;
247 ExInterlockedInsertTailList(&FileSystemListHead
,&fs
->Entry
,
248 &FileSystemListLock
);
251 VOID
IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject
)
254 PLIST_ENTRY current_entry
;
255 FILE_SYSTEM_OBJECT
* current
;
257 DPRINT("IoUnregisterFileSystem(DeviceObject %x)\n",DeviceObject
);
259 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
260 current_entry
= FileSystemListHead
.Flink
;
261 while (current_entry
!=(&FileSystemListHead
))
263 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
264 if (current
->DeviceObject
== DeviceObject
)
266 RemoveEntryList(current_entry
);
268 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
271 current_entry
= current_entry
->Flink
;
273 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
277 /**********************************************************************
279 * IoGetBaseFileSystemDeviceObject@4
282 * Get the DEVICE_OBJECT associated to
291 * From Bo Branten's ntifs.h v13.
295 IoGetBaseFileSystemDeviceObject (
296 IN PFILE_OBJECT FileObject
299 PDEVICE_OBJECT DeviceObject
= NULL
;
303 * If the FILE_OBJECT's VPB is defined,
304 * get the device from it.
306 if (NULL
!= (Vpb
= FileObject
->Vpb
))
308 if (NULL
!= (DeviceObject
= Vpb
->DeviceObject
))
310 /* Vpb->DeviceObject DEFINED! */
315 * If that failed, try the VPB
316 * in the FILE_OBJECT's DeviceObject.
318 DeviceObject
= FileObject
->DeviceObject
;
319 if (NULL
== (Vpb
= DeviceObject
->Vpb
))
321 /* DeviceObject->Vpb UNDEFINED! */
325 * If that pointer to the VPB is again
326 * undefined, return directly the
327 * device object from the FILE_OBJECT.
330 (NULL
== Vpb
->DeviceObject
)