:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / drivers / fs / ext2 / super.c
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * FILE:             services/fs/ext2/super.c
5  * PURPOSE:          ext2 filesystem
6  * PROGRAMMER:       David Welch (welch@mcmail.com)
7  * UPDATE HISTORY: 
8  */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ddk/ntddk.h>
13
14 //#define NDEBUG
15 #include <debug.h>
16
17 #include "ext2fs.h"
18
19 /* GLOBALS *****************************************************************/
20
21 static PDRIVER_OBJECT DriverObject;
22
23 /* FUNCTIONS ****************************************************************/
24
25 NTSTATUS STDCALL
26 Ext2Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
27 {
28    PIO_STACK_LOCATION Stack;
29    PFILE_OBJECT FileObject;
30    PDEVICE_EXTENSION DeviceExtension;
31    NTSTATUS Status;
32    PEXT2_FCB Fcb;
33    
34    DbgPrint("Ext2Close(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
35    
36    Stack = IoGetCurrentIrpStackLocation(Irp);
37    FileObject = Stack->FileObject;
38    DeviceExtension = DeviceObject->DeviceExtension;
39    
40    if (FileObject == DeviceExtension->FileObject)
41      {
42         Status = STATUS_SUCCESS;
43    
44         Irp->IoStatus.Status = Status;
45         Irp->IoStatus.Information = 0;
46         
47         IoCompleteRequest(Irp, IO_NO_INCREMENT);
48         return(Status);
49      }
50
51    Fcb = (PEXT2_FCB)FileObject->FsContext;
52    if (Fcb != NULL)
53      {
54         if (Fcb->Bcb != NULL)
55           {
56              CcRosReleaseFileCache(FileObject, Fcb->Bcb);
57           }
58         ExFreePool(Fcb);
59         FileObject->FsContext = NULL;
60      }
61    
62    Status = STATUS_SUCCESS;
63    
64    Irp->IoStatus.Status = Status;
65    Irp->IoStatus.Information = 0;
66    
67    IoCompleteRequest(Irp, IO_NO_INCREMENT);
68    return(Status);
69 }
70
71 NTSTATUS Ext2Mount(PDEVICE_OBJECT DeviceToMount)
72 {
73    PDEVICE_OBJECT DeviceObject;
74    PDEVICE_EXTENSION DeviceExt;
75    PVOID BlockBuffer;   
76    struct ext2_super_block* superblock;
77    
78    DPRINT("Ext2Mount(DeviceToMount %x)\n",DeviceToMount);
79    
80    BlockBuffer = ExAllocatePool(NonPagedPool,BLOCKSIZE);
81    Ext2ReadSectors(DeviceToMount,
82                    1,
83                    1,
84                    BlockBuffer);
85    superblock = BlockBuffer;
86    
87    if (superblock->s_magic != EXT2_SUPER_MAGIC)
88      {
89         ExFreePool(BlockBuffer);
90         return(STATUS_UNRECOGNIZED_VOLUME);
91      }
92    DPRINT("Volume recognized\n");
93    DPRINT("s_inodes_count %d\n",superblock->s_inodes_count);
94    DPRINT("s_blocks_count %d\n",superblock->s_blocks_count);
95    
96    IoCreateDevice(DriverObject,
97                   sizeof(DEVICE_EXTENSION),
98                   NULL,
99                   FILE_DEVICE_FILE_SYSTEM,
100                   0,
101                   FALSE,
102                   &DeviceObject);
103    DPRINT("DeviceObject %x\n",DeviceObject);
104    DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
105    DeviceExt = (PVOID)DeviceObject->DeviceExtension;
106    DPRINT("DeviceExt %x\n",DeviceExt);
107
108   DeviceExt->StorageDevice = DeviceToMount;
109   DeviceExt->StorageDevice->Vpb->DeviceObject = DeviceObject;
110   DeviceExt->StorageDevice->Vpb->RealDevice = DeviceExt->StorageDevice;
111   DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
112   DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
113   DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
114
115    DPRINT("DeviceExt->StorageDevice %x\n", DeviceExt->StorageDevice);
116    DeviceExt->FileObject = IoCreateStreamFileObject(NULL, DeviceObject);
117    DeviceExt->superblock = superblock;
118    CcRosInitializeFileCache(DeviceExt->FileObject,
119                             &DeviceExt->Bcb,
120                             PAGE_SIZE * 3);
121    
122    DPRINT("Ext2Mount() = STATUS_SUCCESS\n");
123    
124    return(STATUS_SUCCESS);
125 }
126
127 NTSTATUS STDCALL
128 Ext2FileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
129 {
130    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
131    PVPB vpb = Stack->Parameters.Mount.Vpb;
132    PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
133    NTSTATUS Status;
134    
135    Status = Ext2Mount(DeviceToMount);
136    
137    Irp->IoStatus.Status = Status;
138    Irp->IoStatus.Information = 0;
139    
140    IoCompleteRequest(Irp, IO_NO_INCREMENT);
141    return(Status);
142 }
143
144 NTSTATUS STDCALL
145 DriverEntry(PDRIVER_OBJECT _DriverObject,
146             PUNICODE_STRING RegistryPath)
147 /*
148  * FUNCTION: Called by the system to initalize the driver
149  * ARGUMENTS:
150  *           DriverObject = object describing this driver
151  *           RegistryPath = path to our configuration entries
152  * RETURNS: Success or failure
153  */
154 {
155    PDEVICE_OBJECT DeviceObject;
156    NTSTATUS ret;
157    UNICODE_STRING DeviceName = UNICODE_STRING_INITIALIZER(L"\\Device\\Ext2Fsd");
158    
159    DbgPrint("Ext2 FSD 0.0.1\n");
160    
161    DriverObject = _DriverObject;
162    
163    ret = IoCreateDevice(DriverObject,
164                         0,
165                         &DeviceName,
166                         FILE_DEVICE_FILE_SYSTEM,
167                         0,
168                         FALSE,
169                         &DeviceObject);
170    if (ret!=STATUS_SUCCESS)
171      {
172         return(ret);
173      }
174
175    DeviceObject->Flags=0;
176    DriverObject->MajorFunction[IRP_MJ_CLOSE] = Ext2Close;
177    DriverObject->MajorFunction[IRP_MJ_CREATE] = Ext2Create;
178    DriverObject->MajorFunction[IRP_MJ_READ] = Ext2Read;
179    DriverObject->MajorFunction[IRP_MJ_WRITE] = Ext2Write;
180    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
181                       Ext2FileSystemControl;
182    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
183                       Ext2DirectoryControl;
184    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = 
185                       Ext2QueryInformation;
186    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = Ext2SetInformation;
187    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = Ext2FlushBuffers;
188    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = Ext2Shutdown;
189    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Ext2Cleanup;
190    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = Ext2QuerySecurity;
191    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = Ext2SetSecurity;
192    DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = Ext2QueryQuota;
193    DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = Ext2SetQuota;
194    
195    DriverObject->DriverUnload = NULL;
196    
197    IoRegisterFileSystem(DeviceObject);
198    
199    return(STATUS_SUCCESS);
200 }
201