update for HEAD-2003091401
[reactos.git] / drivers / fs / fs_rec / fs_rec.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002,2003 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:             drivers/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_NTFS:
85         Status = FsRecNtfsFsControl(DeviceObject, Irp);
86         break;
87
88       case FS_TYPE_CDFS:
89         Status = FsRecCdfsFsControl(DeviceObject, Irp);
90         break;
91
92       case FS_TYPE_UDFS:
93         Status = FsRecUdfsFsControl(DeviceObject, Irp);
94         break;
95
96       default:
97         Status = STATUS_INVALID_DEVICE_REQUEST;
98     }
99
100   Irp->IoStatus.Status = Status;
101   IoCompleteRequest(Irp,
102                     IO_NO_INCREMENT);
103
104   return(Status);
105 }
106
107
108 VOID STDCALL
109 FsRecUnload(IN PDRIVER_OBJECT DriverObject)
110 {
111   PDEVICE_OBJECT NextDevice;
112   PDEVICE_OBJECT ThisDevice;
113
114   /* Delete all remaining device objects */
115   NextDevice = DriverObject->DeviceObject;
116   while (NextDevice != NULL)
117     {
118       ThisDevice = NextDevice;
119       NextDevice = NextDevice->NextDevice;
120       IoDeleteDevice(ThisDevice);
121     }
122 }
123
124
125 static NTSTATUS
126 FsRecRegisterFs(PDRIVER_OBJECT DriverObject,
127                 PWSTR FsName,
128                 PWSTR RecognizerName,
129                 ULONG DeviceType,
130                 ULONG FsType)
131 {
132   OBJECT_ATTRIBUTES ObjectAttributes;
133   IO_STATUS_BLOCK IoStatus;
134   PDEVICE_EXTENSION DeviceExt;
135   UNICODE_STRING DeviceName;
136   UNICODE_STRING FileName;
137   PDEVICE_OBJECT DeviceObject;
138   HANDLE FileHandle;
139   NTSTATUS Status;
140
141   RtlInitUnicodeString(&FileName,
142                        FsName);
143
144   InitializeObjectAttributes(&ObjectAttributes,
145                              &FileName,
146                              OBJ_CASE_INSENSITIVE,
147                              0,
148                              NULL);
149
150   Status = ZwCreateFile(&FileHandle,
151                         0x100000,
152                         &ObjectAttributes,
153                         &IoStatus,
154                         NULL,
155                         0,
156                         FILE_SHARE_READ | FILE_SHARE_WRITE,
157                         OPEN_EXISTING,
158                         0,
159                         NULL,
160                         0);
161   if (NT_SUCCESS(Status))
162     {
163       ZwClose(FileHandle);
164       return(STATUS_IMAGE_ALREADY_LOADED);
165     }
166
167   /* Create recognizer device object */
168   RtlInitUnicodeString(&DeviceName,
169                        RecognizerName);
170
171   Status = IoCreateDevice(DriverObject,
172                           sizeof(DEVICE_EXTENSION),
173                           &DeviceName,
174                           DeviceType,
175                           0,
176                           FALSE,
177                           &DeviceObject);
178
179   if (NT_SUCCESS(Status))
180     {
181       DeviceExt = DeviceObject->DeviceExtension;
182       DeviceExt->FsType = FsType;
183       IoRegisterFileSystem(DeviceObject);
184       DPRINT("Created recognizer device '%wZ'\n", &DeviceName);
185     }
186
187   return(Status);
188 }
189
190
191 NTSTATUS STDCALL
192 DriverEntry(PDRIVER_OBJECT DriverObject,
193             PUNICODE_STRING RegistryPath)
194 {
195   PCONFIGURATION_INFORMATION ConfigInfo;
196   ULONG DeviceCount;
197   NTSTATUS Status;
198
199   DPRINT("FileSystem recognizer 0.0.2\n");
200
201   DeviceCount = 0;
202
203   DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
204   DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsRecClose;
205   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecClose;
206   DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
207   DriverObject->DriverUnload = FsRecUnload;
208
209   ConfigInfo = IoGetConfigurationInformation();
210
211   if (ConfigInfo->CdRomCount > 0)
212     {
213       Status = FsRecRegisterFs(DriverObject,
214                                L"\\Cdfs",
215                                L"\\FileSystem\\CdfsRecognizer",
216                                FILE_DEVICE_CD_ROM_FILE_SYSTEM,
217                                FS_TYPE_CDFS);
218       if (NT_SUCCESS(Status))
219         {
220           DeviceCount++;
221         }
222
223       Status = FsRecRegisterFs(DriverObject,
224                                L"\\Udfs",
225                                L"\\FileSystem\\UdfsRecognizer",
226                                FILE_DEVICE_CD_ROM_FILE_SYSTEM,
227                                FS_TYPE_UDFS);
228       if (NT_SUCCESS(Status))
229         {
230           DeviceCount++;
231         }
232     }
233
234   Status = FsRecRegisterFs(DriverObject,
235                            L"\\Fat",
236                            L"\\FileSystem\\FatRecognizer",
237                            FILE_DEVICE_DISK_FILE_SYSTEM,
238                            FS_TYPE_VFAT);
239   if (NT_SUCCESS(Status))
240     {
241       DeviceCount++;
242     }
243
244   Status = FsRecRegisterFs(DriverObject,
245                            L"\\Ntfs",
246                            L"\\FileSystem\\NtfsRecognizer",
247                            FILE_DEVICE_DISK_FILE_SYSTEM,
248                            FS_TYPE_NTFS);
249   if (NT_SUCCESS(Status))
250     {
251       DeviceCount++;
252     }
253
254   return((DeviceCount > 0) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL);
255 }
256
257 /* EOF */