2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/fastfat.c
5 * PURPOSE: Initialization routines
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
9 /* INCLUDES *****************************************************************/
14 /* GLOBALS ******************************************************************/
16 FAT_GLOBAL_DATA FatGlobalData
;
18 /* FUNCTIONS ****************************************************************/
23 DriverEntry(PDRIVER_OBJECT DriverObject
,
24 PUNICODE_STRING RegistryPath
)
26 PDEVICE_OBJECT DeviceObject
;
27 UNICODE_STRING DeviceName
= RTL_CONSTANT_STRING(L
"\\Fat");
30 /* Create a device object */
31 Status
= IoCreateDevice(DriverObject
,
34 FILE_DEVICE_DISK_FILE_SYSTEM
,
39 if (!NT_SUCCESS(Status
)) return Status
;
41 /* Zero global storage */
42 RtlZeroMemory(&FatGlobalData
, sizeof(FAT_GLOBAL_DATA
));
43 FatGlobalData
.DriverObject
= DriverObject
;
44 FatGlobalData
.DiskDeviceObject
= DeviceObject
;
46 /* Fill major function handlers */
47 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = FatClose
;
48 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = FatCreate
;
49 DriverObject
->MajorFunction
[IRP_MJ_READ
] = FatRead
;
50 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = FatWrite
;
51 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] = FatFileSystemControl
;
52 DriverObject
->MajorFunction
[IRP_MJ_QUERY_INFORMATION
] = FatQueryInformation
;
53 DriverObject
->MajorFunction
[IRP_MJ_SET_INFORMATION
] = FatSetInformation
;
54 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] = FatDirectoryControl
;
55 DriverObject
->MajorFunction
[IRP_MJ_QUERY_VOLUME_INFORMATION
] = FatQueryVolumeInfo
;
56 DriverObject
->MajorFunction
[IRP_MJ_SET_VOLUME_INFORMATION
] = FatSetVolumeInfo
;
57 DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = FatShutdown
;
58 DriverObject
->MajorFunction
[IRP_MJ_LOCK_CONTROL
] = FatLockControl
;
59 DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = FatDeviceControl
;
60 DriverObject
->MajorFunction
[IRP_MJ_CLEANUP
] = FatCleanup
;
61 DriverObject
->MajorFunction
[IRP_MJ_FLUSH_BUFFERS
] = FatFlushBuffers
;
62 //DriverObject->MajorFunction[IRP_MJ_QUERY_EA]
63 //DriverObject->MajorFunction[IRP_MJ_SET_EA]
64 //DriverObject->MajorFunction[IRP_MJ_PNP]
66 DriverObject
->DriverUnload
= NULL
;
68 /* Initialize cache manager callbacks */
69 FatGlobalData
.CacheMgrCallbacks
.AcquireForLazyWrite
= FatAcquireForLazyWrite
;
70 FatGlobalData
.CacheMgrCallbacks
.ReleaseFromLazyWrite
= FatReleaseFromLazyWrite
;
71 FatGlobalData
.CacheMgrCallbacks
.AcquireForReadAhead
= FatAcquireForReadAhead
;
72 FatGlobalData
.CacheMgrCallbacks
.ReleaseFromReadAhead
= FatReleaseFromReadAhead
;
74 FatGlobalData
.CacheMgrNoopCallbacks
.AcquireForLazyWrite
= FatNoopAcquire
;
75 FatGlobalData
.CacheMgrNoopCallbacks
.ReleaseFromLazyWrite
= FatNoopRelease
;
76 FatGlobalData
.CacheMgrNoopCallbacks
.AcquireForReadAhead
= FatNoopAcquire
;
77 FatGlobalData
.CacheMgrNoopCallbacks
.ReleaseFromReadAhead
= FatNoopRelease
;
79 /* Initialize Fast I/O dispatchers */
80 FatInitFastIoRoutines(&FatGlobalData
.FastIoDispatch
);
81 DriverObject
->FastIoDispatch
= &FatGlobalData
.FastIoDispatch
;
83 /* Initialize lookaside lists */
84 ExInitializeNPagedLookasideList(&FatGlobalData
.NonPagedFcbList
,
92 ExInitializeNPagedLookasideList(&FatGlobalData
.ResourceList
,
100 ExInitializeNPagedLookasideList(&FatGlobalData
.IrpContextList
,
104 sizeof(FAT_IRP_CONTEXT
),
108 /* Initialize synchronization resource for the global data */
109 ExInitializeResourceLite(&FatGlobalData
.Resource
);
111 /* Initialize global VCB list */
112 InitializeListHead(&FatGlobalData
.VcbListHead
);
114 /* Register and reference our filesystem */
115 IoRegisterFileSystem(DeviceObject
);
116 ObReferenceObject(DeviceObject
);
117 return STATUS_SUCCESS
;
122 FatBuildIrpContext(PIRP Irp
,
125 PIO_STACK_LOCATION IrpSp
;
126 PFAT_IRP_CONTEXT IrpContext
;
127 PVOLUME_DEVICE_OBJECT VolumeObject
;
129 /* Get current IRP stack location */
130 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
132 /* Allocate memory for the Irp context */
133 IrpContext
= ExAllocateFromNPagedLookasideList(&FatGlobalData
.IrpContextList
);
135 /* Zero init memory */
136 RtlZeroMemory(IrpContext
, sizeof(FAT_IRP_CONTEXT
));
138 /* Save IRP, MJ and MN */
139 IrpContext
->Irp
= Irp
;
140 IrpContext
->Stack
= IrpSp
;
141 IrpContext
->MajorFunction
= IrpSp
->MajorFunction
;
142 IrpContext
->MinorFunction
= IrpSp
->MinorFunction
;
144 /* Set DeviceObject */
145 if (IrpSp
->FileObject
)
147 IrpContext
->DeviceObject
= IrpSp
->FileObject
->DeviceObject
;
149 /* Save VCB pointer */
150 VolumeObject
= (PVOLUME_DEVICE_OBJECT
)IrpSp
->DeviceObject
;
151 IrpContext
->Vcb
= &VolumeObject
->Vcb
;
153 /* TODO: Handle write-through */
155 else if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
)
157 /* Handle FSCTRL case */
158 IrpContext
->DeviceObject
= IrpSp
->Parameters
.MountVolume
.Vpb
->RealDevice
;
162 if (CanWait
) IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
164 /* Return prepared context */
170 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext
)
174 /* Make sure it has no pinned stuff */
175 ASSERT(IrpContext
->PinCount
== 0);
177 /* If there is a FatIo context associated with it - free it */
178 if (IrpContext
->FatIoContext
)
180 if (!(IrpContext
->Flags
& IRPCONTEXT_STACK_IO_CONTEXT
))
182 /* If a zero mdl was allocated - free it */
183 if (IrpContext
->FatIoContext
->ZeroMdl
)
184 IoFreeMdl(IrpContext
->FatIoContext
->ZeroMdl
);
186 /* Free memory of FatIo context */
187 ExFreePool(IrpContext
->FatIoContext
);
192 ExFreeToNPagedLookasideList(&FatGlobalData
.IrpContextList
, IrpContext
);
197 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL
,
205 /* TODO: Unpin repinned BCBs */
206 //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
207 //FatUnpinRepinnedBcbs( IrpContext );
209 /* Destroy IRP context */
210 FatDestroyIrpContext(IrpContext
);
213 /* Complete the IRP */
216 /* Cleanup IoStatus.Information in case of error input operation */
217 if (NT_ERROR(Status
) && (Irp
->Flags
& IRP_INPUT_OPERATION
))
219 Irp
->IoStatus
.Information
= 0;
222 /* Save status and complete this IRP */
223 Irp
->IoStatus
.Status
= Status
;
224 IoCompleteRequest( Irp
, IO_DISK_INCREMENT
);
230 FatDequeueRequest(IN PVOID Context
)
232 PFAT_IRP_CONTEXT IrpContext
;
234 IrpContext
= (PFAT_IRP_CONTEXT
) Context
;
236 /* Enter critical region. */
237 FsRtlEnterFileSystem();
239 /* Handle top level IRP Correctly. */
240 if (!FlagOn(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
))
241 IoSetTopLevelIrp((PIRP
) FSRTL_FSP_TOP_LEVEL_IRP
);
243 /* Enable Synchronous IO. */
244 SetFlag(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
);
246 /* Invoke the handler routine. */
247 IrpContext
->QueuedOperationHandler(IrpContext
);
249 /* Restore top level IRP. */
250 IoSetTopLevelIrp(NULL
);
252 /* Leave critical region. */
253 FsRtlExitFileSystem();
258 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext
,
259 IN PFAT_OPERATION_HANDLER OperationHandler
)
261 /* Save the worker routine. */
262 IrpContext
->QueuedOperationHandler
= OperationHandler
;
264 /* Indicate if top level IRP was set. */
265 if (IoGetTopLevelIrp() == IrpContext
->Irp
)
266 SetFlag(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
);
268 /* Initialize work item. */
269 ExInitializeWorkItem(&IrpContext
->WorkQueueItem
,
272 ExQueueWorkItem(&IrpContext
->WorkQueueItem
,
278 FatDecodeFileObject(IN PFILE_OBJECT FileObject
,
283 TYPE_OF_OPEN TypeOfOpen
= UnopenedFileObject
;
284 PVOID FsContext
= FileObject
->FsContext
;
285 PVOID FsContext2
= FileObject
->FsContext2
;
287 /* If FsContext is NULL, then everything is NULL */
297 /* CCB is always stored in FsContext2 */
300 /* Switch according to the NodeType */
301 switch (FatNodeType(FsContext
))
308 TypeOfOpen
= ( *Ccb
== NULL
? VirtualVolumeFile
: UserVolumeOpen
);
312 /* Root or normal directory*/
313 case FAT_NTC_ROOT_DCB
:
315 *FcbOrDcb
= FsContext
;
316 *Vcb
= (*FcbOrDcb
)->Vcb
;
318 TypeOfOpen
= (*Ccb
== NULL
? DirectoryFile
: UserDirectoryOpen
);
320 DPRINT1("Referencing a directory: %Z\n", &(*FcbOrDcb
)->FullFileName
);
325 *FcbOrDcb
= FsContext
;
326 *Vcb
= (*FcbOrDcb
)->Vcb
;
328 TypeOfOpen
= (*Ccb
== NULL
? EaFile
: UserFileOpen
);
330 DPRINT1("Referencing a file: %Z\n", &(*FcbOrDcb
)->FullFileName
);
335 DPRINT1("Unknown node type %x\n", FatNodeType(FsContext
));
344 FatSetFileObject(PFILE_OBJECT FileObject
,
345 TYPE_OF_OPEN TypeOfOpen
,
351 /* Check Fcb's type */
352 if (FatNodeType(Fcb
) == FAT_NTC_VCB
)
354 FileObject
->Vpb
= ((PVCB
)Fcb
)->Vpb
;
358 FileObject
->Vpb
= ((PFCB
)Fcb
)->Vcb
->Vpb
;
365 FileObject
->FsContext
= Fcb
;
366 FileObject
->FsContext2
= Ccb
;
373 FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext
,
376 /* Acquire VCB's resource if possible */
377 if (ExAcquireResourceExclusiveLite(&Vcb
->Resource
,
378 BooleanFlagOn(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
)))
390 FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext
,
393 /* Release VCB's resource */
394 ExReleaseResourceLite(&Vcb
->Resource
);
399 FatMapUserBuffer(PIRP Irp
)
401 if (!Irp
->MdlAddress
)
402 return Irp
->UserBuffer
;
404 return MmGetSystemAddressForMdlSafe(Irp
->MdlAddress
, NormalPagePriority
);