1 /* $Id: fs.c,v 1.18 2001/07/15 15:36:31 ekohl 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>
16 #include <internal/pool.h>
19 #include <internal/debug.h>
21 /* TYPES *******************************************************************/
25 PDEVICE_OBJECT DeviceObject
;
29 /* GLOBALS ******************************************************************/
31 static KSPIN_LOCK FileSystemListLock
;
32 static LIST_ENTRY FileSystemListHead
;
34 #define TAG_FILE_SYSTEM TAG('F', 'S', 'Y', 'S')
36 /* FUNCTIONS *****************************************************************/
41 IN HANDLE DeviceHandle
,
42 IN HANDLE EventHandle OPTIONAL
,
43 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
44 IN PVOID ApcContext OPTIONAL
,
45 OUT PIO_STATUS_BLOCK IoStatusBlock
,
46 IN ULONG IoControlCode
,
48 IN ULONG InputBufferSize
,
49 OUT PVOID OutputBuffer
,
50 IN ULONG OutputBufferSize
54 PFILE_OBJECT FileObject
;
55 PDEVICE_OBJECT DeviceObject
;
57 PIO_STACK_LOCATION StackPtr
;
60 DPRINT("NtFsControlFile(DeviceHandle %x EventHandle %x ApcRoutine %x "
61 "ApcContext %x IoStatusBlock %x IoControlCode %x "
62 "InputBuffer %x InputBufferSize %x OutputBuffer %x "
63 "OutputBufferSize %x)\n",
64 DeviceHandle
,EventHandle
,ApcRoutine
,ApcContext
,IoStatusBlock
,
65 IoControlCode
,InputBuffer
,InputBufferSize
,OutputBuffer
,
68 Status
= ObReferenceObjectByHandle(DeviceHandle
,
69 FILE_READ_DATA
| FILE_WRITE_DATA
,
72 (PVOID
*) &FileObject
,
75 if (!NT_SUCCESS(Status
))
80 DeviceObject
= FileObject
->DeviceObject
;
82 KeInitializeEvent(&KEvent
,NotificationEvent
,TRUE
);
84 Irp
= IoBuildDeviceIoControlRequest(IoControlCode
,
94 Irp
->Overlay
.AsynchronousParameters
.UserApcRoutine
= ApcRoutine
;
95 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= ApcContext
;
97 StackPtr
= IoGetNextIrpStackLocation(Irp
);
98 StackPtr
->FileObject
= FileObject
;
99 StackPtr
->DeviceObject
= DeviceObject
;
100 StackPtr
->Parameters
.FileSystemControl
.InputBufferLength
= InputBufferSize
;
101 StackPtr
->Parameters
.FileSystemControl
.OutputBufferLength
=
103 StackPtr
->MajorFunction
= IRP_MJ_FILE_SYSTEM_CONTROL
;
105 Status
= IoCallDriver(DeviceObject
,Irp
);
106 if (Status
== STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
108 KeWaitForSingleObject(&KEvent
,Executive
,KernelMode
,FALSE
,NULL
);
109 return(IoStatusBlock
->Status
);
114 VOID
IoInitFileSystemImplementation(VOID
)
116 InitializeListHead(&FileSystemListHead
);
117 KeInitializeSpinLock(&FileSystemListLock
);
120 VOID
IoShutdownRegisteredFileSystems(VOID
)
123 PLIST_ENTRY current_entry
;
124 FILE_SYSTEM_OBJECT
* current
;
127 IO_STATUS_BLOCK IoStatusBlock
;
130 DPRINT("IoShutdownRegisteredFileSystems()\n");
132 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
133 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
135 current_entry
= FileSystemListHead
.Flink
;
136 while (current_entry
!=(&FileSystemListHead
))
138 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
140 /* send IRP_MJ_SHUTDOWN */
141 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN
,
142 current
->DeviceObject
,
149 Status
= IoCallDriver(current
->DeviceObject
,Irp
);
150 if (Status
==STATUS_PENDING
)
152 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
155 current_entry
= current_entry
->Flink
;
158 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
161 NTSTATUS
IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject
,
162 PDEVICE_OBJECT DeviceToMount
)
166 IO_STATUS_BLOCK IoStatusBlock
;
169 DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
170 DeviceObject
,DeviceToMount
);
172 assert_irql(PASSIVE_LEVEL
);
174 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
175 Irp
= IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME
,
180 Status
= IoCallDriver(DeviceObject
,Irp
);
181 if (Status
==STATUS_PENDING
)
183 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
184 Status
= IoStatusBlock
.Status
;
189 NTSTATUS
IoAskFileSystemToLoad(PDEVICE_OBJECT DeviceObject
)
194 NTSTATUS
IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject
)
196 * FUNCTION: Trys to mount a storage device
198 * DeviceObject = Device to try and mount
203 PLIST_ENTRY current_entry
;
204 FILE_SYSTEM_OBJECT
* current
;
207 assert_irql(PASSIVE_LEVEL
);
209 DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject
);
211 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
212 current_entry
= FileSystemListHead
.Flink
;
213 while (current_entry
!=(&FileSystemListHead
))
215 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
216 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
217 Status
= IoAskFileSystemToMountDevice(current
->DeviceObject
,
219 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
222 case STATUS_FS_DRIVER_REQUIRED
:
223 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
224 (void)IoAskFileSystemToLoad(DeviceObject
);
225 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
226 current_entry
= FileSystemListHead
.Flink
;
230 DeviceObject
->Vpb
->Flags
= DeviceObject
->Vpb
->Flags
|
232 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
233 return(STATUS_SUCCESS
);
235 case STATUS_UNRECOGNIZED_VOLUME
:
237 current_entry
= current_entry
->Flink
;
240 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
241 return(STATUS_UNRECOGNIZED_VOLUME
);
244 VOID STDCALL
IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject
)
246 FILE_SYSTEM_OBJECT
* fs
;
248 DPRINT("IoRegisterFileSystem(DeviceObject %x)\n",DeviceObject
);
250 fs
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(FILE_SYSTEM_OBJECT
),
254 fs
->DeviceObject
= DeviceObject
;
255 ExInterlockedInsertTailList(&FileSystemListHead
,&fs
->Entry
,
256 &FileSystemListLock
);
259 VOID STDCALL
IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject
)
262 PLIST_ENTRY current_entry
;
263 FILE_SYSTEM_OBJECT
* current
;
265 DPRINT("IoUnregisterFileSystem(DeviceObject %x)\n",DeviceObject
);
267 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
268 current_entry
= FileSystemListHead
.Flink
;
269 while (current_entry
!=(&FileSystemListHead
))
271 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
272 if (current
->DeviceObject
== DeviceObject
)
274 RemoveEntryList(current_entry
);
276 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
279 current_entry
= current_entry
->Flink
;
281 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
285 /**********************************************************************
287 * IoGetBaseFileSystemDeviceObject@4
290 * Get the DEVICE_OBJECT associated to
299 * From Bo Branten's ntifs.h v13.
303 IoGetBaseFileSystemDeviceObject (
304 IN PFILE_OBJECT FileObject
307 PDEVICE_OBJECT DeviceObject
= NULL
;
311 * If the FILE_OBJECT's VPB is defined,
312 * get the device from it.
314 if (NULL
!= (Vpb
= FileObject
->Vpb
))
316 if (NULL
!= (DeviceObject
= Vpb
->DeviceObject
))
318 /* Vpb->DeviceObject DEFINED! */
323 * If that failed, try the VPB
324 * in the FILE_OBJECT's DeviceObject.
326 DeviceObject
= FileObject
->DeviceObject
;
327 if (NULL
== (Vpb
= DeviceObject
->Vpb
))
329 /* DeviceObject->Vpb UNDEFINED! */
333 * If that pointer to the VPB is again
334 * undefined, return directly the
335 * device object from the FILE_OBJECT.
338 (NULL
== Vpb
->DeviceObject
)
347 IoRegisterFsRegistrationChange (
348 IN PDRIVER_OBJECT DriverObject
,
349 IN PFSDNOTIFICATIONPROC FSDNotificationProc
353 return (STATUS_NOT_IMPLEMENTED
);
359 IoUnregisterFsRegistrationChange (