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
->MajorFunction
= IrpSp
->MajorFunction
;
141 IrpContext
->MinorFunction
= IrpSp
->MinorFunction
;
143 /* Set DeviceObject */
144 if (IrpSp
->FileObject
)
146 IrpContext
->DeviceObject
= IrpSp
->FileObject
->DeviceObject
;
148 /* Save VCB pointer */
149 VolumeObject
= (PVOLUME_DEVICE_OBJECT
)IrpSp
->DeviceObject
;
150 IrpContext
->Vcb
= &VolumeObject
->Vcb
;
152 /* TODO: Handle write-through */
154 else if (IrpContext
->MajorFunction
== IRP_MJ_FILE_SYSTEM_CONTROL
)
156 /* Handle FSCTRL case */
157 IrpContext
->DeviceObject
= IrpSp
->Parameters
.MountVolume
.Vpb
->RealDevice
;
161 if (CanWait
) IrpContext
->Flags
|= IRPCONTEXT_CANWAIT
;
163 /* Return prepared context */
169 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext
)
173 /* Make sure it has no pinned stuff */
174 ASSERT(IrpContext
->PinCount
== 0);
176 /* If there is a FatIo context associated with it - free it */
177 if (IrpContext
->FatIoContext
)
179 if (!(IrpContext
->Flags
& IRPCONTEXT_STACK_IO_CONTEXT
))
181 /* If a zero mdl was allocated - free it */
182 if (IrpContext
->FatIoContext
->ZeroMdl
)
183 IoFreeMdl(IrpContext
->FatIoContext
->ZeroMdl
);
185 /* Free memory of FatIo context */
186 ExFreePool(IrpContext
->FatIoContext
);
191 ExFreeToNPagedLookasideList(&FatGlobalData
.IrpContextList
, IrpContext
);
196 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL
,
204 /* TODO: Unpin repinned BCBs */
205 //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
206 //FatUnpinRepinnedBcbs( IrpContext );
208 /* Destroy IRP context */
209 FatDestroyIrpContext(IrpContext
);
212 /* Complete the IRP */
215 /* Cleanup IoStatus.Information in case of error input operation */
216 if (NT_ERROR(Status
) && (Irp
->Flags
& IRP_INPUT_OPERATION
))
218 Irp
->IoStatus
.Information
= 0;
221 /* Save status and complete this IRP */
222 Irp
->IoStatus
.Status
= Status
;
223 IoCompleteRequest( Irp
, IO_DISK_INCREMENT
);
229 FatDequeueRequest(IN PVOID Context
)
231 PFAT_IRP_CONTEXT IrpContext
;
233 IrpContext
= (PFAT_IRP_CONTEXT
) Context
;
235 /* Enter critical region. */
236 FsRtlEnterFileSystem();
238 /* Handle top level IRP Correctly. */
239 if (!FlagOn(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
))
240 IoSetTopLevelIrp((PIRP
) FSRTL_FSP_TOP_LEVEL_IRP
);
242 /* Enable Synchronous IO. */
243 SetFlag(IrpContext
->Flags
, IRPCONTEXT_CANWAIT
);
245 /* Invoke the handler routine. */
246 IrpContext
->QueuedOperationHandler(IrpContext
);
248 /* Restore top level IRP. */
249 IoSetTopLevelIrp(NULL
);
251 /* Leave critical region. */
252 FsRtlExitFileSystem();
257 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext
,
258 IN PFAT_OPERATION_HANDLER OperationHandler
)
260 /* Save the worker routine. */
261 IrpContext
->QueuedOperationHandler
= OperationHandler
;
263 /* Indicate if top level IRP was set. */
264 if (IoGetTopLevelIrp() == IrpContext
->Irp
)
265 SetFlag(IrpContext
->Flags
, IRPCONTEXT_TOPLEVEL
);
267 /* Initialize work item. */
268 ExInitializeWorkItem(&IrpContext
->WorkQueueItem
,
271 ExQueueWorkItem(&IrpContext
->WorkQueueItem
,