:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / fs_rec / fs_rec.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 ReactOS Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$
20  *
21  * COPYRIGHT:        See COPYING in the top level directory
22  * PROJECT:          ReactOS kernel
23  * FILE:             services/fs/fs_rec/fs_rec.c
24  * PURPOSE:          Filesystem recognizer driver
25  * PROGRAMMER:       Eric Kohl
26  */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 #include "fs_rec.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 NTSTATUS STDCALL
41 FsRecCreate(IN PDEVICE_OBJECT DeviceObject,
42             IN PIRP Irp)
43 {
44   NTSTATUS Status;
45
46
47   Status = STATUS_SUCCESS;
48
49
50   Irp->IoStatus.Status = Status;
51   IoCompleteRequest(Irp,
52                     IO_NO_INCREMENT);
53
54   return(Status);
55 }
56
57
58 NTSTATUS STDCALL
59 FsRecClose(IN PDEVICE_OBJECT DeviceObject,
60            IN PIRP Irp)
61 {
62   Irp->IoStatus.Status = STATUS_SUCCESS;
63   IoCompleteRequest(Irp,
64                     IO_NO_INCREMENT);
65
66   return(STATUS_SUCCESS);
67 }
68
69
70 NTSTATUS STDCALL
71 FsRecFsControl(IN PDEVICE_OBJECT DeviceObject,
72                IN PIRP Irp)
73 {
74   PDEVICE_EXTENSION DeviceExt;
75   NTSTATUS Status;
76
77   DeviceExt = DeviceObject->DeviceExtension;
78   switch (DeviceExt->FsType)
79     {
80       case FS_TYPE_VFAT:
81         Status = FsRecVfatFsControl(DeviceObject, Irp);
82         break;
83
84       case FS_TYPE_CDFS:
85         Status = FsRecCdfsFsControl(DeviceObject, Irp);
86         break;
87
88       case FS_TYPE_NTFS:
89         Status = FsRecNtfsFsControl(DeviceObject, Irp);
90         break;
91
92       default:
93         Status = STATUS_INVALID_DEVICE_REQUEST;
94     }
95
96   Irp->IoStatus.Status = Status;
97   IoCompleteRequest(Irp,
98                     IO_NO_INCREMENT);
99
100   return(Status);
101 }
102
103
104 VOID STDCALL
105 FsRecUnload(IN PDRIVER_OBJECT DriverObject)
106 {
107   PDEVICE_OBJECT NextDevice;
108   PDEVICE_OBJECT ThisDevice;
109
110   /* Delete all remaining device objects */
111   NextDevice = DriverObject->DeviceObject;
112   while (NextDevice != NULL)
113     {
114       ThisDevice = NextDevice;
115       NextDevice = NextDevice->NextDevice;
116       IoDeleteDevice(ThisDevice);
117     }
118 }
119
120
121 static NTSTATUS
122 FsRecRegisterFs(PDRIVER_OBJECT DriverObject,
123                 PWSTR FsName,
124                 PWSTR RecognizerName,
125                 ULONG DeviceType,
126                 ULONG FsType)
127 {
128   OBJECT_ATTRIBUTES ObjectAttributes;
129   IO_STATUS_BLOCK IoStatus;
130   PDEVICE_EXTENSION DeviceExt;
131   UNICODE_STRING DeviceName;
132   UNICODE_STRING FileName;
133   PDEVICE_OBJECT DeviceObject;
134   HANDLE FileHandle;
135   NTSTATUS Status;
136
137   RtlInitUnicodeString(&FileName,
138                        FsName);
139
140   InitializeObjectAttributes(&ObjectAttributes,
141                              &FileName,
142                              OBJ_CASE_INSENSITIVE,
143                              0,
144                              NULL);
145
146   Status = ZwCreateFile(&FileHandle,
147                         0x100000,
148                         &ObjectAttributes,
149                         &IoStatus,
150                         NULL,
151                         0,
152                         FILE_SHARE_READ | FILE_SHARE_WRITE,
153                         OPEN_EXISTING,
154                         0,
155                         NULL,
156                         0);
157   if (NT_SUCCESS(Status))
158     {
159       ZwClose(FileHandle);
160       return(STATUS_IMAGE_ALREADY_LOADED);
161     }
162
163   /* Create recognizer device object */
164   RtlInitUnicodeString(&DeviceName,
165                        RecognizerName);
166
167   Status = IoCreateDevice(DriverObject,
168                           sizeof(DEVICE_EXTENSION),
169                           &DeviceName,
170                           DeviceType,
171                           0,
172                           FALSE,
173                           &DeviceObject);
174
175   if (NT_SUCCESS(Status))
176     {
177       DeviceExt = DeviceObject->DeviceExtension;
178       DeviceExt->FsType = FsType;
179       IoRegisterFileSystem(DeviceObject);
180       DPRINT("Created recognizer device '%wZ'\n", &DeviceName);
181     }
182
183   return(Status);
184 }
185
186
187 NTSTATUS STDCALL
188 DriverEntry(PDRIVER_OBJECT DriverObject,
189             PUNICODE_STRING RegistryPath)
190 {
191   PCONFIGURATION_INFORMATION ConfigInfo;
192   ULONG DeviceCount;
193   NTSTATUS Status;
194
195   DPRINT("FileSystem recognizer 0.0.1\n");
196
197   DeviceCount = 0;
198
199   DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
200   DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose;
201   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose;
202   DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
203   DriverObject->DriverUnload = FsRecUnload;
204
205   ConfigInfo = IoGetConfigurationInformation();
206
207   if (ConfigInfo->CDRomCount > 0)
208     {
209       Status = FsRecRegisterFs(DriverObject,
210                                L"\\Cdfs",
211                                L"\\FileSystem\\CdfsRecognizer",
212                                FILE_DEVICE_CD_ROM_FILE_SYSTEM,
213                                FS_TYPE_CDFS);
214       if (NT_SUCCESS(Status))
215         {
216           DeviceCount++;
217         }
218     }
219
220   Status = FsRecRegisterFs(DriverObject,
221                            L"\\Fat",
222                            L"\\FileSystem\\FatRecognizer",
223                            FILE_DEVICE_DISK_FILE_SYSTEM,
224                            FS_TYPE_VFAT);
225   if (NT_SUCCESS(Status))
226     {
227       DeviceCount++;
228     }
229
230   Status = FsRecRegisterFs(DriverObject,
231                            L"\\Ntfs",
232                            L"\\FileSystem\\NtfsRecognizer",
233                            FILE_DEVICE_DISK_FILE_SYSTEM,
234                            FS_TYPE_NTFS);
235   if (NT_SUCCESS(Status))
236     {
237       DeviceCount++;
238     }
239
240   return((DeviceCount > 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
241 }
242
243 /* EOF */