Author: dcote Date: Sat Jan 20 20:43:46 2007 New Revision: 25548
URL: http://svn.reactos.org/svn/reactos?rev=25548&view=rev Log: * Adding FsRtlCopyRead(), FsRtlCopyWrite() * Added #ifdef _NTIFS_INCLUDED_ typedef struct _SHARED_CACHE_MAP { definition to cctypes.h header file.
Modified: trunk/reactos/include/ndk/cctypes.h trunk/reactos/ntoskrnl/fsrtl/fastio.c
Modified: trunk/reactos/include/ndk/cctypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/cctypes.h?rev=2... ============================================================================== --- trunk/reactos/include/ndk/cctypes.h (original) +++ trunk/reactos/include/ndk/cctypes.h Sat Jan 20 20:43:46 2007 @@ -34,6 +34,56 @@ extern ULONG NTSYSAPI CcFastReadResourceMiss; extern ULONG NTSYSAPI CcFastReadNoWait;
-#endif -#endif // _CCTYPES_H
+#ifdef _NTIFS_INCLUDED_ + +typedef struct _SHARED_CACHE_MAP { + SHORT NodeTypeCode; + SHORT NodeByteSize; + ULONG OpenCount; + LARGE_INTEGER FileSize; + LIST_ENTRY BcbList; + LARGE_INTEGER SectionSize; + LARGE_INTEGER ValidDataLength; + LARGE_INTEGER ValidDataGoal; + PVACB InitialVacbs[4]; + PVACB Vacbs; + PFILE_OBJECT FileObject; + PVACB ActiveVacb; + PVOID NeedToZero; + ULONG ActivePage; + ULONG NeedToZeroPage; + ULONG ActiveVacbSpinLock; + ULONG VacbActiveCount; + ULONG DirtyPages; + LIST_ENTRY SharedCacheMapLinks; + ULONG Flags; + ULONG Status; + PMCB Mbcb; + PVOID Section; + PKEVENT CreateEvent; + PKEVENT WaitOnActiveCount; + ULONG PagesToWrite; + LONGLONG BeyondLastFlush; + PCACHE_MANAGER_CALLBACKS Callbacks; + PVOID LazyWriteContext; + PLIST_ENTRY PrivateList; + PVOID LogHandle; + PVOID FlushToLsnRoutine; + ULONG DirtyPageThreshold; + ULONG LazyWritePassCount; + PCACHE_UNINITIALIZE_EVENT UninitializeEvent; + PVACB NeedToZeroVacb; + ULONG BcbSpinLock; + PVOID Reserved; + KEVENT Event; + /* FIX ME: This should be PEX_PUSH_LOCK */ + PVOID VacbPushLock; + PPRIVATE_CACHE_MAP PrivateCacheMap; + } SHARED_CACHE_MAP; + + +#endif /* _NTIFS_INCLUDED_ */ +#endif /* NTOS_MODE_USER */ +#endif /* _CCTYPES_H */ +
Modified: trunk/reactos/ntoskrnl/fsrtl/fastio.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/fsrtl/fastio.c?rev... ============================================================================== --- trunk/reactos/ntoskrnl/fsrtl/fastio.c (original) +++ trunk/reactos/ntoskrnl/fsrtl/fastio.c Sat Jan 20 20:43:46 2007 @@ -11,6 +11,8 @@ #include <ntoskrnl.h> #define NDEBUG #include <debug.h> +#include <ntifs.h> +#include <cctypes.h>
/* PUBLIC FUNCTIONS **********************************************************/
@@ -27,11 +29,21 @@ /* * @implemented */ +VOID +NTAPI +FsRtlIncrementCcFastReadNotPossible(VOID) +{ + CcFastReadNotPossible++; +} + +/* + * @implemented + */ VOID NTAPI -FsRtlIncrementCcFastReadNotPossible(VOID) -{ - CcFastReadNotPossible++; +FsRtlIncrementCcFastReadWait(VOID) +{ + CcFastReadWait++; }
/* @@ -39,24 +51,25 @@ */ VOID NTAPI -FsRtlIncrementCcFastReadWait(VOID) -{ - CcFastReadWait++; -} - -/* - * @implemented - */ -VOID -NTAPI FsRtlIncrementCcFastReadNoWait(VOID) { CcFastReadNoWait++; }
-/* - * @unimplemented - */ +_SEH_FILTER(FsRtlCcCopyFilter) +{ + LONG ExceptionDisposition; + + /* Check if this was an expected exception */ + ExceptionDisposition = FsRtlIsNtstatusExpected(_SEH_GetExceptionCode() ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH); + + /* Continue execution if we expected it, otherwise fail the call */ + return ExceptionDisposition; +} + + BOOLEAN NTAPI FsRtlCopyRead(IN PFILE_OBJECT FileObject, @@ -68,13 +81,162 @@ OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) { - KEBUGCHECK(0); - return FALSE; -} - -/* - * @unimplemented - */ + + PFSRTL_COMMON_FCB_HEADER FcbHeader; + LARGE_INTEGER Offset; + PFAST_IO_DISPATCH FastIoDispatch; + PDEVICE_OBJECT Device; + BOOLEAN Result = TRUE; + ULONG PageCount = COMPUTE_PAGES_SPANNED(FileOffset,Length); + + PAGED_CODE(); + ASSERT(FileObject); + ASSERT(FileObject->FsContext); + + /* No actual read */ + if (!Length) + { + /* Return success */ + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = 0; + return TRUE; + } + + if (MAXLONGLONG < (LONGLONG) FileOffset->QuadPart + Length) { + IoStatus->Status = STATUS_INVALID_PARAMETER; + IoStatus->Information = 0; + return FALSE; + } + + /* Get the offset and FCB header */ + Offset.QuadPart = FileOffset->QuadPart + Length; + FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; + + + if (Wait) { + /* Use a Resource Acquire */ + FsRtlEnterFileSystem(); + CcFastReadWait++; + ExAcquireResourceSharedLite(FcbHeader->Resource, TRUE); + } else { + /* Acquire the resource without blocking */ + /* Return false and the I/O manager will retry using the standard IRP method. */ + /* Use a Resource Acquire */ + FsRtlEnterFileSystem(); + if (!ExAcquireResourceSharedLite(FcbHeader->Resource, FALSE)) { + FsRtlExitFileSystem(); + FsRtlIncrementCcFastReadResourceMiss(); + return FALSE; + } + } + + + /* Check if this is a fast I/O cached file */ + if (!(FileObject->PrivateCacheMap) || + (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) { + /* It's not, so fail */ + Result = FALSE; + goto Cleanup; + } + + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); + + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; + + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffset, + Length, + TRUE, + LockKey, + TRUE, + IoStatus, + Device)) + { + /* It's not, fail */ + Result = FALSE; + goto Cleanup; + } + } + + /* Check if we read too much */ + if (Offset.QuadPart > FcbHeader->FileSize.QuadPart){ + /* We did, check if the file offset is past the end */ + if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart){ + /* Set end of file */ + IoStatus->Status = STATUS_END_OF_FILE; + IoStatus->Information = 0; + goto Cleanup; + } + + /* Otherwise, just normalize the length */ + Length = (ULONG)(FcbHeader->FileSize.QuadPart - FileOffset->QuadPart); + } + + /* Set this as top-level IRP */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + + _SEH_TRY { + /* Make sure the IO and file size is below 4GB */ + if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart )) { + + /* Call the cache controller */ + CcFastCopyRead (FileObject,FileOffset->LowPart,Length,PageCount,Buffer,IoStatus); + /* File was accessed */ + FileObject->Flags |= FO_FILE_FAST_IO_READ; + if (IoStatus->Status != STATUS_END_OF_FILE) { + ASSERT(( FcbHeader->FileSize.QuadPart) >= (FileOffset->QuadPart + IoStatus->Information)); + } + + } else { + + /* Call the cache controller */ + Result = CcCopyRead(FileObject, FileOffset, Length, Wait,Buffer, IoStatus); + /* File was accessed */ + FileObject->Flags |= FO_FILE_FAST_IO_READ; + if (Result == TRUE) { + ASSERT( (IoStatus->Status == STATUS_END_OF_FILE) || + ((LONGLONG)(FileOffset->QuadPart + IoStatus->Information) <= FcbHeader->FileSize.QuadPart) + ); + } + } + + /* Update the current file offset */ + if (Result == TRUE) { + FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; + } + } + _SEH_EXCEPT(FsRtlCcCopyFilter) { + Result = FALSE; + } _SEH_END; + + PsGetCurrentThread()->TopLevelIrp = 0; + + /* Return to caller */ +Cleanup: + + ExReleaseResourceLite(FcbHeader->Resource); + FsRtlExitFileSystem(); + + if (Result == FALSE) { + CcFastReadNotPossible += 1; + } + + return Result; + +} + + BOOLEAN NTAPI FsRtlCopyWrite(IN PFILE_OBJECT FileObject, @@ -86,9 +248,437 @@ OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) { - KEBUGCHECK(0); - return FALSE; -} + + BOOLEAN Result = TRUE; + PFAST_IO_DISPATCH FastIoDispatch; + PDEVICE_OBJECT Device; + PFSRTL_COMMON_FCB_HEADER FcbHeader; + + /* WDK doc. Offset=0xffffffffffffffff indicates append to the end of file */ + BOOLEAN FileOffsetAppend = ((FileOffset->HighPart == 0xffffffff) && (FileOffset->LowPart == 0xffffffff)); + BOOLEAN ResourceAquiredShared = FALSE; + + BOOLEAN b_4GB = FALSE; + + BOOLEAN FileSizeModified = FALSE; + LARGE_INTEGER OldFileSize; + LARGE_INTEGER OldValidDataLength; + + LARGE_INTEGER NewSize; + LARGE_INTEGER Offset; + + PAGED_CODE(); + + ASSERT(FileObject); + ASSERT(FileObject->FsContext); + + /* Initialize some of the vars and pointers */ + NewSize.QuadPart = 0; + Offset.QuadPart = FileOffset->QuadPart + Length; + FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; + + /* Nagar p.544 -- Check with Cc if we can write and check if the IO > 64kB (WDK macro) */ + if ( (CcCanIWrite(FileObject, Length,Wait, FALSE) == FALSE) || + (CcCopyWriteWontFlush(FileObject,FileOffset,Length) == FALSE) || + ((FileObject->Flags & FO_WRITE_THROUGH )== TRUE) + ) + { + return FALSE; + } + + /* No actual read */ + if (!Length) + { + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = Length; + return TRUE; + } + + FsRtlEnterFileSystem(); + + /* Nagar p.544/545 -- The CcFastCopyWrite doesn't deal with filesize beyond 4GB*/ + if (Wait && (FcbHeader->AllocationSize.HighPart == 0)) + { + /* If the file offset is not past the file size, then we can acquire the lock shared */ + if ((FileOffsetAppend == FALSE) && (Offset.LowPart <= FcbHeader->ValidDataLength.LowPart)){ + ExAcquireResourceSharedLite(FcbHeader->Resource,TRUE); + ResourceAquiredShared = TRUE; + } else { + ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); + } + + /* Nagar p.544/545 -- If we append, use the file size as offset. Also, check that we aren't crossing the 4GB boundary */ + if ((FileOffsetAppend == TRUE)) { + Offset.LowPart = FcbHeader->FileSize.LowPart; + NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; + b_4GB = (NewSize.LowPart < FcbHeader->FileSize.LowPart); + + } else { + Offset.LowPart = FileOffset->LowPart; + NewSize.LowPart = FileOffset->LowPart + Length; + b_4GB = ((NewSize.LowPart < FileOffset->LowPart) || (FileOffset->HighPart != 0)); + } + + /* Nagar p.544/545 + Make sure that caching is initated. + That fast are allowed for this file stream. + That we are not extending past the allocated size + That we are not creating a hole bigger than 8k + That we are not crossing the 4GB boundary + */ + if ( (FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && + (Offset.LowPart < (FcbHeader->ValidDataLength.LowPart + 0x2000) ) && + !b_4GB + ) + { + /* If we are extending past the file size, we need to release the lock and acquire it + exclusively, because we are going to need to update the FcbHeader */ + if (ResourceAquiredShared && (NewSize.LowPart > (FcbHeader->ValidDataLength.LowPart + 0x2000))) { + /* Then we need to acquire the resource exclusive */ + ExReleaseResourceLite(FcbHeader->Resource); + ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); + if (FileOffsetAppend == TRUE) { + Offset.LowPart = FcbHeader->FileSize.LowPart; // ?? + NewSize.LowPart = FcbHeader->FileSize.LowPart + Length; + /* Make sure we don't cross the 4GB boundary */ + b_4GB = (NewSize.LowPart < Offset.LowPart); + } + + /* Recheck some of the conditions since we let the lock go */ + if ( (FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && + (FcbHeader->AllocationSize.HighPart == 0) && + !b_4GB + ) { + } else { + goto FailAndCleanup; + } + } + + }else { + goto FailAndCleanup; + } + + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; + + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); + + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; + + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffsetAppend? &FcbHeader->FileSize:FileOffset, + Length, + TRUE, + LockKey, + FALSE, + &FastIoCheckIfPossibleStatus, + Device)) + { + /* It's not, fail */ + goto FailAndCleanup; + } + } + + /* If we are going to extend the file then save the old file size + in case the operation fails + */ + if (NewSize.LowPart > FcbHeader->FileSize.LowPart) { + FileSizeModified = TRUE; + OldFileSize.LowPart = FcbHeader->FileSize.LowPart; + OldValidDataLength.LowPart = FcbHeader->ValidDataLength.LowPart; + FcbHeader->FileSize.LowPart = NewSize.LowPart; + } + + /* Set this as top-level IRP */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + + _SEH_TRY { + if (Offset.LowPart > FcbHeader->ValidDataLength.LowPart) { + LARGE_INTEGER OffsetVar; + OffsetVar.LowPart = Offset.LowPart; + OffsetVar.HighPart = 0; + CcZeroData(FileObject,&FcbHeader->ValidDataLength,&OffsetVar,TRUE); + } + + /* Call the cache manager */ + CcFastCopyWrite(FileObject,Offset.LowPart,Length,Buffer); + } + _SEH_EXCEPT(FsRtlCcCopyFilter) { + Result = FALSE; + } _SEH_END; + + /* Remove ourselves at the top level component after the IO is done */ + PsGetCurrentThread()->TopLevelIrp = 0; + + /* Did the operation succeed ? */ + if (Result == TRUE) { + /* Update the valid file size if necessary */ + if (NewSize.LowPart > FcbHeader->ValidDataLength.LowPart){ + FcbHeader->ValidDataLength.LowPart = NewSize.LowPart ; + } + + /* Flag the file as modified */ + FileObject->Flags |= FO_FILE_MODIFIED; + + /* Update the strucutres if the file size changed */ + if (FileSizeModified) { + ((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.LowPart = NewSize.LowPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } + + /* Update the file object current file offset */ + FileObject->CurrentByteOffset.QuadPart = NewSize.LowPart; + + } else { + + /* Result == FALSE if we get here. */ + if (FileSizeModified) { + /* If the file size was modified then restore the old file size */ + if(FcbHeader->PagingIoResource != NULL) { + // Nagar P.544 Restore the old file size if operation didn't succeed. + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource,TRUE); + FcbHeader->FileSize.LowPart = OldFileSize.LowPart; + FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } else { + /* If there is no lock and do it without */ + FcbHeader->FileSize.LowPart = OldFileSize.LowPart; + FcbHeader->ValidDataLength.LowPart = OldValidDataLength.LowPart; + } + } else { + } + } + + goto Cleanup; + + } else { + + LARGE_INTEGER OldFileSize; + + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); + + // Nagar P.544 + /* Check if we need to acquire the resource exclusive */ + if ( (FileOffsetAppend == FALSE) && + ( (FileOffset->QuadPart + Length) <= FcbHeader->ValidDataLength.QuadPart ) + ) + { + /* Acquire the resource shared */ + if (!ExAcquireResourceSharedLite(FcbHeader->Resource,Wait)) { + goto FailAndCleanup; + } + ResourceAquiredShared =TRUE; + } else { + /* Acquire the resource exclusive */ + if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) { + goto FailAndCleanup; + } + } + + /* Check if we are appending */ + if (FileOffsetAppend == TRUE) { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } else { + Offset.QuadPart = FileOffset->QuadPart; + NewSize.QuadPart += FileOffset->QuadPart + Length; + } + + /* Nagar p.544/545 + Make sure that caching is initated. + That fast are allowed for this file stream. + That we are not extending past the allocated size + That we are not creating a hole bigger than 8k + */ + if ( (FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + ((FcbHeader->ValidDataLength.QuadPart + 0x2000) > Offset.QuadPart) && + (MAXLONGLONG > (Offset.QuadPart + Length)) && + (FcbHeader->AllocationSize.QuadPart >= NewSize.QuadPart) + ) + { + /* Check if we can keep the lock shared */ + if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) { + ExReleaseResourceLite(FcbHeader->Resource); + if(!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) { + goto LeaveCriticalAndFail; + } + + /* Compute the offset and the new filesize */ + if (FileOffsetAppend) { + Offset.QuadPart = FcbHeader->FileSize.QuadPart; + NewSize.QuadPart = FcbHeader->FileSize.QuadPart + Length; + } + + /* Recheck the above points since we released and reacquire the lock */ + if ( (FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.QuadPart > NewSize.QuadPart) + ) { + /* Do nothing */ + } else { + goto FailAndCleanup; + } + } + + /* Check if we need to find out if fast I/O is available */ + if (FcbHeader->IsFastIoPossible == FastIoIsQuestionable) + { + IO_STATUS_BLOCK FastIoCheckIfPossibleStatus; + + /* Sanity check */ + ASSERT(!KeIsExecutingDpc()); + + /* Get the Fast I/O table */ + Device = IoGetRelatedDeviceObject(FileObject); + FastIoDispatch = Device->DriverObject->FastIoDispatch; + + /* Sanity check */ + ASSERT(FastIoDispatch != NULL); + ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); + + /* Ask the driver if we can do it */ + if (!FastIoDispatch->FastIoCheckIfPossible(FileObject, + FileOffsetAppend? &FcbHeader->FileSize:FileOffset, + Length, + TRUE, + LockKey, + FALSE, + &FastIoCheckIfPossibleStatus, + Device)) + { + /* It's not, fail */ + goto FailAndCleanup; + } + } + + + /* If we are going to modify the filesize, save the old fs in case the operation fails */ + if (NewSize.QuadPart > FcbHeader->FileSize.QuadPart) { + FileSizeModified = TRUE; + OldFileSize.QuadPart = FcbHeader->FileSize.QuadPart; + OldValidDataLength.QuadPart = FcbHeader->ValidDataLength.QuadPart; + + /* If the high part of the filesize is going to change, grab the Paging IoResouce */ + if (NewSize.HighPart != FcbHeader->FileSize.HighPart && FcbHeader->PagingIoResource) { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } else { + FcbHeader->FileSize.QuadPart = NewSize.QuadPart; + } + } + + /* Nagar p.544 */ + /* Set ourselves as top component */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + _SEH_TRY { + BOOLEAN CallCc = TRUE; + /* Check if there is a gap between the end of the file and the offset + If yes, then we have to zero the data + */ + if (Offset.QuadPart > FcbHeader->ValidDataLength.QuadPart) { + if (!(Result = CcZeroData(FileObject,&FcbHeader->ValidDataLength,&Offset,Wait))) { + /* If this operation fails, then we have to exit + We can jump outside the SEH, so I a using a variable to exit + normally + */ + CallCc = FALSE; + } + } + + /* Unless the CcZeroData failed, call the cache manager */ + if (CallCc) { + Result = CcCopyWrite(FileObject,&Offset,Length, Wait, Buffer); + } + }_SEH_EXCEPT(FsRtlCcCopyFilter) { + Result = FALSE; + } _SEH_END; + + /* Reset the top component */ + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + + /* Did the operation suceeded */ + if (Result) { + /* Check if we need to update the filesize */ + if (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) { + if (NewSize.HighPart != FcbHeader->ValidDataLength.HighPart && FcbHeader->PagingIoResource) { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + } else { + FcbHeader->ValidDataLength.QuadPart = NewSize.QuadPart; + } + + /* Flag the file as modified */ + FileObject->Flags |= FO_FILE_MODIFIED; + /* Check if the filesize has changed */ + if (FileSizeModified) { + /* Update the file sizes */ + ((SHARED_CACHE_MAP*) FileObject->SectionObjectPointer->SharedCacheMap)->FileSize.QuadPart = NewSize.QuadPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } + /* Update the current FO byte offset */ + FileObject->CurrentByteOffset.QuadPart = NewSize.QuadPart; + } + } + else + { + /* The operation did not succeed + Reset the file size to what it should be + */ + if (FileSizeModified) { + if (FcbHeader->PagingIoResource) { + ExAcquireResourceExclusiveLite(FcbHeader->PagingIoResource, TRUE); + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + ExReleaseResourceLite(FcbHeader->PagingIoResource); + }else{ + FcbHeader->FileSize.QuadPart = OldFileSize.QuadPart; + FcbHeader->ValidDataLength.QuadPart = OldValidDataLength.QuadPart; + } + } + } + goto Cleanup; + } else { + goto FailAndCleanup; + } + + ASSERT(0); + } + +LeaveCriticalAndFail: + FsRtlExitFileSystem(); + return FALSE; + + +FailAndCleanup: + + ExReleaseResourceLite(FcbHeader->Resource); + FsRtlExitFileSystem(); + return FALSE; + +Cleanup: + + ExReleaseResourceLite(FcbHeader->Resource); + FsRtlExitFileSystem(); + return Result; +}
/* * @implemented