Corrected additional object manager issues pointed by Philip Susi
[reactos.git] / reactos / drivers / fs / vfat / iface.c
1 /* $Id: iface.c,v 1.40 1999/12/22 14:48:28 dwelch Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * ?? Created
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
20 *
21 */
22
23 /* INCLUDES *****************************************************************/
24
25 #include <wchar.h>
26 #include <internal/string.h>
27 #include <ddk/ntddk.h>
28 #include <ddk/cctypes.h>
29
30 #define NDEBUG
31 #include <internal/debug.h>
32
33 #include "vfat.h"
34
35 /* GLOBALS *****************************************************************/
36
37 static PDRIVER_OBJECT VfatDriverObject;
38
39 /* FUNCTIONS ****************************************************************/
40
41 BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
42 /*
43 * FUNCTION: Tests if the device contains a filesystem that can be mounted
44 * by this fsd
45 */
46 {
47 BootSector* Boot;
48
49 Boot = ExAllocatePool(NonPagedPool,512);
50
51 VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
52
53 DPRINT("Boot->SysType %.5s\n", Boot->SysType);
54 if (strncmp(Boot->SysType,"FAT12",5)==0 ||
55 strncmp(Boot->SysType,"FAT16",5)==0 ||
56 strncmp(((struct _BootSector32 *)(Boot))->SysType,"FAT32",5)==0)
57 {
58 ExFreePool(Boot);
59 return(TRUE);
60 }
61 ExFreePool(Boot);
62 return(FALSE);
63 }
64
65 NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
66 PDEVICE_OBJECT DeviceToMount)
67 /*
68 * FUNCTION: Mounts the device
69 */
70 {
71 DPRINT("Mounting VFAT device...");
72 DPRINT("DeviceExt %x\n",DeviceExt);
73
74 DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
75 VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
76
77 DPRINT("DeviceExt->Boot->BytesPerSector %x\n",
78 DeviceExt->Boot->BytesPerSector);
79
80 DeviceExt->FATStart=DeviceExt->Boot->ReservedSectors;
81 DeviceExt->rootDirectorySectors=
82 (DeviceExt->Boot->RootEntries*32)/DeviceExt->Boot->BytesPerSector;
83 DeviceExt->rootStart=
84 DeviceExt->FATStart+DeviceExt->Boot->FATCount*DeviceExt->Boot->FATSectors;
85 DeviceExt->dataStart=DeviceExt->rootStart+DeviceExt->rootDirectorySectors;
86 DeviceExt->FATEntriesPerSector=DeviceExt->Boot->BytesPerSector/32;
87 DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
88 DeviceExt->Boot->BytesPerSector;
89
90 if (strncmp(DeviceExt->Boot->SysType,"FAT12",5)==0)
91 {
92 DeviceExt->FatType = FAT12;
93 }
94 else if (strncmp(((struct _BootSector32 *)(DeviceExt->Boot))->SysType,"FAT32",5)==0)
95 {
96 DeviceExt->FatType = FAT32;
97 DeviceExt->rootDirectorySectors=DeviceExt->Boot->SectorsPerCluster;
98 DeviceExt->rootStart=
99 DeviceExt->FATStart+DeviceExt->Boot->FATCount
100 *((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
101 DeviceExt->dataStart=DeviceExt->rootStart;
102 }
103 else
104 {
105 DeviceExt->FatType = FAT16;
106 }
107
108 // with FAT32 it's not a good idea to load always fat in memory
109 // because on a 8GB partition with 2 KO clusters, the fat = 8 MO
110 if(DeviceExt->FatType!=FAT32)
111 {
112 DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
113 VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
114 }
115 return STATUS_SUCCESS;
116 }
117
118 NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
119 /*
120 * FUNCTION: Mount the filesystem
121 */
122 {
123 PDEVICE_OBJECT DeviceObject;
124 PDEVICE_EXTENSION DeviceExt;
125
126 IoCreateDevice(VfatDriverObject,
127 sizeof(DEVICE_EXTENSION),
128 NULL,
129 FILE_DEVICE_FILE_SYSTEM,
130 0,
131 FALSE,
132 &DeviceObject);
133 DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
134 DeviceExt = (PVOID)DeviceObject->DeviceExtension;
135 // use same vpb as device disk
136 DeviceObject->Vpb=DeviceToMount->Vpb;
137 FsdMountDevice(DeviceExt,DeviceToMount);
138 DeviceObject->Vpb->Flags |= VPB_MOUNTED;
139 DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
140 DeviceToMount);
141 ExInitializeResourceLite(&DeviceExt->DirResource);
142 ExInitializeResourceLite(&DeviceExt->FatResource);
143
144 KeInitializeSpinLock(&DeviceExt->FcbListLock);
145 InitializeListHead(&DeviceExt->FcbListHead);
146
147 /* read serial number */
148 if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
149 DeviceObject->Vpb->SerialNumber =
150 ((struct _BootSector *)(DeviceExt->Boot))->VolumeID;
151 else if (DeviceExt->FatType == FAT32)
152 DeviceObject->Vpb->SerialNumber =
153 ((struct _BootSector32 *)(DeviceExt->Boot))->VolumeID;
154
155 /* read volume label */
156 ReadVolumeLabel (DeviceExt, DeviceObject->Vpb);
157
158 return(STATUS_SUCCESS);
159 }
160
161 NTSTATUS FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
162 /*
163 * FUNCTION: File system control
164 */
165 {
166 PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
167 // PVPB vpb = Stack->Parameters.Mount.Vpb;
168 PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
169 NTSTATUS Status;
170
171 // DPRINT("VFAT FSC\n");
172 DbgPrint("VFAT FSC\n");
173
174 /* FIXME: should make sure that this is actually a mount request! */
175
176 if (FsdHasFileSystem(DeviceToMount))
177 {
178 DPRINT("VFAT: Recognized volume\n");
179 Status = FsdMount(DeviceToMount);
180 }
181 else
182 {
183 DPRINT("VFAT: Unrecognized Volume\n");
184 Status = STATUS_UNRECOGNIZED_VOLUME;
185 }
186
187 Irp->IoStatus.Status = Status;
188 Irp->IoStatus.Information = 0;
189
190 IoCompleteRequest(Irp, IO_NO_INCREMENT);
191 return(Status);
192 }
193
194 NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT _DriverObject,
195 PUNICODE_STRING RegistryPath)
196 /*
197 * FUNCTION: Called by the system to initalize the driver
198 * ARGUMENTS:
199 * DriverObject = object describing this driver
200 * RegistryPath = path to our configuration entries
201 * RETURNS: Success or failure
202 */
203 {
204 PDEVICE_OBJECT DeviceObject;
205 NTSTATUS ret;
206 UNICODE_STRING DeviceName;
207
208 DbgPrint("VFAT 0.0.6\n");
209
210 VfatDriverObject = _DriverObject;
211
212 RtlInitUnicodeString(&DeviceName, L"\\Device\\Vfat");
213 ret = IoCreateDevice(VfatDriverObject,0,&DeviceName,
214 FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
215 if (ret!=STATUS_SUCCESS)
216 {
217 return(ret);
218 }
219
220 DeviceObject->Flags = DO_DIRECT_IO;
221 VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
222 VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
223 VfatDriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
224 VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
225 VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
226 FsdFileSystemControl;
227 VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
228 FsdQueryInformation;
229 VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
230 VfatSetInformation;
231 VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
232 FsdDirectoryControl;
233 VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
234 VfatQueryVolumeInformation;
235
236 VfatDriverObject->DriverUnload = NULL;
237
238 IoRegisterFileSystem(DeviceObject);
239
240 return(STATUS_SUCCESS);
241 }
242