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

finfo.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/finfo.c
00005  * PURPOSE:         File Information support routines
00006  * PROGRAMMERS:     Aleksey Bragin (aleksey@reactos.org)
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #define NDEBUG
00012 #include "fastfat.h"
00013 
00014 /* FUNCTIONS ****************************************************************/
00015 
00016 VOID
00017 NTAPI
00018 FatiQueryBasicInformation(IN PFAT_IRP_CONTEXT IrpContext,
00019                           IN PFCB Fcb,
00020                           IN PFILE_OBJECT FileObject,
00021                           IN OUT PFILE_BASIC_INFORMATION Buffer,
00022                           IN OUT PLONG Length)
00023 {
00024     /* Zero the buffer */
00025     RtlZeroMemory(Buffer, sizeof(FILE_BASIC_INFORMATION));
00026 
00027     /* Deduct the written length */
00028     *Length -= sizeof(FILE_BASIC_INFORMATION);
00029 
00030     /* Check if it's a dir or a file */
00031     if (FatNodeType(Fcb) == FAT_NTC_FCB)
00032     {
00033         // FIXME: Read dirent and get times from there
00034         Buffer->LastAccessTime.QuadPart = 0;
00035         Buffer->CreationTime.QuadPart = 0;
00036         Buffer->LastWriteTime.QuadPart = 0;
00037     }
00038     else
00039     {
00040         // FIXME: May not be really correct
00041         Buffer->FileAttributes = 0;
00042         DPRINT1("Basic info of a directory '%wZ' is requested!\n", &Fcb->FullFileName);
00043     }
00044 
00045 
00046     /* If attribute is 0, set normal */
00047     if (Buffer->FileAttributes == 0)
00048         Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
00049 }
00050 
00051 VOID
00052 NTAPI
00053 FatiQueryStandardInformation(IN PFAT_IRP_CONTEXT IrpContext,
00054                              IN PFCB Fcb,
00055                              IN PFILE_OBJECT FileObject,
00056                              IN OUT PFILE_STANDARD_INFORMATION Buffer,
00057                              IN OUT PLONG Length)
00058 {
00059     /* Zero the buffer */
00060     RtlZeroMemory(Buffer, sizeof(FILE_STANDARD_INFORMATION));
00061 
00062     /* Deduct the written length */
00063     *Length -= sizeof(FILE_STANDARD_INFORMATION);
00064 
00065     Buffer->NumberOfLinks = 1;
00066     Buffer->DeletePending = FALSE; // FIXME
00067 
00068     /* Check if it's a dir or a file */
00069     if (FatNodeType(Fcb) == FAT_NTC_FCB)
00070     {
00071         Buffer->Directory = FALSE;
00072 
00073         Buffer->EndOfFile.LowPart = Fcb->FatHandle->Filesize;
00074         Buffer->AllocationSize = Buffer->EndOfFile;
00075         DPRINT("Filesize %d, chain length %d\n", Fcb->FatHandle->Filesize, Fcb->FatHandle->iChainLength);
00076     }
00077     else
00078     {
00079         Buffer->Directory = TRUE;
00080     }
00081 }
00082 
00083 VOID
00084 NTAPI
00085 FatiQueryInternalInformation(IN PFAT_IRP_CONTEXT IrpContext,
00086                              IN PFCB Fcb,
00087                              IN PFILE_OBJECT FileObject,
00088                              IN OUT PFILE_INTERNAL_INFORMATION Buffer,
00089                              IN OUT PLONG Length)
00090 {
00091     UNIMPLEMENTED;
00092 }
00093 
00094 VOID
00095 NTAPI
00096 FatiQueryNameInformation(IN PFAT_IRP_CONTEXT IrpContext,
00097                          IN PFCB Fcb,
00098                          IN PFILE_OBJECT FileObject,
00099                          IN OUT PFILE_NAME_INFORMATION Buffer,
00100                          IN OUT PLONG Length)
00101 {
00102     ULONG ByteSize;
00103     ULONG Trim = 0;
00104     BOOLEAN Overflow = FALSE;
00105 
00106     /* Deduct the minimum written length */
00107     *Length -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]);
00108 
00109     /* Build full name if needed */
00110     if (!Fcb->FullFileName.Buffer)
00111     {
00112         FatSetFullFileNameInFcb(IrpContext, Fcb);
00113     }
00114 
00115     DPRINT("FullFileName %wZ\n", &Fcb->FullFileName);
00116 
00117     if (*Length < Fcb->FullFileName.Length - Trim)
00118     {
00119         /* Buffer can't fit all data */
00120         ByteSize = *Length;
00121         Overflow = TRUE;
00122     }
00123     else
00124     {
00125         /* Deduct the amount of bytes we are going to write */
00126         ByteSize = Fcb->FullFileName.Length - Trim;
00127         *Length -= ByteSize;
00128     }
00129 
00130     /* Copy the name */
00131     RtlCopyMemory(Buffer->FileName,
00132                   Fcb->FullFileName.Buffer,
00133                   ByteSize);
00134 
00135     /* Set the length */
00136     Buffer->FileNameLength = Fcb->FullFileName.Length - Trim;
00137 
00138     /* Is this a shortname query? */
00139     if (Trim)
00140     {
00141         /* Yes, not supported atm */
00142         ASSERT(FALSE);
00143     }
00144 
00145     /* Indicate overflow by passing -1 as the length */
00146     if (Overflow) *Length = -1;
00147 }
00148 
00149 NTSTATUS
00150 NTAPI
00151 FatiQueryInformation(IN PFAT_IRP_CONTEXT IrpContext,
00152                      IN PIRP Irp)
00153 {
00154     PFILE_OBJECT FileObject;
00155     PIO_STACK_LOCATION IrpSp;
00156     FILE_INFORMATION_CLASS InfoClass;
00157     TYPE_OF_OPEN FileType;
00158     PVCB Vcb;
00159     PFCB Fcb;
00160     PCCB Ccb;
00161     LONG Length;
00162     PVOID Buffer;
00163     BOOLEAN VcbLocked = FALSE, FcbLocked = FALSE;
00164     NTSTATUS Status = STATUS_SUCCESS;
00165 
00166     /* Get IRP stack location */
00167     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00168 
00169     /* Get the file object */
00170     FileObject = IrpSp->FileObject;
00171 
00172     /* Copy variables to something with shorter names */
00173     InfoClass = IrpSp->Parameters.QueryFile.FileInformationClass;
00174     Length = IrpSp->Parameters.QueryFile.Length;
00175     Buffer = Irp->AssociatedIrp.SystemBuffer;
00176 
00177     DPRINT("FatiQueryInformation\n", 0);
00178     DPRINT("\tIrp                  = %08lx\n", Irp);
00179     DPRINT("\tLength               = %08lx\n", Length);
00180     DPRINT("\tFileInformationClass = %08lx\n", InfoClass);
00181     DPRINT("\tBuffer               = %08lx\n", Buffer);
00182 
00183     FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
00184 
00185     DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
00186 
00187     /* Acquire VCB lock */
00188     if (InfoClass == FileNameInformation ||
00189         InfoClass == FileAllInformation)
00190     {
00191         if (!FatAcquireExclusiveVcb(IrpContext, Vcb))
00192         {
00193             ASSERT(FALSE);
00194         }
00195 
00196         /* Remember we locked the VCB */
00197         VcbLocked = TRUE;
00198     }
00199 
00200     /* Acquire FCB lock */
00201     // FIXME: If not paging file
00202     if (!FatAcquireSharedFcb(IrpContext, Fcb))
00203     {
00204         ASSERT(FALSE);
00205     }
00206     FcbLocked = TRUE;
00207 
00208     switch (InfoClass)
00209     {
00210     case FileBasicInformation:
00211         FatiQueryBasicInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
00212         break;
00213     case FileStandardInformation:
00214         FatiQueryStandardInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
00215         break;
00216     case FileInternalInformation:
00217         FatiQueryInternalInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
00218         break;
00219     case FileNameInformation:
00220         FatiQueryNameInformation(IrpContext, Fcb, FileObject, Buffer, &Length);
00221         break;
00222     default:
00223         DPRINT1("Unimplemented information class %d requested\n", InfoClass);
00224         Status = STATUS_INVALID_PARAMETER;
00225     }
00226 
00227     /* Check for buffer overflow */
00228     if (Length < 0)
00229     {
00230         Status = STATUS_BUFFER_OVERFLOW;
00231         Length = 0;
00232     }
00233 
00234     /* Set IoStatus.Information to amount of filled bytes */
00235     Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;
00236 
00237     /* Release FCB locks */
00238     if (FcbLocked) FatReleaseFcb(IrpContext, Fcb);
00239     if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
00240 
00241     /* Complete request and return status */
00242     FatCompleteRequest(IrpContext, Irp, Status);
00243     return Status;
00244 }
00245 
00246 NTSTATUS
00247 NTAPI
00248 FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
00249 {
00250     NTSTATUS Status;
00251     BOOLEAN TopLevel, CanWait;
00252     PFAT_IRP_CONTEXT IrpContext;
00253 
00254     CanWait = TRUE;
00255     TopLevel = FALSE;
00256     Status = STATUS_INVALID_DEVICE_REQUEST;
00257 
00258     /* Get CanWait flag */
00259     if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
00260         CanWait = IoIsOperationSynchronous(Irp);
00261 
00262     /* Enter FsRtl critical region */
00263     FsRtlEnterFileSystem();
00264 
00265     /* Set Top Level IRP if not set */
00266     TopLevel = FatIsTopLevelIrp(Irp);
00267 
00268     /* Build an irp context */
00269     IrpContext = FatBuildIrpContext(Irp, CanWait);
00270 
00271     /* Perform the actual read */
00272     Status = FatiQueryInformation(IrpContext, Irp);
00273 
00274     /* Restore top level Irp */
00275     if (TopLevel) IoSetTopLevelIrp(NULL);
00276 
00277     /* Leave FsRtl critical region */
00278     FsRtlExitFileSystem();
00279 
00280     return Status;
00281 }
00282 
00283 NTSTATUS
00284 NTAPI
00285 FatSetEndOfFileInfo(IN PFAT_IRP_CONTEXT IrpContext,
00286                     IN PIRP Irp,
00287                     IN PFILE_OBJECT FileObject,
00288                     IN PVCB Vcb,
00289                     IN PFCB Fcb)
00290 {
00291     PFILE_END_OF_FILE_INFORMATION Buffer;
00292     ULONG NewFileSize;
00293     ULONG InitialFileSize;
00294     ULONG InitialValidDataLength;
00295     //ULONG InitialValidDataToDisk;
00296     BOOLEAN CacheMapInitialized = FALSE;
00297     BOOLEAN ResourceAcquired = FALSE;
00298     NTSTATUS Status;
00299 
00300     Buffer = Irp->AssociatedIrp.SystemBuffer;
00301 
00302     if (FatNodeType(Fcb) != FAT_NTC_FCB)
00303     {
00304         /* Trying to change size of a dir */
00305         Status = STATUS_INVALID_DEVICE_REQUEST;
00306         return Status;
00307     }
00308 
00309     /* Validate new size */
00310     if (!FatIsIoRangeValid(Buffer->EndOfFile, 0))
00311     {
00312         Status = STATUS_DISK_FULL;
00313         return Status;
00314     }
00315 
00316     NewFileSize = Buffer->EndOfFile.LowPart;
00317 
00318     /* Lookup allocation size if needed */
00319     if (Fcb->Header.AllocationSize.QuadPart == (LONGLONG)-1)
00320         UNIMPLEMENTED;//FatLookupFileAllocationSize(IrpContext, Fcb);
00321 
00322     /* Cache the file if there is a data section */
00323     if (FileObject->SectionObjectPointer->DataSectionObject &&
00324         (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
00325         !FlagOn(Irp->Flags, IRP_PAGING_IO))
00326     {
00327         if (FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
00328         {
00329             /* This is a really weird condition */
00330             UNIMPLEMENTED;
00331             //Raise(STATUS_FILE_CLOSED);
00332         }
00333 
00334         /*  Initialize the cache map */
00335         CcInitializeCacheMap(FileObject,
00336                              (PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
00337                              FALSE,
00338                              &FatGlobalData.CacheMgrCallbacks,
00339                              Fcb);
00340 
00341         CacheMapInitialized = TRUE;
00342     }
00343 
00344     /* Lazy write case */
00345     if (IoGetCurrentIrpStackLocation(Irp)->Parameters.SetFile.AdvanceOnly)
00346     {
00347         if (!IsFileDeleted(Fcb) &&
00348             (Fcb->Condition == FcbGood))
00349         {
00350             /* Clamp the new file size */
00351             if (NewFileSize >= Fcb->Header.FileSize.LowPart)
00352                 NewFileSize = Fcb->Header.FileSize.LowPart;
00353 
00354             ASSERT(NewFileSize <= Fcb->Header.AllocationSize.LowPart);
00355 
00356             /* Never reduce the file size here! */
00357 
00358             // TODO: Actually change file size
00359             DPRINT1("Actually changing file size is missing\n");
00360 
00361             /* Notify about file size change */
00362             FatNotifyReportChange(IrpContext,
00363                                   Vcb,
00364                                   Fcb,
00365                                   FILE_NOTIFY_CHANGE_SIZE,
00366                                   FILE_ACTION_MODIFIED);
00367         }
00368         else
00369         {
00370             DPRINT1("Cannot set size on deleted file\n");
00371         }
00372 
00373         Status = STATUS_SUCCESS;
00374         return Status;
00375     }
00376 
00377     if ( NewFileSize > Fcb->Header.AllocationSize.LowPart )
00378     {
00379         // TODO: Increase file size
00380         DPRINT1("Actually changing file size is missing\n");
00381     }
00382 
00383     if (Fcb->Header.FileSize.LowPart != NewFileSize)
00384     {
00385         if (NewFileSize < Fcb->Header.FileSize.LowPart)
00386         {
00387             if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
00388                                       &Buffer->EndOfFile))
00389             {
00390                 Status = STATUS_USER_MAPPED_FILE;
00391 
00392                 /* Free up resources if necessary */
00393                 if (CacheMapInitialized)
00394                     CcUninitializeCacheMap(FileObject, NULL, NULL);
00395 
00396                 return Status;
00397             }
00398 
00399             ResourceAcquired = ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE);
00400         }
00401 
00402         /* Set new file sizes */
00403         InitialFileSize = Fcb->Header.FileSize.LowPart;
00404         InitialValidDataLength = Fcb->Header.ValidDataLength.LowPart;
00405         //InitialValidDataToDisk = Fcb->ValidDataToDisk;
00406 
00407         Fcb->Header.FileSize.LowPart = NewFileSize;
00408 
00409         /* Adjust valid data length if new size is less than that */
00410         if (Fcb->Header.ValidDataLength.LowPart > NewFileSize)
00411             Fcb->Header.ValidDataLength.LowPart = NewFileSize;
00412 
00413         //if (Fcb->ValidDataToDisk > NewFileSize)
00414         //    Fcb->ValidDataToDisk = NewFileSize;
00415 
00416         DPRINT1("New file size is 0x%08lx\n", NewFileSize);
00417 
00418         /* Update cache mapping */
00419         CcSetFileSizes(FileObject,
00420                        (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
00421 
00422         /* Notify about size change */
00423         FatNotifyReportChange(IrpContext,
00424                               Vcb,
00425                               Fcb,
00426                               FILE_NOTIFY_CHANGE_SIZE,
00427                               FILE_ACTION_MODIFIED);
00428 
00429         /* Set truncate on close flag */
00430         SetFlag(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE);
00431     }
00432 
00433     /* Set modified flag */
00434     FileObject->Flags |= FO_FILE_MODIFIED;
00435 
00436     /* Free up resources if necessary */
00437     if (CacheMapInitialized)
00438         CcUninitializeCacheMap(FileObject, NULL, NULL);
00439 
00440     if (ResourceAcquired)
00441         ExReleaseResourceLite(Fcb->Header.PagingIoResource);
00442 
00443     return STATUS_SUCCESS;
00444 }
00445 
00446 NTSTATUS
00447 NTAPI
00448 FatiSetInformation(IN PFAT_IRP_CONTEXT IrpContext,
00449                    IN PIRP Irp)
00450 {
00451     PFILE_OBJECT FileObject;
00452     PIO_STACK_LOCATION IrpSp;
00453     FILE_INFORMATION_CLASS InfoClass;
00454     TYPE_OF_OPEN TypeOfOpen;
00455     PVCB Vcb;
00456     PFCB Fcb;
00457     PCCB Ccb;
00458     LONG Length;
00459     PVOID Buffer;
00460     NTSTATUS Status = STATUS_SUCCESS;
00461     BOOLEAN VcbAcquired = FALSE, FcbAcquired = FALSE;
00462 
00463     /* Get IRP stack location */
00464     IrpSp = IoGetCurrentIrpStackLocation(Irp);
00465 
00466     /* Get the file object */
00467     FileObject = IrpSp->FileObject;
00468 
00469     /* Copy variables to something with shorter names */
00470     InfoClass = IrpSp->Parameters.SetFile.FileInformationClass;
00471     Length = IrpSp->Parameters.SetFile.Length;
00472     Buffer = Irp->AssociatedIrp.SystemBuffer;
00473 
00474     DPRINT("FatiSetInformation\n", 0);
00475     DPRINT("\tIrp                  = %08lx\n", Irp);
00476     DPRINT("\tLength               = %08lx\n", Length);
00477     DPRINT("\tFileInformationClass = %08lx\n", InfoClass);
00478     DPRINT("\tFileObject           = %08lx\n", IrpSp->Parameters.SetFile.FileObject);
00479     DPRINT("\tBuffer               = %08lx\n", Buffer);
00480 
00481     TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
00482 
00483     DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, TypeOfOpen);
00484 
00485     switch (TypeOfOpen)
00486     {
00487     case UserVolumeOpen:
00488         Status = STATUS_INVALID_PARAMETER;
00489         /* Complete request and return status */
00490         FatCompleteRequest(IrpContext, Irp, Status);
00491         return Status;
00492     case UserFileOpen:
00493         /* Check oplocks */
00494         if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) &&
00495             ((InfoClass == FileEndOfFileInformation) ||
00496             (InfoClass == FileAllocationInformation)))
00497         {
00498             Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock,
00499                                       Irp,
00500                                       IrpContext,
00501                                       NULL,
00502                                       NULL);
00503 
00504             if (Status != STATUS_SUCCESS)
00505             {
00506                 /* Complete request and return status */
00507                 FatCompleteRequest(IrpContext, Irp, Status);
00508                 return Status;
00509             }
00510 
00511             /* Update Fast IO flag */
00512             Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb);
00513         }
00514         break;
00515 
00516     case UserDirectoryOpen:
00517         break;
00518 
00519     default:
00520         Status = STATUS_INVALID_PARAMETER;
00521         /* Complete request and return status */
00522         FatCompleteRequest(IrpContext, Irp, Status);
00523         return Status;
00524     }
00525 
00526     /* If it's a root DCB - fail */
00527     if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB)
00528     {
00529         if (InfoClass == FileDispositionInformation)
00530             Status = STATUS_CANNOT_DELETE;
00531         else
00532             Status = STATUS_INVALID_PARAMETER;
00533 
00534         /* Complete request and return status */
00535         FatCompleteRequest(IrpContext, Irp, Status);
00536         return Status;
00537     }
00538 
00539     /* Acquire the volume lock if needed */
00540     if (InfoClass == FileDispositionInformation ||
00541         InfoClass == FileRenameInformation)
00542     {
00543         if (!FatAcquireExclusiveVcb(IrpContext, Vcb))
00544         {
00545             UNIMPLEMENTED;
00546         }
00547 
00548         VcbAcquired = TRUE;
00549     }
00550 
00551     /* Acquire FCB lock */
00552     if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE))
00553     {
00554         if (!FatAcquireExclusiveFcb(IrpContext, Fcb))
00555         {
00556             UNIMPLEMENTED;
00557         }
00558 
00559         FcbAcquired = TRUE;
00560     }
00561 
00562     // TODO: VerifyFcb
00563 
00564     switch (InfoClass)
00565     {
00566     case FileBasicInformation:
00567         //Status = FatSetBasicInfo(IrpContext, Irp, Fcb, Ccb);
00568         DPRINT1("FileBasicInformation\n");
00569         break;
00570 
00571     case FileDispositionInformation:
00572         if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
00573             !FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))
00574         {
00575             UNIMPLEMENTED;
00576         }
00577         else
00578         {
00579             //Status = FatSetDispositionInfo(IrpContext, Irp, FileObject, Fcb);
00580             DPRINT1("FileDispositionInformation\n");
00581         }
00582 
00583         break;
00584 
00585     case FileRenameInformation:
00586         if (!FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))
00587         {
00588             UNIMPLEMENTED;
00589         }
00590         else
00591         {
00592             //Status = FatSetRenameInfo(IrpContext, Irp, Vcb, Fcb, Ccb);
00593             DPRINT1("FileRenameInformation\n");
00594 
00595             /* NOTE: Request must not be completed here!
00596             That's why Irp/IrpContext are set to NULL */
00597             if (Status == STATUS_PENDING)
00598             {
00599                 Irp = NULL;
00600                 IrpContext = NULL;
00601             }
00602         }
00603         break;
00604 
00605     case FilePositionInformation:
00606         //Status = FatSetPositionInfo(IrpContext, Irp, FileObject);
00607         DPRINT1("FilePositionInformation\n");
00608         break;
00609 
00610     case FileLinkInformation:
00611         Status = STATUS_INVALID_DEVICE_REQUEST;
00612         break;
00613 
00614     case FileAllocationInformation:
00615         //Status = FatSetAllocationInfo(IrpContext, Irp, Fcb, FileObject);
00616         DPRINT1("FileAllocationInformation\n");
00617         break;
00618 
00619     case FileEndOfFileInformation:
00620         Status = FatSetEndOfFileInfo(IrpContext, Irp, FileObject, Vcb, Fcb);
00621         break;
00622 
00623     default:
00624         Status = STATUS_INVALID_PARAMETER;
00625     }
00626 
00627     /* Release locks */
00628     if (FcbAcquired) FatReleaseFcb(IrpContext, Fcb);
00629     if (VcbAcquired) FatReleaseVcb(IrpContext, Vcb);
00630 
00631     /* Complete request and return status */
00632     FatCompleteRequest(IrpContext, Irp, Status);
00633     return Status;
00634 }
00635 
00636 NTSTATUS
00637 NTAPI
00638 FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
00639 {
00640     NTSTATUS Status;
00641     BOOLEAN TopLevel, CanWait;
00642     PFAT_IRP_CONTEXT IrpContext;
00643 
00644     CanWait = TRUE;
00645     TopLevel = FALSE;
00646     Status = STATUS_INVALID_DEVICE_REQUEST;
00647 
00648     /* Get CanWait flag */
00649     if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
00650         CanWait = IoIsOperationSynchronous(Irp);
00651 
00652     /* Enter FsRtl critical region */
00653     FsRtlEnterFileSystem();
00654 
00655     /* Set Top Level IRP if not set */
00656     TopLevel = FatIsTopLevelIrp(Irp);
00657 
00658     /* Build an irp context */
00659     IrpContext = FatBuildIrpContext(Irp, CanWait);
00660 
00661     /* Perform the actual read */
00662     Status = FatiSetInformation(IrpContext, Irp);
00663 
00664     /* Restore top level Irp */
00665     if (TopLevel) IoSetTopLevelIrp(NULL);
00666 
00667     /* Leave FsRtl critical region */
00668     FsRtlExitFileSystem();
00669 
00670     return Status;
00671 }
00672 
00673 /* EOF */

Generated on Sun May 27 2012 04:27:36 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.