Author: dgorbachev Date: Mon Nov 16 02:56:48 2009 New Revision: 44196
URL: http://svn.reactos.org/svn/reactos?rev=44196&view=rev Log: Break long expressions, fix formatting.
Modified: trunk/reactos/ntoskrnl/fsrtl/fastio.c
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 [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/fsrtl/fastio.c [iso-8859-1] Mon Nov 16 02:56:48 2009 @@ -74,9 +74,9 @@ PFAST_IO_DISPATCH FastIoDispatch; PDEVICE_OBJECT Device; BOOLEAN Result = TRUE; - ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(FileOffset,Length); - - PAGED_CODE(); + ULONG PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(FileOffset, Length); + + PAGED_CODE(); ASSERT(FileObject); ASSERT(FileObject->FsContext);
@@ -89,41 +89,45 @@ return TRUE; }
- if (MAXLONGLONG < (LONGLONG) FileOffset->QuadPart + Length) { - IoStatus->Status = STATUS_INVALID_PARAMETER; - IoStatus->Information = 0; - return FALSE; + 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) { + if (Wait) + { /* Use a Resource Acquire */ FsRtlEnterFileSystem(); - CcFastReadWait++; + 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 */ + } + 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; - } - } - + 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)) { + (FcbHeader->IsFastIoPossible == FastIoIsNotPossible)) + { /* It's not, so fail */ - Result = FALSE; - goto Cleanup; + Result = FALSE; + goto Cleanup; }
/* Check if we need to find out if fast I/O is available */ @@ -134,7 +138,7 @@
/* Get the Fast I/O table */ Device = IoGetRelatedDeviceObject(FileObject); - FastIoDispatch = Device->DriverObject->FastIoDispatch; + FastIoDispatch = Device->DriverObject->FastIoDispatch;
/* Sanity check */ ASSERT(FastIoDispatch != NULL); @@ -154,12 +158,14 @@ Result = FALSE; goto Cleanup; } - } + }
/* Check if we read too much */ - if (Offset.QuadPart > FcbHeader->FileSize.QuadPart){ + if (Offset.QuadPart > FcbHeader->FileSize.QuadPart) + { /* We did, check if the file offset is past the end */ - if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart){ + if (FileOffset->QuadPart >= FcbHeader->FileSize.QuadPart) + { /* Set end of file */ IoStatus->Status = STATUS_END_OF_FILE; IoStatus->Information = 0; @@ -171,45 +177,67 @@ }
/* Set this as top-level IRP */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; - - _SEH2_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 { + PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + + _SEH2_TRY + { + /* Make sure the IO and file size is below 4GB */ + if (Wait && !(Offset.HighPart | FcbHeader->FileSize.HighPart)) + {
/* Call the cache controller */ - Result = CcCopyRead(FileObject, FileOffset, Length, Wait,Buffer, IoStatus); + CcFastCopyRead(FileObject, + FileOffset->LowPart, + Length, + PageCount, + 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) - ); - } - } + 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; - } - } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; - - PsGetCurrentThread()->TopLevelIrp = 0; + if (Result == TRUE) + { + FileObject->CurrentByteOffset.QuadPart += IoStatus->Information; + } + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END; + + PsGetCurrentThread()->TopLevelIrp = 0;
/* Return to caller */ Cleanup: @@ -217,12 +245,12 @@ ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem();
- if (Result == FALSE) { + if (Result == FALSE) + { CcFastReadNotPossible += 1; - } + }
return Result; - }
@@ -240,22 +268,23 @@ OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject) { - 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 == (LONG)0xffffffff) && (FileOffset->LowPart == 0xffffffff)); + PSHARED_CACHE_MAP SharedCacheMap; + + /* WDK doc. + * Offset == 0xffffffffffffffff indicates append to the end of file. + */ + BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)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;
@@ -269,13 +298,14 @@ 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; + /* 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 */ @@ -288,385 +318,477 @@
FsRtlEnterFileSystem();
- /* Nagar p.544/545 -- The CcFastCopyWrite doesn't deal with filesize beyond 4GB*/ + /* 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); - } + /* 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; - - _SEH2_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); - } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + if ((FileObject->PrivateCacheMap != NULL) && + (FcbHeader->IsFastIoPossible != FastIoIsNotPossible) && + (FcbHeader->AllocationSize.LowPart >= NewSize.LowPart) && + (FcbHeader->AllocationSize.HighPart == 0) && + !b_4GB) + { + /* Do nothing? */ + } + 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; + + _SEH2_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); + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_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 ; - } + 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; - } + FileObject->Flags |= FO_FILE_MODIFIED; + + /* Update the strucutres if the file size changed */ + if (FileSizeModified) + { + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + 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 LeaveCriticalAndFail; - } - ResourceAquiredShared =TRUE; - } else { - /* Acquire the resource exclusive */ - if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource,Wait)) { - goto LeaveCriticalAndFail; - } - } - - /* 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; - } + 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 + { + /* Do nothing? */ + } + } + + 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 LeaveCriticalAndFail; + } + ResourceAquiredShared = TRUE; + } + else + { + /* Acquire the resource exclusive */ + if (!ExAcquireResourceExclusiveLite(FcbHeader->Resource, Wait)) + { + goto LeaveCriticalAndFail; + } + } + + /* 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; - _SEH2_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; - } - } + 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; + + _SEH2_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); - } - }_SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + if (CallCc) + { + Result = CcCopyWrite(FileObject, &Offset, Length, Wait, Buffer); + } + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END;
/* Reset the top component */ - PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; + 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; - } - } + 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); - } + FileObject->Flags |= FO_FILE_MODIFIED; + + /* Check if the filesize has changed */ + if (FileSizeModified) + { + /* Update the file sizes */ + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + 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; + } + }
LeaveCriticalAndFail: + FsRtlExitFileSystem(); return FALSE; -
FailAndCleanup:
@@ -686,7 +808,7 @@ */ NTSTATUS NTAPI -FsRtlGetFileSize(IN PFILE_OBJECT FileObject, +FsRtlGetFileSize(IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize) { FILE_STANDARD_INFORMATION Info; @@ -699,30 +821,35 @@ PIRP Irp; BOOLEAN OldHardError;
- PAGED_CODE();
/* Get Device Object and Fast Calls */ DeviceObject = IoGetRelatedDeviceObject(FileObject); FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
- /* Check if we support Fast Calls, and check FastIoQueryStandardInfo */ - /* Call the function and see if it succeeds */ - if ( !FastDispatch || - !FastDispatch->FastIoQueryStandardInfo || - !FastDispatch->FastIoQueryStandardInfo(FileObject,TRUE, - &Info,&IoStatus,DeviceObject)) - { - /* If any of the above failed, then we are going to send an IRP to the device object */ - /* Initialize the even for the IO */ - KeInitializeEvent(&Event,NotificationEvent,FALSE); + /* Check if we support Fast Calls, and check FastIoQueryStandardInfo. + * Call the function and see if it succeeds. + */ + if (!FastDispatch || + !FastDispatch->FastIoQueryStandardInfo || + !FastDispatch->FastIoQueryStandardInfo(FileObject, + TRUE, + &Info, + &IoStatus, + DeviceObject)) + { + /* If any of the above failed, then we are going to send an + * IRP to the device object. Initialize the event for the IO. + */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + /* Allocate the IRP */ - Irp = IoAllocateIrp(DeviceObject->StackSize,FALSE); + Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); + if (Irp == NULL) { return STATUS_INSUFFICIENT_RESOURCES; } -
/* Don't process hard error */ OldHardError = IoSetThreadHardErrorMode(FALSE); @@ -742,16 +869,18 @@ IoStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION; IoStackLocation->FileObject = FileObject; IoStackLocation->DeviceObject = DeviceObject; - IoStackLocation->Parameters.QueryFile.Length = ALIGN_UP(sizeof(FILE_INFORMATION_CLASS),ULONG); - IoStackLocation->Parameters.QueryFile.FileInformationClass = FileStandardInformation; + IoStackLocation->Parameters.QueryFile.Length = + ALIGN_UP(sizeof(FILE_INFORMATION_CLASS), ULONG); + IoStackLocation->Parameters.QueryFile.FileInformationClass = + FileStandardInformation;
/* Send the IRP to the related device object */ - Status = IoCallDriver(DeviceObject,Irp); + Status = IoCallDriver(DeviceObject, Irp);
/* Standard DDK IRP result processing */ if (Status == STATUS_PENDING) { - KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL); + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); }
/* If there was a synchronous error, signal it */ @@ -766,7 +895,7 @@ /* Check the sync/async IO result */ if (NT_SUCCESS(IoStatus.Status)) { - /* Was the request for a directory ? */ + /* Was the request for a directory? */ if (Info.Directory) { IoStatus.Status = STATUS_FILE_IS_A_DIRECTORY; @@ -779,7 +908,6 @@
return IoStatus.Status; } -
/* * @implemented @@ -818,8 +946,7 @@ FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
/* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlRead && - BaseDeviceObject != DeviceObject) + if (FastDispatch && FastDispatch->MdlRead && BaseDeviceObject != DeviceObject) { return FALSE; } @@ -853,9 +980,7 @@ if (FastDispatch && FastDispatch->MdlReadComplete) { /* Use the fast path */ - return FastDispatch->MdlReadComplete(FileObject, - MdlChain, - DeviceObject); + return FastDispatch->MdlReadComplete(FileObject, MdlChain, DeviceObject); }
/* Get the Base File System (Volume) and Fast Calls */ @@ -863,8 +988,9 @@ FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
/* If the Base Device Object has its own FastDispatch Routine, fail */ - if ((BaseDeviceObject != DeviceObject) && FastDispatch - && FastDispatch->MdlReadComplete) + if ((BaseDeviceObject != DeviceObject) && + FastDispatch && + FastDispatch->MdlReadComplete) { return FALSE; } @@ -876,8 +1002,8 @@ /* * @implemented */ - BOOLEAN - NTAPI +BOOLEAN +NTAPI FsRtlMdlReadCompleteDev(IN PFILE_OBJECT FileObject, IN PMDL MemoryDescriptorList, IN PDEVICE_OBJECT DeviceObject) @@ -886,7 +1012,6 @@ CcMdlReadComplete2(MemoryDescriptorList, FileObject); return TRUE; } -
/* * @implemented @@ -995,10 +1120,13 @@ CcMdlRead(FileObject, FileOffset, Length, MdlChain, IoStatus); FileObject->Flags |= FO_FILE_FAST_IO_READ; } - _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END;
/* Remove the top-level IRP flag */ @@ -1006,8 +1134,10 @@
/* Return to caller */ Cleanup: + ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem(); + return Result; }
@@ -1042,7 +1172,8 @@ FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
/* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->MdlWriteComplete && + if (FastDispatch && + FastDispatch->MdlWriteComplete && BaseDeviceObject != DeviceObject) { return FALSE; @@ -1067,12 +1198,11 @@ { if (FileObject->Flags & FO_WRITE_THROUGH) { - return FALSE; - } - + return FALSE; + }
/* Call the Cache Manager */ - CcMdlWriteComplete2(FileObject,FileOffset,MdlChain); + CcMdlWriteComplete2(FileObject, FileOffset, MdlChain); return TRUE; }
@@ -1113,7 +1243,8 @@ FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
/* If the Base Device Object has its own FastDispatch Routine, fail */ - if (FastDispatch && FastDispatch->PrepareMdlWrite && + if (FastDispatch && + FastDispatch->PrepareMdlWrite && BaseDeviceObject != DeviceObject) { return FALSE; @@ -1146,14 +1277,19 @@ PFAST_IO_DISPATCH FastIoDispatch; PDEVICE_OBJECT Device; PFSRTL_COMMON_FCB_HEADER FcbHeader; + PSHARED_CACHE_MAP SharedCacheMap;
LARGE_INTEGER OldFileSize; LARGE_INTEGER OldValidDataLength; LARGE_INTEGER NewSize; LARGE_INTEGER Offset;
- /* WDK doc. Offset=0xffffffffffffffff indicates append to the end of file */ - BOOLEAN FileOffsetAppend = ((FileOffset->HighPart == (LONG)0xffffffff) && (FileOffset->LowPart == 0xffffffff)); + /* WDK doc. + * Offset == 0xffffffffffffffff indicates append to the end of file. + */ + BOOLEAN FileOffsetAppend = (FileOffset->HighPart == (LONG)0xffffffff) && + (FileOffset->LowPart == 0xffffffff); + BOOLEAN FileSizeModified = FALSE; BOOLEAN ResourceAquiredShared = FALSE;
@@ -1165,11 +1301,13 @@
Offset.QuadPart = FileOffset->QuadPart + Length;
- /* Nagar p.544 -- Check with Cc if we can write */ - if ( (!CcCanIWrite(FileObject, Length,TRUE,FALSE))|| - (FileObject->Flags & FO_WRITE_THROUGH)) - { - return FALSE; + /* Nagar p.544. + * Check with Cc if we can write. + */ + if (!CcCanIWrite(FileObject, Length, TRUE, FALSE) || + (FileObject->Flags & FO_WRITE_THROUGH)) + { + return FALSE; }
IoStatus->Status = STATUS_SUCCESS; @@ -1184,180 +1322,218 @@ FsRtlEnterFileSystem();
/* Check we are going to extend the file */ - if ( (FileOffsetAppend == FALSE) && - ( (FileOffset->QuadPart + Length) <= FcbHeader->ValidDataLength.QuadPart ) - ) - { - /* Acquire the resource shared */ - ExAcquireResourceSharedLite(FcbHeader->Resource,TRUE); - ResourceAquiredShared =TRUE; - } else - { - /* Acquire the resource exclusive */ - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); - } - - /* 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; - } - - if ( (FileObject->PrivateCacheMap) && - (FcbHeader->IsFastIoPossible) && - (MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) && - (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart) ) + if ((FileOffsetAppend == FALSE) && + (FileOffset->QuadPart + Length <= FcbHeader->ValidDataLength.QuadPart)) + { + /* Acquire the resource shared */ + ExAcquireResourceSharedLite(FcbHeader->Resource, TRUE); + ResourceAquiredShared = TRUE; + } + else + { + /* Acquire the resource exclusive */ + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE); + } + + /* 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; + } + + if ((FileObject->PrivateCacheMap) && + (FcbHeader->IsFastIoPossible) && + (MAXLONGLONG >= (LONGLONG) FileOffset->QuadPart + Length) && + (NewSize.QuadPart <= FcbHeader->AllocationSize.QuadPart)) { /* Check if we can keep the lock shared */ - if (ResourceAquiredShared && (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart) ) { - ExReleaseResourceLite(FcbHeader->Resource); - ExAcquireResourceExclusiveLite(FcbHeader->Resource,TRUE); + if (ResourceAquiredShared && + (NewSize.QuadPart > FcbHeader->ValidDataLength.QuadPart)) + { + ExReleaseResourceLite(FcbHeader->Resource); + ExAcquireResourceExclusiveLite(FcbHeader->Resource, TRUE);
/* 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) - { - /* 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, - FALSE, - IoStatus, - 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; - _SEH2_TRY - { - /* 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) { - Result = CcZeroData(FileObject,&FcbHeader->ValidDataLength,&Offset,TRUE); - if (Result) - { - CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus); - } - } else { - CcPrepareMdlWrite(FileObject,&Offset,Length,MdlChain,IoStatus); - } - - }_SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) - { - Result = FALSE; - } _SEH2_END; + 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) + { + /* 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, + FALSE, + IoStatus, + 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; + _SEH2_TRY + { + /* 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) + { + Result = CcZeroData(FileObject, + &FcbHeader->ValidDataLength, + &Offset, + TRUE); + if (Result) + { + CcPrepareMdlWrite(FileObject, + &Offset, + Length, + MdlChain, + IoStatus); + } + } + else + { + CcPrepareMdlWrite(FileObject, &Offset, Length, MdlChain, IoStatus); + } + + } + _SEH2_EXCEPT(FsRtlIsNtstatusExpected(_SEH2_GetExceptionCode()) ? + EXCEPTION_EXECUTE_HANDLER : + EXCEPTION_CONTINUE_SEARCH) + { + Result = FALSE; + } + _SEH2_END;
/* Reset the top component */ - PsGetCurrentThread()->TopLevelIrp = 0; + PsGetCurrentThread()->TopLevelIrp = 0;
/* 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; - } - } + 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; - } - - } - 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; - + FileObject->Flags |= FO_FILE_MODIFIED; + + /* Check if the filesize has changed */ + if (FileSizeModified) + { + SharedCacheMap = + (PSHARED_CACHE_MAP)FileObject->SectionObjectPointer->SharedCacheMap; + SharedCacheMap->FileSize.QuadPart = NewSize.QuadPart; + FileObject->Flags |= FO_FILE_SIZE_CHANGED; + } + } + 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; } -
FailAndCleanup:
@@ -1370,7 +1546,6 @@ ExReleaseResourceLite(FcbHeader->Resource); FsRtlExitFileSystem(); return Result; - }
/* @@ -1380,10 +1555,8 @@ NTAPI FsRtlAcquireFileExclusive(IN PFILE_OBJECT FileObject) { - /* - PAGED_CODE(); - FsRtlAcquireFileExclusiveCommon(FileObject,0,0); - */ + /* PAGED_CODE(); */ + /* FsRtlAcquireFileExclusiveCommon(FileObject, 0, 0); */ KeBugCheck(FILE_SYSTEM); }
@@ -1394,7 +1567,6 @@ NTAPI FsRtlReleaseFile(IN PFILE_OBJECT FileObject) { - KeBugCheck(FILE_SYSTEM); }
@@ -1423,4 +1595,3 @@ UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED; } -