ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fastfat.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS FAT file system driver
00003  * LICENSE:         GNU GPLv3 as published by the Free Software Foundation
00004  * FILE:            drivers/filesystems/fastfat/fastfat.c
00005  * PURPOSE:         Initialization routines
00006  * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #define NDEBUG
00012 #include "fastfat.h"
00013 
00014 /* GLOBALS ******************************************************************/
00015 
00016 FAT_GLOBAL_DATA FatGlobalData;
00017 FAST_MUTEX FatCloseQueueMutex;
00018 
00019 /* FUNCTIONS ****************************************************************/
00020 
00021 
00022 NTSTATUS
00023 NTAPI
00024 DriverEntry(PDRIVER_OBJECT DriverObject,
00025             PUNICODE_STRING RegistryPath)
00026 {
00027     PDEVICE_OBJECT DeviceObject;
00028     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Fat");
00029     NTSTATUS Status;
00030 
00031     /* Create a device object */
00032     Status = IoCreateDevice(DriverObject,
00033                             0,
00034                             &DeviceName,
00035                             FILE_DEVICE_DISK_FILE_SYSTEM,
00036                             0,
00037                             FALSE,
00038                             &DeviceObject);
00039 
00040     if (!NT_SUCCESS(Status)) return Status;
00041 
00042     /* Zero global storage */
00043     RtlZeroMemory(&FatGlobalData, sizeof(FAT_GLOBAL_DATA));
00044     FatGlobalData.DriverObject = DriverObject;
00045     FatGlobalData.DiskDeviceObject = DeviceObject;
00046     FatGlobalData.SystemProcess = PsGetCurrentProcess();
00047 
00048     /* Fill major function handlers */
00049     DriverObject->MajorFunction[IRP_MJ_CLOSE] = FatClose;
00050     DriverObject->MajorFunction[IRP_MJ_CREATE] = FatCreate;
00051     DriverObject->MajorFunction[IRP_MJ_READ] = FatRead;
00052     DriverObject->MajorFunction[IRP_MJ_WRITE] = FatWrite;
00053     DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FatFileSystemControl;
00054     DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = FatQueryInformation;
00055     DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = FatSetInformation;
00056     DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = FatDirectoryControl;
00057     DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = FatQueryVolumeInfo;
00058     DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = FatSetVolumeInfo;
00059     DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = FatShutdown;
00060     DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = FatLockControl;
00061     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = FatDeviceControl;
00062     DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FatCleanup;
00063     DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = FatFlushBuffers;
00064     //DriverObject->MajorFunction[IRP_MJ_QUERY_EA]
00065     //DriverObject->MajorFunction[IRP_MJ_SET_EA]
00066     //DriverObject->MajorFunction[IRP_MJ_PNP]
00067 
00068     DriverObject->DriverUnload = NULL;
00069 
00070     /* Initialize cache manager callbacks */
00071     FatGlobalData.CacheMgrCallbacks.AcquireForLazyWrite = FatAcquireForLazyWrite;
00072     FatGlobalData.CacheMgrCallbacks.ReleaseFromLazyWrite = FatReleaseFromLazyWrite;
00073     FatGlobalData.CacheMgrCallbacks.AcquireForReadAhead = FatAcquireForReadAhead;
00074     FatGlobalData.CacheMgrCallbacks.ReleaseFromReadAhead = FatReleaseFromReadAhead;
00075 
00076     FatGlobalData.CacheMgrNoopCallbacks.AcquireForLazyWrite = FatNoopAcquire;
00077     FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromLazyWrite = FatNoopRelease;
00078     FatGlobalData.CacheMgrNoopCallbacks.AcquireForReadAhead = FatNoopAcquire;
00079     FatGlobalData.CacheMgrNoopCallbacks.ReleaseFromReadAhead = FatNoopRelease;
00080 
00081     /* Initialize Fast I/O dispatchers */
00082     FatInitFastIoRoutines(&FatGlobalData.FastIoDispatch);
00083     DriverObject->FastIoDispatch = &FatGlobalData.FastIoDispatch;
00084 
00085     /* Initialize lookaside lists */
00086     ExInitializeNPagedLookasideList(&FatGlobalData.NonPagedFcbList,
00087                                     NULL,
00088                                     NULL,
00089                                     0,
00090                                     sizeof(FCB),
00091                                     TAG_FCB,
00092                                     0);
00093 
00094     ExInitializeNPagedLookasideList(&FatGlobalData.ResourceList,
00095                                     NULL,
00096                                     NULL,
00097                                     0,
00098                                     sizeof(ERESOURCE),
00099                                     TAG_CCB,
00100                                     0);
00101 
00102     ExInitializeNPagedLookasideList(&FatGlobalData.IrpContextList,
00103                                     NULL,
00104                                     NULL,
00105                                     0,
00106                                     sizeof(FAT_IRP_CONTEXT),
00107                                     TAG_IRP,
00108                                     0);
00109 
00110     /* Initialize synchronization resource for the global data */
00111     ExInitializeResourceLite(&FatGlobalData.Resource);
00112 
00113     /* Initialize queued close stuff */
00114     InitializeListHead(&FatGlobalData.AsyncCloseList);
00115     InitializeListHead(&FatGlobalData.DelayedCloseList);
00116     FatGlobalData.FatCloseItem = IoAllocateWorkItem(DeviceObject);
00117     ExInitializeFastMutex(&FatCloseQueueMutex);
00118 
00119     /* Initialize global VCB list */
00120     InitializeListHead(&FatGlobalData.VcbListHead);
00121 
00122     /* Register and reference our filesystem */
00123     IoRegisterFileSystem(DeviceObject);
00124     ObReferenceObject(DeviceObject);
00125     return STATUS_SUCCESS;
00126 }
00127 
00128 PFAT_IRP_CONTEXT
00129 NTAPI
00130 FatBuildIrpContext(PIRP Irp,
00131                    BOOLEAN CanWait)
00132 {
00133     PIO_STACK_LOCATION IrpSp;
00134     PFAT_IRP_CONTEXT IrpContext;
00135     PVOLUME_DEVICE_OBJECT VolumeObject;
00136 
00137     /* Get current IRP stack location */
00138     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00139 
00140     /* Allocate memory for the Irp context */
00141     IrpContext = ExAllocateFromNPagedLookasideList(&FatGlobalData.IrpContextList);
00142 
00143     /* Zero init memory */
00144     RtlZeroMemory(IrpContext, sizeof(FAT_IRP_CONTEXT));
00145 
00146     /* Save IRP, MJ and MN */
00147     IrpContext->Irp = Irp;
00148     IrpContext->Stack = IrpSp;
00149     IrpContext->MajorFunction = IrpSp->MajorFunction;
00150     IrpContext->MinorFunction = IrpSp->MinorFunction;
00151 
00152     /* Set DeviceObject */
00153     if (IrpSp->FileObject)
00154     {
00155         IrpContext->DeviceObject = IrpSp->FileObject->DeviceObject;
00156 
00157         /* Save VCB pointer */
00158         VolumeObject = (PVOLUME_DEVICE_OBJECT)IrpSp->DeviceObject;
00159         IrpContext->Vcb = &VolumeObject->Vcb;
00160 
00161         /* TODO: Handle write-through */
00162     }
00163     else if (IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL)
00164     {
00165         /* Handle FSCTRL case */
00166         IrpContext->DeviceObject = IrpSp->Parameters.MountVolume.Vpb->RealDevice;
00167     }
00168 
00169     /* Set Wait flag */
00170     if (CanWait) IrpContext->Flags |= IRPCONTEXT_CANWAIT;
00171 
00172     /* Return prepared context */
00173     return IrpContext;
00174 }
00175 
00176 VOID
00177 NTAPI
00178 FatDestroyIrpContext(PFAT_IRP_CONTEXT IrpContext)
00179 {
00180     PAGED_CODE();
00181 
00182     /* Make sure it has no pinned stuff */
00183     ASSERT(IrpContext->PinCount == 0);
00184 
00185     /* If there is a FatIo context associated with it - free it */
00186     if (IrpContext->FatIoContext)
00187     {
00188         if (!(IrpContext->Flags & IRPCONTEXT_STACK_IO_CONTEXT))
00189         {
00190             /* If a zero mdl was allocated - free it */
00191             if (IrpContext->FatIoContext->ZeroMdl)
00192                 IoFreeMdl(IrpContext->FatIoContext->ZeroMdl);
00193 
00194             /* Free memory of FatIo context */
00195             ExFreePool(IrpContext->FatIoContext);
00196         }
00197     }
00198 
00199     /* Free memory */
00200     ExFreeToNPagedLookasideList(&FatGlobalData.IrpContextList, IrpContext);
00201 }
00202 
00203 VOID
00204 NTAPI
00205 FatCompleteRequest(PFAT_IRP_CONTEXT IrpContext OPTIONAL,
00206                    PIRP Irp OPTIONAL,
00207                    NTSTATUS Status)
00208 {
00209     PAGED_CODE();
00210 
00211     if (IrpContext)
00212     {
00213         /* TODO: Unpin repinned BCBs */
00214         //ASSERT(IrpContext->Repinned.Bcb[0] == NULL);
00215         //FatUnpinRepinnedBcbs( IrpContext );
00216 
00217         /* Destroy IRP context */
00218         FatDestroyIrpContext(IrpContext);
00219     }
00220 
00221     /* Complete the IRP */
00222     if (Irp)
00223     {
00224         /* Cleanup IoStatus.Information in case of error input operation */
00225         if (NT_ERROR(Status) && (Irp->Flags & IRP_INPUT_OPERATION))
00226         {
00227             Irp->IoStatus.Information = 0;
00228         }
00229 
00230         /* Save status and complete this IRP */
00231         Irp->IoStatus.Status = Status;
00232         IoCompleteRequest( Irp, IO_DISK_INCREMENT );
00233     }
00234 }
00235 
00236 VOID
00237 NTAPI
00238 FatDequeueRequest(IN PVOID Context)
00239 {
00240     PFAT_IRP_CONTEXT IrpContext;
00241 
00242     IrpContext = (PFAT_IRP_CONTEXT) Context;
00243 
00244     /* Enter critical region. */
00245     FsRtlEnterFileSystem();
00246 
00247     /* Handle top level IRP Correctly. */
00248     if (!FlagOn(IrpContext->Flags, IRPCONTEXT_TOPLEVEL))
00249         IoSetTopLevelIrp((PIRP) FSRTL_FSP_TOP_LEVEL_IRP);
00250 
00251     /* Enable Synchronous IO. */
00252     SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
00253 
00254     /* Invoke the handler routine. */
00255     IrpContext->QueuedOperationHandler(IrpContext);
00256 
00257     /* Restore top level IRP. */
00258     IoSetTopLevelIrp(NULL);
00259 
00260     /* Leave critical region. */
00261     FsRtlExitFileSystem();
00262 }
00263 
00264 VOID
00265 NTAPI
00266 FatQueueRequest(IN PFAT_IRP_CONTEXT IrpContext,
00267                 IN PFAT_OPERATION_HANDLER OperationHandler)
00268 {
00269     /* Save the worker routine. */
00270     IrpContext->QueuedOperationHandler = OperationHandler;
00271 
00272     /* Indicate if top level IRP was set. */
00273     if (IoGetTopLevelIrp() == IrpContext->Irp)
00274         SetFlag(IrpContext->Flags, IRPCONTEXT_TOPLEVEL);
00275 
00276     /* Initialize work item. */
00277     ExInitializeWorkItem(&IrpContext->WorkQueueItem,
00278         FatDequeueRequest,
00279         IrpContext);
00280     ExQueueWorkItem(&IrpContext->WorkQueueItem,
00281         DelayedWorkQueue);
00282 }
00283 
00284 TYPE_OF_OPEN
00285 NTAPI
00286 FatDecodeFileObject(IN PFILE_OBJECT FileObject,
00287                     OUT PVCB *Vcb,
00288                     OUT PFCB *FcbOrDcb,
00289                     OUT PCCB *Ccb)
00290 {
00291     TYPE_OF_OPEN TypeOfOpen = UnopenedFileObject;
00292     PVOID FsContext = FileObject->FsContext;
00293     PVOID FsContext2 = FileObject->FsContext2;
00294 
00295     /* If FsContext is NULL, then everything is NULL */
00296     if (!FsContext)
00297     {
00298         *Ccb = NULL;
00299         *FcbOrDcb = NULL;
00300         *Vcb = NULL;
00301 
00302         return TypeOfOpen;
00303     }
00304 
00305     /* CCB is always stored in FsContext2 */
00306     *Ccb = FsContext2;
00307 
00308     /* Switch according to the NodeType */
00309     switch (FatNodeType(FsContext))
00310     {
00311         /* Volume */
00312         case FAT_NTC_VCB:
00313             *FcbOrDcb = NULL;
00314             *Vcb = FsContext;
00315 
00316             TypeOfOpen = ( *Ccb == NULL ? VirtualVolumeFile : UserVolumeOpen );
00317 
00318             break;
00319 
00320         /* Root or normal directory*/
00321         case FAT_NTC_ROOT_DCB:
00322         case FAT_NTC_DCB:
00323             *FcbOrDcb = FsContext;
00324             *Vcb = (*FcbOrDcb)->Vcb;
00325 
00326             TypeOfOpen = (*Ccb == NULL ? DirectoryFile : UserDirectoryOpen);
00327 
00328             DPRINT("Referencing a directory: %wZ\n", &(*FcbOrDcb)->FullFileName);
00329             break;
00330 
00331         /* File */
00332         case FAT_NTC_FCB:
00333             *FcbOrDcb = FsContext;
00334             *Vcb = (*FcbOrDcb)->Vcb;
00335 
00336             TypeOfOpen = (*Ccb == NULL ? EaFile : UserFileOpen);
00337 
00338             DPRINT("Referencing a file: %wZ\n", &(*FcbOrDcb)->FullFileName);
00339 
00340             break;
00341 
00342         default:
00343             DPRINT1("Unknown node type %x\n", FatNodeType(FsContext));
00344             ASSERT(FALSE);
00345     }
00346 
00347     return TypeOfOpen;
00348 }
00349 
00350 VOID
00351 NTAPI
00352 FatSetFileObject(PFILE_OBJECT FileObject,
00353                  TYPE_OF_OPEN TypeOfOpen,
00354                  PVOID Fcb,
00355                  PCCB Ccb)
00356 {
00357     if (Fcb)
00358     {
00359         /* Check Fcb's type  */
00360         if (FatNodeType(Fcb) == FAT_NTC_VCB)
00361         {
00362             FileObject->Vpb = ((PVCB)Fcb)->Vpb;
00363         }
00364         else
00365         {
00366             FileObject->Vpb = ((PFCB)Fcb)->Vcb->Vpb;
00367         }
00368     }
00369 
00370     /* Set FsContext */
00371     if (FileObject)
00372     {
00373         FileObject->FsContext  = Fcb;
00374         FileObject->FsContext2 = Ccb;
00375     }
00376 }
00377 
00378 
00379 BOOLEAN
00380 NTAPI
00381 FatAcquireExclusiveVcb(IN PFAT_IRP_CONTEXT IrpContext,
00382                        IN PVCB Vcb)
00383 {
00384     /* Acquire VCB's resource if possible */
00385     if (ExAcquireResourceExclusiveLite(&Vcb->Resource,
00386                                        BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
00387     {
00388         return TRUE;
00389     }
00390     else
00391     {
00392         return FALSE;
00393     }
00394 }
00395 
00396 BOOLEAN
00397 NTAPI
00398 FatAcquireSharedVcb(IN PFAT_IRP_CONTEXT IrpContext,
00399                     IN PVCB Vcb)
00400 {
00401     /* Acquire VCB's resource if possible */
00402     if (ExAcquireResourceSharedLite(&Vcb->Resource,
00403                                     BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
00404     {
00405         return TRUE;
00406     }
00407     else
00408     {
00409         return FALSE;
00410     }
00411 }
00412 
00413 VOID
00414 NTAPI
00415 FatReleaseVcb(IN PFAT_IRP_CONTEXT IrpContext,
00416               IN PVCB Vcb)
00417 {
00418     /* Release VCB's resource */
00419     ExReleaseResourceLite(&Vcb->Resource);
00420 }
00421 
00422 BOOLEAN
00423 NTAPI
00424 FatAcquireExclusiveFcb(IN PFAT_IRP_CONTEXT IrpContext,
00425                        IN PFCB Fcb)
00426 {
00427 RetryLockingE:
00428     /* Try to acquire the exclusive lock*/
00429     if (ExAcquireResourceExclusiveLite(Fcb->Header.Resource,
00430         BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
00431     {
00432         /* Wait same way MS's FASTFAT wait, i.e.
00433            checking that there are outstanding async writes,
00434            or someone is waiting on it*/
00435         if (Fcb->OutstandingAsyncWrites &&
00436             ((IrpContext->MajorFunction != IRP_MJ_WRITE) ||
00437              !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) ||
00438              ExGetSharedWaiterCount(Fcb->Header.Resource) ||
00439              ExGetExclusiveWaiterCount(Fcb->Header.Resource)))
00440         {
00441             KeWaitForSingleObject(Fcb->OutstandingAsyncEvent,
00442                                   Executive,
00443                                   KernelMode,
00444                                   FALSE,
00445                                   NULL);
00446 
00447             /* Release the lock */
00448             FatReleaseFcb(IrpContext, Fcb);
00449 
00450             /* Retry */
00451             goto RetryLockingE;
00452         }
00453 
00454         /* Return success */
00455         return TRUE;
00456     }
00457 
00458     /* Return failure */
00459     return FALSE;
00460 }
00461 
00462 BOOLEAN
00463 NTAPI
00464 FatAcquireSharedFcb(IN PFAT_IRP_CONTEXT IrpContext,
00465                     IN PFCB Fcb)
00466 {
00467 RetryLockingS:
00468     /* Try to acquire the shared lock*/
00469     if (ExAcquireResourceSharedLite(Fcb->Header.Resource,
00470         BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
00471     {
00472         /* Wait same way MS's FASTFAT wait, i.e.
00473            checking that there are outstanding async writes,
00474            or someone is waiting on it*/
00475         if (Fcb->OutstandingAsyncWrites &&
00476             ((IrpContext->MajorFunction != IRP_MJ_WRITE) ||
00477              !FlagOn(IrpContext->Irp->Flags, IRP_NOCACHE) ||
00478              ExGetSharedWaiterCount(Fcb->Header.Resource) ||
00479              ExGetExclusiveWaiterCount(Fcb->Header.Resource)))
00480         {
00481             KeWaitForSingleObject(Fcb->OutstandingAsyncEvent,
00482                                   Executive,
00483                                   KernelMode,
00484                                   FALSE,
00485                                   NULL);
00486 
00487             /* Release the lock */
00488             FatReleaseFcb(IrpContext, Fcb);
00489 
00490             /* Retry */
00491             goto RetryLockingS;
00492         }
00493 
00494         /* Return success */
00495         return TRUE;
00496     }
00497 
00498     /* Return failure */
00499     return FALSE;
00500 }
00501 
00502 VOID
00503 NTAPI
00504 FatReleaseFcb(IN PFAT_IRP_CONTEXT IrpContext,
00505               IN PFCB Fcb)
00506 {
00507     /* Release FCB's resource */
00508     ExReleaseResourceLite(Fcb->Header.Resource);
00509 }
00510 
00511 PVOID
00512 FASTCALL
00513 FatMapUserBuffer(PIRP Irp)
00514 {
00515     if (!Irp->MdlAddress)
00516         return Irp->UserBuffer;
00517     else
00518         return MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
00519 }
00520 
00521 BOOLEAN
00522 NTAPI
00523 FatIsTopLevelIrp(IN PIRP Irp)
00524 {
00525     if (!IoGetTopLevelIrp())
00526     {
00527         IoSetTopLevelIrp(Irp);
00528         return TRUE;
00529     }
00530 
00531     return FALSE;
00532 }
00533 
00534 VOID
00535 NTAPI
00536 FatNotifyReportChange(IN PFAT_IRP_CONTEXT IrpContext,
00537                       IN PVCB Vcb,
00538                       IN PFCB Fcb,
00539                       IN ULONG Filter,
00540                       IN ULONG Action)
00541 {
00542     if (Fcb->FullFileName.Buffer == NULL)
00543         FatSetFullFileNameInFcb(IrpContext, Fcb);
00544 
00545     ASSERT(Fcb->FullFileName.Length != 0 );
00546     ASSERT(Fcb->FileNameLength != 0 );
00547     ASSERT(Fcb->FullFileName.Length > Fcb->FileNameLength );
00548     ASSERT(Fcb->FullFileName.Buffer[(Fcb->FullFileName.Length - Fcb->FileNameLength)/sizeof(WCHAR) - 1] == L'\\' );
00549 
00550     FsRtlNotifyFullReportChange(Vcb->NotifySync,
00551                                 &Vcb->NotifyList,
00552                                 (PSTRING)&Fcb->FullFileName,
00553                                 (USHORT)(Fcb->FullFileName.Length -
00554                                          Fcb->FileNameLength),
00555                                 NULL,
00556                                 NULL,
00557                                 Filter,
00558                                 Action,
00559                                 NULL);
00560 }
00561 
00562 /* EOF */

Generated on Sun May 27 2012 04:27:46 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.