2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/fs.c
5 * PURPOSE: Filesystem functions
6 * PROGRAMMER: David Welch (welch@mcmail.com)
11 /* INCLUDES *****************************************************************/
13 #include <ddk/ntddk.h>
14 #include <internal/io.h>
17 #include <internal/debug.h>
19 /* TYPES *******************************************************************/
23 PDEVICE_OBJECT DeviceObject
;
27 /* GLOBALS ******************************************************************/
29 static KSPIN_LOCK FileSystemListLock
= {0,};
30 static LIST_ENTRY FileSystemListHead
= {NULL
,NULL
};
32 /* FUNCTIONS *****************************************************************/
37 IN HANDLE DeviceHandle
,
38 IN HANDLE EventHandle OPTIONAL
,
39 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
40 IN PVOID ApcContext OPTIONAL
,
41 OUT PIO_STATUS_BLOCK IoStatusBlock
,
42 IN ULONG IoControlCode
,
44 IN ULONG InputBufferSize
,
45 OUT PVOID OutputBuffer
,
46 IN ULONG OutputBufferSize
49 return(ZwFsControlFile(DeviceHandle
,
61 NTSTATUS STDCALL
ZwFsControlFile(IN HANDLE DeviceHandle
,
62 IN HANDLE EventHandle OPTIONAL
,
63 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL
,
64 IN PVOID ApcContext OPTIONAL
,
65 OUT PIO_STATUS_BLOCK IoStatusBlock
,
66 IN ULONG IoControlCode
,
68 IN ULONG InputBufferSize
,
69 OUT PVOID OutputBuffer
,
70 IN ULONG OutputBufferSize
)
73 PFILE_OBJECT FileObject
;
75 PIO_STACK_LOCATION StackPtr
;
78 if (InputBufferSize
> 0)
80 Status
= ObReferenceObjectByHandle(DeviceHandle
,
81 FILE_WRITE_DATA
|FILE_READ_DATA
,
84 (PVOID
*) &FileObject
,
86 if (Status
!= STATUS_SUCCESS
)
91 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
92 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
93 FileObject
->DeviceObject
,
101 ObDereferenceObject(FileObject
);
102 return(STATUS_UNSUCCESSFUL
);
104 StackPtr
= IoGetNextIrpStackLocation(Irp
);
105 if (StackPtr
== NULL
)
107 ObDereferenceObject(FileObject
);
108 return(STATUS_UNSUCCESSFUL
);
110 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
111 StackPtr
->FileObject
= FileObject
;
112 StackPtr
->Parameters
.Write
.Length
= InputBufferSize
;
113 DPRINT("FileObject->DeviceObject %x\n",FileObject
->DeviceObject
);
114 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
115 if (Status
==STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
117 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
119 ObDereferenceObject(FileObject
);
120 return(Irp
->IoStatus
.Status
);
123 if (OutputBufferSize
> 0)
126 Status
= ObReferenceObjectByHandle(DeviceHandle
,
127 FILE_WRITE_DATA
|FILE_READ_DATA
,
130 (PVOID
*) &FileObject
,
132 if (Status
!= STATUS_SUCCESS
)
137 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
139 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
140 FileObject
->DeviceObject
,
148 ObDereferenceObject(FileObject
);
149 return(STATUS_UNSUCCESSFUL
);
151 StackPtr
= IoGetNextIrpStackLocation(Irp
);
152 if (StackPtr
== NULL
)
154 return(STATUS_UNSUCCESSFUL
);
156 StackPtr
->Parameters
.DeviceIoControl
.IoControlCode
= IoControlCode
;
157 StackPtr
->FileObject
= FileObject
;
158 StackPtr
->Parameters
.Read
.Length
= OutputBufferSize
;
159 DPRINT("FileObject->DeviceObject %x\n",FileObject
->DeviceObject
);
160 Status
= IoCallDriver(FileObject
->DeviceObject
,Irp
);
161 if (Status
==STATUS_PENDING
&& (FileObject
->Flags
& FO_SYNCHRONOUS_IO
))
163 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
165 return(Irp
->IoStatus
.Status
);
170 VOID
IoInitFileSystemImplementation(VOID
)
172 InitializeListHead(&FileSystemListHead
);
173 KeInitializeSpinLock(&FileSystemListLock
);
176 NTSTATUS
IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject
,
177 PDEVICE_OBJECT DeviceToMount
)
181 IO_STATUS_BLOCK IoStatusBlock
;
184 DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
185 DeviceObject
,DeviceToMount
);
187 assert_irql(PASSIVE_LEVEL
);
189 KeInitializeEvent(&Event
,NotificationEvent
,FALSE
);
190 Irp
= IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME
,
195 Status
= IoCallDriver(DeviceObject
,Irp
);
196 if (Status
==STATUS_PENDING
)
198 KeWaitForSingleObject(&Event
,Executive
,KernelMode
,FALSE
,NULL
);
199 Status
= IoStatusBlock
.Status
;
204 NTSTATUS
IoAskFileSystemToLoad(PDEVICE_OBJECT DeviceObject
)
209 NTSTATUS
IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject
)
211 * FUNCTION: Trys to mount a storage device
213 * DeviceObject = Device to try and mount
218 PLIST_ENTRY current_entry
;
219 FILE_SYSTEM_OBJECT
* current
;
222 assert_irql(PASSIVE_LEVEL
);
224 DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject
);
226 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
227 current_entry
= FileSystemListHead
.Flink
;
228 while (current_entry
!=(&FileSystemListHead
))
230 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
231 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
232 Status
= IoAskFileSystemToMountDevice(current
->DeviceObject
,
234 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
237 case STATUS_FS_DRIVER_REQUIRED
:
238 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
239 (void)IoAskFileSystemToLoad(DeviceObject
);
240 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
241 current_entry
= FileSystemListHead
.Flink
;
245 DeviceObject
->Vpb
->Flags
= DeviceObject
->Vpb
->Flags
|
247 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
248 return(STATUS_SUCCESS
);
250 case STATUS_UNRECOGNIZED_VOLUME
:
252 current_entry
= current_entry
->Flink
;
255 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
256 return(STATUS_UNRECOGNIZED_VOLUME
);
259 VOID
IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject
)
261 FILE_SYSTEM_OBJECT
* fs
;
263 DPRINT("IoRegisterFileSystem(DeviceObject %x)\n",DeviceObject
);
265 fs
=ExAllocatePool(NonPagedPool
,sizeof(FILE_SYSTEM_OBJECT
));
268 fs
->DeviceObject
= DeviceObject
;
269 ExInterlockedInsertTailList(&FileSystemListHead
,&fs
->Entry
,
270 &FileSystemListLock
);
273 VOID
IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject
)
276 PLIST_ENTRY current_entry
;
277 FILE_SYSTEM_OBJECT
* current
;
279 DPRINT("IoUnregisterFileSystem(DeviceObject %x)\n",DeviceObject
);
281 KeAcquireSpinLock(&FileSystemListLock
,&oldlvl
);
282 current_entry
= FileSystemListHead
.Flink
;
283 while (current_entry
!=(&FileSystemListHead
))
285 current
= CONTAINING_RECORD(current_entry
,FILE_SYSTEM_OBJECT
,Entry
);
286 if (current
->DeviceObject
== DeviceObject
)
288 RemoveEntryList(current_entry
);
290 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);
293 current_entry
= current_entry
->Flink
;
295 KeReleaseSpinLock(&FileSystemListLock
,oldlvl
);