1 /* $Id: iface.c,v 1.44 2000/12/29 13:45:01 ekohl Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/vfat/iface.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
10 * 24-10-1998 Fixed bugs in long filename support
11 * Fixed a bug that prevented unsuccessful file open requests being reported
12 * Now works with long filenames that span over a sector boundary
13 * 28-10-1998 Reads entire FAT into memory
14 * VFatReadSector modified to read in more than one sector at a time
15 * 7-11-1998 Fixed bug that assumed that directory data could be fragmented
16 * 8-12-1998 Added FAT32 support
17 * Added initial writability functions
18 * WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
19 * 12-12-1998 Added basic support for FILE_STANDARD_INFORMATION request
23 /* INCLUDES *****************************************************************/
25 #include <ddk/ntddk.h>
33 /* GLOBALS *****************************************************************/
35 static PDRIVER_OBJECT VfatDriverObject
;
37 /* FUNCTIONS ****************************************************************/
39 BOOLEAN
FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount
)
41 * FUNCTION: Tests if the device contains a filesystem that can be mounted
47 Boot
= ExAllocatePool(NonPagedPool
,512);
49 VFATReadSectors(DeviceToMount
, 0, 1, (UCHAR
*)Boot
);
51 DPRINT("Boot->SysType %.5s\n", Boot
->SysType
);
52 if (strncmp(Boot
->SysType
,"FAT12",5)==0 ||
53 strncmp(Boot
->SysType
,"FAT16",5)==0 ||
54 strncmp(((struct _BootSector32
*)(Boot
))->SysType
,"FAT32",5)==0)
63 NTSTATUS
FsdMountDevice(PDEVICE_EXTENSION DeviceExt
,
64 PDEVICE_OBJECT DeviceToMount
)
66 * FUNCTION: Mounts the device
69 DPRINT("Mounting VFAT device...");
70 DPRINT("DeviceExt %x\n",DeviceExt
);
72 DeviceExt
->Boot
= ExAllocatePool(NonPagedPool
,512);
73 VFATReadSectors(DeviceToMount
, 0, 1, (UCHAR
*)DeviceExt
->Boot
);
75 DPRINT("DeviceExt->Boot->BytesPerSector %x\n",
76 DeviceExt
->Boot
->BytesPerSector
);
78 DeviceExt
->FATStart
=DeviceExt
->Boot
->ReservedSectors
;
79 DeviceExt
->rootDirectorySectors
=
80 (DeviceExt
->Boot
->RootEntries
*32)/DeviceExt
->Boot
->BytesPerSector
;
82 DeviceExt
->FATStart
+DeviceExt
->Boot
->FATCount
*DeviceExt
->Boot
->FATSectors
;
83 DeviceExt
->dataStart
=DeviceExt
->rootStart
+DeviceExt
->rootDirectorySectors
;
84 DeviceExt
->FATEntriesPerSector
=DeviceExt
->Boot
->BytesPerSector
/32;
85 DeviceExt
->BytesPerCluster
= DeviceExt
->Boot
->SectorsPerCluster
*
86 DeviceExt
->Boot
->BytesPerSector
;
88 if (strncmp(DeviceExt
->Boot
->SysType
,"FAT12",5)==0)
90 DeviceExt
->FatType
= FAT12
;
92 else if (strncmp(((struct _BootSector32
*)(DeviceExt
->Boot
))->SysType
,"FAT32",5)==0)
94 DeviceExt
->FatType
= FAT32
;
95 DeviceExt
->rootDirectorySectors
=DeviceExt
->Boot
->SectorsPerCluster
;
97 DeviceExt
->FATStart
+DeviceExt
->Boot
->FATCount
98 *((struct _BootSector32
*)( DeviceExt
->Boot
))->FATSectors32
;
99 DeviceExt
->dataStart
=DeviceExt
->rootStart
;
103 DeviceExt
->FatType
= FAT16
;
106 // with FAT32 it's not a good idea to load always fat in memory
107 // because on a 8GB partition with 2 KO clusters, the fat = 8 MO
108 if(DeviceExt
->FatType
!=FAT32
)
110 DeviceExt
->FAT
= ExAllocatePool(NonPagedPool
, BLOCKSIZE
*DeviceExt
->Boot
->FATSectors
);
111 VFATReadSectors(DeviceToMount
, DeviceExt
->FATStart
, DeviceExt
->Boot
->FATSectors
, (UCHAR
*)DeviceExt
->FAT
);
113 return STATUS_SUCCESS
;
116 NTSTATUS
FsdMount(PDEVICE_OBJECT DeviceToMount
)
118 * FUNCTION: Mount the filesystem
121 PDEVICE_OBJECT DeviceObject
;
122 PDEVICE_EXTENSION DeviceExt
;
124 IoCreateDevice(VfatDriverObject
,
125 sizeof(DEVICE_EXTENSION
),
127 FILE_DEVICE_FILE_SYSTEM
,
131 DeviceObject
->Flags
= DeviceObject
->Flags
| DO_DIRECT_IO
;
132 DeviceExt
= (PVOID
)DeviceObject
->DeviceExtension
;
133 // use same vpb as device disk
134 DeviceObject
->Vpb
=DeviceToMount
->Vpb
;
135 FsdMountDevice(DeviceExt
,DeviceToMount
);
136 DeviceObject
->Vpb
->Flags
|= VPB_MOUNTED
;
137 DeviceExt
->StorageDevice
= IoAttachDeviceToDeviceStack(DeviceObject
,
139 ExInitializeResourceLite(&DeviceExt
->DirResource
);
140 ExInitializeResourceLite(&DeviceExt
->FatResource
);
142 KeInitializeSpinLock(&DeviceExt
->FcbListLock
);
143 InitializeListHead(&DeviceExt
->FcbListHead
);
145 /* read serial number */
146 if (DeviceExt
->FatType
== FAT12
|| DeviceExt
->FatType
== FAT16
)
147 DeviceObject
->Vpb
->SerialNumber
=
148 ((struct _BootSector
*)(DeviceExt
->Boot
))->VolumeID
;
149 else if (DeviceExt
->FatType
== FAT32
)
150 DeviceObject
->Vpb
->SerialNumber
=
151 ((struct _BootSector32
*)(DeviceExt
->Boot
))->VolumeID
;
153 /* read volume label */
154 ReadVolumeLabel (DeviceExt
, DeviceObject
->Vpb
);
156 return(STATUS_SUCCESS
);
159 NTSTATUS STDCALL
FsdFileSystemControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
161 * FUNCTION: File system control
164 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
165 // PVPB vpb = Stack->Parameters.Mount.Vpb;
166 PDEVICE_OBJECT DeviceToMount
= Stack
->Parameters
.Mount
.DeviceObject
;
169 // DPRINT("VFAT FSC\n");
170 DbgPrint("VFAT FSC\n");
172 /* FIXME: should make sure that this is actually a mount request! */
174 if (FsdHasFileSystem(DeviceToMount
))
176 DPRINT("VFAT: Recognized volume\n");
177 Status
= FsdMount(DeviceToMount
);
181 DPRINT("VFAT: Unrecognized Volume\n");
182 Status
= STATUS_UNRECOGNIZED_VOLUME
;
185 Irp
->IoStatus
.Status
= Status
;
186 Irp
->IoStatus
.Information
= 0;
188 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
192 NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT _DriverObject
,
193 PUNICODE_STRING RegistryPath
)
195 * FUNCTION: Called by the system to initalize the driver
197 * DriverObject = object describing this driver
198 * RegistryPath = path to our configuration entries
199 * RETURNS: Success or failure
202 PDEVICE_OBJECT DeviceObject
;
204 UNICODE_STRING DeviceName
;
206 DbgPrint("VFAT 0.0.6\n");
208 VfatDriverObject
= _DriverObject
;
210 RtlInitUnicodeString(&DeviceName
, L
"\\Device\\Vfat");
211 ret
= IoCreateDevice(VfatDriverObject
,0,&DeviceName
,
212 FILE_DEVICE_FILE_SYSTEM
,0,FALSE
,&DeviceObject
);
213 if (ret
!=STATUS_SUCCESS
)
218 DeviceObject
->Flags
= DO_DIRECT_IO
;
219 VfatDriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FsdClose
;
220 VfatDriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FsdCreate
;
221 VfatDriverObject
->MajorFunction
[IRP_MJ_READ
] = FsdRead
;
222 VfatDriverObject
->MajorFunction
[IRP_MJ_WRITE
] = FsdWrite
;
223 VfatDriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] =
224 FsdFileSystemControl
;
225 VfatDriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] =
227 VfatDriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] =
229 VfatDriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] =
231 VfatDriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] =
232 VfatQueryVolumeInformation
;
233 VfatDriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] =
236 VfatDriverObject
->DriverUnload
= NULL
;
238 IoRegisterFileSystem(DeviceObject
);
240 return(STATUS_SUCCESS
);