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 /* Register and reference our filesystem */
112 IoRegisterFileSystem(DeviceObject
);
113 ObReferenceObject(DeviceObject
);
114 return STATUS_SUCCESS
;
119 FatBuildIrpContext(PIRP Irp
,
122 PIO_STACK_LOCATION IrpSp
;
123 PFAT_IRP_CONTEXT IrpContext
;
124 PVOLUME_DEVICE_OBJECT VolumeObject
;
126 /* Get current IRP stack location */
127 IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
129 /* Allocate memory for the Irp context */
130 IrpContext
= ExAllocateFromNPagedLookasideList(&FatGlobalData
.IrpContextList
);
132 /* Zero init memory */
133 RtlZeroMemory(IrpContext
, sizeof(FAT_IRP_CONTEXT
));
135 /* Save IRP, MJ and MN */
136 IrpContext
->Irp
= Irp
;
137 IrpContext
->MajorFunction
= IrpSp
->MajorFunction
;
138 IrpContext
->MinorFunction
= IrpSp
->MinorFunction
;
140 /* Set DeviceObject */
141 if (IrpSp
->FileObject
)
143 IrpContext
->DeviceObject
= IrpSp
->FileObject
->DeviceObject
;
145 /* Save VCB pointer */
146 VolumeObject
= (PVOLUME_DEVICE_OBJECT
)IrpSp
->DeviceObject
;
147 IrpContext
->Vcb
= &VolumeObject
->Vcb
;
149 /* TODO: Handle write-through */
151 else if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
)
153 /* Handle FSCTRL case */
154 IrpContext
->DeviceObject
= IrpSp
->Parameters
.MountVolume
.Vpb
->RealDevice
;
158 if (CanWait
) IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
160 /* Return prepared context */
166 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext
)
170 /* Make sure it has no pinned stuff */
171 ASSERT(IrpContext
->PinCount
== 0);
173 /* If there is a FatIo context associated with it - free it */
174 if (IrpContext
->FatIoContext
)
176 if (!(IrpContext
->Flags
& IRPCONTEXT_STACK_IO_CONTEXT
))
178 /* If a zero mdl was allocated - free it */
179 if (IrpContext
->FatIoContext
->ZeroMdl
)
180 IoFreeMdl(IrpContext
->FatIoContext
->ZeroMdl
);
182 /* Free memory of FatIo context */
183 ExFreePool(IrpContext
->FatIoContext
);
188 ExFreeToNPagedLookasideList(&FatGlobalData
.IrpContextList
, IrpContext
);
193 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL
,
201 /* TODO: Unpin repinned BCBs */
202 //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
203 //FatUnpinRepinnedBcbs( IrpContext );
205 /* Destroy IRP context */
206 FatDestroyIrpContext(IrpContext
);
209 /* Complete the IRP */
212 /* Cleanup IoStatus.Information in case of error input operation */
213 if (NT_ERROR(Status
) && (Irp
->Flags
& IRP_INPUT_OPERATION
))
215 Irp
->IoStatus
.Information
= 0;
218 /* Save status and complete this IRP */
219 Irp
->IoStatus
.Status
= Status
;
220 IoCompleteRequest( Irp
, IO_DISK_INCREMENT
);
226 FatDequeueRequest(IN PVOID Context
)
228 PFAT_IRP_CONTEXT IrpContext
;
230 IrpContext
= (PFAT_IRP_CONTEXT
) Context
;
232 /* Enter critical region. */
233 FsRtlEnterFileSystem();
235 /* Handle top level IRP Correctly. */
236 if (!FlagOn(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
))
237 IoSetTopLevelIrp((PIRP
) FSRTL_FSP_TOP_LEVEL_IRP
);
239 /* Enable Synchronous IO. */
240 SetFlag(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
);
242 /* Invoke the handler routine. */
243 IrpContext
->QueuedOperationHandler(IrpContext
);
245 /* Restore top level IRP. */
246 IoSetTopLevelIrp(NULL
);
248 /* Leave critical region. */
249 FsRtlExitFileSystem();
254 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext
,
255 IN PFAT_OPERATION_HANDLER OperationHandler
)
257 /* Save the worker routine. */
258 IrpContext
->QueuedOperationHandler
= OperationHandler
;
260 /* Indicate if top level IRP was set. */
261 if (IoGetTopLevelIrp() == IrpContext
->Irp
)
262 SetFlag(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
);
264 /* Initialize work item. */
265 ExInitializeWorkItem(&IrpContext
->WorkQueueItem
,
268 ExQueueWorkItem(&IrpContext
->WorkQueueItem
,