Changes to support the COFF driver loader
[reactos.git] / reactos / ntoskrnl / io / fs.c
1 /*
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)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <internal/io.h>
15
16 #define NDEBUG
17 #include <internal/debug.h>
18
19 /* TYPES *******************************************************************/
20
21 typedef struct
22 {
23 PDEVICE_OBJECT DeviceObject;
24 LIST_ENTRY Entry;
25 } FILE_SYSTEM_OBJECT;
26
27 /* GLOBALS ******************************************************************/
28
29 static KSPIN_LOCK FileSystemListLock = {0,};
30 static LIST_ENTRY FileSystemListHead = {NULL,NULL};
31
32 /* FUNCTIONS *****************************************************************/
33
34 NTSTATUS
35 STDCALL
36 NtFsControlFile(
37 IN HANDLE DeviceHandle,
38 IN HANDLE Event OPTIONAL,
39 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
40 IN PVOID ApcContext OPTIONAL,
41 OUT PIO_STATUS_BLOCK IoStatusBlock,
42 IN ULONG IoControlCode,
43 IN PVOID InputBuffer,
44 IN ULONG InputBufferSize,
45 OUT PVOID OutputBuffer,
46 IN ULONG OutputBufferSize
47 )
48 {
49 return(ZwFsControlFile(DeviceHandle,
50 Event,
51 ApcRoutine,
52 ApcContext,
53 IoStatusBlock,
54 IoControlCode,
55 InputBuffer,
56 InputBufferSize,
57 OutputBuffer,
58 OutputBufferSize));
59 }
60
61 NTSTATUS
62 STDCALL
63 ZwFsControlFile(
64 IN HANDLE DeviceHandle,
65 IN HANDLE Event OPTIONAL,
66 IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
67 IN PVOID ApcContext OPTIONAL,
68 OUT PIO_STATUS_BLOCK IoStatusBlock,
69 IN ULONG IoControlCode,
70 IN PVOID InputBuffer,
71 IN ULONG InputBufferSize,
72 OUT PVOID OutputBuffer,
73 IN ULONG OutputBufferSize
74 )
75 {
76 UNIMPLEMENTED;
77 }
78
79 VOID IoInitFileSystemImplementation(VOID)
80 {
81 InitializeListHead(&FileSystemListHead);
82 KeInitializeSpinLock(&FileSystemListLock);
83 }
84
85 NTSTATUS IoAskFileSystemToMountDevice(PDEVICE_OBJECT DeviceObject,
86 PDEVICE_OBJECT DeviceToMount)
87 {
88 PIRP Irp;
89 KEVENT Event;
90 IO_STATUS_BLOCK IoStatusBlock;
91 NTSTATUS Status;
92
93 DPRINT("IoAskFileSystemToMountDevice(DeviceObject %x, DeviceToMount %x)\n",
94 DeviceObject,DeviceToMount);
95
96 KeInitializeEvent(&Event,NotificationEvent,FALSE);
97 Irp = IoBuildFilesystemControlRequest(IRP_MN_MOUNT_VOLUME,
98 DeviceObject,
99 &Event,
100 &IoStatusBlock,
101 DeviceToMount);
102 Status = IoCallDriver(DeviceObject,Irp);
103 if (Status==STATUS_PENDING)
104 {
105 KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
106 Status = IoStatusBlock.Status;
107 }
108 return(Status);
109 }
110
111 NTSTATUS IoAskFileSystemToLoad(PDEVICE_OBJECT DeviceObject)
112 {
113 UNIMPLEMENTED;
114 }
115
116 NTSTATUS IoTryToMountStorageDevice(PDEVICE_OBJECT DeviceObject)
117 /*
118 * FUNCTION: Trys to mount a storage device
119 * ARGUMENTS:
120 * DeviceObject = Device to try and mount
121 * RETURNS: Status
122 */
123 {
124 KIRQL oldlvl;
125 PLIST_ENTRY current_entry;
126 FILE_SYSTEM_OBJECT* current;
127 NTSTATUS Status;
128
129 DPRINT("IoTryToMountStorageDevice(DeviceObject %x)\n",DeviceObject);
130
131 KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
132 current_entry = FileSystemListHead.Flink;
133 while (current_entry!=(&FileSystemListHead))
134 {
135 current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry);
136 Status = IoAskFileSystemToMountDevice(current->DeviceObject,
137 DeviceObject);
138 switch (Status)
139 {
140 case STATUS_FS_DRIVER_REQUIRED:
141 KeReleaseSpinLock(&FileSystemListLock,oldlvl);
142 (void)IoAskFileSystemToLoad(DeviceObject);
143 KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
144 current_entry = FileSystemListHead.Flink;
145 break;
146
147 case STATUS_SUCCESS:
148 DeviceObject->Vpb->Flags = DeviceObject->Vpb->Flags |
149 VPB_MOUNTED;
150 KeReleaseSpinLock(&FileSystemListLock,oldlvl);
151 return(STATUS_SUCCESS);
152
153 case STATUS_UNRECOGNIZED_VOLUME:
154 default:
155 current_entry = current_entry->Flink;
156 }
157 }
158 CHECKPOINT;
159 KeReleaseSpinLock(&FileSystemListLock,oldlvl);
160 CHECKPOINT;
161 return(STATUS_UNRECOGNIZED_VOLUME);
162 }
163
164 VOID IoRegisterFileSystem(PDEVICE_OBJECT DeviceObject)
165 {
166 FILE_SYSTEM_OBJECT* fs;
167
168 DPRINT("IoRegisterFileSystem(DeviceObject %x)\n",DeviceObject);
169
170 fs=ExAllocatePool(NonPagedPool,sizeof(FILE_SYSTEM_OBJECT));
171 assert(fs!=NULL);
172
173 fs->DeviceObject = DeviceObject;
174 ExInterlockedInsertTailList(&FileSystemListHead,&fs->Entry,
175 &FileSystemListLock);
176 }
177
178 VOID IoUnregisterFileSystem(PDEVICE_OBJECT DeviceObject)
179 {
180 KIRQL oldlvl;
181 PLIST_ENTRY current_entry;
182 FILE_SYSTEM_OBJECT* current;
183
184 DPRINT("IoUnregisterFileSystem(DeviceObject %x)\n",DeviceObject);
185
186 KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
187 current_entry = FileSystemListHead.Flink;
188 while (current_entry!=(&FileSystemListHead))
189 {
190 current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry);
191 if (current->DeviceObject == DeviceObject)
192 {
193 RemoveEntryList(current_entry);
194 ExFreePool(current);
195 KeReleaseSpinLock(&FileSystemListLock,oldlvl);
196 return;
197 }
198 current_entry = current_entry->Flink;
199 }
200 KeReleaseSpinLock(&FileSystemListLock,oldlvl);
201 }
202
203